aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Francois-Rene Rideau <tunes@google.com>2015-10-07 19:25:38 +0000
committerGravatar Han-Wen Nienhuys <hanwen@google.com>2015-10-08 12:11:40 +0000
commit79be96fcf183d992d8b6347816f8511c8956435d (patch)
tree03b8ca084436f62a8750eac91518dd8038b39a26 /src
parentc86cfe6112ae4fdd18de5a2ed68fe55ef2d34b04 (diff)
Description redacted.
-- MOS_MIGRATED_REVID=104886879
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/CommandHelper.java35
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java137
2 files changed, 163 insertions, 9 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/CommandHelper.java b/src/main/java/com/google/devtools/build/lib/analysis/CommandHelper.java
index 13a30b05f8..0a48b2c50f 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/CommandHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/CommandHelper.java
@@ -37,6 +37,8 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import javax.annotation.Nullable;
+
/**
* Provides shared functionality for parameterized command-line launching
* e.g. {@link com.google.devtools.build.lib.view.genrule.GenRule}
@@ -169,17 +171,20 @@ public final class CommandHelper {
}
/**
- * Resolves the 'cmd' attribute, and expands known locations for $(location)
+ * Resolves a command, and expands known locations for $(location)
* variables.
*/
- @SkylarkCallable(doc = "Experimental.")
public String resolveCommandAndExpandLabels(
- Boolean supportLegacyExpansion, Boolean allowDataInLabel) {
- String command = ruleContext.attributes().get("cmd", Type.STRING);
- command =
- new LocationExpander(ruleContext, labelMap, allowDataInLabel)
- .expandAttribute("cmd", command);
-
+ String command,
+ @Nullable String attribute,
+ Boolean supportLegacyExpansion,
+ Boolean allowDataInLabel) {
+ LocationExpander expander = new LocationExpander(ruleContext, labelMap, allowDataInLabel);
+ if (attribute != null) {
+ command = expander.expandAttribute(attribute, command);
+ } else {
+ command = expander.expand(command);
+ }
if (supportLegacyExpansion) {
command = expandLabels(command, labelMap);
}
@@ -187,6 +192,20 @@ public final class CommandHelper {
}
/**
+ * Resolves the 'cmd' attribute, and expands known locations for $(location)
+ * variables.
+ */
+ @SkylarkCallable(doc = "Experimental.")
+ public String resolveCommandAndExpandLabels(
+ Boolean supportLegacyExpansion, Boolean allowDataInLabel) {
+ return resolveCommandAndExpandLabels(
+ ruleContext.attributes().get("cmd", Type.STRING),
+ "cmd",
+ supportLegacyExpansion,
+ allowDataInLabel);
+ }
+
+ /**
* Expands labels occurring in the string "expr" in the rule 'cmd'.
* Each label must be valid, be a declared prerequisite, and expand to a
* unique path.
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
index cd51e3cb8b..5bf0ac617d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java
@@ -49,17 +49,23 @@ import com.google.devtools.build.lib.syntax.BuiltinFunction;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.EvalUtils;
+import com.google.devtools.build.lib.syntax.Printer;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
+import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.SkylarkSignature;
import com.google.devtools.build.lib.syntax.SkylarkSignature.Param;
import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
+import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.syntax.Type.ConversionException;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
@@ -125,7 +131,7 @@ public class SkylarkRuleImplementationFunctions {
@Param(name = "input_manifests", type = Map.class, noneable = true,
defaultValue = "None",
doc = "sets the map of input manifests files; "
- + "they are typicially generated by the command_helper")},
+ + "they are typically generated by the command_helper")},
useLocation = true)
private static final BuiltinFunction createSpawnAction = new BuiltinFunction("action") {
public Runtime.NoneType invoke(
@@ -489,6 +495,32 @@ public class SkylarkRuleImplementationFunctions {
}
};
+
+ // TODO(bazel-team): find a better way to typecheck this argument.
+ @SuppressWarnings("unchecked")
+ private static Map<Label, Iterable<Artifact>> checkLabelDict(Map<?, ?> labelDict, Location loc)
+ throws EvalException {
+ for (Map.Entry<?, ?> entry : labelDict.entrySet()) {
+ Object key = entry.getKey();
+ if (!(key instanceof Label)) {
+ throw new EvalException(
+ loc, Printer.format("invalid key %r in 'label_dict'", key));
+ }
+ Object val = entry.getValue();
+ if (!(val instanceof Iterable)) {
+ throw new EvalException(
+ loc, Printer.format("invalid value %r in 'label_dict'", val));
+ }
+ for (Object file : (Iterable) val) {
+ if (!(file instanceof Artifact)) {
+ throw new EvalException(
+ loc, Printer.format("invalid value %r in 'label_dict'", val));
+ }
+ }
+ }
+ return (Map<Label, Iterable<Artifact>>) labelDict;
+ }
+
@SkylarkSignature(
name = "command_helper",
doc = "Experimental. Creates a command helper class.",
@@ -527,6 +559,109 @@ public class SkylarkRuleImplementationFunctions {
}
};
+ @SkylarkSignature(
+ name = "resolve_command",
+ doc = "Experimental."
+ + "Returns a tuple of the list of resolved inputs, "
+ + "the argv list for the resolved command, and "
+ + "the dict mapping locations to runfiles required to run the command",
+ objectType = SkylarkRuleContext.class,
+ returnType = Tuple.class,
+ mandatoryPositionals = {
+ @Param(name = "self", type = SkylarkRuleContext.class, doc = "this RuleContext")
+ },
+ optionalNamedOnly = {
+ @Param(
+ name = "command",
+ type = String.class, // string
+ defaultValue = "''",
+ doc = "command to resolve"
+ ),
+ @Param(
+ name = "attribute",
+ type = String.class, // string
+ noneable = true,
+ doc = "name of the associated attribute for which to issue an error, or None"
+ ),
+ @Param(
+ name = "suffix",
+ type = String.class, // string
+ defaultValue = "'.script.sh'",
+ doc = "suffix of script if command line too long"
+ ),
+ @Param(
+ name = "expand_locations",
+ type = Boolean.class,
+ defaultValue = "False",
+ doc = "shall we expand $(location) variables?"
+ ),
+ @Param(
+ name = "make_variables",
+ type = Map.class, // dict(string, string)
+ noneable = true,
+ doc = "make variables to expand, or None"
+ ),
+ @Param(
+ name = "tools",
+ defaultValue = "[]",
+ type = SkylarkList.class,
+ generic1 = TransitiveInfoCollection.class,
+ doc = "list of tools (list of targets)"
+ ),
+ @Param(
+ name = "label_dict",
+ type = Map.class,
+ defaultValue = "{}",
+ doc =
+ "dictionary of resolved labels and the corresponding list of Files "
+ + "(a dict of Label : list of Files)"
+ )
+ },
+ useLocation = true, useEnvironment = true
+ )
+ private static final BuiltinFunction resolveCommand =
+ new BuiltinFunction("resolve_command") {
+ @SuppressWarnings("unchecked")
+ public Tuple invoke(
+ SkylarkRuleContext ctx,
+ String command,
+ Object attributeO,
+ String suffix,
+ Boolean expandLocations,
+ Object makeVariablesO,
+ SkylarkList tools,
+ Map<?, ?> labelDictM,
+ Location loc,
+ Environment env)
+ throws ConversionException, EvalException {
+ Label ruleLabel = ctx.getLabel();
+ Map<Label, Iterable<Artifact>> labelDict = checkLabelDict(labelDictM, loc);
+ // The best way to fix this probably is to convert CommandHelper to Skylark.
+ CommandHelper helper = new CommandHelper(
+ ctx.getRuleContext(),
+ castList(tools, TransitiveInfoCollection.class),
+ ImmutableMap.copyOf(labelDict));
+ String attribute = Type.STRING.convertOptional(attributeO, "attribute", ruleLabel);
+ if (expandLocations) {
+ command = helper.resolveCommandAndExpandLabels(
+ command, attribute, false, false);
+ }
+ // TODO(bazel_team): Implement heuristic label expansion
+ if (!EvalUtils.isNullOrNone(makeVariablesO)) {
+ Map<String, String> makeVariables = Type.STRING_DICT.convert(
+ makeVariablesO, "make_variables", ruleLabel);
+ command = ctx.expandMakeVariables(attribute, command, makeVariables);
+ }
+ List<Artifact> inputs = new ArrayList<>();
+ inputs.addAll(helper.getResolvedTools());
+ List<String> argv = helper.buildCommandLine(command, inputs, suffix);
+ return Tuple.of(
+ new MutableList(inputs, env),
+ new MutableList(argv, env),
+ helper.getRemoteRunfileManifestMap());
+ }
+ };
+
static {
SkylarkSignatureProcessor.configureSkylarkFunctions(SkylarkRuleImplementationFunctions.class);
}