diff options
author | kchodorow <kchodorow@google.com> | 2017-04-19 18:58:50 +0200 |
---|---|---|
committer | Klaus Aehlig <aehlig@google.com> | 2017-04-20 11:06:33 +0200 |
commit | dfcd5da86e2acfd42ca09c7f65e012465ab3e382 (patch) | |
tree | c97a59df14ca5e7c3953b4fac038c09b2033d207 /src/main/java/com/google/devtools/build | |
parent | ac64fd7b27ca511738801b7ac2dbb9439615183b (diff) |
Add repository override option
RELNOTES: Adds a --override_repository option that takes a repository
name and path. This forces Bazel to use the directory at that path
for the repository. Example usage:
`--override_repository=foo=/home/user/gitroot/foo`.
Fixes #1266
PiperOrigin-RevId: 153599291
Diffstat (limited to 'src/main/java/com/google/devtools/build')
12 files changed, 173 insertions, 26 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD index a3707e7b65..4c4a80e983 100644 --- a/src/main/java/com/google/devtools/build/lib/BUILD +++ b/src/main/java/com/google/devtools/build/lib/BUILD @@ -752,6 +752,7 @@ java_library( "//src/main/java/com/google/devtools/common/options", "//third_party:aether", "//third_party:apache_commons_compress", + "//third_party:auto_value", "//third_party:guava", "//third_party:jgit", "//third_party:jsr305", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java index 4c7388031f..91b2226c49 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java @@ -16,6 +16,8 @@ package com.google.devtools.build.lib.bazel; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.RuleDefinition; @@ -31,6 +33,7 @@ import com.google.devtools.build.lib.bazel.repository.MavenServerRepositoryFunct import com.google.devtools.build.lib.bazel.repository.NewGitRepositoryFunction; import com.google.devtools.build.lib.bazel.repository.NewHttpArchiveFunction; import com.google.devtools.build.lib.bazel.repository.RepositoryOptions; +import com.google.devtools.build.lib.bazel.repository.RepositoryOptions.RepositoryOverride; import com.google.devtools.build.lib.bazel.repository.cache.RepositoryCache; import com.google.devtools.build.lib.bazel.repository.downloader.HttpDownloader; import com.google.devtools.build.lib.bazel.repository.skylark.SkylarkRepositoryFunction; @@ -47,6 +50,7 @@ import com.google.devtools.build.lib.bazel.rules.workspace.MavenJarRule; import com.google.devtools.build.lib.bazel.rules.workspace.MavenServerRule; import com.google.devtools.build.lib.bazel.rules.workspace.NewGitRepositoryRule; import com.google.devtools.build.lib.bazel.rules.workspace.NewHttpArchiveRule; +import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.pkgcache.PackageCacheOptions; import com.google.devtools.build.lib.rules.repository.LocalRepositoryFunction; import com.google.devtools.build.lib.rules.repository.LocalRepositoryRule; @@ -61,12 +65,15 @@ import com.google.devtools.build.lib.runtime.Command; import com.google.devtools.build.lib.runtime.CommandEnvironment; import com.google.devtools.build.lib.runtime.ServerBuilder; import com.google.devtools.build.lib.runtime.WorkspaceBuilder; +import com.google.devtools.build.lib.skyframe.PrecomputedValue; +import com.google.devtools.build.lib.skyframe.PrecomputedValue.Injected; import com.google.devtools.build.lib.skyframe.SkyFunctions; import com.google.devtools.build.lib.skyframe.SkyValueDirtinessChecker; import com.google.devtools.build.lib.util.AbruptExitException; import com.google.devtools.build.lib.util.io.TimestampGranularityMonitor; import com.google.devtools.build.lib.vfs.FileSystem; import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.SkyValue; import com.google.devtools.common.options.OptionsBase; @@ -88,6 +95,7 @@ public class BazelRepositoryModule extends BlazeModule { private final RepositoryCache repositoryCache = new RepositoryCache(); private final HttpDownloader httpDownloader = new HttpDownloader(repositoryCache); private final MavenDownloader mavenDownloader = new MavenDownloader(repositoryCache); + private ImmutableMap<RepositoryName, PathFragment> overrides = ImmutableMap.of(); private FileSystem filesystem; public BazelRepositoryModule() { @@ -152,7 +160,6 @@ public class BazelRepositoryModule extends BlazeModule { builder.addSkyFunction(SkyFunctions.REPOSITORY, new RepositoryLoaderFunction()); builder.addSkyFunction(SkyFunctions.REPOSITORY_DIRECTORY, delegator); builder.addSkyFunction(MavenServerFunction.NAME, new MavenServerFunction()); - filesystem = directories.getFileSystem(); } @@ -184,17 +191,37 @@ public class BazelRepositoryModule extends BlazeModule { } else { repositoryCache.setRepositoryCachePath(null); } + + if (repoOptions.repositoryOverrides != null) { + ImmutableMap.Builder<RepositoryName, PathFragment> builder = ImmutableMap.builder(); + for (RepositoryOverride override : repoOptions.repositoryOverrides) { + builder.put(override.repositoryName(), override.path()); + } + ImmutableMap<RepositoryName, PathFragment> newOverrides = builder.build(); + if (!Maps.difference(overrides, newOverrides).areEqual()) { + overrides = newOverrides; + } + } else { + overrides = ImmutableMap.of(); + } } } @Override + public ImmutableList<Injected> getPrecomputedValues() { + return ImmutableList.of( + PrecomputedValue.injected( + RepositoryDelegatorFunction.REPOSITORY_OVERRIDES, overrides)); + } + + @Override public void beforeCommand(Command command, CommandEnvironment env) throws AbruptExitException { delegator.setClientEnvironment(env.getActionClientEnv()); } @Override public Iterable<Class<? extends OptionsBase>> getCommandOptions(Command command) { - return "fetch".equals(command.name()) || "build".equals(command.name()) + return ImmutableSet.of("fetch", "build", "query").contains(command.name()) ? ImmutableList.<Class<? extends OptionsBase>>of(RepositoryOptions.class) : ImmutableList.<Class<? extends OptionsBase>>of(); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java index 3fdf939f4c..0072f10ecb 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/RepositoryOptions.java @@ -14,11 +14,17 @@ package com.google.devtools.build.lib.bazel.repository; +import com.google.auto.value.AutoValue; +import com.google.devtools.build.lib.cmdline.LabelSyntaxException; +import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.util.OptionsUtils; import com.google.devtools.build.lib.vfs.PathFragment; +import com.google.devtools.common.options.Converter; import com.google.devtools.common.options.Option; import com.google.devtools.common.options.OptionsBase; import com.google.devtools.common.options.OptionsParser.OptionUsageRestrictions; +import com.google.devtools.common.options.OptionsParsingException; +import java.util.List; /** * Command-line options for repositories. @@ -36,4 +42,54 @@ public class RepositoryOptions extends OptionsBase { ) public PathFragment experimentalRepositoryCache; -}
\ No newline at end of file + @Option(name = "override_repository", + defaultValue = "null", + allowMultiple = true, + converter = RepositoryOverrideConverter.class, + help = "Overrides a repository with a local directory.") + public List<RepositoryOverride> repositoryOverrides; + + /** + * Converts from an equals-separated pair of strings into RepositoryName->PathFragment mapping. + */ + public static class RepositoryOverrideConverter implements Converter<RepositoryOverride> { + + @Override + public RepositoryOverride convert(String input) throws OptionsParsingException { + String[] pieces = input.split("="); + if (pieces.length != 2) { + throw new OptionsParsingException( + "Repository overrides must be of the form 'repository-name=path'", input); + } + PathFragment path = PathFragment.create(pieces[1]); + if (!path.isAbsolute()) { + throw new OptionsParsingException( + "Repository override directory must be an absolute path", input); + } + try { + return RepositoryOverride.create(RepositoryName.create("@" + pieces[0]), path); + } catch (LabelSyntaxException e) { + throw new OptionsParsingException("Invalid repository name given to override", input); + } + } + + @Override + public String getTypeDescription() { + return "an equals-separated mapping of repository name to path"; + } + } + + /** + * A repository override, represented by a name and an absolute path to a repository. + */ + @AutoValue + public abstract static class RepositoryOverride { + + private static RepositoryOverride create(RepositoryName repositoryName, PathFragment path) { + return new AutoValue_RepositoryOptions_RepositoryOverride(repositoryName, path); + } + + public abstract RepositoryName repositoryName(); + public abstract PathFragment path(); + } +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java index ee387f735d..916569c4cb 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/LocalRepositoryFunction.java @@ -40,14 +40,20 @@ public class LocalRepositoryFunction extends RepositoryFunction { BlazeDirectories directories, Environment env, Map<String, String> markerData) throws InterruptedException, RepositoryFunctionException { PathFragment pathFragment = RepositoryFunction.getTargetPath(rule, directories.getWorkspace()); + return LocalRepositoryFunction.symlink(outputDirectory, pathFragment, env); + } + + public static RepositoryDirectoryValue.Builder symlink( + Path source, PathFragment destination, Environment env) + throws RepositoryFunctionException, InterruptedException { try { - outputDirectory.createSymbolicLink(pathFragment); + source.createSymbolicLink(destination); } catch (IOException e) { throw new RepositoryFunctionException( - new IOException("Could not create symlink to repository " + pathFragment + ": " + new IOException("Could not create symlink to repository " + destination + ": " + e.getMessage(), e), Transience.TRANSIENT); } - FileValue repositoryValue = getRepositoryDirectory(outputDirectory, env); + FileValue repositoryValue = getRepositoryDirectory(source, env); if (repositoryValue == null) { // TODO(bazel-team): If this returns null, we unnecessarily recreate the symlink above on the // second execution. @@ -56,10 +62,10 @@ public class LocalRepositoryFunction extends RepositoryFunction { if (!repositoryValue.isDirectory()) { throw new RepositoryFunctionException( - new IOException(rule + " must specify an existing directory"), Transience.TRANSIENT); + new IOException(source + " must be an existing directory"), Transience.TRANSIENT); } - return RepositoryDirectoryValue.builder().setPath(outputDirectory); + return RepositoryDirectoryValue.builder().setPath(source); } @Override diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java index 771231b72b..259950beda 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryDelegatorFunction.java @@ -25,10 +25,13 @@ import com.google.devtools.build.lib.packages.RuleFormatter; import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException; import com.google.devtools.build.lib.skyframe.FileValue; import com.google.devtools.build.lib.skyframe.PrecomputedValue; +import com.google.devtools.build.lib.skyframe.PrecomputedValue.Precomputed; +import com.google.devtools.build.lib.skyframe.SkyFunctions; import com.google.devtools.build.lib.syntax.EvalException; import com.google.devtools.build.lib.util.Fingerprint; import com.google.devtools.build.lib.vfs.FileSystemUtils; import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.skyframe.SkyFunction; import com.google.devtools.build.skyframe.SkyFunctionException; import com.google.devtools.build.skyframe.SkyFunctionException.Transience; @@ -49,6 +52,8 @@ import javax.annotation.Nullable; * this function. */ public final class RepositoryDelegatorFunction implements SkyFunction { + public static final Precomputed<Map<RepositoryName, PathFragment>> REPOSITORY_OVERRIDES = + new Precomputed<>(SkyKey.create(SkyFunctions.PRECOMPUTED, "repository_overrides")); // The marker file version is inject in the rule key digest so the rule key is always different // when we decide to update the format. @@ -93,13 +98,22 @@ public final class RepositoryDelegatorFunction implements SkyFunction { public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException { RepositoryName repositoryName = (RepositoryName) skyKey.argument(); - Rule rule = RepositoryFunction.getRule(repositoryName, null, env); - if (rule == null) { + BlazeDirectories directories = PrecomputedValue.BLAZE_DIRECTORIES.get(env); + Map<RepositoryName, PathFragment> overrides = REPOSITORY_OVERRIDES.get(env); + if (env.valuesMissing()) { return null; } - BlazeDirectories directories = PrecomputedValue.BLAZE_DIRECTORIES.get(env); - if (directories == null) { + Path repoRoot = RepositoryFunction.getExternalRepositoryDirectory(directories) + .getRelative(repositoryName.strippedName()); + Path markerPath = getMarkerPath(directories, repositoryName.strippedName()); + if (overrides.containsKey(repositoryName)) { + return setupOverride( + repositoryName, overrides.get(repositoryName), env, repoRoot, markerPath); + } + + Rule rule = RepositoryFunction.getRule(repositoryName, null, env); + if (rule == null) { return null; } RepositoryFunction handler; @@ -110,23 +124,20 @@ public final class RepositoryDelegatorFunction implements SkyFunction { } if (handler == null) { throw new RepositoryFunctionException( - new EvalException(Location.fromFile(directories.getWorkspace().getRelative("WORKSPACE")), + new EvalException( + Location.fromFile(directories.getWorkspace().getRelative("WORKSPACE")), "Could not find handler for " + rule), Transience.PERSISTENT); } handler.setClientEnvironment(clientEnvironment); - Path repoRoot = - RepositoryFunction.getExternalRepositoryDirectory(directories).getRelative(rule.getName()); byte[] ruleSpecificData = handler.getRuleSpecificMarkerData(rule, env); if (ruleSpecificData == null) { return null; } String ruleKey = computeRuleKey(rule, ruleSpecificData); Map<String, String> markerData = new TreeMap<>(); - Path markerPath = getMarkerPath(directories, rule); - if (handler.isLocal(rule)) { // Local repositories are always fetched because the operation is generally fast and they do // not depend on non-local data, so it does not make much sense to try to cache from across @@ -207,7 +218,7 @@ public final class RepositoryDelegatorFunction implements SkyFunction { .setFetchingDelayed().build(); } - private final String computeRuleKey(Rule rule, byte[] ruleSpecificData) { + private String computeRuleKey(Rule rule, byte[] ruleSpecificData) { return new Fingerprint().addBytes(RuleFormatter.serializeRule(rule).build().toByteArray()) .addBytes(ruleSpecificData) .addInt(MARKER_FILE_VERSION).hexDigestAndReset(); @@ -226,7 +237,7 @@ public final class RepositoryDelegatorFunction implements SkyFunction { * system is up to date. */ @Nullable - private final byte[] isFilesystemUpToDate(Path markerPath, Rule rule, String ruleKey, + private byte[] isFilesystemUpToDate(Path markerPath, Rule rule, String ruleKey, RepositoryFunction handler, Environment env) throws RepositoryFunctionException, InterruptedException { try { @@ -310,7 +321,7 @@ public final class RepositoryDelegatorFunction implements SkyFunction { return result.toString(); } - private final byte[] writeMarkerFile( + private byte[] writeMarkerFile( Path markerPath, Map<String, String> markerData, String ruleKey) throws RepositoryFunctionException { try { @@ -329,13 +340,30 @@ public final class RepositoryDelegatorFunction implements SkyFunction { } } - private static Path getMarkerPath(BlazeDirectories directories, Rule rule) { + private static Path getMarkerPath(BlazeDirectories directories, String ruleName) { return RepositoryFunction.getExternalRepositoryDirectory(directories) - .getChild("@" + rule.getName() + ".marker"); + .getChild("@" + ruleName + ".marker"); } @Override public String extractTag(SkyKey skyKey) { return null; } + + private RepositoryDirectoryValue setupOverride( + RepositoryName repositoryName, PathFragment sourcePath, Environment env, Path repoRoot, + Path markerPath) + throws RepositoryFunctionException, InterruptedException { + setupRepositoryRoot(repoRoot); + RepositoryDirectoryValue.Builder directoryValue = LocalRepositoryFunction.symlink( + repoRoot, sourcePath, env); + if (directoryValue == null) { + return null; + } + String ruleKey = new Fingerprint().addBytes(repositoryName.strippedName().getBytes()) + .addBytes(repoRoot.getFileSystem().getPath(sourcePath).getPathString().getBytes()) + .addInt(MARKER_FILE_VERSION).hexDigestAndReset(); + byte[] digest = writeMarkerFile(markerPath, new TreeMap<String, String>(), ruleKey); + return directoryValue.setDigest(digest).build(); + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java index 51486eda50..8afb6eeb83 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/repository/RepositoryFunction.java @@ -470,7 +470,12 @@ public abstract class RepositoryFunction { // function so we get invalidation when the repository is fetched. // For the repository directory itself, we cannot depends on the RepositoryDirectoryValue // (cycle). - env.getValue(RepositoryDirectoryValue.key(RepositoryName.create("@" + repositoryName))); + env.getValue( + RepositoryDirectoryValue.key( + RepositoryName.createFromValidStrippedName(repositoryName))); + } else { + // Invalidate external/<repo> if the repository overrides change. + RepositoryDelegatorFunction.REPOSITORY_OVERRIDES.get(env); } } catch (RepositoryFunction.RepositoryNotFoundException ex) { // The repository we are looking for does not exist so we should depend on the whole @@ -478,7 +483,7 @@ public abstract class RepositoryFunction { // already requested all repository functions from the WORKSPACE file from Skyframe as part // of the resolution. Therefore we are safe to ignore that Exception. return; - } catch (RepositoryFunctionException | LabelSyntaxException ex) { + } catch (RepositoryFunctionException ex) { // This should never happen. throw new IllegalStateException( "Repository " + repositoryName + " cannot be resolved for path " + rootedPath, ex); diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java index 3b26e1e990..26a96d00ab 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeCommandDispatcher.java @@ -511,6 +511,10 @@ public class BlazeCommandDispatcher { env.getEventBus().post(originalCommandLine); + for (BlazeModule module : runtime.getBlazeModules()) { + env.getSkyframeExecutor().injectExtraPrecomputedValues(module.getPrecomputedValues()); + } + ExitCode outcome = command.exec(env, optionsParser); outcome = env.precompleteCommand(outcome); numericExitCode = outcome.getNumericExitCode(); diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java index 39d6d4a9af..f05586c844 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java @@ -27,6 +27,7 @@ import com.google.devtools.build.lib.packages.Package; import com.google.devtools.build.lib.packages.PackageFactory; import com.google.devtools.build.lib.packages.RuleClassProvider; import com.google.devtools.build.lib.rules.test.CoverageReportActionFactory; +import com.google.devtools.build.lib.skyframe.PrecomputedValue; import com.google.devtools.build.lib.util.AbruptExitException; import com.google.devtools.build.lib.util.Clock; import com.google.devtools.build.lib.vfs.FileSystem; @@ -290,4 +291,8 @@ public abstract class BlazeModule { */ void exit(AbruptExitException exception); } + + public ImmutableList<PrecomputedValue.Injected> getPrecomputedValues() { + return ImmutableList.of(); + } } diff --git a/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java b/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java index 4fcea318cb..7f2d2e81fb 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java @@ -495,6 +495,10 @@ public final class CommandEnvironment { if (!skyframeExecutor.hasIncrementalState()) { skyframeExecutor.resetEvaluator(); } + + for (BlazeModule module : runtime.getBlazeModules()) { + skyframeExecutor.injectExtraPrecomputedValues(module.getPrecomputedValues()); + } skyframeExecutor.sync( reporter, options.getOptions(PackageCacheOptions.class), diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java index f0d06e0be8..2619af2b39 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java @@ -60,6 +60,11 @@ public final class PrecomputedValue implements SkyValue { void inject(Injectable injectable) { injectable.inject(precomputed.key, new PrecomputedValue(supplier.get())); } + + @Override + public String toString() { + return precomputed + ": " + supplier.get(); + } } public static <T> Injected injected(Precomputed<T> precomputed, Supplier<T> value) { diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java index fe5b1d4513..dfc2657aa7 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java @@ -701,12 +701,13 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { PrecomputedValue.BLAZE_DIRECTORIES.set(injectable(), directories); PrecomputedValue.PRODUCT_NAME.set(injectable(), productName); injectBuildInfoFactories(); - injectExtraPrecomputedValues(); + injectExtraPrecomputedValues(extraPrecomputedValues); needToInjectPrecomputedValuesForAnalysis = false; } } - private void injectExtraPrecomputedValues() { + public void injectExtraPrecomputedValues( + List<PrecomputedValue.Injected> extraPrecomputedValues) { for (PrecomputedValue.Injected injected : extraPrecomputedValues) { injected.inject(injectable()); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameValue.java index 1fccf6d4da..c752d5829d 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceNameValue.java @@ -98,5 +98,10 @@ public class WorkspaceNameValue implements SkyValue { public int hashCode() { return HASHCODE; } + + @Override + public String toString() { + return "#"; + } } } |