aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/actions/ActionInputHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/actions/ActionInputHelper.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/ActionInputHelper.java160
1 files changed, 160 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ActionInputHelper.java b/src/main/java/com/google/devtools/build/lib/actions/ActionInputHelper.java
new file mode 100644
index 0000000000..0fed9283b8
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/actions/ActionInputHelper.java
@@ -0,0 +1,160 @@
+// 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.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Collections2;
+import com.google.common.collect.Iterables;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Helper utility to create ActionInput instances.
+ */
+public final class ActionInputHelper {
+ private ActionInputHelper() {
+ }
+
+ @VisibleForTesting
+ public static Artifact.MiddlemanExpander actionGraphMiddlemanExpander(
+ final ActionGraph actionGraph) {
+ return new Artifact.MiddlemanExpander() {
+ @Override
+ public void expand(Artifact mm, Collection<? super Artifact> output) {
+ // Skyframe is stricter in that it checks that "mm" is a input of the action, because
+ // it cannot expand arbitrary middlemen without access to a global action graph.
+ // We could check this constraint here too, but it seems unnecessary. This code is
+ // going away anyway.
+ Preconditions.checkArgument(mm.isMiddlemanArtifact(),
+ "%s is not a middleman artifact", mm);
+ Action middlemanAction = actionGraph.getGeneratingAction(mm);
+ Preconditions.checkState(middlemanAction != null, mm);
+ // TODO(bazel-team): Consider expanding recursively or throwing an exception here.
+ // Most likely, this code will cause silent errors if we ever have a middleman that
+ // contains a middleman.
+ if (middlemanAction.getActionType() == Action.MiddlemanType.AGGREGATING_MIDDLEMAN) {
+ Artifact.addNonMiddlemanArtifacts(middlemanAction.getInputs(), output,
+ Functions.<Artifact>identity());
+ }
+
+ }
+ };
+ }
+
+ /**
+ * Most ActionInputs are created and never used again. On the off chance that one is, however, we
+ * implement equality via path comparison. Since file caches are keyed by ActionInput, equality
+ * checking does come up.
+ */
+ private static class BasicActionInput implements ActionInput {
+ private final String path;
+ public BasicActionInput(String path) {
+ this.path = Preconditions.checkNotNull(path);
+ }
+
+ @Override
+ public String getExecPathString() {
+ return path;
+ }
+
+ @Override
+ public int hashCode() {
+ return path.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (other == null) {
+ return false;
+ }
+ if (!this.getClass().equals(other.getClass())) {
+ return false;
+ }
+ return this.path.equals(((BasicActionInput) other).path);
+ }
+
+ @Override
+ public String toString() {
+ return "BasicActionInput: " + path;
+ }
+ }
+
+ /**
+ * Creates an ActionInput with just the given relative path and no digest.
+ *
+ * @param path the relative path of the input.
+ * @return a ActionInput.
+ */
+ public static ActionInput fromPath(String path) {
+ return new BasicActionInput(path);
+ }
+
+ private static final Function<String, ActionInput> FROM_PATH =
+ new Function<String, ActionInput>() {
+ @Override
+ public ActionInput apply(String path) {
+ return fromPath(path);
+ }
+ };
+
+ /**
+ * Creates a sequence of {@link ActionInput}s from a sequence of string paths.
+ */
+ public static Collection<ActionInput> fromPaths(Collection<String> paths) {
+ return Collections2.transform(paths, FROM_PATH);
+ }
+
+ /**
+ * Expands middleman artifacts in a sequence of {@link ActionInput}s.
+ *
+ * <p>Non-middleman artifacts are returned untouched.
+ */
+ public static List<ActionInput> expandMiddlemen(Iterable<? extends ActionInput> inputs,
+ Artifact.MiddlemanExpander middlemanExpander) {
+
+ List<ActionInput> result = new ArrayList<>();
+ List<Artifact> containedArtifacts = new ArrayList<>();
+ for (ActionInput input : inputs) {
+ if (!(input instanceof Artifact)) {
+ result.add(input);
+ continue;
+ }
+ containedArtifacts.add((Artifact) input);
+ }
+ Artifact.addExpandedArtifacts(containedArtifacts, result, middlemanExpander);
+ return result;
+ }
+
+ /** Formatter for execPath String output. Public because Artifact uses it directly. */
+ public static final Function<ActionInput, String> EXEC_PATH_STRING_FORMATTER =
+ new Function<ActionInput, String>() {
+ @Override
+ public String apply(ActionInput input) {
+ return input.getExecPathString();
+ }
+ };
+
+ public static Iterable<String> toExecPaths(Iterable<? extends ActionInput> artifacts) {
+ return Iterables.transform(artifacts, EXEC_PATH_STRING_FORMATTER);
+ }
+}