blob: 81c27fec481a6d86817afb69b7e935d46ce183e5 [file] [log] [blame]
Damien Martin-Guillerez777f3af2017-02-08 17:22:02 +00001// Copyright 2017 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.devtools.build.lib.skyframe;
16
17import com.google.common.collect.ImmutableList;
janakr5fb2a482018-03-02 17:48:57 -080018import com.google.common.collect.Interner;
19import com.google.devtools.build.lib.concurrent.BlazeInterners;
20import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
21import com.google.devtools.build.skyframe.AbstractSkyKey;
Damien Martin-Guillerez777f3af2017-02-08 17:22:02 +000022import com.google.devtools.build.skyframe.SkyFunction;
janakr5fb2a482018-03-02 17:48:57 -080023import com.google.devtools.build.skyframe.SkyFunctionName;
Damien Martin-Guillerez777f3af2017-02-08 17:22:02 +000024import com.google.devtools.build.skyframe.SkyKey;
25import com.google.devtools.build.skyframe.SkyValue;
26import java.util.Collections;
27import java.util.LinkedHashMap;
28import java.util.Map;
29import javax.annotation.Nullable;
30
31/**
32 * Skyframe function that provides the effective value for a client environment variable. This will
33 * either be the value coming from the default client environment, or the value coming from the
34 * --action_env flag, if the variable's value is explicitly set.
35 */
36public final class ActionEnvironmentFunction implements SkyFunction {
37
38 @Nullable
39 @Override
40 public String extractTag(SkyKey skyKey) {
41 return null;
42 }
43
44 @Nullable
45 @Override
46 public SkyValue compute(SkyKey skyKey, Environment env) throws InterruptedException {
47 Map<String, String> actionEnv = PrecomputedValue.ACTION_ENV.get(env);
48 String key = (String) skyKey.argument();
49 if (actionEnv.containsKey(key) && actionEnv.get(key) != null) {
50 return new ClientEnvironmentValue(actionEnv.get(key));
51 }
janakr5fb2a482018-03-02 17:48:57 -080052 return env.getValue(ClientEnvironmentFunction.key(key));
Damien Martin-Guillerez777f3af2017-02-08 17:22:02 +000053 }
54
55 /** @return the SkyKey to invoke this function for the environment variable {@code variable}. */
janakr5fb2a482018-03-02 17:48:57 -080056 public static Key key(String variable) {
57 return Key.create(variable);
58 }
59
60 @AutoCodec.VisibleForSerialization
61 @AutoCodec
62 static class Key extends AbstractSkyKey<String> {
63 private static final Interner<Key> interner = BlazeInterners.newWeakInterner();
64
65 private Key(String arg) {
66 super(arg);
67 }
68
69 @AutoCodec.VisibleForSerialization
70 @AutoCodec.Instantiator
71 static Key create(String arg) {
72 return interner.intern(new Key(arg));
73 }
74
75 @Override
76 public SkyFunctionName functionName() {
77 return SkyFunctions.ACTION_ENVIRONMENT_VARIABLE;
78 }
Damien Martin-Guillerez777f3af2017-02-08 17:22:02 +000079 }
80
81 /**
82 * Returns a map of environment variable key => values, getting them from Skyframe. Returns null
83 * if and only if some dependencies from Skyframe still need to be resolved.
84 */
85 public static Map<String, String> getEnvironmentView(Environment env, Iterable<String> keys)
86 throws InterruptedException {
87 ImmutableList.Builder<SkyKey> skyframeKeysBuilder = ImmutableList.builder();
88 for (String key : keys) {
89 skyframeKeysBuilder.add(key(key));
90 }
91 ImmutableList<SkyKey> skyframeKeys = skyframeKeysBuilder.build();
92 Map<SkyKey, SkyValue> values = env.getValues(skyframeKeys);
93 if (env.valuesMissing()) {
94 return null;
95 }
96 // To return the initial order and support null values, we use a LinkedHashMap.
97 LinkedHashMap<String, String> result = new LinkedHashMap<>();
98 for (SkyKey key : skyframeKeys) {
99 ClientEnvironmentValue value = (ClientEnvironmentValue) values.get(key);
100 result.put(key.argument().toString(), value.getValue());
101 }
102 return Collections.unmodifiableMap(result);
103 }
104}