diff options
author | 2015-10-07 19:25:38 +0000 | |
---|---|---|
committer | 2015-10-08 12:11:40 +0000 | |
commit | 79be96fcf183d992d8b6347816f8511c8956435d (patch) | |
tree | 03b8ca084436f62a8750eac91518dd8038b39a26 /src | |
parent | c86cfe6112ae4fdd18de5a2ed68fe55ef2d34b04 (diff) |
Description redacted.
--
MOS_MIGRATED_REVID=104886879
Diffstat (limited to 'src')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/analysis/CommandHelper.java | 35 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleImplementationFunctions.java | 137 |
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); } |