blob: fd691183c012d5f29a13d176e5a75a5f64b63bd6 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
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.
14package com.google.devtools.build.lib.skyframe;
15
janakr93e3eea2017-03-30 22:09:37 +000016import com.google.common.base.Function;
tomlua155b532017-11-08 20:12:47 +010017import com.google.common.base.Preconditions;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010018import com.google.common.base.Predicate;
fellybb07aa92018-09-04 09:42:39 -070019import com.google.common.base.Supplier;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010020import com.google.common.collect.ImmutableList;
Rumou Duan73876202016-06-06 18:52:08 +000021import com.google.common.collect.ImmutableMap;
22import com.google.common.collect.Iterables;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010023import com.google.devtools.build.lib.actions.Action;
Rumou Duan33bab462016-04-25 17:55:12 +000024import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
25import com.google.devtools.build.lib.actions.ActionAnalysisMetadata.MiddlemanType;
janakr93e3eea2017-03-30 22:09:37 +000026import com.google.devtools.build.lib.actions.ActionLookupValue;
27import com.google.devtools.build.lib.actions.ActionLookupValue.ActionLookupKey;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010028import com.google.devtools.build.lib.actions.Artifact;
Rumou Duan73876202016-06-06 18:52:08 +000029import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
janakr0c42fc82018-09-14 10:37:25 -070030import com.google.devtools.build.lib.actions.ArtifactFileMetadata;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010031import com.google.devtools.build.lib.actions.ArtifactOwner;
shahane35e8cf2018-06-18 08:14:01 -070032import com.google.devtools.build.lib.actions.ArtifactSkyKey;
shahan602cc852018-06-06 20:09:57 -070033import com.google.devtools.build.lib.actions.FileArtifactValue;
34import com.google.devtools.build.lib.actions.FileValue;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010035import com.google.devtools.build.lib.actions.MissingInputFileException;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000036import com.google.devtools.build.lib.cmdline.Label;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010037import com.google.devtools.build.lib.events.Event;
38import com.google.devtools.build.lib.events.EventHandler;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010039import com.google.devtools.build.lib.util.Pair;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010040import com.google.devtools.build.lib.vfs.RootedPath;
41import com.google.devtools.build.skyframe.SkyFunction;
42import com.google.devtools.build.skyframe.SkyFunctionException;
43import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
44import com.google.devtools.build.skyframe.SkyKey;
45import com.google.devtools.build.skyframe.SkyValue;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010046import java.io.IOException;
janakr93e3eea2017-03-30 22:09:37 +000047import java.util.ArrayList;
Googler84bfb9a2018-07-12 05:41:49 -070048import java.util.Comparator;
janakr93e3eea2017-03-30 22:09:37 +000049import java.util.List;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010050import java.util.Map;
janakr93e3eea2017-03-30 22:09:37 +000051import javax.annotation.Nullable;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010052
Janak Ramakrishnanad77f972016-07-29 20:58:42 +000053/** A builder of values for {@link ArtifactSkyKey} keys. */
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010054class ArtifactFunction implements SkyFunction {
55
fellybb07aa92018-09-04 09:42:39 -070056 private final Supplier<Boolean> usesActionFS;
57
58 public ArtifactFunction(Supplier<Boolean> usesActionFS) {
59 this.usesActionFS = usesActionFS;
60 }
61
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010062 @Override
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +000063 public SkyValue compute(SkyKey skyKey, Environment env)
64 throws ArtifactFunctionException, InterruptedException {
janakrbf4123d2018-07-24 11:38:19 -070065 Artifact artifact = ArtifactSkyKey.artifact(skyKey);
66 boolean isMandatory = ArtifactSkyKey.isMandatory(skyKey);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010067 if (artifact.isSourceArtifact()) {
68 try {
janakrbf4123d2018-07-24 11:38:19 -070069 return createSourceValue(artifact, isMandatory, env);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010070 } catch (MissingInputFileException e) {
71 // The error is not necessarily truly transient, but we mark it as such because we have
72 // the above side effect of posting an event to the EventBus. Importantly, that event
73 // is potentially used to report root causes.
74 throw new ArtifactFunctionException(e, Transience.TRANSIENT);
75 }
76 }
77
janakrbaf52ae2018-02-14 09:03:18 -080078 ActionLookupKey actionLookupKey = getActionLookupKey(artifact);
janakr93e3eea2017-03-30 22:09:37 +000079 ActionLookupValue actionLookupValue = getActionLookupValue(actionLookupKey, env, artifact);
80 if (actionLookupValue == null) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010081 return null;
82 }
janakr93e3eea2017-03-30 22:09:37 +000083 Integer actionIndex = actionLookupValue.getGeneratingActionIndex(artifact);
84 if (artifact.hasParent() && actionIndex == null) {
85 // If a TreeFileArtifact is created by a templated action, then it should have the proper
86 // reference to its owner. However, if it was created as part of a directory, by the first
87 // TreeArtifact-generating action in a chain, then its parent's generating action also
88 // generated it. This catches that case.
89 actionIndex = actionLookupValue.getGeneratingActionIndex(artifact.getParent());
90 }
91 Preconditions.checkNotNull(
92 actionIndex, "%s %s %s", artifact, actionLookupKey, actionLookupValue);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010093
Rumou Duan73876202016-06-06 18:52:08 +000094 // If the action is an ActionTemplate, we need to expand the ActionTemplate into concrete
95 // actions, execute those actions in parallel and then aggregate the action execution results.
janakrcb314a22018-02-15 10:33:53 -080096 if (artifact.isTreeArtifact() && actionLookupValue.isActionTemplate(actionIndex)) {
97 // Create the directory structures for the output TreeArtifact first.
fellybb07aa92018-09-04 09:42:39 -070098 if (!usesActionFS.get()) {
99 try {
100 artifact.getPath().createDirectoryAndParents();
101 } catch (IOException e) {
102 env.getListener()
103 .handle(
104 Event.error(
105 String.format(
106 "Failed to create output directory for TreeArtifact %s: %s",
107 artifact, e.getMessage())));
108 throw new ArtifactFunctionException(e, Transience.TRANSIENT);
109 }
Rumou Duan73876202016-06-06 18:52:08 +0000110 }
janakrcb314a22018-02-15 10:33:53 -0800111
112 return createTreeArtifactValueFromActionKey(actionLookupKey, actionIndex, artifact, env);
Rumou Duan73876202016-06-06 18:52:08 +0000113 }
janakr93e3eea2017-03-30 22:09:37 +0000114 ActionExecutionValue actionValue =
115 (ActionExecutionValue) env.getValue(ActionExecutionValue.key(actionLookupKey, actionIndex));
116 if (actionValue == null) {
117 return null;
118 }
119
120 if (artifact.isTreeArtifact()) {
121 // We get a request for the whole tree artifact. We can just return the associated
122 // TreeArtifactValue.
123 return Preconditions.checkNotNull(actionValue.getTreeArtifactValue(artifact), artifact);
124 }
125 if (artifact.isMiddlemanArtifact()) {
126 Action action =
127 Preconditions.checkNotNull(
128 actionLookupValue.getAction(actionIndex),
129 "Null middleman action? %s %s %s %s",
130 artifact,
131 actionLookupKey,
132 actionLookupValue,
133 actionIndex);
134 if (isAggregatingValue(action)) {
buchgrd4d3d502018-08-02 06:47:19 -0700135 return createAggregatingValue(
136 artifact, action, actionValue.getArtifactValue(artifact), env);
janakr93e3eea2017-03-30 22:09:37 +0000137 }
138 }
139 return createSimpleFileArtifactValue(artifact, actionValue);
Rumou Duan73876202016-06-06 18:52:08 +0000140 }
141
janakrcb314a22018-02-15 10:33:53 -0800142 private static TreeArtifactValue createTreeArtifactValueFromActionKey(
143 ActionLookupKey actionLookupKey,
144 int actionIndex,
145 final Artifact treeArtifact,
146 Environment env)
147 throws InterruptedException {
Rumou Duan73876202016-06-06 18:52:08 +0000148 // Request the list of expanded actions from the ActionTemplate.
janakrbaf52ae2018-02-14 09:03:18 -0800149 ActionTemplateExpansionValue.ActionTemplateExpansionKey templateKey =
janakrcb314a22018-02-15 10:33:53 -0800150 ActionTemplateExpansionValue.key(actionLookupKey, actionIndex);
janakr93e3eea2017-03-30 22:09:37 +0000151 ActionTemplateExpansionValue expansionValue =
152 (ActionTemplateExpansionValue) env.getValue(templateKey);
Rumou Duan73876202016-06-06 18:52:08 +0000153
154 // The expanded actions are not yet available.
155 if (env.valuesMissing()) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100156 return null;
157 }
158
janakr93e3eea2017-03-30 22:09:37 +0000159 List<SkyKey> expandedActionExecutionKeys = new ArrayList<>(expansionValue.getNumActions());
160 for (int i = 0; i < expansionValue.getNumActions(); i++) {
161 expandedActionExecutionKeys.add(ActionExecutionValue.key(templateKey, i));
162 }
Rumou Duan73876202016-06-06 18:52:08 +0000163 Map<SkyKey, SkyValue> expandedActionValueMap = env.getValues(expandedActionExecutionKeys);
164
165 // The execution values of the expanded actions are not yet all available.
166 if (env.valuesMissing()) {
167 return null;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100168 }
Rumou Duan73876202016-06-06 18:52:08 +0000169
170 // Aggregate the ArtifactValues for individual TreeFileArtifacts into a TreeArtifactValue for
171 // the parent TreeArtifact.
172 ImmutableMap.Builder<TreeFileArtifact, FileArtifactValue> map = ImmutableMap.builder();
janakr93e3eea2017-03-30 22:09:37 +0000173 for (int i = 0; i < expansionValue.getNumActions(); i++) {
174 final ActionExecutionValue actionExecutionValue =
175 (ActionExecutionValue)
176 Preconditions.checkNotNull(
177 expandedActionValueMap.get(expandedActionExecutionKeys.get(i)),
janakrcb314a22018-02-15 10:33:53 -0800178 "Missing tree value: %s %s %s %s %s",
janakr93e3eea2017-03-30 22:09:37 +0000179 treeArtifact,
janakrcb314a22018-02-15 10:33:53 -0800180 actionLookupKey,
181 actionIndex,
janakr93e3eea2017-03-30 22:09:37 +0000182 expansionValue,
tomlu32d2edc2017-11-08 18:14:23 +0100183 expandedActionValueMap);
janakr93e3eea2017-03-30 22:09:37 +0000184 Iterable<TreeFileArtifact> treeFileArtifacts =
185 Iterables.transform(
186 Iterables.filter(
187 actionExecutionValue.getAllFileValues().keySet(),
188 new Predicate<Artifact>() {
189 @Override
190 public boolean apply(Artifact artifact) {
191 Preconditions.checkState(
192 artifact.hasParent(),
janakrcb314a22018-02-15 10:33:53 -0800193 "No parent: %s %s %s %s %s",
janakr93e3eea2017-03-30 22:09:37 +0000194 artifact,
195 treeArtifact,
196 actionExecutionValue,
janakrcb314a22018-02-15 10:33:53 -0800197 actionLookupKey,
198 actionIndex);
janakr93e3eea2017-03-30 22:09:37 +0000199 return artifact.getParent().equals(treeArtifact);
200 }
201 }),
202 new Function<Artifact, TreeFileArtifact>() {
203 @Override
204 public TreeFileArtifact apply(Artifact artifact) {
205 return (TreeFileArtifact) artifact;
206 }
207 });
Rumou Duan73876202016-06-06 18:52:08 +0000208
209 Preconditions.checkState(
210 !Iterables.isEmpty(treeFileArtifacts),
janakr93e3eea2017-03-30 22:09:37 +0000211 "Action denoted by %s does not output TreeFileArtifact under %s",
212 expandedActionExecutionKeys.get(i),
Rumou Duan73876202016-06-06 18:52:08 +0000213 treeArtifact);
214
215 for (TreeFileArtifact treeFileArtifact : treeFileArtifacts) {
Janak Ramakrishnan59fec4e2017-03-20 17:51:39 +0000216 FileArtifactValue value =
217 createSimpleFileArtifactValue(treeFileArtifact, actionExecutionValue);
Rumou Duan73876202016-06-06 18:52:08 +0000218 map.put(treeFileArtifact, value);
219 }
220 }
221
222 // Return the aggregated TreeArtifactValue.
223 return TreeArtifactValue.create(map.build());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100224 }
225
Janak Ramakrishnanad77f972016-07-29 20:58:42 +0000226 private FileArtifactValue createSourceValue(Artifact artifact, boolean mandatory, Environment env)
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000227 throws MissingInputFileException, InterruptedException {
tomluee6a6862018-01-17 14:36:26 -0800228 SkyKey fileSkyKey =
229 FileValue.key(RootedPath.toRootedPath(artifact.getRoot().getRoot(), artifact.getPath()));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100230 FileValue fileValue;
231 try {
ulfjacke4794532018-01-12 02:11:17 -0800232 fileValue = (FileValue) env.getValueOrThrow(fileSkyKey, IOException.class);
233 } catch (IOException e) {
ulfjackef5c35b2017-07-25 15:17:49 +0200234 throw makeMissingInputFileException(artifact, mandatory, e, env.getListener());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100235 }
236 if (fileValue == null) {
237 return null;
238 }
239 if (!fileValue.exists()) {
Googler17810ad2017-11-29 10:54:23 -0800240 if (!mandatory) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100241 return FileArtifactValue.MISSING_FILE_MARKER;
242 } else {
ulfjackef5c35b2017-07-25 15:17:49 +0200243 throw makeMissingInputFileException(artifact, mandatory, null, env.getListener());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100244 }
245 }
246 try {
247 return FileArtifactValue.create(artifact, fileValue);
248 } catch (IOException e) {
ulfjackef5c35b2017-07-25 15:17:49 +0200249 throw makeMissingInputFileException(artifact, mandatory, e, env.getListener());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100250 }
251 }
252
ulfjackef5c35b2017-07-25 15:17:49 +0200253 private static MissingInputFileException makeMissingInputFileException(
254 Artifact artifact, boolean mandatory, Exception failure, EventHandler reporter) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100255 String extraMsg = (failure == null) ? "" : (":" + failure.getMessage());
buchgrd4d3d502018-08-02 06:47:19 -0700256 MissingInputFileException ex =
257 new MissingInputFileException(constructErrorMessage(artifact) + extraMsg, null);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100258 if (mandatory) {
259 reporter.handle(Event.error(ex.getLocation(), ex.getMessage()));
260 }
261 return ex;
262 }
263
264 // Non-aggregating artifact -- should contain at most one piece of artifact data.
265 // data may be null if and only if artifact is a middleman artifact.
Janak Ramakrishnan59fec4e2017-03-20 17:51:39 +0000266 private static FileArtifactValue createSimpleFileArtifactValue(
ulfjackef5c35b2017-07-25 15:17:49 +0200267 Artifact artifact, ActionExecutionValue actionValue) {
Rumou Duan73876202016-06-06 18:52:08 +0000268 FileArtifactValue value = actionValue.getArtifactValue(artifact);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100269 if (value != null) {
270 return value;
271 }
272 // Middleman artifacts have no corresponding files, so their ArtifactValues should have already
273 // been constructed during execution of the action.
274 Preconditions.checkState(!artifact.isMiddlemanArtifact(), artifact);
janakr0c42fc82018-09-14 10:37:25 -0700275 ArtifactFileMetadata data =
buchgrd4d3d502018-08-02 06:47:19 -0700276 Preconditions.checkNotNull(actionValue.getData(artifact), "%s %s", artifact, actionValue);
277 Preconditions.checkNotNull(
278 data.getDigest(), "Digest should already have been calculated for %s (%s)", artifact, data);
Janak Ramakrishnan59fec4e2017-03-20 17:51:39 +0000279 // Directories are special-cased because their mtimes are used, so should have been constructed
280 // during execution of the action (in ActionMetadataHandler#maybeStoreAdditionalData).
281 Preconditions.checkState(data.isFile(), "Unexpected not file %s (%s)", artifact, data);
ulfjack8896d2e2018-01-19 02:55:21 -0800282 return FileArtifactValue.createNormalFile(data);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100283 }
284
shahan7bcb8ed2018-06-27 16:25:59 -0700285 @Nullable
Janak Ramakrishnanad77f972016-07-29 20:58:42 +0000286 private static AggregatingArtifactValue createAggregatingValue(
287 Artifact artifact,
288 ActionAnalysisMetadata action,
289 FileArtifactValue value,
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000290 SkyFunction.Environment env)
291 throws InterruptedException {
buchgrd4d3d502018-08-02 06:47:19 -0700292 ImmutableList.Builder<Pair<Artifact, FileArtifactValue>> fileInputsBuilder =
293 ImmutableList.builder();
294 ImmutableList.Builder<Pair<Artifact, TreeArtifactValue>> directoryInputsBuilder =
295 ImmutableList.builder();
janakrbf4123d2018-07-24 11:38:19 -0700296 for (Map.Entry<SkyKey, SkyValue> entry : env.getValues(action.getInputs()).entrySet()) {
Janak Ramakrishnanad77f972016-07-29 20:58:42 +0000297 Artifact input = ArtifactSkyKey.artifact(entry.getKey());
298 SkyValue inputValue = entry.getValue();
shahan7bcb8ed2018-06-27 16:25:59 -0700299 if (inputValue == null) {
300 return null;
301 }
Benjamin Peterson63748e42018-06-03 22:11:16 -0700302 if (inputValue instanceof FileArtifactValue) {
buchgrd4d3d502018-08-02 06:47:19 -0700303 fileInputsBuilder.add(Pair.of(input, (FileArtifactValue) inputValue));
Benjamin Peterson63748e42018-06-03 22:11:16 -0700304 } else if (inputValue instanceof TreeArtifactValue) {
buchgrd4d3d502018-08-02 06:47:19 -0700305 directoryInputsBuilder.add(Pair.of(input, (TreeArtifactValue) inputValue));
Benjamin Peterson63748e42018-06-03 22:11:16 -0700306 } else {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100307 // We do not recurse in aggregating middleman artifacts.
buchgrd4d3d502018-08-02 06:47:19 -0700308 Preconditions.checkState(
309 !(inputValue instanceof AggregatingArtifactValue),
310 "%s %s %s",
311 artifact,
312 action,
313 inputValue);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100314 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100315 }
buchgrd4d3d502018-08-02 06:47:19 -0700316
317 ImmutableList<Pair<Artifact, FileArtifactValue>> fileInputs =
318 ImmutableList.sortedCopyOf(
319 Comparator.comparing(pair -> pair.getFirst().getExecPathString()),
320 fileInputsBuilder.build());
321 ImmutableList<Pair<Artifact, TreeArtifactValue>> directoryInputs =
322 ImmutableList.sortedCopyOf(
323 Comparator.comparing(pair -> pair.getFirst().getExecPathString()),
324 directoryInputsBuilder.build());
325
Benjamin Petersonc868c472018-05-28 08:37:15 -0700326 return (action.getActionType() == MiddlemanType.AGGREGATING_MIDDLEMAN)
buchgrd4d3d502018-08-02 06:47:19 -0700327 ? new AggregatingArtifactValue(fileInputs, directoryInputs, value)
328 : new RunfilesArtifactValue(fileInputs, directoryInputs, value);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100329 }
330
331 /**
332 * Returns whether this value needs to contain the data of all its inputs. Currently only tests to
Benjamin Petersonc868c472018-05-28 08:37:15 -0700333 * see if the action is an aggregating or runfiles middleman action. However, may include Fileset
334 * artifacts in the future.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100335 */
Rumou Duan33bab462016-04-25 17:55:12 +0000336 private static boolean isAggregatingValue(ActionAnalysisMetadata action) {
Benjamin Petersonc868c472018-05-28 08:37:15 -0700337 switch (action.getActionType()) {
338 case AGGREGATING_MIDDLEMAN:
339 case RUNFILES_MIDDLEMAN:
340 return true;
341 default:
342 return false;
343 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100344 }
345
346 @Override
347 public String extractTag(SkyKey skyKey) {
janakrbf4123d2018-07-24 11:38:19 -0700348 return Label.print(ArtifactSkyKey.artifact(skyKey).getOwner());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100349 }
350
janakrbaf52ae2018-02-14 09:03:18 -0800351 static ActionLookupKey getActionLookupKey(Artifact artifact) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100352 ArtifactOwner artifactOwner = artifact.getArtifactOwner();
353
354 Preconditions.checkState(artifactOwner instanceof ActionLookupKey, "", artifact, artifactOwner);
janakr573807d2018-01-11 14:02:35 -0800355 return (ActionLookupKey) artifactOwner;
Rumou Duan73876202016-06-06 18:52:08 +0000356 }
357
janakr93e3eea2017-03-30 22:09:37 +0000358 @Nullable
janakrb9d8d582018-06-13 21:57:19 -0700359 static ActionLookupValue getActionLookupValue(
janakr93e3eea2017-03-30 22:09:37 +0000360 SkyKey actionLookupKey, SkyFunction.Environment env, Artifact artifact)
361 throws InterruptedException {
362 ActionLookupValue value = (ActionLookupValue) env.getValue(actionLookupKey);
363 if (value == null) {
364 ArtifactOwner artifactOwner = artifact.getArtifactOwner();
365 Preconditions.checkState(
janakr573807d2018-01-11 14:02:35 -0800366 artifactOwner == CoverageReportValue.COVERAGE_REPORT_KEY,
janakr93e3eea2017-03-30 22:09:37 +0000367 "Not-yet-present artifact owner: %s (%s %s)",
368 artifactOwner,
369 artifact,
370 actionLookupKey);
371 return null;
Rumou Duan73876202016-06-06 18:52:08 +0000372 }
janakr93e3eea2017-03-30 22:09:37 +0000373 return value;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100374 }
375
376 private static final class ArtifactFunctionException extends SkyFunctionException {
377 ArtifactFunctionException(MissingInputFileException e, Transience transience) {
378 super(e, transience);
379 }
380
Rumou Duan3ddb4c92016-06-13 20:10:48 +0000381 ArtifactFunctionException(IOException e, Transience transience) {
382 super(e, transience);
383 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100384 }
385
386 private static String constructErrorMessage(Artifact artifact) {
387 if (artifact.getOwner() == null) {
388 return String.format("missing input file '%s'", artifact.getPath().getPathString());
389 } else {
390 return String.format("missing input file '%s'", artifact.getOwner());
391 }
392 }
393}