diff options
author | Lukacs Berki <lberki@google.com> | 2015-04-20 10:48:55 +0000 |
---|---|---|
committer | Han-Wen Nienhuys <hanwen@google.com> | 2015-04-20 16:40:51 +0000 |
commit | a4dea59f91bbfbb30d1d281f8c05bf6113ee9c01 (patch) | |
tree | fa1bf3f084a13d8819c4119f25607ced0c0aab8c /src/main | |
parent | a0a79689260be76002a3058fb461e57a96e26f47 (diff) |
Pass in the test environment using BuildConfiguration.Options.testEnvironment instead of special-casing it in a large number of classes.
The variables in the client environment are read in BlazeRuntime#beforeCommand() now.
Note that this entails a slight loss of caching: before, "--test_env=a=A,b=B" and "--test_env=b=B,a=A" were equivalent, now they are not, since instead of comparing Map<String, String>, List<Map.Entry<String,String>> instances are compared.
--
MOS_MIGRATED_REVID=91570828
Diffstat (limited to 'src/main')
10 files changed, 57 insertions, 86 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationCollectionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationCollectionFactory.java index e63a631739..340af2826b 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationCollectionFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfigurationCollectionFactory.java @@ -20,8 +20,6 @@ import com.google.devtools.build.lib.analysis.config.InvalidConfigurationExcepti import com.google.devtools.build.lib.analysis.config.PackageProviderForConfigurations; import com.google.devtools.build.lib.events.EventHandler; -import java.util.Map; - import javax.annotation.Nullable; /** @@ -36,7 +34,6 @@ public interface ConfigurationCollectionFactory { * via configuration transitions. * @param loadedPackageProvider the package provider * @param buildOptions top-level build options representing the command-line - * @param testEnv the test environment * @param errorEventListener the event listener for errors * @param performSanityCheck flag to signal about performing sanity check. Can be false only for * tests in skyframe. Legacy mode uses loadedPackageProvider == null condition for this. @@ -48,7 +45,6 @@ public interface ConfigurationCollectionFactory { ConfigurationFactory configurationFactory, PackageProviderForConfigurations loadedPackageProvider, BuildOptions buildOptions, - Map<String, String> testEnv, EventHandler errorEventListener, boolean performSanityCheck) throws InvalidConfigurationException; } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java index 1b002a5420..e6e55d437b 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java @@ -79,6 +79,7 @@ import java.util.List; import java.util.Map; import java.util.Queue; import java.util.Set; +import java.util.TreeMap; import javax.annotation.Nullable; @@ -995,7 +996,6 @@ public final class BuildConfiguration implements Serializable { BuildConfiguration(BlazeDirectories directories, Map<Class<? extends Fragment>, Fragment> fragmentsMap, BuildOptions buildOptions, - Map<String, String> testEnv, boolean actionsDisabled) { this.actionsEnabled = !actionsDisabled; this.fragments = ImmutableMap.copyOf(fragmentsMap); @@ -1003,6 +1003,13 @@ public final class BuildConfiguration implements Serializable { this.buildOptions = buildOptions; this.options = buildOptions.get(Options.class); + Map<String, String> testEnv = new TreeMap<>(); + for (Map.Entry<String, String> entry : this.options.testEnvironment) { + if (entry.getValue() != null) { + testEnv.put(entry.getKey(), entry.getValue()); + } + } + this.testEnvironment = ImmutableMap.copyOf(testEnv); this.mnemonic = buildMnemonic(); @@ -1054,7 +1061,7 @@ public final class BuildConfiguration implements Serializable { globalMakeEnv = globalMakeEnvBuilder.build(); cacheKey = computeCacheKey( - directories, fragmentsMap, this.buildOptions, this.testEnvironment); + directories, fragmentsMap, this.buildOptions); shortCacheKey = shortName + "-" + Fingerprint.md5Digest(cacheKey); } @@ -1773,8 +1780,7 @@ public final class BuildConfiguration implements Serializable { * parameters and any additional component suppliers. */ static String computeCacheKey(BlazeDirectories directories, - Map<Class<? extends Fragment>, Fragment> fragments, - BuildOptions buildOptions, Map<String, String> testEnvironment) { + Map<Class<? extends Fragment>, Fragment> fragments, BuildOptions buildOptions) { // Creates a full fingerprint of all constructor parameters, used for // canonicalization. @@ -1792,9 +1798,6 @@ public final class BuildConfiguration implements Serializable { keys.add(String.valueOf(System.identityHashCode(directories.getOutputBase().getFileSystem()))); keys.add(directories.getOutputBase().toString()); keys.add(buildOptions.computeCacheKey()); - // This is needed so that if we have --test_env=VAR, the configuration key is updated if the - // environment variable VAR is updated. - keys.add(testEnvironment.toString()); keys.add(directories.getWorkspace().toString()); for (Fragment fragment : fragments.values()) { diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationKey.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationKey.java index 53fba105b3..065f3937b2 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationKey.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfigurationKey.java @@ -14,14 +14,12 @@ package com.google.devtools.build.lib.analysis.config; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.ListMultimap; import com.google.devtools.build.lib.analysis.BlazeDirectories; import com.google.devtools.build.lib.syntax.Label; -import java.util.Map; import java.util.Objects; import java.util.Set; @@ -32,7 +30,6 @@ public final class BuildConfigurationKey { private final BuildOptions buildOptions; private final BlazeDirectories directories; - private final Map<String, String> testEnv; private final ImmutableSortedSet<String> multiCpu; /** @@ -40,17 +37,15 @@ public final class BuildConfigurationKey { * * Note that the BuildConfiguration.Options instance must not contain unresolved relative paths. */ - public BuildConfigurationKey(BuildOptions buildOptions, BlazeDirectories directories, - Map<String, String> testEnv, Set<String> multiCpu) { + public BuildConfigurationKey( + BuildOptions buildOptions, BlazeDirectories directories, Set<String> multiCpu) { this.buildOptions = Preconditions.checkNotNull(buildOptions); this.directories = Preconditions.checkNotNull(directories); - this.testEnv = ImmutableMap.copyOf(testEnv); this.multiCpu = ImmutableSortedSet.copyOf(multiCpu); } - public BuildConfigurationKey(BuildOptions buildOptions, BlazeDirectories directories, - Map<String, String> testEnv) { - this(buildOptions, directories, testEnv, ImmutableSet.<String>of()); + public BuildConfigurationKey(BuildOptions buildOptions, BlazeDirectories directories) { + this(buildOptions, directories, ImmutableSet.<String>of()); } public BuildOptions getBuildOptions() { @@ -61,10 +56,6 @@ public final class BuildConfigurationKey { return directories; } - public Map<String, String> getTestEnv() { - return testEnv; - } - public ImmutableSortedSet<String> getMultiCpu() { return multiCpu; } @@ -81,12 +72,11 @@ public final class BuildConfigurationKey { BuildConfigurationKey k = (BuildConfigurationKey) o; return buildOptions.equals(k.buildOptions) && directories.equals(k.directories) - && testEnv.equals(k.testEnv) && multiCpu.equals(k.multiCpu); } @Override public int hashCode() { - return Objects.hash(buildOptions, directories, testEnv, multiCpu); + return Objects.hash(buildOptions, directories, multiCpu); } } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationFactory.java index 2db6c3122d..56b259e004 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigurationFactory.java @@ -84,8 +84,7 @@ public final class ConfigurationFactory { BuildConfigurationKey key, EventHandler errorEventListener) throws InvalidConfigurationException { return configurationCollectionFactory.createConfigurations(this, - loadedPackageProvider, buildOptions, key.getTestEnv(), - errorEventListener, performSanityCheck); + loadedPackageProvider, buildOptions, errorEventListener, performSanityCheck); } /** @@ -94,10 +93,10 @@ public final class ConfigurationFactory { */ @Nullable public BuildConfiguration getHostConfiguration( - PackageProviderForConfigurations loadedPackageProvider, Map<String, String> testEnv, + PackageProviderForConfigurations loadedPackageProvider, BuildOptions buildOptions, boolean fallback) throws InvalidConfigurationException { return getConfiguration(loadedPackageProvider, buildOptions.createHostOptions(fallback), - testEnv, false, hostConfigCache); + false, hostConfigCache); } /** @@ -106,7 +105,7 @@ public final class ConfigurationFactory { */ @Nullable public BuildConfiguration getConfiguration(PackageProviderForConfigurations loadedPackageProvider, - BuildOptions buildOptions, Map<String, String> testEnv, + BuildOptions buildOptions, boolean actionsDisabled, Cache<String, BuildConfiguration> cache) throws InvalidConfigurationException { @@ -136,11 +135,10 @@ public final class ConfigurationFactory { fragments = ImmutableMap.copyOf(fragments); String key = BuildConfiguration.computeCacheKey( - directories, fragments, buildOptions, testEnv); + directories, fragments, buildOptions); BuildConfiguration configuration = cache.getIfPresent(key); if (configuration == null) { - configuration = new BuildConfiguration(directories, fragments, buildOptions, - testEnv, actionsDisabled); + configuration = new BuildConfiguration(directories, fragments, buildOptions, actionsDisabled); cache.put(key, configuration); } return configuration; diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelConfigurationCollection.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelConfigurationCollection.java index eb3d1889f9..10eca9d5bc 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelConfigurationCollection.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelConfigurationCollection.java @@ -58,7 +58,6 @@ public class BazelConfigurationCollection implements ConfigurationCollectionFact ConfigurationFactory configurationFactory, PackageProviderForConfigurations loadedPackageProvider, BuildOptions buildOptions, - Map<String, String> testEnv, EventHandler errorEventListener, boolean performSanityCheck) throws InvalidConfigurationException { @@ -71,7 +70,7 @@ public class BazelConfigurationCollection implements ConfigurationCollectionFact // Target configuration BuildConfiguration targetConfiguration = configurationFactory.getConfiguration( - loadedPackageProvider, buildOptions, testEnv, false, cache); + loadedPackageProvider, buildOptions, false, cache); if (targetConfiguration == null) { return null; } @@ -82,7 +81,7 @@ public class BazelConfigurationCollection implements ConfigurationCollectionFact // Note that this passes in the dataConfiguration, not the target // configuration. This is intentional. BuildConfiguration hostConfiguration = getHostConfigurationFromRequest(configurationFactory, - loadedPackageProvider, testEnv, dataConfiguration, buildOptions); + loadedPackageProvider, dataConfiguration, buildOptions); if (hostConfiguration == null) { return null; } @@ -131,7 +130,7 @@ public class BazelConfigurationCollection implements ConfigurationCollectionFact @Nullable private BuildConfiguration getHostConfigurationFromRequest( ConfigurationFactory configurationFactory, - PackageProviderForConfigurations loadedPackageProvider, Map<String, String> testEnv, + PackageProviderForConfigurations loadedPackageProvider, BuildConfiguration requestConfig, BuildOptions buildOptions) throws InvalidConfigurationException { BuildConfiguration.Options commonOptions = buildOptions.get(BuildConfiguration.Options.class); @@ -139,7 +138,7 @@ public class BazelConfigurationCollection implements ConfigurationCollectionFact return requestConfig; } else { BuildConfiguration hostConfig = configurationFactory.getHostConfiguration( - loadedPackageProvider, testEnv, buildOptions, /*fallback=*/false); + loadedPackageProvider, buildOptions, /*fallback=*/false); if (hostConfig == null) { return null; } 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 cee47ee2fd..6d0c14b035 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 @@ -390,7 +390,7 @@ public class BlazeCommandDispatcher { try { // Notify the BlazeRuntime, so it can do some initial setup. - runtime.beforeCommand(commandName, optionsParser, commonOptions, execStartTimeNanos); + runtime.beforeCommand(commandAnnotation, optionsParser, commonOptions, execStartTimeNanos); // Allow the command to edit options after parsing: command.editOptions(runtime, optionsParser); } catch (AbruptExitException e) { 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 91985bb4c2..2309b6e9a8 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 @@ -226,29 +226,6 @@ public final class BlazeRuntime { private final ProjectFile.Provider projectFileProvider; - /** - * Returns user-specified test environment variables and their values, as - * set by the --test_env options. - * - * @param envOverrides The --test_env flag values. - * @param clientEnvironment The full client environment. - */ - private static Map<String, String> computeTestEnv(List<Map.Entry<String, String>> envOverrides, - Map<String, String> clientEnvironment) { - Map<String, String> testEnv = new TreeMap<>(); - for (Map.Entry<String, String> var : envOverrides) { - if (var.getValue() != null) { - testEnv.put(var.getKey(), var.getValue()); - } else { - String value = clientEnvironment.get(var.getKey()); - if (value != null) { - testEnv.put(var.getKey(), value); - } - } - } - return testEnv; - } - private class BlazeModuleEnvironment implements BlazeModule.ModuleEnvironment { @Override public Path getFileFromDepot(Label label) @@ -734,7 +711,7 @@ public final class BlazeRuntime { * @param options The CommonCommandOptions used by every command. * @throws AbruptExitException if this command is unsuitable to be run as specified */ - void beforeCommand(String commandName, OptionsParser optionsParser, + void beforeCommand(Command command, OptionsParser optionsParser, CommonCommandOptions options, long execStartTimeNanos) throws AbruptExitException { commandStartTime -= options.startupTime; @@ -807,7 +784,31 @@ public final class BlazeRuntime { } } - eventBus.post(new CommandStartEvent(commandName, commandId, clientEnv, workingDirectory)); + if (command.builds()) { + Map<String, String> testEnv = new TreeMap<>(); + for (Map.Entry<String, String> entry : + optionsParser.getOptions(BuildConfiguration.Options.class).testEnvironment) { + testEnv.put(entry.getKey(), entry.getValue()); + } + + try { + for (Map.Entry<String, String> entry : testEnv.entrySet()) { + if (entry.getValue() == null) { + String clientValue = clientEnv.get(entry.getKey()); + if (clientValue != null) { + optionsParser.parse(OptionPriority.SOFTWARE_REQUIREMENT, + "test environment variable from client environment", + ImmutableList.of( + "--test_env=" + entry.getKey() + "=" + clientEnv.get(entry.getKey()))); + } + } + } + } catch (OptionsParsingException e) { + throw new IllegalStateException(e); + } + } + + eventBus.post(new CommandStartEvent(command.name(), commandId, clientEnv, workingDirectory)); // Initialize exit code to dummy value for afterCommand. storedExitCode.set(ExitCode.RESERVED.getNumericExitCode()); } @@ -985,10 +986,7 @@ public final class BlazeRuntime { */ public BuildConfigurationKey getBuildConfigurationKey(BuildOptions buildOptions, ImmutableSortedSet<String> multiCpu) { - Map<String, String> testEnv = computeTestEnv( - buildOptions.get(BuildConfiguration.Options.class).testEnvironment, - clientEnv); - return new BuildConfigurationKey(buildOptions, directories, testEnv, multiCpu); + return new BuildConfigurationKey(buildOptions, directories, multiCpu); } /** diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfigurationCollectionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfigurationCollectionFunction.java index 085238d1cf..5e16f0c00b 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfigurationCollectionFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfigurationCollectionFunction.java @@ -33,7 +33,6 @@ import com.google.devtools.build.skyframe.SkyValue; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Set; import javax.annotation.Nullable; @@ -44,15 +43,12 @@ import javax.annotation.Nullable; public class ConfigurationCollectionFunction implements SkyFunction { private final Supplier<ConfigurationFactory> configurationFactory; - private final Supplier<Map<String, String>> testEnv; private final Supplier<Set<Package>> configurationPackages; public ConfigurationCollectionFunction( Supplier<ConfigurationFactory> configurationFactory, - Supplier<Map<String, String>> testEnv, Supplier<Set<Package>> configurationPackages) { this.configurationFactory = configurationFactory; - this.testEnv = testEnv; this.configurationPackages = configurationPackages; } @@ -61,7 +57,6 @@ public class ConfigurationCollectionFunction implements SkyFunction { ConfigurationCollectionFunctionException { ConfigurationCollectionKey collectionKey = (ConfigurationCollectionKey) skyKey.argument(); try { - PrecomputedValue.TEST_ENVIRONMENT_VARIABLES.get(env); BlazeDirectories directories = PrecomputedValue.BLAZE_DIRECTORIES.get(env); if (env.valuesMissing()) { return null; @@ -70,8 +65,8 @@ public class ConfigurationCollectionFunction implements SkyFunction { BuildConfigurationCollection result = getConfigurations(env.getListener(), new SkyframePackageLoaderWithValueEnvironment(env, configurationPackages.get()), - new BuildConfigurationKey(collectionKey.getBuildOptions(), directories, testEnv.get(), - collectionKey.getMultiCpu())); + new BuildConfigurationKey( + collectionKey.getBuildOptions(), directories, collectionKey.getMultiCpu())); // BuildConfigurationCollection can be created, but dependencies to some files might be // missing. In that case we need to build configurationCollection again. 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 5c9a337694..18abc269f5 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 @@ -93,9 +93,6 @@ public class PrecomputedValue implements SkyValue { static final Precomputed<Map<BuildInfoKey, BuildInfoFactory>> BUILD_INFO_FACTORIES = new Precomputed<>(new SkyKey(SkyFunctions.PRECOMPUTED, "build_info_factories")); - static final Precomputed<Map<String, String>> TEST_ENVIRONMENT_VARIABLES = - new Precomputed<>(new SkyKey(SkyFunctions.PRECOMPUTED, "test_environment")); - static final Precomputed<BlazeDirectories> BLAZE_DIRECTORIES = new Precomputed<>(new SkyKey(SkyFunctions.PRECOMPUTED, "blaze_directories")); 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 fd170a1f95..ed41872152 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 @@ -230,7 +230,6 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { new SkyframeIncrementalBuildMonitor(); private MutableSupplier<ConfigurationFactory> configurationFactory = new MutableSupplier<>(); - private MutableSupplier<Map<String, String>> testEnv = new MutableSupplier<>(); private MutableSupplier<ImmutableList<ConfigurationFragmentFactory>> configurationFragments = new MutableSupplier<>(); private MutableSupplier<Set<Package>> configurationPackages = new MutableSupplier<>(); @@ -316,7 +315,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { map.put(SkyFunctions.POST_CONFIGURED_TARGET, new PostConfiguredTargetFunction(new BuildViewProvider())); map.put(SkyFunctions.CONFIGURATION_COLLECTION, new ConfigurationCollectionFunction( - configurationFactory, testEnv, configurationPackages)); + configurationFactory, configurationPackages)); map.put(SkyFunctions.CONFIGURATION_FRAGMENT, new ConfigurationFragmentFunction( configurationFragments, configurationPackages)); map.put(SkyFunctions.WORKSPACE_FILE, new WorkspaceFileFunction(pkgFactory, directories)); @@ -864,14 +863,10 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { throws InvalidConfigurationException, InterruptedException { this.configurationPackages.set(Sets.<Package>newConcurrentHashSet()); - this.testEnv.set(configurationKey.getTestEnv()); this.configurationFactory.set(configurationFactory); this.configurationFragments.set(ImmutableList.copyOf(configurationFactory.getFactories())); // TODO(bazel-team): find a way to use only BuildConfigurationKey instead of - // TestEnvironmentVariables and BlazeDirectories. There is a problem only with - // TestEnvironmentVariables because BuildConfigurationKey stores client environment variables - // and we don't want to rebuild everything when any variable changes. - PrecomputedValue.TEST_ENVIRONMENT_VARIABLES.set(injectable(), configurationKey.getTestEnv()); + // BlazeDirectories. PrecomputedValue.BLAZE_DIRECTORIES.set(injectable(), configurationKey.getDirectories()); SkyKey skyKey = ConfigurationCollectionValue.key(configurationKey.getBuildOptions(), |