aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/actions/BaseSpawn.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/actions/BaseSpawn.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/BaseSpawn.java214
1 files changed, 214 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/BaseSpawn.java b/src/main/java/com/google/devtools/build/lib/actions/BaseSpawn.java
new file mode 100644
index 0000000000..dd879c2b88
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/actions/BaseSpawn.java
@@ -0,0 +1,214 @@
+// Copyright 2014 Google Inc. 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.actions;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.devtools.build.lib.actions.extra.EnvironmentVariable;
+import com.google.devtools.build.lib.actions.extra.SpawnInfo;
+import com.google.devtools.build.lib.util.CommandDescriptionForm;
+import com.google.devtools.build.lib.util.CommandFailureUtils;
+import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * Base implementation of a Spawn.
+ */
+@Immutable
+public class BaseSpawn implements Spawn {
+ private final ImmutableList<String> arguments;
+ private final ImmutableMap<String, String> environment;
+ private final ImmutableMap<String, String> executionInfo;
+ private final ImmutableMap<PathFragment, Artifact> runfilesManifests;
+ private final ActionMetadata action;
+ private final ResourceSet localResources;
+
+ /**
+ * Returns a new Spawn. The caller must not modify the parameters after the call; neither will
+ * this method.
+ */
+ public BaseSpawn(List<String> arguments,
+ Map<String, String> environment,
+ Map<String, String> executionInfo,
+ Map<PathFragment, Artifact> runfilesManifests,
+ ActionMetadata action,
+ ResourceSet localResources) {
+ this.arguments = ImmutableList.copyOf(arguments);
+ this.environment = ImmutableMap.copyOf(environment);
+ this.executionInfo = ImmutableMap.copyOf(executionInfo);
+ this.runfilesManifests = ImmutableMap.copyOf(runfilesManifests);
+ this.action = action;
+ this.localResources = localResources;
+ }
+
+ /**
+ * Returns a new Spawn.
+ */
+ public BaseSpawn(List<String> arguments,
+ Map<String, String> environment,
+ Map<String, String> executionInfo,
+ // TODO(bazel-team): have this always be non-null.
+ @Nullable Artifact runfilesManifest,
+ ActionMetadata action,
+ ResourceSet localResources) {
+ this(arguments, environment, executionInfo,
+ ((runfilesManifest != null)
+ ? ImmutableMap.of(runfilesForFragment(new PathFragment(arguments.get(0))),
+ runfilesManifest)
+ : ImmutableMap.<PathFragment, Artifact>of()),
+ action, localResources);
+ }
+
+ public static PathFragment runfilesForFragment(PathFragment pathFragment) {
+ return pathFragment.getParentDirectory().getChild(pathFragment.getBaseName() + ".runfiles");
+ }
+
+ /**
+ * Returns a new Spawn.
+ */
+ public BaseSpawn(List<String> arguments,
+ Map<String, String> environment,
+ Map<String, String> executionInfo,
+ ActionMetadata action,
+ ResourceSet localResources) {
+ this(arguments, environment, executionInfo,
+ ImmutableMap.<PathFragment, Artifact>of(), action, localResources);
+ }
+
+ @Override
+ public boolean isRemotable() {
+ return !executionInfo.containsKey("local");
+ }
+
+ @Override
+ public final ImmutableMap<String, String> getExecutionInfo() {
+ return executionInfo;
+ }
+
+ @Override
+ public String asShellCommand(Path workingDir) {
+ return asShellCommand(getArguments(), workingDir, getEnvironment());
+ }
+
+ @Override
+ public ImmutableMap<PathFragment, Artifact> getRunfilesManifests() {
+ return runfilesManifests;
+ }
+
+ @Override
+ public ImmutableList<Artifact> getFilesetManifests() {
+ return ImmutableList.<Artifact>of();
+ }
+
+ @Override
+ public SpawnInfo getExtraActionInfo() {
+ SpawnInfo.Builder info = SpawnInfo.newBuilder();
+
+ info.addAllArgument(getArguments());
+ for (Map.Entry<String, String> variable : getEnvironment().entrySet()) {
+ info.addVariable(EnvironmentVariable.newBuilder()
+ .setName(variable.getKey())
+ .setValue(variable.getValue()).build());
+ }
+ for (ActionInput input : getInputFiles()) {
+ // Explicitly ignore middleman artifacts here.
+ if (!(input instanceof Artifact) || !((Artifact) input).isMiddlemanArtifact()) {
+ info.addInputFile(input.getExecPathString());
+ }
+ }
+ info.addAllOutputFile(ActionInputHelper.toExecPaths(getOutputFiles()));
+ return info.build();
+ }
+
+ @Override
+ public ImmutableList<String> getArguments() {
+ // TODO(bazel-team): this method should be final, as the correct value of the args can be
+ // injected in the ctor.
+ return arguments;
+ }
+
+ @Override
+ public ImmutableMap<String, String> getEnvironment() {
+ if (getRunfilesManifests().size() != 1) {
+ return environment;
+ }
+
+ ImmutableMap.Builder<String, String> env = ImmutableMap.builder();
+ env.putAll(environment);
+ for (Map.Entry<PathFragment, Artifact> e : getRunfilesManifests().entrySet()) {
+ // TODO(bazel-team): Unify these into a single env variable.
+ env.put("JAVA_RUNFILES", e.getKey().getPathString() + "/");
+ env.put("PYTHON_RUNFILES", e.getKey().getPathString() + "/");
+ }
+ return env.build();
+ }
+
+ @Override
+ public Iterable<? extends ActionInput> getInputFiles() {
+ return action.getInputs();
+ }
+
+ @Override
+ public Collection<? extends ActionInput> getOutputFiles() {
+ return action.getOutputs();
+ }
+
+ @Override
+ public ActionMetadata getResourceOwner() {
+ return action;
+ }
+
+ @Override
+ public ResourceSet getLocalResources() {
+ return localResources;
+ }
+
+ @Override
+ public ActionOwner getOwner() { return action.getOwner(); }
+
+ @Override
+ public String getMnemonic() { return action.getMnemonic(); }
+
+ /**
+ * Convert a working dir + environment map + arg list into a Bourne shell
+ * command.
+ */
+ public static String asShellCommand(Collection<String> arguments,
+ Path workingDirectory,
+ Map<String, String> environment) {
+ // We print this command out in such a way that it can safely be
+ // copied+pasted as a Bourne shell command. This is extremely valuable for
+ // debugging.
+ return CommandFailureUtils.describeCommand(CommandDescriptionForm.COMPLETE,
+ arguments, environment, workingDirectory.getPathString());
+ }
+
+ /**
+ * A local spawn requiring zero resources.
+ */
+ public static class Local extends BaseSpawn {
+ public Local(List<String> arguments, Map<String, String> environment, ActionMetadata action) {
+ super(arguments, environment, ImmutableMap.<String, String>of("local", ""),
+ action, ResourceSet.ZERO);
+ }
+ }
+}