aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleImplementationFunctions.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleImplementationFunctions.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleImplementationFunctions.java743
1 files changed, 0 insertions, 743 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleImplementationFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleImplementationFunctions.java
deleted file mode 100644
index d2151172bc..0000000000
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleImplementationFunctions.java
+++ /dev/null
@@ -1,743 +0,0 @@
-// Copyright 2014 The Bazel Authors. 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.analysis.skylark;
-
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.analysis.AliasProvider;
-import com.google.devtools.build.lib.analysis.CommandHelper;
-import com.google.devtools.build.lib.analysis.FileProvider;
-import com.google.devtools.build.lib.analysis.LocationExpander;
-import com.google.devtools.build.lib.analysis.Runfiles;
-import com.google.devtools.build.lib.analysis.RunfilesProvider;
-import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
-import com.google.devtools.build.lib.analysis.configuredtargets.AbstractConfiguredTarget;
-import com.google.devtools.build.lib.cmdline.Label;
-import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.skylarkinterface.Param;
-import com.google.devtools.build.lib.skylarkinterface.ParamType;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
-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.SkylarkDict;
-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.SkylarkSemantics;
-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.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-// TODO(bazel-team): function argument names are often duplicated,
-// figure out a nicely readable way to get rid of the duplications.
-/**
- * A helper class to provide an easier API for Skylark rule implementations
- * and hide the original Java API. This is experimental code.
- */
-public class SkylarkRuleImplementationFunctions {
-
- // TODO(bazel-team): add all the remaining parameters
- // TODO(bazel-team): merge executable and arguments
- /**
- * A Skylark built-in function to create and register a SpawnAction using a dictionary of
- * parameters: action( inputs = [input1, input2, ...], outputs = [output1, output2, ...],
- * executable = executable, arguments = [argument1, argument2, ...], mnemonic = 'Mnemonic',
- * command = 'command', )
- */
- @SkylarkSignature(
- name = "action",
- doc =
- "DEPRECATED. Use <a href=\"actions.html#run\">ctx.actions.run()</a> or"
- + " <a href=\"actions.html#run_shell\">ctx.actions.run_shell()</a>. <br>"
- + "Creates an action that runs an executable or a shell command."
- + " You must specify either <code>command</code> or <code>executable</code>.\n"
- + "Actions and genrules are very similar, but have different use cases. Actions are "
- + "used inside rules, and genrules are used inside macros. Genrules also have make "
- + "variable expansion.",
- objectType = SkylarkRuleContext.class,
- returnType = Runtime.NoneType.class,
- parameters = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "This RuleContext."),
- @Param(
- name = "outputs",
- type = SkylarkList.class,
- generic1 = Artifact.class,
- named = true,
- positional = false,
- doc = "List of the output files of the action."
- ),
- @Param(
- name = "inputs",
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- generic1 = Artifact.class,
- defaultValue = "[]",
- named = true,
- positional = false,
- doc = "List of the input files of the action."
- ),
- @Param(
- name = "executable",
- type = Object.class,
- allowedTypes = {
- @ParamType(type = Artifact.class),
- @ParamType(type = String.class),
- @ParamType(type = Runtime.NoneType.class),
- },
- defaultValue = "None",
- named = true,
- positional = false,
- doc = "The executable file to be called by the action."
- ),
- @Param(
- name = "arguments",
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- },
- defaultValue = "[]",
- named = true,
- positional = false,
- doc =
- "Command line arguments of the action."
- + "Must be a list of strings or actions.args() objects."
- ),
- @Param(
- name = "mnemonic",
- type = String.class,
- noneable = true,
- defaultValue = "None",
- named = true,
- positional = false,
- doc = "A one-word description of the action, e.g. CppCompile or GoLink."
- ),
- @Param(
- name = "command",
- type = Object.class,
- allowedTypes = {
- @ParamType(type = String.class),
- @ParamType(type = SkylarkList.class, generic1 = String.class),
- @ParamType(type = Runtime.NoneType.class),
- },
- defaultValue = "None",
- named = true,
- positional = false,
- doc =
- "Shell command to execute. It is usually preferable to "
- + "use <code>executable</code> instead. "
- + "Arguments are available with <code>$1</code>, <code>$2</code>, etc."
- ),
- @Param(
- name = "progress_message",
- type = String.class,
- noneable = true,
- defaultValue = "None",
- named = true,
- positional = false,
- doc =
- "Progress message to show to the user during the build, "
- + "e.g. \"Compiling foo.cc to create foo.o\"."
- ),
- @Param(
- name = "use_default_shell_env",
- type = Boolean.class,
- defaultValue = "False",
- named = true,
- positional = false,
- doc = "Whether the action should use the built in shell environment or not."
- ),
- @Param(
- name = "env",
- type = SkylarkDict.class,
- noneable = true,
- defaultValue = "None",
- named = true,
- positional = false,
- doc = "Sets the dictionary of environment variables."
- ),
- @Param(
- name = "execution_requirements",
- type = SkylarkDict.class,
- noneable = true,
- defaultValue = "None",
- named = true,
- positional = false,
- doc =
- "Information for scheduling the action. See "
- + "<a href=\"$BE_ROOT/common-definitions.html#common.tags\">tags</a> "
- + "for useful keys."
- ),
- @Param(
- // TODO(bazel-team): The name here isn't accurate anymore. This is technically experimental,
- // so folks shouldn't be too attached, but consider renaming to be more accurate/opaque.
- name = "input_manifests",
- type = SkylarkList.class,
- noneable = true,
- defaultValue = "None",
- named = true,
- positional = false,
- doc =
- "(Experimental) sets the input runfiles metadata; "
- + "they are typically generated by resolve_command."
- )
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction createSpawnAction =
- new BuiltinFunction("action") {
- public Runtime.NoneType invoke(
- SkylarkRuleContext ctx,
- SkylarkList outputs,
- Object inputs,
- Object executableUnchecked,
- Object arguments,
- Object mnemonicUnchecked,
- Object commandUnchecked,
- Object progressMessage,
- Boolean useDefaultShellEnv,
- Object envUnchecked,
- Object executionRequirementsUnchecked,
- Object inputManifestsUnchecked,
- Location loc,
- Environment env)
- throws EvalException {
- checkDeprecated(
- "ctx.actions.run or ctx.actions.run_shell", "ctx.action", loc, env.getSemantics());
- ctx.checkMutable("action");
- if ((commandUnchecked == Runtime.NONE) == (executableUnchecked == Runtime.NONE)) {
- throw new EvalException(
- loc, "You must specify either 'command' or 'executable' argument");
- }
- boolean hasCommand = commandUnchecked != Runtime.NONE;
- if (!hasCommand) {
- ctx.actions()
- .run(
- outputs,
- inputs,
- executableUnchecked,
- arguments,
- mnemonicUnchecked,
- progressMessage,
- useDefaultShellEnv,
- envUnchecked,
- executionRequirementsUnchecked,
- inputManifestsUnchecked);
-
- } else {
- ctx.actions()
- .runShell(
- outputs,
- inputs,
- arguments,
- mnemonicUnchecked,
- commandUnchecked,
- progressMessage,
- useDefaultShellEnv,
- envUnchecked,
- executionRequirementsUnchecked,
- inputManifestsUnchecked);
- }
- return Runtime.NONE;
- }
- };
-
- static void checkDeprecated(
- String newApi, String oldApi, Location loc, SkylarkSemantics semantics)
- throws EvalException {
- if (semantics.incompatibleNewActionsApi()) {
- throw new EvalException(
- loc,
- "Use " + newApi + " instead of " + oldApi + ". \n"
- + "Use --incompatible_new_actions_api=false to temporarily disable this check.");
- }
- }
-
- @SkylarkSignature(
- name = "expand_location",
- doc =
- "Expands all <code>$(location ...)</code> templates in the given string by replacing "
- + "<code>$(location //x)</code> with the path of the output file of target //x. "
- + "Expansion only works for labels that point to direct dependencies of this rule or "
- + "that are explicitly listed in the optional argument <code>targets</code>. "
- + "<br/><br/>"
- + "<code>$(location ...)</code> will cause an error if the referenced target has "
- + "multiple outputs. In this case, please use <code>$(locations ...)</code> since it "
- + "produces a space-separated list of output paths. It can be safely used for a "
- + "single output file, too.",
- objectType = SkylarkRuleContext.class,
- returnType = String.class,
- parameters = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
- @Param(name = "input", type = String.class, doc = "String to be expanded."),
- @Param(
- name = "targets",
- type = SkylarkList.class,
- generic1 = AbstractConfiguredTarget.class,
- defaultValue = "[]",
- doc = "List of targets for additional lookup information."
- ),
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction expandLocation =
- new BuiltinFunction("expand_location") {
- @SuppressWarnings("unused")
- public String invoke(
- SkylarkRuleContext ctx,
- String input,
- SkylarkList targets,
- Location loc,
- Environment env)
- throws EvalException {
- ctx.checkMutable("expand_location");
- try {
- return LocationExpander.withExecPaths(
- ctx.getRuleContext(),
- makeLabelMap(targets.getContents(TransitiveInfoCollection.class, "targets")))
- .expand(input);
- } catch (IllegalStateException ise) {
- throw new EvalException(loc, ise);
- }
- }
- };
-
- /**
- * Builds a map: Label -> List of files from the given labels
- *
- * @param knownLabels List of known labels
- * @return Immutable map with immutable collections as values
- */
- private static ImmutableMap<Label, ImmutableCollection<Artifact>> makeLabelMap(
- Iterable<TransitiveInfoCollection> knownLabels) {
- ImmutableMap.Builder<Label, ImmutableCollection<Artifact>> builder = ImmutableMap.builder();
-
- for (TransitiveInfoCollection current : knownLabels) {
- builder.put(
- AliasProvider.getDependencyLabel(current),
- ImmutableList.copyOf(current.getProvider(FileProvider.class).getFilesToBuild()));
- }
-
- return builder.build();
- }
-
- @SkylarkSignature(
- name = "file_action",
- doc = "DEPRECATED. Use <a href =\"actions.html#write\">ctx.actions.write</a> instead. <br>"
- + "Creates a file write action.",
- objectType = SkylarkRuleContext.class,
- returnType = Runtime.NoneType.class,
- parameters = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
- @Param(name = "output", type = Artifact.class, doc = "The output file."),
- @Param(name = "content", type = String.class, doc = "The contents of the file."),
- @Param(
- name = "executable",
- type = Boolean.class,
- defaultValue = "False",
- doc = "Whether the output file should be executable (default is False)."
- )
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction createFileWriteAction =
- new BuiltinFunction("file_action") {
- public Runtime.NoneType invoke(
- SkylarkRuleContext ctx, Artifact output, String content, Boolean executable,
- Location loc, Environment env)
- throws EvalException {
- checkDeprecated("ctx.actions.write", "ctx.file_action", loc, env.getSemantics());
- ctx.checkMutable("file_action");
- ctx.actions().write(output, content, executable);
- return Runtime.NONE;
- }
- };
-
- @SkylarkSignature(
- name = "empty_action",
- doc =
- "DEPRECATED. Use <a href=\"actions.html#do_nothing\">ctx.actions.do_nothing</a> instead."
- + " <br>"
- + "Creates an empty action that neither executes a command nor produces any "
- + "output, but that is useful for inserting 'extra actions'.",
- objectType = SkylarkRuleContext.class,
- returnType = Runtime.NoneType.class,
- parameters = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
- @Param(
- name = "mnemonic",
- type = String.class,
- named = true,
- positional = false,
- doc = "A one-word description of the action, e.g. CppCompile or GoLink."
- ),
- @Param(
- name = "inputs",
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- generic1 = Artifact.class,
- named = true,
- positional = false,
- defaultValue = "[]",
- doc = "List of the input files of the action."
- ),
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction createEmptyAction =
- new BuiltinFunction("empty_action") {
- @SuppressWarnings("unused")
- public Runtime.NoneType invoke(SkylarkRuleContext ctx, String mnemonic, Object inputs,
- Location loc, Environment env)
- throws EvalException {
- checkDeprecated("ctx.actions.do_nothing", "ctx.empty_action", loc, env.getSemantics());
- ctx.checkMutable("empty_action");
- ctx.actions().doNothing(mnemonic, inputs);
- return Runtime.NONE;
- }
- };
-
- @SkylarkSignature(
- name = "template_action",
- doc = "DEPRECATED. "
- + "Use <a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a> instead."
- + "<br>Creates a template expansion action.",
- objectType = SkylarkRuleContext.class,
- returnType = Runtime.NoneType.class,
- parameters = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
- @Param(
- name = "template",
- type = Artifact.class,
- named = true,
- positional = false,
- doc = "The template file, which is a UTF-8 encoded text file."
- ),
- @Param(
- name = "output",
- type = Artifact.class,
- named = true,
- positional = false,
- doc = "The output file, which is a UTF-8 encoded text file."
- ),
- @Param(
- name = "substitutions",
- type = SkylarkDict.class,
- named = true,
- positional = false,
- doc = "Substitutions to make when expanding the template."
- ),
- @Param(
- name = "executable",
- type = Boolean.class,
- defaultValue = "False",
- named = true,
- positional = false,
- doc = "Whether the output file should be executable (default is False)."
- )
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction createTemplateAction =
- new BuiltinFunction("template_action", Arrays.<Object>asList(false)) {
- public Runtime.NoneType invoke(
- SkylarkRuleContext ctx,
- Artifact template,
- Artifact output,
- SkylarkDict<?, ?> substitutionsUnchecked,
- Boolean executable, Location loc, Environment env)
- throws EvalException {
- checkDeprecated("ctx.actions.expand_template", "ctx.template_action", loc,
- env.getSemantics());
- ctx.checkMutable("template_action");
- ctx.actions().expandTemplate(template, output, substitutionsUnchecked, executable);
- return Runtime.NONE;
- }
- };
-
- // TODO(bazel-team): Remove runfile states from Skylark.
- @SkylarkSignature(name = "runfiles",
- doc = "Creates a runfiles object.",
- objectType = SkylarkRuleContext.class,
- returnType = Runfiles.class,
- parameters = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "This context."),
- @Param(name = "files", type = SkylarkList.class, generic1 = Artifact.class,
- defaultValue = "[]", doc = "The list of files to be added to the runfiles."),
- // TODO(bazel-team): If we have a memory efficient support for lazy list containing
- // NestedSets we can remove this and just use files = [file] + list(set)
- // Also, allow empty set for init
- @Param(name = "transitive_files", type = SkylarkNestedSet.class, generic1 = Artifact.class,
- noneable = true, defaultValue = "None",
- doc = "The (transitive) set of files to be added to the runfiles. The depset should "
- + "use the `default` order (which, as the name implies, is the default)."),
- @Param(name = "collect_data", type = Boolean.class, defaultValue = "False",
- doc = "Whether to collect the data "
- + "runfiles from the dependencies in srcs, data and deps attributes."),
- @Param(name = "collect_default", type = Boolean.class, defaultValue = "False",
- doc = "Whether to collect the default "
- + "runfiles from the dependencies in srcs, data and deps attributes."),
- @Param(name = "symlinks", type = SkylarkDict.class, defaultValue = "{}",
- doc = "The map of symlinks to be added to the runfiles, prefixed by workspace name."),
- @Param(name = "root_symlinks", type = SkylarkDict.class, defaultValue = "{}",
- doc = "The map of symlinks to be added to the runfiles.")},
- useLocation = true)
- private static final BuiltinFunction runfiles = new BuiltinFunction("runfiles") {
- public Runfiles invoke(SkylarkRuleContext ctx, SkylarkList files, Object transitiveFiles,
- Boolean collectData, Boolean collectDefault,
- SkylarkDict<?, ?> symlinks, SkylarkDict<?, ?> rootSymlinks,
- Location loc) throws EvalException, ConversionException {
- ctx.checkMutable("runfiles");
- Runfiles.Builder builder = new Runfiles.Builder(
- ctx.getRuleContext().getWorkspaceName(),
- ctx.getConfiguration().legacyExternalRunfiles());
- boolean checkConflicts = false;
- if (EvalUtils.toBoolean(collectData)) {
- builder.addRunfiles(ctx.getRuleContext(), RunfilesProvider.DATA_RUNFILES);
- }
- if (EvalUtils.toBoolean(collectDefault)) {
- builder.addRunfiles(ctx.getRuleContext(), RunfilesProvider.DEFAULT_RUNFILES);
- }
- if (!files.isEmpty()) {
- builder.addArtifacts(files.getContents(Artifact.class, "files"));
- }
- if (transitiveFiles != Runtime.NONE) {
- builder.addTransitiveArtifacts(((SkylarkNestedSet) transitiveFiles).getSet(Artifact.class));
- }
- if (!symlinks.isEmpty()) {
- // If Skylark code directly manipulates symlinks, activate more stringent validity checking.
- checkConflicts = true;
- for (Map.Entry<String, Artifact> entry : symlinks.getContents(
- String.class, Artifact.class, "symlinks").entrySet()) {
- builder.addSymlink(PathFragment.create(entry.getKey()), entry.getValue());
- }
- }
- if (!rootSymlinks.isEmpty()) {
- checkConflicts = true;
- for (Map.Entry<String, Artifact> entry : rootSymlinks.getContents(
- String.class, Artifact.class, "root_symlinks").entrySet()) {
- builder.addRootSymlink(PathFragment.create(entry.getKey()), entry.getValue());
- }
- }
- Runfiles runfiles = builder.build();
- if (checkConflicts) {
- runfiles.setConflictPolicy(Runfiles.ConflictPolicy.ERROR);
- }
- return runfiles;
- }
- };
-
- /**
- * Ensures the given {@link Map} has keys that have {@link Label} type and values that have either
- * {@link Iterable} or {@link SkylarkNestedSet} type, and raises {@link EvalException} otherwise.
- * Returns a corresponding map where any sets are replaced by iterables.
- */
- // TODO(bazel-team): find a better way to typecheck this argument.
- @SuppressWarnings("unchecked")
- private static Map<Label, Iterable<Artifact>> checkLabelDict(
- Map<?, ?> labelDict, Location loc, Environment env) throws EvalException {
- Map<Label, Iterable<Artifact>> convertedMap = new HashMap<>();
- 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));
- }
- ImmutableList.Builder<Artifact> files = ImmutableList.builder();
- Object val = entry.getValue();
- Iterable<?> valIter;
- try {
- valIter = EvalUtils.toIterableStrict(val, loc, env);
- } catch (EvalException ex) {
- // EvalException is thrown only if the type is wrong.
- throw new EvalException(
- loc, Printer.format("invalid value %r in 'label_dict': " + ex, val));
- }
- for (Object file : valIter) {
- if (!(file instanceof Artifact)) {
- throw new EvalException(
- loc, Printer.format("invalid value %r in 'label_dict'", val));
- }
- files.add((Artifact) file);
- }
- convertedMap.put((Label) key, files.build());
- }
- return convertedMap;
- }
-
- /** suffix of script to be used in case the command is too long to fit on a single line */
- private static final String SCRIPT_SUFFIX = ".script.sh";
-
- @SkylarkSignature(
- name = "resolve_command",
- // TODO(bazel-team): The naming here isn't entirely accurate (input_manifests is no longer
- // manifests), but this is experimental/should be opaque to the end user.
- doc =
- "<i>(Experimental)</i> "
- + "Returns a tuple <code>(inputs, command, input_manifests)</code> of the list of "
- + "resolved inputs, the argv list for the resolved command, and the runfiles metadata"
- + "required to run the command, all of them suitable for passing as the same-named "
- + "arguments of the <code>ctx.action</code> method.",
- objectType = SkylarkRuleContext.class,
- returnType = Tuple.class,
- parameters = {
- @Param(name = "self", type = SkylarkRuleContext.class, doc = "This RuleContext."),
- @Param(
- name = "command",
- type = String.class, // string
- defaultValue = "''",
- named = true,
- positional = false,
- doc = "Command to resolve."
- ),
- @Param(
- name = "attribute",
- type = String.class, // string
- defaultValue = "None",
- noneable = true,
- named = true,
- positional = false,
- doc = "Name of the associated attribute for which to issue an error, or None."
- ),
- @Param(
- name = "expand_locations",
- type = Boolean.class,
- defaultValue = "False",
- named = true,
- positional = false,
- doc =
- "Shall we expand $(location) variables? "
- + "See <a href=\"#expand_location\">ctx.expand_location()</a> for more details."
- ),
- @Param(
- name = "make_variables",
- type = SkylarkDict.class, // dict(string, string)
- noneable = true,
- defaultValue = "None",
- named = true,
- positional = false,
- doc = "Make variables to expand, or None."
- ),
- @Param(
- name = "tools",
- defaultValue = "[]",
- type = SkylarkList.class,
- generic1 = TransitiveInfoCollection.class,
- named = true,
- positional = false,
- doc = "List of tools (list of targets)."
- ),
- @Param(
- name = "label_dict",
- type = SkylarkDict.class,
- defaultValue = "{}",
- named = true,
- positional = false,
- doc =
- "Dictionary of resolved labels and the corresponding list of Files "
- + "(a dict of Label : list of Files)."
- ),
- @Param(
- name = "execution_requirements",
- type = SkylarkDict.class,
- defaultValue = "{}",
- named = true,
- positional = false,
- doc =
- "Information for scheduling the action to resolve this command. See "
- + "<a href=\"$BE_ROOT/common-definitions.html#common.tags\">tags</a> "
- + "for useful keys."
- ),
- },
- useLocation = true,
- useEnvironment = true
- )
- private static final BuiltinFunction resolveCommand =
- new BuiltinFunction("resolve_command") {
- @SuppressWarnings("unchecked")
- public Tuple<Object> invoke(
- SkylarkRuleContext ctx,
- String command,
- Object attributeUnchecked,
- Boolean expandLocations,
- Object makeVariablesUnchecked,
- SkylarkList tools,
- SkylarkDict<?, ?> labelDictUnchecked,
- SkylarkDict<?, ?> executionRequirementsUnchecked,
- Location loc,
- Environment env)
- throws ConversionException, EvalException {
- ctx.checkMutable("resolve_command");
- Label ruleLabel = ctx.getLabel();
- Map<Label, Iterable<Artifact>> labelDict = checkLabelDict(labelDictUnchecked, loc, env);
- // The best way to fix this probably is to convert CommandHelper to Skylark.
- CommandHelper helper =
- new CommandHelper(
- ctx.getRuleContext(),
- tools.getContents(TransitiveInfoCollection.class, "tools"),
- ImmutableMap.copyOf(labelDict));
- String attribute =
- Type.STRING.convertOptional(attributeUnchecked, "attribute", ruleLabel);
- if (expandLocations) {
- command = helper.resolveCommandAndExpandLabels(
- command, attribute, /*allowDataInLabel=*/false);
- }
- if (!EvalUtils.isNullOrNone(makeVariablesUnchecked)) {
- Map<String, String> makeVariables =
- Type.STRING_DICT.convert(makeVariablesUnchecked, "make_variables", ruleLabel);
- command = ctx.expandMakeVariables(attribute, command, makeVariables);
- }
- List<Artifact> inputs = new ArrayList<>();
- inputs.addAll(helper.getResolvedTools());
-
- ImmutableMap<String, String> executionRequirements =
- ImmutableMap.copyOf(
- SkylarkDict.castSkylarkDictOrNoneToDict(
- executionRequirementsUnchecked,
- String.class,
- String.class,
- "execution_requirements"));
- List<String> argv =
- helper.buildCommandLine(command, inputs, SCRIPT_SUFFIX, executionRequirements);
- return Tuple.<Object>of(
- MutableList.copyOf(env, inputs),
- MutableList.copyOf(env, argv),
- helper.getToolsRunfilesSuppliers());
- }
- };
-
- static {
- SkylarkSignatureProcessor.configureSkylarkFunctions(SkylarkRuleImplementationFunctions.class);
- }
-}