blob: 44a79f9314afc2df0dc61afd223cbc127367c471 [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.
14
15package com.google.devtools.build.lib.actions;
16
tomlua155b532017-11-08 20:12:47 +010017import com.google.common.base.Preconditions;
kush2ce45a22018-05-02 14:15:37 -070018import com.google.common.collect.ImmutableList;
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +000019import com.google.common.collect.ImmutableMap;
ulfjack77c9f5e2017-06-19 14:17:52 +020020import com.google.common.eventbus.EventBus;
Michael Thvedt434e68e2016-02-09 00:57:46 +000021import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010022import com.google.devtools.build.lib.actions.cache.MetadataHandler;
philwo3bcb9f62017-09-06 12:52:21 +020023import com.google.devtools.build.lib.clock.Clock;
ulfjack77c9f5e2017-06-19 14:17:52 +020024import com.google.devtools.build.lib.cmdline.Label;
25import com.google.devtools.build.lib.events.Event;
ulfjack77c9f5e2017-06-19 14:17:52 +020026import com.google.devtools.build.lib.events.EventKind;
Benjamin Peterson1bbeadc2018-04-26 05:27:10 -070027import com.google.devtools.build.lib.events.ExtendedEventHandler;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010028import com.google.devtools.build.lib.util.io.FileOutErr;
tomluf903eb52017-10-27 12:12:11 -040029import com.google.devtools.build.lib.vfs.FileSystem;
ulfjack77c9f5e2017-06-19 14:17:52 +020030import com.google.devtools.build.lib.vfs.Path;
kush2ce45a22018-05-02 14:15:37 -070031import com.google.devtools.build.lib.vfs.PathFragment;
shahanb1dd4e32018-05-09 08:23:31 -070032import com.google.devtools.build.lib.vfs.Root;
Janak Ramakrishnan29c5ab42015-05-14 19:38:12 +000033import com.google.devtools.build.skyframe.SkyFunction;
34import com.google.devtools.build.skyframe.SkyFunction.Environment;
ulfjack77c9f5e2017-06-19 14:17:52 +020035import com.google.devtools.common.options.OptionsClassProvider;
ulfjack1a328e32017-04-06 10:25:16 +000036import java.io.Closeable;
37import java.io.IOException;
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +000038import java.util.Map;
Janak Ramakrishnan29c5ab42015-05-14 19:38:12 +000039import javax.annotation.Nullable;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010040
41/**
42 * A class that groups services in the scope of the action. Like the FileOutErr object.
43 */
ulfjack1a328e32017-04-06 10:25:16 +000044public class ActionExecutionContext implements Closeable {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010045
ahumeskybe31bb82018-07-26 13:37:45 -070046 /** Enum for --subcommands flag */
47 public enum ShowSubcommands {
48 TRUE(true, false), PRETTY_PRINT(true, true), FALSE(false, false);
49
50 private final boolean shouldShowSubcommands;
51 private final boolean prettyPrintArgs;
52
53 private ShowSubcommands(boolean shouldShowSubcommands, boolean prettyPrintArgs) {
54 this.shouldShowSubcommands = shouldShowSubcommands;
55 this.prettyPrintArgs = prettyPrintArgs;
56 }
57 }
58
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010059 private final Executor executor;
shahan499503b2018-06-07 18:57:07 -070060 private final MetadataProvider actionInputFileCache;
ulfjack7599a4d2017-07-21 13:58:33 +020061 private final ActionInputPrefetcher actionInputPrefetcher;
tomlu3d1a1942017-11-29 14:01:21 -080062 private final ActionKeyContext actionKeyContext;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010063 private final MetadataHandler metadataHandler;
64 private final FileOutErr fileOutErr;
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +000065 private final ImmutableMap<String, String> clientEnv;
kush2ce45a22018-05-02 14:15:37 -070066 private final ImmutableMap<PathFragment, ImmutableList<FilesetOutputSymlink>>
67 inputFilesetMappings;
shahanb1dd4e32018-05-09 08:23:31 -070068 @Nullable private final ArtifactExpander artifactExpander;
69 @Nullable private final Environment env;
70
71 @Nullable private final FileSystem actionFileSystem;
felly39974a42018-08-09 14:28:14 -070072 @Nullable private final Object skyframeDepsResult;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010073
kush2ce45a22018-05-02 14:15:37 -070074 @Nullable private ImmutableList<FilesetOutputSymlink> outputSymlinks;
75
fellyd3d86442018-06-08 18:29:43 -070076 private final ArtifactPathResolver pathResolver;
77
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +000078 private ActionExecutionContext(
79 Executor executor,
shahan499503b2018-06-07 18:57:07 -070080 MetadataProvider actionInputFileCache,
ulfjack7599a4d2017-07-21 13:58:33 +020081 ActionInputPrefetcher actionInputPrefetcher,
tomlu3d1a1942017-11-29 14:01:21 -080082 ActionKeyContext actionKeyContext,
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +000083 MetadataHandler metadataHandler,
84 FileOutErr fileOutErr,
85 Map<String, String> clientEnv,
kush2ce45a22018-05-02 14:15:37 -070086 ImmutableMap<PathFragment, ImmutableList<FilesetOutputSymlink>> inputFilesetMappings,
Michael Thvedt434e68e2016-02-09 00:57:46 +000087 @Nullable ArtifactExpander artifactExpander,
shahanb1dd4e32018-05-09 08:23:31 -070088 @Nullable SkyFunction.Environment env,
felly39974a42018-08-09 14:28:14 -070089 @Nullable FileSystem actionFileSystem,
90 @Nullable Object skyframeDepsResult) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010091 this.actionInputFileCache = actionInputFileCache;
ulfjack7599a4d2017-07-21 13:58:33 +020092 this.actionInputPrefetcher = actionInputPrefetcher;
tomlu3d1a1942017-11-29 14:01:21 -080093 this.actionKeyContext = actionKeyContext;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010094 this.metadataHandler = metadataHandler;
95 this.fileOutErr = fileOutErr;
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +000096 this.clientEnv = ImmutableMap.copyOf(clientEnv);
kush2ce45a22018-05-02 14:15:37 -070097 this.inputFilesetMappings = inputFilesetMappings;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010098 this.executor = executor;
Michael Thvedt434e68e2016-02-09 00:57:46 +000099 this.artifactExpander = artifactExpander;
Janak Ramakrishnan29c5ab42015-05-14 19:38:12 +0000100 this.env = env;
shahanb1dd4e32018-05-09 08:23:31 -0700101 this.actionFileSystem = actionFileSystem;
felly39974a42018-08-09 14:28:14 -0700102 this.skyframeDepsResult = skyframeDepsResult;
fellyfc83d752018-06-13 14:57:29 -0700103 this.pathResolver = ArtifactPathResolver.createPathResolver(actionFileSystem,
fellyd3d86442018-06-08 18:29:43 -0700104 // executor is only ever null in testing.
105 executor == null ? null : executor.getExecRoot());
Janak Ramakrishnan29c5ab42015-05-14 19:38:12 +0000106 }
107
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000108 public ActionExecutionContext(
109 Executor executor,
shahan499503b2018-06-07 18:57:07 -0700110 MetadataProvider actionInputFileCache,
ulfjack7599a4d2017-07-21 13:58:33 +0200111 ActionInputPrefetcher actionInputPrefetcher,
tomlu3d1a1942017-11-29 14:01:21 -0800112 ActionKeyContext actionKeyContext,
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000113 MetadataHandler metadataHandler,
114 FileOutErr fileOutErr,
115 Map<String, String> clientEnv,
kush2ce45a22018-05-02 14:15:37 -0700116 ImmutableMap<PathFragment, ImmutableList<FilesetOutputSymlink>> inputFilesetMappings,
shahanb1dd4e32018-05-09 08:23:31 -0700117 ArtifactExpander artifactExpander,
felly39974a42018-08-09 14:28:14 -0700118 @Nullable FileSystem actionFileSystem,
119 @Nullable Object skyframeDepsResult) {
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000120 this(
121 executor,
122 actionInputFileCache,
ulfjack7599a4d2017-07-21 13:58:33 +0200123 actionInputPrefetcher,
tomlu3d1a1942017-11-29 14:01:21 -0800124 actionKeyContext,
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000125 metadataHandler,
126 fileOutErr,
127 clientEnv,
kush2ce45a22018-05-02 14:15:37 -0700128 inputFilesetMappings,
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000129 artifactExpander,
shahanb1dd4e32018-05-09 08:23:31 -0700130 /*env=*/ null,
felly39974a42018-08-09 14:28:14 -0700131 actionFileSystem,
132 skyframeDepsResult);
Janak Ramakrishnan29c5ab42015-05-14 19:38:12 +0000133 }
134
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000135 public static ActionExecutionContext forInputDiscovery(
136 Executor executor,
shahan499503b2018-06-07 18:57:07 -0700137 MetadataProvider actionInputFileCache,
ulfjack7599a4d2017-07-21 13:58:33 +0200138 ActionInputPrefetcher actionInputPrefetcher,
tomlu3d1a1942017-11-29 14:01:21 -0800139 ActionKeyContext actionKeyContext,
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000140 MetadataHandler metadataHandler,
141 FileOutErr fileOutErr,
142 Map<String, String> clientEnv,
shahanb1dd4e32018-05-09 08:23:31 -0700143 Environment env,
144 @Nullable FileSystem actionFileSystem) {
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000145 return new ActionExecutionContext(
ulfjack7599a4d2017-07-21 13:58:33 +0200146 executor,
147 actionInputFileCache,
148 actionInputPrefetcher,
tomlu3d1a1942017-11-29 14:01:21 -0800149 actionKeyContext,
ulfjack7599a4d2017-07-21 13:58:33 +0200150 metadataHandler,
151 fileOutErr,
152 clientEnv,
kush2ce45a22018-05-02 14:15:37 -0700153 ImmutableMap.of(),
shahanb1dd4e32018-05-09 08:23:31 -0700154 /*artifactExpander=*/ null,
155 env,
felly39974a42018-08-09 14:28:14 -0700156 actionFileSystem,
157 /*skyframeDepsResult=*/ null);
ulfjack7599a4d2017-07-21 13:58:33 +0200158 }
159
160 public ActionInputPrefetcher getActionInputPrefetcher() {
161 return actionInputPrefetcher;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100162 }
163
shahan499503b2018-06-07 18:57:07 -0700164 public MetadataProvider getMetadataProvider() {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100165 return actionInputFileCache;
166 }
167
168 public MetadataHandler getMetadataHandler() {
169 return metadataHandler;
170 }
171
tomluf903eb52017-10-27 12:12:11 -0400172 public FileSystem getFileSystem() {
felly7fd3b002018-05-24 15:03:40 -0700173 if (actionFileSystem != null) {
174 return actionFileSystem;
175 }
tomluf903eb52017-10-27 12:12:11 -0400176 return executor.getFileSystem();
177 }
178
ulfjack77c9f5e2017-06-19 14:17:52 +0200179 public Path getExecRoot() {
felly7fd3b002018-05-24 15:03:40 -0700180 return actionFileSystem != null
181 ? actionFileSystem.getPath(executor.getExecRoot().asFragment())
182 : executor.getExecRoot();
ulfjack77c9f5e2017-06-19 14:17:52 +0200183 }
184
185 /**
shahan18726b72018-03-15 14:18:46 -0700186 * Returns the path for an ActionInput.
187 *
188 * <p>Notably, in the future, we want any action-scoped artifacts to resolve paths using this
189 * method instead of {@link Artifact#getPath} because that does not allow filesystem injection.
190 *
shahanb1dd4e32018-05-09 08:23:31 -0700191 * <p>TODO(shahan): cleanup {@link Action}-scoped references to {@link Artifact.getPath} and
192 * {@link Artifact.getRoot}.
shahan18726b72018-03-15 14:18:46 -0700193 */
194 public Path getInputPath(ActionInput input) {
fellyd3d86442018-06-08 18:29:43 -0700195 return pathResolver.toPath(input);
shahan18726b72018-03-15 14:18:46 -0700196 }
197
shahanb1dd4e32018-05-09 08:23:31 -0700198 public Root getRoot(Artifact artifact) {
fellyd3d86442018-06-08 18:29:43 -0700199 return pathResolver.transformRoot(artifact.getRoot().getRoot());
200 }
201
fellyd3d86442018-06-08 18:29:43 -0700202 public ArtifactPathResolver getPathResolver() {
203 return pathResolver;
shahanb1dd4e32018-05-09 08:23:31 -0700204 }
205
shahan18726b72018-03-15 14:18:46 -0700206 /**
ulfjack77c9f5e2017-06-19 14:17:52 +0200207 * Returns whether failures should have verbose error messages.
208 */
209 public boolean getVerboseFailures() {
210 return executor.getVerboseFailures();
211 }
212
213 /**
214 * Returns the command line options of the Blaze command being executed.
215 */
216 public OptionsClassProvider getOptions() {
217 return executor.getOptions();
218 }
219
220 public Clock getClock() {
221 return executor.getClock();
222 }
223
224 public EventBus getEventBus() {
225 return executor.getEventBus();
226 }
227
Benjamin Peterson1bbeadc2018-04-26 05:27:10 -0700228 public ExtendedEventHandler getEventHandler() {
ulfjack77c9f5e2017-06-19 14:17:52 +0200229 return executor.getEventHandler();
230 }
231
kush2ce45a22018-05-02 14:15:37 -0700232 public ImmutableMap<PathFragment, ImmutableList<FilesetOutputSymlink>> getInputFilesetMappings() {
233 return inputFilesetMappings;
234 }
235
236 @Nullable
237 public ImmutableList<FilesetOutputSymlink> getOutputSymlinks() {
238 return outputSymlinks;
239 }
240
241 public void setOutputSymlinks(ImmutableList<FilesetOutputSymlink> outputSymlinks) {
242 Preconditions.checkState(
243 this.outputSymlinks == null,
244 "Unexpected reassignment of the outputSymlinks of a Fileset from\n:%s to:\n%s",
245 this.outputSymlinks,
246 outputSymlinks);
247 this.outputSymlinks = outputSymlinks;
248 }
249
ulfjack77c9f5e2017-06-19 14:17:52 +0200250 /**
251 * Looks up and returns an action context implementation of the given interface type.
252 */
253 public <T extends ActionContext> T getContext(Class<? extends T> type) {
254 return executor.getContext(type);
255 }
256
ulfjack77c9f5e2017-06-19 14:17:52 +0200257 /**
ulfjack77c9f5e2017-06-19 14:17:52 +0200258 * Report a subcommand event to this Executor's Reporter and, if action
259 * logging is enabled, post it on its EventBus.
260 */
ahumeskybe31bb82018-07-26 13:37:45 -0700261 public void maybeReportSubcommand(Spawn spawn) {
262 ShowSubcommands showSubcommands = executor.reportsSubcommands();
263 if (!showSubcommands.shouldShowSubcommands) {
264 return;
265 }
266
ulfjack77c9f5e2017-06-19 14:17:52 +0200267 String reason;
268 ActionOwner owner = spawn.getResourceOwner().getOwner();
269 if (owner == null) {
270 reason = spawn.getResourceOwner().prettyPrint();
271 } else {
272 reason = Label.print(owner.getLabel())
273 + " [" + spawn.getResourceOwner().prettyPrint() + "]";
274 }
ahumeskybe31bb82018-07-26 13:37:45 -0700275 String message = Spawns.asShellCommand(spawn, getExecRoot(), showSubcommands.prettyPrintArgs);
ulfjack77c9f5e2017-06-19 14:17:52 +0200276 getEventHandler().handle(Event.of(EventKind.SUBCOMMAND, null, "# " + reason + "\n" + message));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100277 }
278
Klaus Aehlig4c10f3f2016-08-26 15:58:48 +0000279 public ImmutableMap<String, String> getClientEnv() {
280 return clientEnv;
281 }
282
Michael Thvedt434e68e2016-02-09 00:57:46 +0000283 public ArtifactExpander getArtifactExpander() {
284 return artifactExpander;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100285 }
286
felly39974a42018-08-09 14:28:14 -0700287 @Nullable
288 public Object getSkyframeDepsResult() {
289 return skyframeDepsResult;
290 }
291
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100292 /**
293 * Provide that {@code FileOutErr} that the action should use for redirecting the output and error
294 * stream.
295 */
296 public FileOutErr getFileOutErr() {
297 return fileOutErr;
298 }
299
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100300 /**
Janak Ramakrishnan29c5ab42015-05-14 19:38:12 +0000301 * Provides a mechanism for the action to request values from Skyframe while it discovers inputs.
302 */
303 public Environment getEnvironmentForDiscoveringInputs() {
304 return Preconditions.checkNotNull(env);
305 }
306
tomlu3d1a1942017-11-29 14:01:21 -0800307 public ActionKeyContext getActionKeyContext() {
308 return actionKeyContext;
309 }
310
ulfjack1a328e32017-04-06 10:25:16 +0000311 @Override
312 public void close() throws IOException {
313 fileOutErr.close();
314 }
315
Janak Ramakrishnan29c5ab42015-05-14 19:38:12 +0000316 /**
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100317 * Allows us to create a new context that overrides the FileOutErr with another one. This is
318 * useful for muting the output for example.
319 */
320 public ActionExecutionContext withFileOutErr(FileOutErr fileOutErr) {
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000321 return new ActionExecutionContext(
322 executor,
323 actionInputFileCache,
ulfjack7599a4d2017-07-21 13:58:33 +0200324 actionInputPrefetcher,
tomlu3d1a1942017-11-29 14:01:21 -0800325 actionKeyContext,
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000326 metadataHandler,
327 fileOutErr,
328 clientEnv,
kush2ce45a22018-05-02 14:15:37 -0700329 inputFilesetMappings,
Klaus Aehligd2fcd9d2016-08-26 08:16:25 +0000330 artifactExpander,
shahanb1dd4e32018-05-09 08:23:31 -0700331 env,
felly39974a42018-08-09 14:28:14 -0700332 actionFileSystem,
333 skyframeDepsResult);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100334 }
335}