From 3d1a194ff9e76f25f1a7242ff2d021523ba8e4a0 Mon Sep 17 00:00:00 2001 From: tomlu Date: Wed, 29 Nov 2017 14:01:21 -0800 Subject: Add ActionKeyContext to Action#getKey. This key context can be used by actions to share partial key computations, for instance when computing MD5s for nested sets. RELNOTES: None PiperOrigin-RevId: 177359607 --- .../devtools/build/lib/actions/AbstractAction.java | 16 +++++---- .../google/devtools/build/lib/actions/Action.java | 3 +- .../build/lib/actions/ActionCacheChecker.java | 8 +++-- .../build/lib/actions/ActionExecutionContext.java | 12 +++++++ .../build/lib/actions/ActionExecutionMetadata.java | 32 +++++++++-------- .../build/lib/actions/ActionKeyContext.java | 41 ++++++++++++++++++++++ .../build/lib/actions/ActionLookupValue.java | 19 ++++++---- .../google/devtools/build/lib/actions/Actions.java | 25 ++++++++----- .../com/google/devtools/build/lib/actions/BUILD | 1 + .../devtools/build/lib/actions/FailAction.java | 2 +- .../build/lib/actions/MapBasedActionGraph.java | 22 ++++++++---- .../build/lib/actions/MiddlemanAction.java | 2 +- .../build/lib/actions/MutableActionGraph.java | 22 +++++++----- 13 files changed, 148 insertions(+), 57 deletions(-) create mode 100644 src/main/java/com/google/devtools/build/lib/actions/ActionKeyContext.java (limited to 'src/main/java/com/google/devtools/build/lib/actions') diff --git a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java index d1d805fcd5..04f74585c2 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java +++ b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java @@ -295,16 +295,17 @@ public abstract class AbstractAction implements Action, SkylarkValue { /** * See the javadoc for {@link com.google.devtools.build.lib.actions.Action} and {@link - * com.google.devtools.build.lib.actions.ActionExecutionMetadata#getKey()} for the contract for - * {@link #computeKey()}. + * ActionExecutionMetadata#getKey(ActionKeyContext)} for the contract for {@link + * #computeKey(ActionKeyContext)}. */ - protected abstract String computeKey() throws CommandLineExpansionException; + protected abstract String computeKey(ActionKeyContext actionKeyContext) + throws CommandLineExpansionException; @Override - public final synchronized String getKey() { + public final synchronized String getKey(ActionKeyContext actionKeyContext) { if (cachedKey == null) { try { - cachedKey = computeKey(); + cachedKey = computeKey(actionKeyContext); } catch (CommandLineExpansionException e) { cachedKey = KEY_ERROR; } @@ -481,12 +482,13 @@ public abstract class AbstractAction implements Action, SkylarkValue { } @Override - public ExtraActionInfo.Builder getExtraActionInfo() throws CommandLineExpansionException { + public ExtraActionInfo.Builder getExtraActionInfo(ActionKeyContext actionKeyContext) + throws CommandLineExpansionException { ActionOwner owner = getOwner(); ExtraActionInfo.Builder result = ExtraActionInfo.newBuilder() .setOwner(owner.getLabel().toString()) - .setId(getKey()) + .setId(getKey(actionKeyContext)) .setMnemonic(getMnemonic()); Iterable aspectDescriptors = owner.getAspectDescriptors(); AspectDescriptor lastAspect = null; diff --git a/src/main/java/com/google/devtools/build/lib/actions/Action.java b/src/main/java/com/google/devtools/build/lib/actions/Action.java index e1c1b35cff..217ce5d59d 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/Action.java +++ b/src/main/java/com/google/devtools/build/lib/actions/Action.java @@ -192,5 +192,6 @@ public interface Action extends ActionExecutionMetadata, Describable { *

As this method is called from the ExtraAction, make sure it is ok to call this method from a * different thread than the one this action is executed on. */ - ExtraActionInfo.Builder getExtraActionInfo() throws CommandLineExpansionException; + ExtraActionInfo.Builder getExtraActionInfo(ActionKeyContext actionKeyContext) + throws CommandLineExpansionException; } diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java b/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java index 8a49c9c40c..8e4dc88a46 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionCacheChecker.java @@ -74,6 +74,7 @@ public class ActionCacheChecker { }; private final ActionCache actionCache; + private final ActionKeyContext actionKeyContext; private final Predicate executionFilter; private final ArtifactResolver artifactResolver; private final CacheConfig cacheConfig; @@ -103,10 +104,12 @@ public class ActionCacheChecker { public ActionCacheChecker( ActionCache actionCache, ArtifactResolver artifactResolver, + ActionKeyContext actionKeyContext, Predicate executionFilter, @Nullable CacheConfig cacheConfig) { this.actionCache = actionCache; this.executionFilter = executionFilter; + this.actionKeyContext = actionKeyContext; this.artifactResolver = artifactResolver; this.cacheConfig = cacheConfig != null @@ -303,7 +306,7 @@ public class ActionCacheChecker { reportChanged(handler, action); actionCache.accountMiss(MissReason.DIFFERENT_FILES); return true; - } else if (!entry.getActionKey().equals(action.getKey())) { + } else if (!entry.getActionKey().equals(action.getKey(actionKeyContext))) { reportCommand(handler, action); actionCache.accountMiss(MissReason.DIFFERENT_ACTION_KEY); return true; @@ -356,7 +359,8 @@ public class ActionCacheChecker { } Map usedClientEnv = computeUsedClientEnv(action, clientEnv); ActionCache.Entry entry = - new ActionCache.Entry(action.getKey(), usedClientEnv, action.discoversInputs()); + new ActionCache.Entry( + action.getKey(actionKeyContext), usedClientEnv, action.discoversInputs()); for (Artifact output : action.getOutputs()) { // Remove old records from the cache if they used different key. String execPath = output.getExecPathString(); diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java index fc8a6bfb47..f356559a86 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java @@ -43,6 +43,7 @@ public class ActionExecutionContext implements Closeable { private final Executor executor; private final ActionInputFileCache actionInputFileCache; private final ActionInputPrefetcher actionInputPrefetcher; + private final ActionKeyContext actionKeyContext; private final MetadataHandler metadataHandler; private final FileOutErr fileOutErr; private final ImmutableMap clientEnv; @@ -54,6 +55,7 @@ public class ActionExecutionContext implements Closeable { Executor executor, ActionInputFileCache actionInputFileCache, ActionInputPrefetcher actionInputPrefetcher, + ActionKeyContext actionKeyContext, MetadataHandler metadataHandler, FileOutErr fileOutErr, Map clientEnv, @@ -61,6 +63,7 @@ public class ActionExecutionContext implements Closeable { @Nullable SkyFunction.Environment env) { this.actionInputFileCache = actionInputFileCache; this.actionInputPrefetcher = actionInputPrefetcher; + this.actionKeyContext = actionKeyContext; this.metadataHandler = metadataHandler; this.fileOutErr = fileOutErr; this.clientEnv = ImmutableMap.copyOf(clientEnv); @@ -73,6 +76,7 @@ public class ActionExecutionContext implements Closeable { Executor executor, ActionInputFileCache actionInputFileCache, ActionInputPrefetcher actionInputPrefetcher, + ActionKeyContext actionKeyContext, MetadataHandler metadataHandler, FileOutErr fileOutErr, Map clientEnv, @@ -81,6 +85,7 @@ public class ActionExecutionContext implements Closeable { executor, actionInputFileCache, actionInputPrefetcher, + actionKeyContext, metadataHandler, fileOutErr, clientEnv, @@ -92,6 +97,7 @@ public class ActionExecutionContext implements Closeable { Executor executor, ActionInputFileCache actionInputFileCache, ActionInputPrefetcher actionInputPrefetcher, + ActionKeyContext actionKeyContext, MetadataHandler metadataHandler, FileOutErr fileOutErr, Map clientEnv, @@ -100,6 +106,7 @@ public class ActionExecutionContext implements Closeable { executor, actionInputFileCache, actionInputPrefetcher, + actionKeyContext, metadataHandler, fileOutErr, clientEnv, @@ -216,6 +223,10 @@ public class ActionExecutionContext implements Closeable { return Preconditions.checkNotNull(env); } + public ActionKeyContext getActionKeyContext() { + return actionKeyContext; + } + @Override public void close() throws IOException { fileOutErr.close(); @@ -230,6 +241,7 @@ public class ActionExecutionContext implements Closeable { executor, actionInputFileCache, actionInputPrefetcher, + actionKeyContext, metadataHandler, fileOutErr, clientEnv, diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionMetadata.java b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionMetadata.java index 7f4b569b13..ec94b6c72a 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionMetadata.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionExecutionMetadata.java @@ -59,35 +59,36 @@ public interface ActionExecutionMetadata extends ActionAnalysisMetadata { *

Examples of changes that should affect the key are: * *

*/ - String getKey(); + String getKey(ActionKeyContext actionKeyContext); /** - * Returns a human-readable description of the inputs to {@link #getKey()}. - * Used in the output from '--explain', and in error messages for - * '--check_up_to_date' and '--check_tests_up_to_date'. - * May return null, meaning no extra information is available. + * Returns a human-readable description of the inputs to {@link #getKey(ActionKeyContext)}. Used + * in the output from '--explain', and in error messages for '--check_up_to_date' and + * '--check_tests_up_to_date'. May return null, meaning no extra information is available. * *

If the return value is non-null, for consistency it should be a multiline message of the * form: + * *

    *   Summary
    *     Fieldname: value
    *     Fieldname: value
    *     ...
    * 
+ * * where each line after the first one is intended two spaces, and where any fields that might * contain newlines or other funny characters are escaped using {@link - * com.google.devtools.build.lib.shell.ShellUtils#shellEscape}. - * For example: + * com.google.devtools.build.lib.shell.ShellUtils#shellEscape}. For example: + * *
    *   Compiling foo.cc
    *     Command: /usr/bin/gcc
@@ -97,7 +98,8 @@ public interface ActionExecutionMetadata extends ActionAnalysisMetadata {
    *     Argument: foo.o
    * 
*/ - @Nullable String describeKey(); + @Nullable + String describeKey(); /** * Get the {@link RunfilesSupplier} providing runfiles needed by this action. diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionKeyContext.java b/src/main/java/com/google/devtools/build/lib/actions/ActionKeyContext.java new file mode 100644 index 0000000000..6ba29a7655 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionKeyContext.java @@ -0,0 +1,41 @@ +// Copyright 2017 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.actions; + +import com.google.devtools.build.lib.collect.nestedset.NestedSet; +import com.google.devtools.build.lib.collect.nestedset.NestedSetFingerprintCache; +import com.google.devtools.build.lib.util.Fingerprint; + +/** Contains state that aids in action key computation via {@link AbstractAction#computeKey}. */ +public class ActionKeyContext { + private static final class ArtifactNestedSetFingerprintCache + extends NestedSetFingerprintCache { + @Override + protected void addItemFingerprint(Fingerprint fingerprint, Artifact item) { + fingerprint.addPath(item.getExecPath()); + } + } + + private final ArtifactNestedSetFingerprintCache artifactNestedSetFingerprintCache = + new ArtifactNestedSetFingerprintCache(); + + public void addArtifactsToFingerprint(Fingerprint fingerprint, NestedSet artifacts) { + artifactNestedSetFingerprintCache.addNestedSetToFingerprint(fingerprint, artifacts); + } + + public void clear() { + artifactNestedSetFingerprintCache.clear(); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java b/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java index bf6e3a0099..ffe650a19b 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ActionLookupValue.java @@ -42,9 +42,9 @@ public class ActionLookupValue implements SkyValue { private final ImmutableMap generatingActionIndex; private static Actions.GeneratingActions filterSharedActionsAndThrowRuntimeIfConflict( - List actions) { + ActionKeyContext actionKeyContext, List actions) { try { - return Actions.filterSharedActionsAndThrowActionConflict(actions); + return Actions.filterSharedActionsAndThrowActionConflict(actionKeyContext, actions); } catch (ActionConflictException e) { // Programming bug. throw new IllegalStateException(e); @@ -53,12 +53,19 @@ public class ActionLookupValue implements SkyValue { @VisibleForTesting public ActionLookupValue( - List actions, boolean removeActionsAfterEvaluation) { - this(filterSharedActionsAndThrowRuntimeIfConflict(actions), removeActionsAfterEvaluation); + ActionKeyContext actionKeyContext, + List actions, + boolean removeActionsAfterEvaluation) { + this( + filterSharedActionsAndThrowRuntimeIfConflict(actionKeyContext, actions), + removeActionsAfterEvaluation); } - protected ActionLookupValue(ActionAnalysisMetadata action, boolean removeActionAfterEvaluation) { - this(ImmutableList.of(action), removeActionAfterEvaluation); + protected ActionLookupValue( + ActionKeyContext actionKeyContext, + ActionAnalysisMetadata action, + boolean removeActionAfterEvaluation) { + this(actionKeyContext, ImmutableList.of(action), removeActionAfterEvaluation); } protected ActionLookupValue( diff --git a/src/main/java/com/google/devtools/build/lib/actions/Actions.java b/src/main/java/com/google/devtools/build/lib/actions/Actions.java index 4acd7fefd7..91438261c7 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/Actions.java +++ b/src/main/java/com/google/devtools/build/lib/actions/Actions.java @@ -54,7 +54,8 @@ public final class Actions { *

This method implements an equivalence relationship across actions, based on the action * class, the key, and the list of inputs and outputs. */ - public static boolean canBeShared(ActionAnalysisMetadata a, ActionAnalysisMetadata b) { + public static boolean canBeShared( + ActionKeyContext actionKeyContext, ActionAnalysisMetadata a, ActionAnalysisMetadata b) { if (!a.getMnemonic().equals(b.getMnemonic())) { return false; } @@ -66,7 +67,7 @@ public final class Actions { Action actionA = (Action) a; Action actionB = (Action) b; - if (!actionA.getKey().equals(actionB.getKey())) { + if (!actionA.getKey(actionKeyContext).equals(actionB.getKey(actionKeyContext))) { return false; } // Don't bother to check input and output counts first; the expected result for these tests is @@ -89,10 +90,11 @@ public final class Actions { * of indirection. * @throws ActionConflictException iff there are two actions generate the same output */ - public static GeneratingActions findAndThrowActionConflict(List actions) + public static GeneratingActions findAndThrowActionConflict( + ActionKeyContext actionKeyContext, List actions) throws ActionConflictException { return Actions.maybeFilterSharedActionsAndThrowIfConflict( - actions, /*allowSharedAction=*/ false); + actionKeyContext, actions, /*allowSharedAction=*/ false); } /** @@ -106,13 +108,16 @@ public final class Actions { * output */ public static GeneratingActions filterSharedActionsAndThrowActionConflict( - List actions) throws ActionConflictException { + ActionKeyContext actionKeyContext, List actions) + throws ActionConflictException { return Actions.maybeFilterSharedActionsAndThrowIfConflict( - actions, /*allowSharedAction=*/ true); + actionKeyContext, actions, /*allowSharedAction=*/ true); } private static GeneratingActions maybeFilterSharedActionsAndThrowIfConflict( - List actions, boolean allowSharedAction) + ActionKeyContext actionKeyContext, + List actions, + boolean allowSharedAction) throws ActionConflictException { Map generatingActions = new HashMap<>(); int actionIndex = 0; @@ -120,8 +125,10 @@ public final class Actions { for (Artifact artifact : action.getOutputs()) { Integer previousIndex = generatingActions.put(artifact, actionIndex); if (previousIndex != null && previousIndex != actionIndex) { - if (!allowSharedAction || !Actions.canBeShared(actions.get(previousIndex), action)) { - throw new ActionConflictException(artifact, actions.get(previousIndex), action); + if (!allowSharedAction + || !Actions.canBeShared(actionKeyContext, actions.get(previousIndex), action)) { + throw new ActionConflictException( + actionKeyContext, artifact, actions.get(previousIndex), action); } } } diff --git a/src/main/java/com/google/devtools/build/lib/actions/BUILD b/src/main/java/com/google/devtools/build/lib/actions/BUILD index f481e5f257..9b8d8bc600 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/BUILD +++ b/src/main/java/com/google/devtools/build/lib/actions/BUILD @@ -28,6 +28,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/causes", "//src/main/java/com/google/devtools/build/lib/collect", "//src/main/java/com/google/devtools/build/lib/collect/nestedset", + "//src/main/java/com/google/devtools/build/lib/collect/nestedset:fingerprint_cache", "//src/main/java/com/google/devtools/build/lib/concurrent", "//src/main/java/com/google/devtools/build/lib/profiler", "//src/main/java/com/google/devtools/build/lib/shell", diff --git a/src/main/java/com/google/devtools/build/lib/actions/FailAction.java b/src/main/java/com/google/devtools/build/lib/actions/FailAction.java index 7f217409c8..86c22e0855 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/FailAction.java +++ b/src/main/java/com/google/devtools/build/lib/actions/FailAction.java @@ -45,7 +45,7 @@ public final class FailAction extends AbstractAction { } @Override - protected String computeKey() { + protected String computeKey(ActionKeyContext actionKeyContext) { return GUID; } diff --git a/src/main/java/com/google/devtools/build/lib/actions/MapBasedActionGraph.java b/src/main/java/com/google/devtools/build/lib/actions/MapBasedActionGraph.java index 9b27881aa6..f35f963bf7 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/MapBasedActionGraph.java +++ b/src/main/java/com/google/devtools/build/lib/actions/MapBasedActionGraph.java @@ -23,9 +23,14 @@ import javax.annotation.concurrent.ThreadSafe; */ @ThreadSafe public final class MapBasedActionGraph implements MutableActionGraph { + private final ActionKeyContext actionKeyContext; private final ConcurrentMultimapWithHeadElement generatingActionMap = new ConcurrentMultimapWithHeadElement<>(); + public MapBasedActionGraph(ActionKeyContext actionKeyContext) { + this.actionKeyContext = actionKeyContext; + } + @Override @Nullable public ActionAnalysisMetadata getGeneratingAction(Artifact artifact) { @@ -36,10 +41,11 @@ public final class MapBasedActionGraph implements MutableActionGraph { public void registerAction(ActionAnalysisMetadata action) throws ActionConflictException { for (Artifact artifact : action.getOutputs()) { ActionAnalysisMetadata previousAction = generatingActionMap.putAndGet(artifact, action); - if (previousAction != null && previousAction != action - && !Actions.canBeShared(action, previousAction)) { + if (previousAction != null + && previousAction != action + && !Actions.canBeShared(actionKeyContext, action, previousAction)) { generatingActionMap.remove(artifact, action); - throw new ActionConflictException(artifact, previousAction, action); + throw new ActionConflictException(actionKeyContext, artifact, previousAction, action); } } } @@ -49,9 +55,13 @@ public final class MapBasedActionGraph implements MutableActionGraph { for (Artifact artifact : action.getOutputs()) { generatingActionMap.remove(artifact, action); ActionAnalysisMetadata otherAction = generatingActionMap.get(artifact); - Preconditions.checkState(otherAction == null - || (otherAction != action && Actions.canBeShared(action, otherAction)), - "%s %s", action, otherAction); + Preconditions.checkState( + otherAction == null + || (otherAction != action + && Actions.canBeShared(actionKeyContext, action, otherAction)), + "%s %s", + action, + otherAction); } } diff --git a/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java b/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java index f0c5972c6a..787f05248d 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java +++ b/src/main/java/com/google/devtools/build/lib/actions/MiddlemanAction.java @@ -56,7 +56,7 @@ public final class MiddlemanAction extends AbstractAction { } @Override - protected String computeKey() { + protected String computeKey(ActionKeyContext actionKeyContext) { // TODO(bazel-team): Need to take middlemanType into account here. // Only the set of inputs matters, and the dependency checker is // responsible for considering those. diff --git a/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java b/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java index 1b1955a5e5..24a74ad28c 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java +++ b/src/main/java/com/google/devtools/build/lib/actions/MutableActionGraph.java @@ -61,15 +61,19 @@ public interface MutableActionGraph extends ActionGraph { * about the artifact for which the conflict is found, and data about the two conflicting actions * and their owners. */ - public static final class ActionConflictException extends Exception { + final class ActionConflictException extends Exception { + private final ActionKeyContext actionKeyContext; private final Artifact artifact; private final ActionAnalysisMetadata previousAction; private final ActionAnalysisMetadata attemptedAction; private static final int MAX_DIFF_ARTIFACTS_TO_REPORT = 5; - public ActionConflictException(Artifact artifact, ActionAnalysisMetadata previousAction, + public ActionConflictException( + ActionKeyContext actionKeyContext, + Artifact artifact, + ActionAnalysisMetadata previousAction, ActionAnalysisMetadata attemptedAction) { super( String.format( @@ -77,6 +81,7 @@ public interface MutableActionGraph extends ActionGraph { artifact.prettyPrint(), previousAction.prettyPrint(), attemptedAction.prettyPrint())); + this.actionKeyContext = actionKeyContext; this.artifact = artifact; this.previousAction = previousAction; this.attemptedAction = attemptedAction; @@ -91,7 +96,7 @@ public interface MutableActionGraph extends ActionGraph { "file '" + artifact.prettyPrint() + "' is generated by these conflicting actions:\n" - + suffix(attemptedAction, previousAction); + + suffix(actionKeyContext, attemptedAction, previousAction); eventListener.handle(Event.error(msg)); } @@ -143,14 +148,13 @@ public interface MutableActionGraph extends ActionGraph { } } - private static String getKey(ActionAnalysisMetadata action) { - return action instanceof Action - ? ((Action) action).getKey() - : null; + private static String getKey(ActionKeyContext actionKeyContext, ActionAnalysisMetadata action) { + return action instanceof Action ? ((Action) action).getKey(actionKeyContext) : null; } // See also Actions.canBeShared() - private static String suffix(ActionAnalysisMetadata a, ActionAnalysisMetadata b) { + private static String suffix( + ActionKeyContext actionKeyContext, ActionAnalysisMetadata a, ActionAnalysisMetadata b) { // Note: the error message reveals to users the names of intermediate files that are not // documented in the BUILD language. This error-reporting logic is rather elaborate but it // does help to diagnose some tricky situations. @@ -167,7 +171,7 @@ public interface MutableActionGraph extends ActionGraph { addStringDetail(sb, "Configuration", aNull ? null : aOwner.getConfigurationChecksum(), bNull ? null : bOwner.getConfigurationChecksum()); addStringDetail(sb, "Mnemonic", a.getMnemonic(), b.getMnemonic()); - addStringDetail(sb, "Action key", getKey(a), getKey(b)); + addStringDetail(sb, "Action key", getKey(actionKeyContext, a), getKey(actionKeyContext, b)); if ((a instanceof ActionExecutionMetadata) && (b instanceof ActionExecutionMetadata)) { addStringDetail( -- cgit v1.2.3