aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google
diff options
context:
space:
mode:
authorGravatar Damien Martin-Guillerez <dmarting@google.com>2017-02-08 17:22:02 +0000
committerGravatar Kristina Chodorow <kchodorow@google.com>2017-02-08 17:50:55 +0000
commit777f3afea4195e094d45bdfc317b236146117ff7 (patch)
tree98d58442dc08e35a66370795ec67a53574985732 /src/main/java/com/google
parentf5bb3d248ff1dd9e5157551bbf5052c61a7643ce (diff)
Introduce a Skyframe function: ActionEnvironmentFunction
ActionEnvironmentFunction returns the list of environment variable with the one overwritten by --action_env being replaced. This let other Skyframe function declares dependency to any value of the environment and being influenced by the --action_env flag. This will be used to declare dependency of remote repositories on environment variables (step 3 of https://bazel.build/designs/2016/10/18/repository-invalidation.html) -- Change-Id: I1ed3fb6f48e8e17d4d64c903fccecb6ed7596350 Reviewed-on: https://cr.bazel.build/7974 PiperOrigin-RevId: 146918603 MOS_MIGRATED_REVID=146918603
Diffstat (limited to 'src/main/java/com/google')
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ActionEnvironmentFunction.java78
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java15
5 files changed, 99 insertions, 3 deletions
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 29bf5a53c7..3590138b5c 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
@@ -477,9 +477,7 @@ public final class CommandEnvironment {
getWorkingDirectory(),
defaultsPackageContents,
getCommandId(),
- // TODO(bazel-team): this optimization disallows rule-specified additional dependencies
- // on the client environment!
- getWhitelistedClientEnv(),
+ clientEnv,
timestampGranularityMonitor,
options);
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionEnvironmentFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionEnvironmentFunction.java
new file mode 100644
index 0000000000..ea4cde03df
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionEnvironmentFunction.java
@@ -0,0 +1,78 @@
+// 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.skyframe;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.skyframe.SkyFunction;
+import com.google.devtools.build.skyframe.SkyKey;
+import com.google.devtools.build.skyframe.SkyValue;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.annotation.Nullable;
+
+/**
+ * Skyframe function that provides the effective value for a client environment variable. This will
+ * either be the value coming from the default client environment, or the value coming from the
+ * --action_env flag, if the variable's value is explicitly set.
+ */
+public final class ActionEnvironmentFunction implements SkyFunction {
+
+ @Nullable
+ @Override
+ public String extractTag(SkyKey skyKey) {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException {
+ Map<String, String> actionEnv = PrecomputedValue.ACTION_ENV.get(env);
+ String key = (String) skyKey.argument();
+ if (actionEnv.containsKey(key) && actionEnv.get(key) != null) {
+ return new ClientEnvironmentValue(actionEnv.get(key));
+ }
+ return env.getValue(SkyKey.create(SkyFunctions.CLIENT_ENVIRONMENT_VARIABLE, key));
+ }
+
+ /** @return the SkyKey to invoke this function for the environment variable {@code variable}. */
+ public static SkyKey key(String variable) {
+ return SkyKey.create(SkyFunctions.ACTION_ENVIRONMENT_VARIABLE, variable);
+ }
+
+ /**
+ * Returns a map of environment variable key => values, getting them from Skyframe. Returns null
+ * if and only if some dependencies from Skyframe still need to be resolved.
+ */
+ public static Map<String, String> getEnvironmentView(Environment env, Iterable<String> keys)
+ throws InterruptedException {
+ ImmutableList.Builder<SkyKey> skyframeKeysBuilder = ImmutableList.builder();
+ for (String key : keys) {
+ skyframeKeysBuilder.add(key(key));
+ }
+ ImmutableList<SkyKey> skyframeKeys = skyframeKeysBuilder.build();
+ Map<SkyKey, SkyValue> values = env.getValues(skyframeKeys);
+ if (env.valuesMissing()) {
+ return null;
+ }
+ // To return the initial order and support null values, we use a LinkedHashMap.
+ LinkedHashMap<String, String> result = new LinkedHashMap<>();
+ for (SkyKey key : skyframeKeys) {
+ ClientEnvironmentValue value = (ClientEnvironmentValue) values.get(key);
+ result.put(key.argument().toString(), value.getValue());
+ }
+ return Collections.unmodifiableMap(result);
+ }
+}
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 05b9277789..a53475a7ff 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
@@ -83,6 +83,9 @@ public final class PrecomputedValue implements SkyValue {
static final Precomputed<UUID> BUILD_ID =
new Precomputed<>(SkyKey.create(SkyFunctions.PRECOMPUTED, "build_id"));
+ static final Precomputed<Map<String, String>> ACTION_ENV =
+ new Precomputed<>(SkyKey.create(SkyFunctions.PRECOMPUTED, "action_env"));
+
static final Precomputed<WorkspaceStatusAction> WORKSPACE_STATUS_KEY =
new Precomputed<>(SkyKey.create(SkyFunctions.PRECOMPUTED, "workspace_status_action"));
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
index 3e138adaff..476e313a8a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
@@ -24,6 +24,8 @@ public final class SkyFunctions {
public static final SkyFunctionName PRECOMPUTED = SkyFunctionName.create("PRECOMPUTED");
public static final SkyFunctionName CLIENT_ENVIRONMENT_VARIABLE =
SkyFunctionName.create("CLIENT_ENVIRONMENT_VARIABLE");
+ public static final SkyFunctionName ACTION_ENVIRONMENT_VARIABLE =
+ SkyFunctionName.create("ACTION_ENVIRONMENT_VARIABLE");
public static final SkyFunctionName FILE_STATE = SkyFunctionName.create("FILE_STATE");
public static final SkyFunctionName DIRECTORY_LISTING_STATE =
SkyFunctionName.create("DIRECTORY_LISTING_STATE");
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 06017becd6..25c087de7a 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
@@ -146,10 +146,13 @@ import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
@@ -350,6 +353,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory {
ImmutableMap.Builder<SkyFunctionName, SkyFunction> map = ImmutableMap.builder();
map.put(SkyFunctions.PRECOMPUTED, new PrecomputedFunction());
map.put(SkyFunctions.CLIENT_ENVIRONMENT_VARIABLE, new ClientEnvironmentFunction(clientEnv));
+ map.put(SkyFunctions.ACTION_ENVIRONMENT_VARIABLE, new ActionEnvironmentFunction());
map.put(SkyFunctions.FILE_STATE, new FileStateFunction(tsgm, externalFilesHelper));
map.put(SkyFunctions.DIRECTORY_LISTING_STATE,
new DirectoryListingStateFunction(externalFilesHelper));
@@ -940,6 +944,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory {
String defaultsPackageContents,
UUID commandId,
Map<String, String> clientEnv,
+ Map<String, String> actionEnv,
TimestampGranularityMonitor tsgm) {
Preconditions.checkNotNull(pkgLocator);
Preconditions.checkNotNull(tsgm);
@@ -948,6 +953,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory {
this.tsgm.set(tsgm);
maybeInjectPrecomputedValuesForAnalysis();
setCommandId(commandId);
+ PrecomputedValue.ACTION_ENV.set(injectable(), actionEnv);
this.clientEnv.set(clientEnv);
setBlacklistedPackagePrefixesFile(getBlacklistedPackagePrefixesFile());
setShowLoadingProgress(packageCacheOptions.showLoadingProgress);
@@ -1699,6 +1705,14 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory {
TimestampGranularityMonitor tsgm,
OptionsClassProvider options)
throws InterruptedException, AbruptExitException {
+ // ImmutableMap does not support null values, so use a LinkedHashMap instead.
+ LinkedHashMap<String, String> actionEnvironment = new LinkedHashMap<>();
+ BuildConfiguration.Options opt = options.getOptions(BuildConfiguration.Options.class);
+ if (opt != null) {
+ for (Entry<String, String> v : opt.actionEnvironment) {
+ actionEnvironment.put(v.getKey(), v.getValue());
+ }
+ }
preparePackageLoading(
createPackageLocator(
eventHandler,
@@ -1710,6 +1724,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory {
defaultsPackageContents,
commandId,
clientEnv,
+ Collections.unmodifiableMap(actionEnvironment),
tsgm);
setDeletedPackages(packageCacheOptions.getDeletedPackages());