diff options
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.java | 214 |
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); + } + } +} |