aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar Ulf Adams <ulfjack@google.com>2016-07-05 08:13:41 +0000
committerGravatar Klaus Aehlig <aehlig@google.com>2016-07-05 10:27:20 +0000
commite8d9c4cb9b7ce0a41cde67622997a86be876ede9 (patch)
tree245e73e58177ef4780622dc65cd3570a4565a2c1 /src/main/java/com/google
parent66d8dd8baf1d1de4834f327e05a1deddae5c7b94 (diff)
Rewrite workspace creation to use a builder class.
An instance of the builder is passed to all modules, which can each add / set things on the builder. This reduces the BlazeModule API surface, while also being more flexible for future changes. -- MOS_MIGRATED_REVID=126613981
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/BazelDiffAwarenessModule.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/BazelRepositoryModule.java23
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java14
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java95
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java112
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/WorkspaceBuilder.java215
7 files changed, 244 insertions, 231 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelDiffAwarenessModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelDiffAwarenessModule.java
index aabf86c440..4140a7d5e7 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/BazelDiffAwarenessModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelDiffAwarenessModule.java
@@ -14,7 +14,9 @@
package com.google.devtools.build.lib.bazel;
import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.runtime.BlazeModule;
+import com.google.devtools.build.lib.runtime.WorkspaceBuilder;
import com.google.devtools.build.lib.skyframe.DiffAwareness;
import com.google.devtools.build.lib.skyframe.LocalDiffAwareness;
@@ -23,11 +25,9 @@ import com.google.devtools.build.lib.skyframe.LocalDiffAwareness;
*/
public class BazelDiffAwarenessModule extends BlazeModule {
@Override
- public Iterable<DiffAwareness.Factory> getDiffAwarenessFactories(boolean watchFS) {
- ImmutableList.Builder<DiffAwareness.Factory> builder = ImmutableList.builder();
- if (watchFS) {
- builder.add(new LocalDiffAwareness.Factory(ImmutableList.<String>of()));
+ public void workspaceInit(BlazeDirectories directories, WorkspaceBuilder builder) {
+ if (builder.enableWatchFs()) {
+ builder.addDiffAwarenessFactory(new LocalDiffAwareness.Factory(ImmutableList.<String>of()));
}
- return builder.build();
}
}
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 3c51885c60..12c4bd208e 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
@@ -56,12 +56,11 @@ import com.google.devtools.build.lib.runtime.BlazeCommand;
import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.Command;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
+import com.google.devtools.build.lib.runtime.WorkspaceBuilder;
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.skyframe.SkyFunction;
-import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.common.options.OptionsProvider;
@@ -133,8 +132,12 @@ public class BazelRepositoryModule extends BlazeModule {
};
@Override
- public Iterable<SkyValueDirtinessChecker> getCustomDirtinessCheckers() {
- return ImmutableList.of(REPOSITORY_VALUE_CHECKER);
+ public void workspaceInit(BlazeDirectories directories, WorkspaceBuilder builder) {
+ builder.addCustomDirtinessChecker(REPOSITORY_VALUE_CHECKER);
+ // Create the repository function everything flows through.
+ builder.addSkyFunction(SkyFunctions.REPOSITORY, new RepositoryLoaderFunction());
+ builder.addSkyFunction(SkyFunctions.REPOSITORY_DIRECTORY, delegator);
+ builder.addSkyFunction(MavenServerFunction.NAME, new MavenServerFunction());
}
@Override
@@ -164,18 +167,6 @@ public class BazelRepositoryModule extends BlazeModule {
}
@Override
- public ImmutableMap<SkyFunctionName, SkyFunction> getSkyFunctions(BlazeDirectories directories) {
- ImmutableMap.Builder<SkyFunctionName, SkyFunction> builder = ImmutableMap.builder();
-
- // Create the repository function everything flows through.
- builder.put(SkyFunctions.REPOSITORY, new RepositoryLoaderFunction());
-
- builder.put(SkyFunctions.REPOSITORY_DIRECTORY, delegator);
- builder.put(MavenServerFunction.NAME, new MavenServerFunction());
- return builder.build();
- }
-
- @Override
public void beforeCommand(Command command, CommandEnvironment env) throws AbruptExitException {
delegator.setClientEnvironment(env.getClientEnv());
skylarkRepositoryFunction.setCommandEnvironment(env);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java b/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java
index 4704497d4f..894a27c1d4 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/BazelWorkspaceStatusModule.java
@@ -32,6 +32,7 @@ import com.google.devtools.build.lib.actions.Executor;
import com.google.devtools.build.lib.actions.ResourceSet;
import com.google.devtools.build.lib.actions.Root;
import com.google.devtools.build.lib.actions.SimpleActionContextProvider;
+import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.BuildInfo;
import com.google.devtools.build.lib.analysis.WorkspaceStatusAction;
import com.google.devtools.build.lib.analysis.WorkspaceStatusAction.Key;
@@ -41,6 +42,7 @@ import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.Command;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.runtime.GotOptionsEvent;
+import com.google.devtools.build.lib.runtime.WorkspaceBuilder;
import com.google.devtools.build.lib.shell.CommandException;
import com.google.devtools.build.lib.shell.CommandResult;
import com.google.devtools.build.lib.util.CommandBuilder;
@@ -286,7 +288,7 @@ public class BazelWorkspaceStatusModule extends BlazeModule {
}
@Override
- public WorkspaceStatusAction.Factory getWorkspaceStatusActionFactory() {
- return new BazelStatusActionFactory();
+ public void workspaceInit(BlazeDirectories directories, WorkspaceBuilder builder) {
+ builder.setWorkspaceStatusActionFactory(new BazelStatusActionFactory());
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java
index e5fb01ad7c..a169f0c5a0 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java
@@ -40,10 +40,9 @@ import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.Command;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.runtime.GotOptionsEvent;
+import com.google.devtools.build.lib.runtime.WorkspaceBuilder;
import com.google.devtools.build.lib.skyframe.PrecomputedValue;
import com.google.devtools.build.lib.util.ResourceFileLoader;
-import com.google.devtools.build.skyframe.SkyFunction;
-import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.common.options.Converters.AssignmentConverter;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;
@@ -190,8 +189,9 @@ public class BazelRulesModule extends BlazeModule {
}
@Override
- public Iterable<PrecomputedValue.Injected> getPrecomputedSkyframeValues() {
- return ImmutableList.of(PrecomputedValue.injected(
+ public void workspaceInit(BlazeDirectories directories, WorkspaceBuilder builder) {
+ builder.addSkyFunction(FdoSupportValue.SKYFUNCTION, new FdoSupportFunction());
+ builder.addPrecomputedValue(PrecomputedValue.injected(
GenQuery.QUERY_OUTPUT_FORMATTERS,
new Supplier<ImmutableList<OutputFormatter>>() {
@Override
@@ -200,10 +200,4 @@ public class BazelRulesModule extends BlazeModule {
}
}));
}
-
- @Override
- public ImmutableMap<SkyFunctionName, SkyFunction> getSkyFunctions(BlazeDirectories directories) {
- return ImmutableMap.<SkyFunctionName, SkyFunction>of(
- FdoSupportValue.SKYFUNCTION, new FdoSupportFunction());
- }
}
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 79d0c935c8..03580b2c3a 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
@@ -14,7 +14,6 @@
package com.google.devtools.build.lib.runtime;
import com.google.common.base.Function;
-import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.ActionContextConsumer;
@@ -23,14 +22,12 @@ import com.google.devtools.build.lib.actions.ActionInputFileCache;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.BlazeVersionInfo;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
-import com.google.devtools.build.lib.analysis.WorkspaceStatusAction;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.exec.OutputService;
import com.google.devtools.build.lib.packages.AttributeContainer;
import com.google.devtools.build.lib.packages.NoSuchThingException;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.PackageFactory;
-import com.google.devtools.build.lib.packages.Preprocessor;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClassProvider;
import com.google.devtools.build.lib.query2.AbstractBlazeQueryEnvironment;
@@ -40,18 +37,11 @@ import com.google.devtools.build.lib.query2.output.OutputFormatter;
import com.google.devtools.build.lib.rules.test.CoverageReportActionFactory;
import com.google.devtools.build.lib.runtime.commands.InfoItem;
import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
-import com.google.devtools.build.lib.skyframe.DiffAwareness;
-import com.google.devtools.build.lib.skyframe.PrecomputedValue.Injected;
-import com.google.devtools.build.lib.skyframe.SkyValueDirtinessChecker;
-import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
-import com.google.devtools.build.lib.skyframe.SkyframeExecutorFactory;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.Clock;
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.SkyFunction;
-import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsProvider;
@@ -110,17 +100,10 @@ public abstract class BlazeModule {
}
/**
- * May yield a supplier that provides factories for the Preprocessor to apply. Only one of the
- * configured modules may return non-null.
- *
- * <p>The factory yielded by the supplier will be checked with
- * {@link Preprocessor.Factory#isStillValid} at the beginning of each incremental build. This
- * allows modules to have preprocessors customizable by flags.
- *
- * <p>This method will be called during Blaze startup (after #blazeStartup).
+ * Called when Blaze initializes a new workspace.
*/
- public Preprocessor.Factory.Supplier getPreprocessorFactorySupplier() {
- return null;
+ @SuppressWarnings("unused")
+ public void workspaceInit(BlazeDirectories directories, WorkspaceBuilder builder) {
}
/**
@@ -151,26 +134,6 @@ public abstract class BlazeModule {
}
/**
- * Returns the {@link DiffAwareness} strategies this module contributes. These will be used to
- * determine which files, if any, changed between Blaze commands.
- *
- * <p>This method will be called during Blaze startup (after #blazeStartup).
- */
- @SuppressWarnings("unused")
- public Iterable<? extends DiffAwareness.Factory> getDiffAwarenessFactories(boolean watchFS) {
- return ImmutableList.of();
- }
-
- /**
- * Returns the workspace status action factory contributed by this module.
- *
- * <p>There should always be exactly one of these in a Blaze instance.
- */
- public WorkspaceStatusAction.Factory getWorkspaceStatusActionFactory() {
- return null;
- }
-
- /**
* PlatformSet is a group of platforms characterized by a regular expression. For example, the
* entry "oldlinux": "i[34]86-libc[345]-linux" might define a set of platforms representing
* certain older linux releases.
@@ -189,10 +152,6 @@ public abstract class BlazeModule {
return ImmutableMap.<String, String>of();
}
- public Iterable<SkyValueDirtinessChecker> getCustomDirtinessCheckers() {
- return ImmutableList.of();
- }
-
@Nullable
protected Function<RuleClass, AttributeContainer> getAttributeContainerSupplier() {
return null;
@@ -341,13 +300,6 @@ public abstract class BlazeModule {
}
/**
- * Action inputs are allowed to be missing for all inputs where this predicate returns true.
- */
- public Predicate<PathFragment> getAllowedMissingInputs() {
- return null;
- }
-
- /**
* Perform module specific check of current command environment.
*/
public void checkEnvironment(CommandEnvironment env) {
@@ -388,47 +340,6 @@ public abstract class BlazeModule {
}
/**
- * Returns a factory for creating {@link SkyframeExecutor} objects. If the module does not
- * provide any SkyframeExecutorFactory, it returns null. Note that only one factory per
- * Bazel/Blaze runtime is allowed.
- *
- * @param directories the workspace directories
- */
- public SkyframeExecutorFactory getSkyframeExecutorFactory(BlazeDirectories directories) {
- return null;
- }
-
- /** Returns a map of "extra" SkyFunctions for SkyValues that this module may want to build. */
- public ImmutableMap<SkyFunctionName, SkyFunction> getSkyFunctions(BlazeDirectories directories) {
- return ImmutableMap.of();
- }
-
- /**
- * Returns the extra precomputed values that the module makes available in Skyframe.
- *
- * <p>This method is called once per Blaze instance at the very beginning of its life.
- * If it creates the injected values by using a {@code com.google.common.base.Supplier},
- * that supplier is asked for the value it contains just before the loading phase begins. This
- * functionality can be used to implement precomputed values that are not constant during the
- * lifetime of a Blaze instance (naturally, they must be constant over the course of a build)
- *
- * <p>The following things must be done in order to define a new precomputed values:
- * <ul>
- * <li> Create a public static final variable of type
- * {@link com.google.devtools.build.lib.skyframe.PrecomputedValue.Precomputed}
- * <li> Set its value by adding an {@link Injected} in this method (it can be created using the
- * aforementioned variable and the value or a supplier of the value)
- * <li> Reference the value in Skyframe functions by calling get {@code get} method on the
- * {@link com.google.devtools.build.lib.skyframe.PrecomputedValue.Precomputed} variable. This
- * will never return null, because its value will have been injected before most of the Skyframe
- * values are computed.
- * </ul>
- */
- public Iterable<Injected> getPrecomputedSkyframeValues() {
- return ImmutableList.of();
- }
-
- /**
* Optionally returns a provider for project files that can be used to bundle targets and
* command-line options.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
index f95aecd3e3..ec7c7a0a6c 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
@@ -16,7 +16,6 @@ package com.google.devtools.build.lib.runtime;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
-import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@@ -30,7 +29,6 @@ import com.google.common.util.concurrent.Uninterruptibles;
import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.analysis.BlazeVersionInfo;
import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
-import com.google.devtools.build.lib.analysis.WorkspaceStatusAction;
import com.google.devtools.build.lib.analysis.config.BinTools;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigurationFactory;
@@ -40,7 +38,6 @@ import com.google.devtools.build.lib.flags.CommandNameCache;
import com.google.devtools.build.lib.packages.AttributeContainer;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.PackageFactory;
-import com.google.devtools.build.lib.packages.Preprocessor;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClassProvider;
import com.google.devtools.build.lib.profiler.AutoProfiler;
@@ -74,12 +71,6 @@ import com.google.devtools.build.lib.server.signal.InterruptSignalHandler;
import com.google.devtools.build.lib.shell.JavaSubprocessFactory;
import com.google.devtools.build.lib.shell.Subprocess;
import com.google.devtools.build.lib.shell.SubprocessBuilder;
-import com.google.devtools.build.lib.skyframe.DiffAwareness;
-import com.google.devtools.build.lib.skyframe.PrecomputedValue;
-import com.google.devtools.build.lib.skyframe.SequencedSkyframeExecutorFactory;
-import com.google.devtools.build.lib.skyframe.SkyValueDirtinessChecker;
-import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
-import com.google.devtools.build.lib.skyframe.SkyframeExecutorFactory;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.BlazeClock;
import com.google.devtools.build.lib.util.Clock;
@@ -97,8 +88,6 @@ import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.UnixFileSystem;
import com.google.devtools.build.lib.vfs.WindowsFileSystem;
import com.google.devtools.build.lib.windows.WindowsSubprocessFactory;
-import com.google.devtools.build.skyframe.SkyFunction;
-import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionPriority;
import com.google.devtools.common.options.OptionsBase;
@@ -218,103 +207,14 @@ public final class BlazeRuntime {
public void initWorkspace(BlazeDirectories directories, BinTools binTools)
throws AbruptExitException {
- SkyframeExecutorFactory skyframeExecutorFactory = null;
+ boolean watchFS = startupOptionsProvider != null
+ && startupOptionsProvider.getOptions(BlazeServerStartupOptions.class).watchFS;
+ WorkspaceBuilder builder = new WorkspaceBuilder(directories, binTools, watchFS);
for (BlazeModule module : blazeModules) {
- SkyframeExecutorFactory skyFactory = module.getSkyframeExecutorFactory(directories);
- if (skyFactory != null) {
- Preconditions.checkState(skyframeExecutorFactory == null,
- "At most one Skyframe factory supported. But found two: %s and %s", skyFactory,
- skyframeExecutorFactory);
- skyframeExecutorFactory = skyFactory;
- }
- }
- if (skyframeExecutorFactory == null) {
- skyframeExecutorFactory = new SequencedSkyframeExecutorFactory();
- }
-
- WorkspaceStatusAction.Factory workspaceStatusActionFactory = null;
- for (BlazeModule module : blazeModules) {
- WorkspaceStatusAction.Factory candidate = module.getWorkspaceStatusActionFactory();
- if (candidate != null) {
- Preconditions.checkState(workspaceStatusActionFactory == null,
- "more than one module defines a workspace status action factory");
- workspaceStatusActionFactory = candidate;
- }
- }
-
- Iterable<DiffAwareness.Factory> diffAwarenessFactories;
- {
- ImmutableList.Builder<DiffAwareness.Factory> builder = new ImmutableList.Builder<>();
- boolean watchFS = startupOptionsProvider != null
- && startupOptionsProvider.getOptions(BlazeServerStartupOptions.class).watchFS;
- for (BlazeModule module : blazeModules) {
- builder.addAll(module.getDiffAwarenessFactories(watchFS));
- }
- diffAwarenessFactories = builder.build();
- }
-
- // Merge filters from Blaze modules that allow some action inputs to be missing.
- Predicate<PathFragment> allowedMissingInputs = null;
- for (BlazeModule module : blazeModules) {
- Predicate<PathFragment> modulePredicate = module.getAllowedMissingInputs();
- if (modulePredicate != null) {
- Preconditions.checkArgument(allowedMissingInputs == null,
- "More than one Blaze module allows missing inputs.");
- allowedMissingInputs = modulePredicate;
- }
- }
- if (allowedMissingInputs == null) {
- allowedMissingInputs = Predicates.alwaysFalse();
+ module.workspaceInit(directories, builder);
}
-
- Preprocessor.Factory.Supplier preprocessorFactorySupplier = null;
- for (BlazeModule module : blazeModules) {
- Preprocessor.Factory.Supplier modulePreprocessorFactorySupplier =
- module.getPreprocessorFactorySupplier();
- if (modulePreprocessorFactorySupplier != null) {
- Preconditions.checkState(preprocessorFactorySupplier == null,
- "more than one module defines a preprocessor factory supplier");
- preprocessorFactorySupplier = modulePreprocessorFactorySupplier;
- }
- }
- if (preprocessorFactorySupplier == null) {
- preprocessorFactorySupplier = Preprocessor.Factory.Supplier.NullSupplier.INSTANCE;
- }
-
- // We use an immutable map builder for the nice side effect that it throws if a duplicate key
- // is inserted.
- ImmutableMap.Builder<SkyFunctionName, SkyFunction> skyFunctions = ImmutableMap.builder();
- for (BlazeModule module : blazeModules) {
- skyFunctions.putAll(module.getSkyFunctions(directories));
- }
-
- ImmutableList.Builder<PrecomputedValue.Injected> precomputedValues = ImmutableList.builder();
- for (BlazeModule module : blazeModules) {
- precomputedValues.addAll(module.getPrecomputedSkyframeValues());
- }
-
- ImmutableList.Builder<SkyValueDirtinessChecker> customDirtinessCheckers =
- ImmutableList.builder();
- for (BlazeModule module : blazeModules) {
- customDirtinessCheckers.addAll(module.getCustomDirtinessCheckers());
- }
-
- SkyframeExecutor skyframeExecutor = skyframeExecutorFactory.create(
- packageFactory,
- directories,
- binTools,
- workspaceStatusActionFactory,
- ruleClassProvider.getBuildInfoFactories(),
- diffAwarenessFactories,
- allowedMissingInputs,
- preprocessorFactorySupplier,
- skyFunctions.build(),
- precomputedValues.build(),
- customDirtinessCheckers.build(),
- getProductName());
- this.workspace = new BlazeWorkspace(
- this, directories, skyframeExecutor, eventBusExceptionHandler, workspaceStatusActionFactory,
- binTools);
+ this.workspace = builder.build(
+ this, packageFactory, ruleClassProvider, getProductName(), eventBusExceptionHandler);
}
@Nullable public CoverageReportActionFactory getCoverageReportActionFactory() {
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/WorkspaceBuilder.java b/src/main/java/com/google/devtools/build/lib/runtime/WorkspaceBuilder.java
new file mode 100644
index 0000000000..d7f0bfd2f2
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/runtime/WorkspaceBuilder.java
@@ -0,0 +1,215 @@
+// Copyright 2016 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.runtime;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.eventbus.SubscriberExceptionHandler;
+import com.google.devtools.build.lib.analysis.BlazeDirectories;
+import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
+import com.google.devtools.build.lib.analysis.WorkspaceStatusAction;
+import com.google.devtools.build.lib.analysis.config.BinTools;
+import com.google.devtools.build.lib.packages.PackageFactory;
+import com.google.devtools.build.lib.packages.Preprocessor;
+import com.google.devtools.build.lib.skyframe.DiffAwareness;
+import com.google.devtools.build.lib.skyframe.PrecomputedValue;
+import com.google.devtools.build.lib.skyframe.PrecomputedValue.Injected;
+import com.google.devtools.build.lib.skyframe.SequencedSkyframeExecutorFactory;
+import com.google.devtools.build.lib.skyframe.SkyValueDirtinessChecker;
+import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
+import com.google.devtools.build.lib.skyframe.SkyframeExecutorFactory;
+import com.google.devtools.build.lib.util.AbruptExitException;
+import com.google.devtools.build.lib.util.Preconditions;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import com.google.devtools.build.skyframe.SkyFunction;
+import com.google.devtools.build.skyframe.SkyFunctionName;
+
+import java.util.Map;
+
+/**
+ * Builder class to create a {@link BlazeWorkspace} instance. This class is part of the module API,
+ * which allows modules to affect how the workspace is initialized.
+ */
+public final class WorkspaceBuilder {
+ private final BlazeDirectories directories;
+ private final BinTools binTools;
+ private final boolean watchFs;
+
+ private SkyframeExecutorFactory skyframeExecutorFactory;
+ private WorkspaceStatusAction.Factory workspaceStatusActionFactory;
+ private final ImmutableList.Builder<DiffAwareness.Factory> diffAwarenessFactories =
+ ImmutableList.builder();
+ private Predicate<PathFragment> allowedMissingInputs;
+ private Preprocessor.Factory.Supplier preprocessorFactorySupplier;
+ // We use an immutable map builder for the nice side effect that it throws if a duplicate key
+ // is inserted.
+ private final ImmutableMap.Builder<SkyFunctionName, SkyFunction> skyFunctions =
+ ImmutableMap.builder();
+ private final ImmutableList.Builder<PrecomputedValue.Injected> precomputedValues =
+ ImmutableList.builder();
+ private final ImmutableList.Builder<SkyValueDirtinessChecker> customDirtinessCheckers =
+ ImmutableList.builder();
+
+ WorkspaceBuilder(BlazeDirectories directories, BinTools binTools, boolean watchFs) {
+ this.directories = directories;
+ this.binTools = binTools;
+ this.watchFs = watchFs;
+ }
+
+ BlazeWorkspace build(
+ BlazeRuntime runtime,
+ PackageFactory packageFactory,
+ ConfiguredRuleClassProvider ruleClassProvider,
+ String productName,
+ SubscriberExceptionHandler eventBusExceptionHandler) throws AbruptExitException {
+ // Set default values if none are set.
+ if (skyframeExecutorFactory == null) {
+ skyframeExecutorFactory = new SequencedSkyframeExecutorFactory();
+ }
+ if (allowedMissingInputs == null) {
+ allowedMissingInputs = Predicates.alwaysFalse();
+ }
+ if (preprocessorFactorySupplier == null) {
+ preprocessorFactorySupplier = Preprocessor.Factory.Supplier.NullSupplier.INSTANCE;
+ }
+
+ SkyframeExecutor skyframeExecutor = skyframeExecutorFactory.create(
+ packageFactory,
+ directories,
+ binTools,
+ workspaceStatusActionFactory,
+ ruleClassProvider.getBuildInfoFactories(),
+ diffAwarenessFactories.build(),
+ allowedMissingInputs,
+ preprocessorFactorySupplier,
+ skyFunctions.build(),
+ precomputedValues.build(),
+ customDirtinessCheckers.build(),
+ productName);
+ return new BlazeWorkspace(
+ runtime, directories, skyframeExecutor, eventBusExceptionHandler,
+ workspaceStatusActionFactory, binTools);
+ }
+
+ public boolean enableWatchFs() {
+ return watchFs;
+ }
+
+ /**
+ * Sets a factory for creating {@link SkyframeExecutor} objects. Note that only one factory per
+ * workspace is allowed.
+ */
+ public WorkspaceBuilder setSkyframeExecutorFactory(
+ SkyframeExecutorFactory skyframeExecutorFactory) {
+ Preconditions.checkState(this.skyframeExecutorFactory == null,
+ "At most one Skyframe factory supported. But found two: %s and %s",
+ this.skyframeExecutorFactory, skyframeExecutorFactory);
+ this.skyframeExecutorFactory = Preconditions.checkNotNull(skyframeExecutorFactory);
+ return this;
+ }
+
+ /**
+ * Sets the workspace status action factory contributed by this module. Only one factory per
+ * workspace is allowed.
+ */
+ public WorkspaceBuilder setWorkspaceStatusActionFactory(
+ WorkspaceStatusAction.Factory workspaceStatusActionFactory) {
+ Preconditions.checkState(this.workspaceStatusActionFactory == null,
+ "At most one workspace status action factory supported. But found two: %s and %s",
+ this.workspaceStatusActionFactory, workspaceStatusActionFactory);
+ this.workspaceStatusActionFactory = Preconditions.checkNotNull(workspaceStatusActionFactory);
+ return this;
+ }
+
+ /**
+ * Add a {@link DiffAwareness} factory. These will be used to determine which files, if any,
+ * changed between Blaze commands.
+ */
+ public WorkspaceBuilder addDiffAwarenessFactory(DiffAwareness.Factory factory) {
+ this.diffAwarenessFactories.add(Preconditions.checkNotNull(factory));
+ return this;
+ }
+
+ /**
+ * Action inputs are allowed to be missing for all inputs where this predicate returns true. Only
+ * one predicate may be set per workspace.
+ */
+ public WorkspaceBuilder setAllowedMissingInputs(Predicate<PathFragment> allowedMissingInputs) {
+ Preconditions.checkArgument(this.allowedMissingInputs == null,
+ "At most one module may set allowed missing inputs. But found two: %s and %s",
+ this.allowedMissingInputs, allowedMissingInputs);
+ this.allowedMissingInputs = Preconditions.checkNotNull(allowedMissingInputs);
+ return this;
+ }
+
+ /**
+ * Sets a supplier that provides factories for the Preprocessor to apply. Only one factory per
+ * workspace is allowed.
+ *
+ * <p>The factory yielded by the supplier will be checked with
+ * {@link Preprocessor.Factory#isStillValid} at the beginning of each incremental build. This
+ * allows modules to have preprocessors customizable by flags.
+ */
+ public WorkspaceBuilder setPreprocessorFactorySupplier(
+ Preprocessor.Factory.Supplier preprocessorFactorySupplier) {
+ Preconditions.checkState(this.preprocessorFactorySupplier == null,
+ "At most one module defines a preprocessor factory supplier. But found two: %s and %s",
+ this.preprocessorFactorySupplier, preprocessorFactorySupplier);
+ this.preprocessorFactorySupplier = Preconditions.checkNotNull(preprocessorFactorySupplier);
+ return this;
+ }
+
+ /** Add an "extra" SkyFunction for SkyValues. */
+ public WorkspaceBuilder addSkyFunction(SkyFunctionName name, SkyFunction skyFunction) {
+ Preconditions.checkNotNull(name);
+ Preconditions.checkNotNull(skyFunction);
+ this.skyFunctions.put(name, skyFunction);
+ return this;
+ }
+
+ /** Add "extra" SkyFunctions for SkyValues. */
+ public WorkspaceBuilder addSkyFunctions(Map<SkyFunctionName, SkyFunction> skyFunctions) {
+ this.skyFunctions.putAll(Preconditions.checkNotNull(skyFunctions));
+ return this;
+ }
+
+ /**
+ * Adds an extra precomputed value to Skyframe.
+ *
+ * <p>This functionality can be used to implement precomputed values that are not constant during
+ * the lifetime of a Blaze instance (naturally, they must be constant over the course of a build).
+ *
+ * <p>The following things must be done in order to define a new precomputed values:
+ * <ul>
+ * <li> Create a public static final variable of type
+ * {@link com.google.devtools.build.lib.skyframe.PrecomputedValue.Precomputed}.
+ * <li> Set its value by adding an {@link Injected} via this method (it can be created using the
+ * aforementioned variable and the value or a supplier of the value).
+ * <li> Reference the value in Skyframe functions by calling the {@code get} method on the
+ * {@link com.google.devtools.build.lib.skyframe.PrecomputedValue.Precomputed} variable.
+ * </ul>
+ */
+ public WorkspaceBuilder addPrecomputedValue(PrecomputedValue.Injected precomputedValue) {
+ this.precomputedValues.add(Preconditions.checkNotNull(precomputedValue));
+ return this;
+ }
+
+ public WorkspaceBuilder addCustomDirtinessChecker(
+ SkyValueDirtinessChecker customDirtinessChecker) {
+ this.customDirtinessCheckers.add(Preconditions.checkNotNull(customDirtinessChecker));
+ return this;
+ }
+} \ No newline at end of file