aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java76
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java868
-rw-r--r--src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ActionApi.java104
-rw-r--r--src/main/java/com/google/devtools/build/lib/skylarkbuildapi/CommandLineArgsApi.java520
-rw-r--r--src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkActionFactoryApi.java523
6 files changed, 1191 insertions, 910 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
index b9eea4edba..d41e7d2dcb 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/AbstractAction.java
@@ -30,11 +30,9 @@ import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.AspectDescriptor;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.skylarkbuildapi.ActionApi;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
@@ -58,22 +56,7 @@ import javax.annotation.concurrent.GuardedBy;
*/
@Immutable
@ThreadSafe
-@SkylarkModule(
- name = "Action",
- category = SkylarkModuleCategory.BUILTIN,
- doc =
- "An action created during rule analysis."
- + "<p>This object is visible for the purpose of testing, and may be obtained from an "
- + "<a href=\"globals.html#Actions\">Actions</a> provider. It is normally not necessary "
- + "to access <code>Action</code> objects or their fields within a rule's implementation "
- + "function. You may instead want to see the "
- + "<a href='../rules.$DOC_EXT#actions'>Rules page</a> for a general discussion of how to "
- + "use actions when defining custom rules, or the <a href='actions.html'>API reference"
- + "</a> for creating actions."
- + "<p>Some fields of this object are only applicable for certain kinds of actions. "
- + "Fields that are inapplicable are set to <code>None</code>."
-)
-public abstract class AbstractAction implements Action, SkylarkValue {
+public abstract class AbstractAction implements Action, ActionApi {
/**
* An arbitrary default resource set. Currently 250MB of memory, 50% CPU and 0% of total I/O.
*/
@@ -302,11 +285,6 @@ public abstract class AbstractAction implements Action, SkylarkValue {
+ getOutputs() + "]" + ")";
}
- @SkylarkCallable(
- name = "mnemonic",
- structField = true,
- doc = "The mnemonic for this action."
- )
@Override
public abstract String getMnemonic();
@@ -580,68 +558,34 @@ public abstract class AbstractAction implements Action, SkylarkValue {
return ImmutableList.of();
}
- @SkylarkCallable(
- name = "inputs",
- doc = "A set of the input files of this action.",
- structField = true)
+ @Override
public SkylarkNestedSet getSkylarkInputs() {
return SkylarkNestedSet.of(Artifact.class, NestedSetBuilder.wrap(
Order.STABLE_ORDER, getInputs()));
}
- @SkylarkCallable(
- name = "outputs",
- doc = "A set of the output files of this action.",
- structField = true)
+ @Override
public SkylarkNestedSet getSkylarkOutputs() {
return SkylarkNestedSet.of(Artifact.class, NestedSetBuilder.wrap(
Order.STABLE_ORDER, getOutputs()));
}
- @SkylarkCallable(
- name = "argv",
- doc =
- "For actions created by <a href=\"actions.html#run\">ctx.actions.run()</a> "
- + "or <a href=\"actions.html#run_shell\">ctx.actions.run_shell()</a> an immutable "
- + "list of the arguments for the command line to be executed. Note that "
- + "for shell actions the first two arguments will be the shell path "
- + "and <code>\"-c\"</code>.",
- structField = true,
- allowReturnNones = true
- )
- public SkylarkList<String> getSkylarkArgv() throws CommandLineExpansionException {
+ @Override
+ public SkylarkList<String> getSkylarkArgv() throws EvalException {
return null;
}
- @SkylarkCallable(
- name = "content",
- doc = "For actions created by <a href=\"actions.html#write\">ctx.actions.write()</a> or "
- + "<a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a>,"
- + " the contents of the file to be written.",
- structField = true,
- allowReturnNones = true)
+ @Override
public String getSkylarkContent() throws IOException {
return null;
}
- @SkylarkCallable(
- name = "substitutions",
- doc = "For actions created by "
- + "<a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a>,"
- + " an immutable dict holding the substitution mapping.",
- structField = true,
- allowReturnNones = true)
+ @Override
public SkylarkDict<String, String> getSkylarkSubstitutions() {
return null;
}
- @SkylarkCallable(
- name = "env",
- structField = true,
- doc = "The 'fixed' environment variables for this action. This includes only environment "
- + "settings which are explicitly set by the action definition, and thus omits settings "
- + "which are only pre-set in the execution environment."
- )
+ @Override
public SkylarkDict<String, String> getEnv() {
return SkylarkDict.copyOf(null, env.getFixedEnv());
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java
index 5532b2223d..6cabc59955 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java
@@ -65,8 +65,10 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.NestedSetView;
+import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
+import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.util.Fingerprint;
import com.google.devtools.build.lib.util.LazyString;
@@ -229,8 +231,12 @@ public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifie
}
@Override
- public SkylarkList<String> getSkylarkArgv() throws CommandLineExpansionException {
- return SkylarkList.createImmutable(getArguments());
+ public SkylarkList<String> getSkylarkArgv() throws EvalException {
+ try {
+ return SkylarkList.createImmutable(getArguments());
+ } catch (CommandLineExpansionException exception) {
+ throw new EvalException(Location.BUILTIN, exception);
+ }
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
index 731ccf1cbe..4121df20b1 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java
@@ -42,13 +42,12 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.TargetUtils;
-import com.google.devtools.build.lib.skylarkinterface.Param;
-import com.google.devtools.build.lib.skylarkinterface.ParamType;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkbuildapi.CommandLineArgsApi;
+import com.google.devtools.build.lib.skylarkbuildapi.FileApi;
+import com.google.devtools.build.lib.skylarkbuildapi.SkylarkActionFactoryApi;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.BaseFunction;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.EvalException;
@@ -71,14 +70,7 @@ import java.util.UUID;
import javax.annotation.Nullable;
/** Provides a Skylark interface for all action creation needs. */
-@SkylarkModule(
- name = "actions",
- category = SkylarkModuleCategory.BUILTIN,
- doc =
- "Module providing functions to create actions. "
- + "Access this module using <a href=\"ctx.html#actions\"><code>ctx.actions</code></a>."
-)
-public class SkylarkActionFactory implements SkylarkValue {
+public class SkylarkActionFactory implements SkylarkActionFactoryApi {
private final SkylarkRuleContext context;
private final SkylarkSemantics skylarkSemantics;
private RuleContext ruleContext;
@@ -100,44 +92,7 @@ public class SkylarkActionFactory implements SkylarkValue {
: ruleContext.getBinOrGenfilesDirectory();
}
- @SkylarkCallable(
- name = "declare_file",
- doc =
- "Declares that the rule or aspect creates a file with the given filename. "
- + "If <code>sibling</code> is not specified, the file name is relative to the package"
- + "directory, otherwise the file is in the same directory as <code>sibling</code>."
- + "Files cannot be created outside of the current package."
- + "<p>Remember that in addition to declaring a file, you must separately create an "
- + "action that emits the file. Creating that action will require passing the returned "
- + "<code>File</code> object to the action's construction function."
- + "<p>Note that <a href='../rules.$DOC_EXT#files'>predeclared output files</a> do not "
- + "need to be (and cannot be) declared using this function. You can obtain their "
- + "<code>File</code> objects from <a href=\"ctx.html#outputs\"><code>ctx.outputs</code>"
- + "</a> instead. "
- + "<a href=\"https://github.com/bazelbuild/examples/tree/master/rules/"
- + "computed_dependencies/hash.bzl\">See example of use</a>",
- parameters = {
- @Param(
- name = "filename",
- type = String.class,
- doc =
- "If no 'sibling' provided, path of the new file, relative "
- + "to the current package. Otherwise a base name for a file "
- + "('sibling' determines a directory)."
- ),
- @Param(
- name = "sibling",
- doc =
- "A file that lives in the same directory as the newly created file. "
- + "The file must be in the current package.",
- type = Artifact.class,
- noneable = true,
- positional = false,
- named = true,
- defaultValue = "None"
- )
- }
- )
+ @Override
public Artifact declareFile(String filename, Object sibling) throws EvalException {
context.checkMutable("actions.declare_file");
if (Runtime.NONE.equals(sibling)) {
@@ -149,31 +104,7 @@ public class SkylarkActionFactory implements SkylarkValue {
}
}
- @SkylarkCallable(
- name = "declare_directory",
- doc =
- "Declares that rule or aspect create a directory with the given name, in the "
- + "current package. You must create an action that generates the directory.",
- parameters = {
- @Param(
- name = "filename",
- type = String.class,
- doc =
- "If no 'sibling' provided, path of the new directory, relative "
- + "to the current package. Otherwise a base name for a file "
- + "('sibling' defines a directory)."
- ),
- @Param(
- name = "sibling",
- doc = "A file that lives in the same directory as the newly declared directory.",
- type = Artifact.class,
- noneable = true,
- positional = false,
- named = true,
- defaultValue = "None"
- )
- }
- )
+ @Override
public Artifact declareDirectory(String filename, Object sibling) throws EvalException {
context.checkMutable("actions.declare_directory");
if (Runtime.NONE.equals(sibling)) {
@@ -186,34 +117,7 @@ public class SkylarkActionFactory implements SkylarkValue {
}
}
-
- @SkylarkCallable(
- name = "do_nothing",
- doc =
- "Creates an empty action that neither executes a command nor produces any "
- + "output, but that is useful for inserting 'extra actions'.",
- parameters = {
- @Param(
- name = "mnemonic",
- type = String.class,
- named = true,
- positional = false,
- doc = "A one-word description of the action, for example, 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."
- ),
- }
- )
+ @Override
public void doNothing(String mnemonic, Object inputs) throws EvalException {
context.checkMutable("actions.do_nothing");
NestedSet<Artifact> inputSet = inputs instanceof SkylarkNestedSet
@@ -235,45 +139,19 @@ public class SkylarkActionFactory implements SkylarkValue {
ruleContext.registerAction(action);
}
- @SkylarkCallable(
- name = "write",
- doc =
- "Creates a file write action. When the action is executed, it will write the given content "
- + "to a file. This is used to generate files using information available in the "
- + "analysis phase. If the file is large and with a lot of static content, consider "
- + "using <a href=\"#expand_template\"><code>expand_template</code></a>.",
- parameters = {
- @Param(name = "output", type = Artifact.class, doc = "The output file.", named = true),
- @Param(
- name = "content",
- type = Object.class,
- allowedTypes = {@ParamType(type = String.class), @ParamType(type = Args.class)},
- doc =
- "the contents of the file. "
- + "May be a either a string or an "
- + "<a href=\"actions.html#args\"><code>actions.args()</code></a> object.",
- named = true
- ),
- @Param(
- name = "is_executable",
- type = Boolean.class,
- defaultValue = "False",
- doc = "Whether the output file should be executable.",
- named = true
- )
- }
- )
- public void write(Artifact output, Object content, Boolean isExecutable) throws EvalException {
+ @Override
+ public void write(FileApi output, Object content, Boolean isExecutable) throws EvalException {
context.checkMutable("actions.write");
final Action action;
if (content instanceof String) {
- action = FileWriteAction.create(ruleContext, output, (String) content, isExecutable);
+ action =
+ FileWriteAction.create(ruleContext, (Artifact) output, (String) content, isExecutable);
} else if (content instanceof Args) {
Args args = (Args) content;
action =
new ParameterFileWriteAction(
ruleContext.getActionOwner(),
- output,
+ (Artifact) output,
args.build(),
args.parameterFileType,
StandardCharsets.UTF_8);
@@ -283,138 +161,7 @@ public class SkylarkActionFactory implements SkylarkValue {
ruleContext.registerAction(action);
}
- @SkylarkCallable(
- name = "run",
- doc =
- "Creates an action that runs an executable. "
- + "<a href=\"https://github.com/bazelbuild/examples/tree/master/rules/"
- + "actions_run/execute.bzl\">See example of use</a>",
- parameters = {
- @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 or depset of the input files of the action."
- ),
- @Param(
- name = "executable",
- type = Object.class,
- allowedTypes = {
- @ParamType(type = Artifact.class),
- @ParamType(type = String.class),
- },
- named = true,
- positional = false,
- doc = "The executable file to be called by the action."
- ),
- @Param(
- name = "tools",
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- generic1 = Artifact.class,
- defaultValue = "unbound",
- named = true,
- positional = false,
- doc =
- "List or depset of any tools needed by the action. Tools are inputs with additional "
- + "runfiles that are automatically made available to the action."
- ),
- @Param(
- name = "arguments",
- type = Object.class,
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- },
- defaultValue = "[]",
- named = true,
- positional = false,
- doc =
- "Command line arguments of the action. "
- + "Must be a list of strings or "
- + "<a href=\"actions.html#args\"><code>actions.args()</code></a> objects."
- ),
- @Param(
- name = "mnemonic",
- type = String.class,
- noneable = true,
- defaultValue = "None",
- named = true,
- positional = false,
- doc = "A one-word description of the action, for example, CppCompile or GoLink."
- ),
- @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, "
- + "for example, \"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
- )
+ @Override
public void run(
SkylarkList outputs,
Object inputs,
@@ -485,148 +232,7 @@ public class SkylarkActionFactory implements SkylarkValue {
return ruleContext;
}
- @SkylarkCallable(
- name = "run_shell",
- doc =
- "Creates an action that runs a shell command. "
- + "<a href=\"https://github.com/bazelbuild/examples/tree/master/rules/"
- + "shell_command/size.bzl\">See example of use</a>",
- parameters = {
- @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 or depset of the input files of the action."
- ),
- @Param(
- name = "tools",
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- generic1 = Artifact.class,
- defaultValue = "unbound",
- named = true,
- positional = false,
- doc =
- "List or depset of any tools needed by the action. Tools are inputs with additional "
- + "runfiles that are automatically made available to 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 "
- + "<a href=\"actions.html#args\"><code>actions.args()</code></a> objects.<br>"
- + "Blaze passes the elements in this attribute as arguments to the command."
- + "The command can access these arguments as <code>$1</code>, <code>$2</code>, etc."
- ),
- @Param(
- name = "mnemonic",
- type = String.class,
- noneable = true,
- defaultValue = "None",
- named = true,
- positional = false,
- doc = "A one-word description of the action, for example, 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),
- },
- named = true,
- positional = false,
- doc =
- "Shell command to execute.<br><br>"
- + "<b>Passing a sequence of strings to this attribute is deprecated and Blaze may "
- + "stop accepting such values in the future.</b><br><br>"
- + "The command can access the elements of the <code>arguments</code> object via "
- + "<code>$1</code>, <code>$2</code>, etc.<br>"
- + "When this argument is a string, it must be a valid shell command. For example: "
- + "\"<code>echo foo > $1</code>\". Blaze uses the same shell to execute the "
- + "command as it does for genrules."
- ),
- @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, "
- + "for example, \"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
- )
+ @Override
public void runShell(
SkylarkList outputs,
Object inputs,
@@ -835,52 +441,10 @@ public class SkylarkActionFactory implements SkylarkValue {
return mnemonic + "FromSkylark";
}
- @SkylarkCallable(
- name = "expand_template",
- doc =
- "Creates a template expansion action. When the action is executed, it will "
- + "generate a file based on a template. Parts of the template will be replaced "
- + "using the <code>substitutions</code> dictionary. Whenever a key of the "
- + "dictionary appears in the template, it is replaced with the associated value. "
- + "There is no special syntax for the keys. You may, for example, use curly braces "
- + "to avoid conflicts (for example, <code>{KEY}</code>). "
- + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/expand_template/hello.bzl\">"
- + "See example of use</a>",
- parameters = {
- @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 = "is_executable",
- type = Boolean.class,
- defaultValue = "False",
- named = true,
- positional = false,
- doc = "Whether the output file should be executable."
- )
- }
- )
+ @Override
public void expandTemplate(
- Artifact template,
- Artifact output,
+ FileApi template,
+ FileApi output,
SkylarkDict<?, ?> substitutionsUnchecked,
Boolean executable)
throws EvalException {
@@ -901,8 +465,8 @@ public class SkylarkActionFactory implements SkylarkValue {
TemplateExpansionAction action =
new TemplateExpansionAction(
ruleContext.getActionOwner(),
- template,
- output,
+ (Artifact) template,
+ (Artifact) output,
substitutionsBuilder.build(),
executable);
ruleContext.registerAction(action);
@@ -1004,7 +568,7 @@ public class SkylarkActionFactory implements SkylarkValue {
+ "</pre>"
)
@VisibleForTesting
- public static class Args extends SkylarkMutable {
+ public static class Args extends SkylarkMutable implements CommandLineArgsApi {
private final Mutability mutability;
private final SkylarkSemantics skylarkSemantics;
private final SkylarkCustomCommandLine.Builder commandLine;
@@ -1012,95 +576,7 @@ public class SkylarkActionFactory implements SkylarkValue {
private String flagFormatString;
private boolean useAlways;
- @SkylarkCallable(
- name = "add",
- doc =
- "Appends an argument to this command line."
- + ""
- + "<p><b>Deprecation note:</b> The <code>before_each</code>, <code>join_with</code> "
- + "and <code>map_fn</code> params are replaced by the <a href='#add_all'><code>"
- + "add_all()</code></a> and <a href='#add_joined'><code>add_joined()</code></a> "
- + "methods. These parameters will be removed, and are currently disallowed if the "
- + "<a href='../backward-compatibility.$DOC_EXT#new-args-api'><code>"
- + "--incompatible_disallow_old_style_args_add</code></a> flag is set. Likewise, "
- + "<code>value</code> should now be a scalar value, not a list, tuple, or depset of "
- + "items.",
- parameters = {
- @Param(
- name = "arg_name_or_value",
- doc =
- "If two positional parameters are passed this is interpreted as the arg name. "
- + "The arg name is added before the value without any processing. "
- + "If only one positional parameter is passed, it is interpreted as "
- + "<code>value</code> (see below)."
- ),
- @Param(
- name = "value",
- defaultValue = "unbound",
- doc =
- "The object to append. It will be converted to a string using the standard "
- + "conversion mentioned above. Since there is no <code>map_each</code> parameter "
- + "for this function, <code>value</code> should be either a string or a <code>"
- + "File</code>."
- + ""
- + "<p><i>Deprecated behavior:</i> <code>value</code> may also be a list, tuple, "
- + "or depset of multiple items to append."
- ),
- @Param(
- name = "format",
- type = String.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc =
- "A format string pattern, to be applied to the stringified version of <code>value"
- + "</code>."
- + ""
- + "<p><i>Deprecated behavior:</i> If <code>value</code> is a list or depset, "
- + "formatting is applied to each item."
- ),
- @Param(
- name = "before_each",
- type = String.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc =
- "<i>Deprecated:</i> Only supported when <code>value</code> is a list, tuple, or "
- + "depset. This string will be appended prior to appending each item."
- ),
- @Param(
- name = "join_with",
- type = String.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc =
- "<i>Deprecated:</i> Only supported when <code>value</code> is a list, tuple, or "
- + "depset. All items will be joined together using this string to form a single "
- + "arg to append."
- ),
- @Param(
- name = "map_fn",
- type = BaseFunction.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc =
- "<i>Deprecated:</i> Only supported when <code>value</code> is a list, tuple, or "
- + "depset. This is a function that transforms the sequence of items into a list "
- + "of strings. The sequence of items is given as a positional argument -- the "
- + "function must not take any other parameters -- and the returned list's length "
- + "must equal the number of items. Use <code>map_each</code> of <code>add_all"
- + "</code> or <code>add_joined</code> instead."
- )
- },
- useLocation = true
- )
+ @Override
public NoneType addArgument(
Object argNameOrValue,
Object value,
@@ -1169,148 +645,7 @@ public class SkylarkActionFactory implements SkylarkValue {
return Runtime.NONE;
}
- @SkylarkCallable(
- name = "add_all",
- doc =
- "Appends multiple arguments to this command line. For depsets, the items are "
- + "evaluated lazily during the execution phase."
- + ""
- + "<p>Most of the processing occurs over a list of arguments to be appended, as per "
- + "the following steps:"
- + "<ol>"
- + "<li>If <code>map_each</code> is given, it is applied to each input item, and the "
- + " resulting lists of strings are concatenated to form the initial argument "
- + " list. Otherwise, the initial argument list is the result of applying the "
- + " standard conversion to each item."
- + "<li>Each argument in the list is formatted with <code>format_each</code>, if "
- + " present."
- + "<li>If <code>uniquify</code> is true, duplicate arguments are removed. The first "
- + " occurrence is the one that remains."
- + "<li>If a <code>before_each</code> string is given, it is inserted as a new "
- + " argument before each existing argument in the list. This effectively doubles "
- + " the number of arguments to be appended by this point."
- + "<li>Except in the case that the list is empty and <code>omit_if_empty</code> is "
- + " true (the default), the arg name and <code>terminate_with</code> are "
- + " inserted as the first and last arguments, respectively, if they are given."
- + "</ol>"
- + "Note that empty strings are valid arguments that are subject to all these "
- + "processing steps.",
- parameters = {
- @Param(
- name = "arg_name_or_values",
- doc =
- "If two positional parameters are passed this is interpreted as the arg name. "
- + "The arg name is added before the <code>values</code> without any processing. "
- + "This arg name will not be added if <code>omit_if_empty</code> is true "
- + "(the default) and no other items are appended (as happens if "
- + "<code>values</code> is empty or all of its items are filtered). "
- + "If only one positional parameter is passed, it is interpreted as "
- + "<code>values</code> (see below)."
- ),
- @Param(
- name = "values",
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- defaultValue = "unbound",
- doc = "The list, tuple, or depset whose items will be appended."
- ),
- @Param(
- name = "map_each",
- type = BaseFunction.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc =
- "A function that converts each item to zero or more strings, which may be further "
- + "processed before appending. If this param is not provided, the standard "
- + "conversion is used."
- + ""
- + "<p>The function takes in the item as a positional parameter and must have no "
- + "other parameters. The return value's type depends on how many arguments "
- + "are to be produced for the item:"
- + "<ul>"
- + "<li>In the common case when each item turns into one string, the function "
- + " should return that string."
- + "<li>If the item is to be filtered out entirely, the function should return "
- + " <code>None</code>."
- + "<li>If the item turns into multiple strings, the function returns a list of "
- + " those strings."
- + "</ul>"
- + "Returning a single string or <code>None</code> has the same effect as "
- + "returning a list of length 1 or length 0 respectively. However, it is more "
- + "efficient and readable to avoid creating a list where it is not needed."
- + ""
- + "<p><i>Warning:</i> <a href='globals.html#print'><code>print()</code></a> "
- + "statements that are executed during the call to <code>map_each</code> will "
- + "not produce any visible output."
- ),
- @Param(
- name = "format_each",
- type = String.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc =
- "An optional format string pattern, applied to each string returned by the "
- + "<code>map_each</code> function. "
- + "The format string must have exactly one '%s' placeholder."
- ),
- @Param(
- name = "before_each",
- type = String.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc =
- "An optional string to append before each argument derived from <code>values</code> "
- + "is appended."
- ),
- @Param(
- name = "omit_if_empty",
- type = Boolean.class,
- named = true,
- positional = false,
- defaultValue = "True",
- doc =
- "If true, if there are no arguments derived from <code>values</code> to be appended, "
- + "then all further processing is suppressed and the command line will be "
- + "unchanged. If false, the arg name and <code>terminate_with</code>, "
- + "if provided, will still be appended regardless of whether or not there are "
- + "other arguments."
- ),
- @Param(
- name = "uniquify",
- type = Boolean.class,
- named = true,
- positional = false,
- defaultValue = "False",
- doc =
- "If true, duplicate arguments that are derived from <code>values</code> will be "
- + "omitted. Only the first occurrence of each argument will remain. Usually this "
- + "feature is not needed because depsets already omit duplicates, but it can be "
- + "useful if <code>map_each</code> emits the same string for multiple items."
- ),
- @Param(
- name = "terminate_with",
- type = String.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc =
- "An optional string to append after all other arguments. This string will not be "
- + "added if <code>omit_if_empty</code> is true (the default) and no other items "
- + "are appended (as happens if <code>values</code> is empty or all of its items "
- + "are filtered)."
- ),
- },
- useLocation = true
- )
+ @Override
public NoneType addAll(
Object argNameOrValue,
Object values,
@@ -1350,111 +685,7 @@ public class SkylarkActionFactory implements SkylarkValue {
return Runtime.NONE;
}
- @SkylarkCallable(
- name = "add_joined",
- doc =
- "Appends an argument to this command line by concatenating together multiple values "
- + "using a separator. For depsets, the items are evaluated lazily during the "
- + "execution phase."
- + ""
- + "<p>Processing is similar to <a href='#add_all'><code>add_all()</code></a>, but "
- + "the list of arguments derived from <code>values</code> is combined into a single "
- + "argument as if by <code>join_with.join(...)</code>, and then formatted using the "
- + "given <code>format_joined</code> string template. Unlike <code>add_all()</code>, "
- + "there is no <code>before_each</code> or <code>terminate_with</code> parameter "
- + "since these are not generally useful when the items are combined into a single "
- + "argument."
- + ""
- + "<p>If after filtering there are no strings to join into an argument, and if "
- + "<code>omit_if_empty</code> is true (the default), no processing is done. "
- + "Otherwise if there are no strings to join but <code>omit_if_empty</code> is "
- + "false, the joined string will be an empty string.",
- parameters = {
- @Param(
- name = "arg_name_or_values",
- doc =
- "If two positional parameters are passed this is interpreted as the arg name. "
- + "The arg name is added before <code>values</code> without any processing. "
- + "This arg will not be added if <code>omit_if_empty</code> is true "
- + "(the default) and there are no strings derived from <code>values</code> "
- + "to join together (which can happen if <code>values</code> is empty "
- + "or all of its items are filtered)."
- + "If only one positional parameter is passed, it is interpreted as "
- + "<code>values</code> (see below)."
- ),
- @Param(
- name = "values",
- allowedTypes = {
- @ParamType(type = SkylarkList.class),
- @ParamType(type = SkylarkNestedSet.class),
- },
- defaultValue = "unbound",
- doc = "The list, tuple, or depset whose items will be joined."
- ),
- @Param(
- name = "join_with",
- type = String.class,
- named = true,
- positional = false,
- doc =
- "A delimiter string used to join together the strings obtained from applying "
- + "<code>map_each</code> and <code>format_each</code>, in the same manner as "
- + "<a href='string.html#join'><code>string.join()</code></a>."
- ),
- @Param(
- name = "map_each",
- type = BaseFunction.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc = "Same as for <a href='#add_all.map_each'><code>add_all</code></a>."
- ),
- @Param(
- name = "format_each",
- type = String.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc = "Same as for <a href='#add_all.format_each'><code>add_all</code></a>."
- ),
- @Param(
- name = "format_joined",
- type = String.class,
- named = true,
- positional = false,
- defaultValue = "None",
- noneable = true,
- doc =
- "An optional format string pattern applied to the joined string. "
- + "The format string must have exactly one '%s' placeholder."
- ),
- @Param(
- name = "omit_if_empty",
- type = Boolean.class,
- named = true,
- positional = false,
- defaultValue = "True",
- doc =
- "If true, if there are no strings to join together (either because <code>values"
- + "</code> is empty or all its items are filtered), then all further processing "
- + "is suppressed and the command line will be unchanged. If false, then even if "
- + "there are no strings to join together, two arguments will be appended: "
- + "the arg name followed by an empty string (which is the logical join "
- + "of zero strings)."
- ),
- @Param(
- name = "uniquify",
- type = Boolean.class,
- named = true,
- positional = false,
- defaultValue = "False",
- doc = "Same as for <a href='#add_all.uniquify'><code>add_all</code></a>."
- )
- },
- useLocation = true
- )
+ @Override
public NoneType addJoined(
Object argNameOrValue,
Object values,
@@ -1596,35 +827,7 @@ public class SkylarkActionFactory implements SkylarkValue {
}
}
- @SkylarkCallable(
- name = "use_param_file",
- doc =
- "Spills the args to a params file, replacing them with a pointer to the param file. "
- + "Use when your args may be too large for the system's command length limits ",
- parameters = {
- @Param(
- name = "param_file_arg",
- type = String.class,
- named = true,
- doc =
- "A format string with a single \"%s\". "
- + "If the args are spilled to a params file then they are replaced "
- + "with an argument consisting of this string formatted with "
- + "the path of the params file."
- ),
- @Param(
- name = "use_always",
- type = Boolean.class,
- named = true,
- positional = false,
- defaultValue = "False",
- doc =
- "Whether to always spill the args to a params file. If false, "
- + "bazel will decide whether the arguments need to be spilled "
- + "based on your system and arg length."
- )
- }
- )
+ @Override
public void useParamsFile(String paramFileArg, Boolean useAlways) throws EvalException {
if (isImmutable()) {
throw new EvalException(null, "cannot modify frozen value");
@@ -1638,22 +841,7 @@ public class SkylarkActionFactory implements SkylarkValue {
this.useAlways = useAlways;
}
- @SkylarkCallable(
- name = "set_param_file_format",
- doc = "Sets the format of the param file when written to disk",
- parameters = {
- @Param(
- name = "format",
- type = String.class,
- named = true,
- doc =
- "The format of the param file. Must be one of:<br>"
- + "\"shell\": All arguments are shell quoted and separated by whitespace<br>"
- + "\"multiline\": All arguments are unquoted and separated by newline characters"
- + "The format defaults to \"shell\" if not called."
- )
- }
- )
+ @Override
public void setParamFileFormat(String format) throws EvalException {
if (isImmutable()) {
throw new EvalException(null, "cannot modify frozen value");
@@ -1695,11 +883,7 @@ public class SkylarkActionFactory implements SkylarkValue {
}
}
- @SkylarkCallable(
- name = "args",
- doc = "Returns an Args object that can be used to build memory-efficient command lines.",
- useEnvironment = true
- )
+ @Override
public Args args(Environment env) {
return new Args(env.mutability(), skylarkSemantics);
}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ActionApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ActionApi.java
new file mode 100644
index 0000000000..ec38289f58
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/ActionApi.java
@@ -0,0 +1,104 @@
+// Copyright 2018 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.skylarkbuildapi;
+
+import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.SkylarkDict;
+import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import java.io.IOException;
+
+/** Interface for actions in Skylark. */
+@SkylarkModule(
+ name = "Action",
+ category = SkylarkModuleCategory.BUILTIN,
+ doc =
+ "An action created during rule analysis."
+ + "<p>This object is visible for the purpose of testing, and may be obtained from an "
+ + "<a href=\"globals.html#Actions\">Actions</a> provider. It is normally not necessary "
+ + "to access <code>Action</code> objects or their fields within a rule's "
+ + "implementation function. You may instead want to see the "
+ + "<a href='../rules.$DOC_EXT#actions'>Rules page</a> for a general discussion of how "
+ + "to use actions when defining custom rules, or the <a href='actions.html'>API "
+ + "reference</a> for creating actions."
+ + "<p>Some fields of this object are only applicable for certain kinds of actions. "
+ + "Fields that are inapplicable are set to <code>None</code>.")
+public interface ActionApi extends SkylarkValue {
+
+ @SkylarkCallable(
+ name = "mnemonic",
+ structField = true,
+ doc = "The mnemonic for this action."
+ )
+ public abstract String getMnemonic();
+
+ @SkylarkCallable(
+ name = "inputs",
+ doc = "A set of the input files of this action.",
+ structField = true)
+ public SkylarkNestedSet getSkylarkInputs();
+
+ @SkylarkCallable(
+ name = "outputs",
+ doc = "A set of the output files of this action.",
+ structField = true)
+ public SkylarkNestedSet getSkylarkOutputs();
+
+ @SkylarkCallable(
+ name = "argv",
+ doc =
+ "For actions created by <a href=\"actions.html#run\">ctx.actions.run()</a> "
+ + "or <a href=\"actions.html#run_shell\">ctx.actions.run_shell()</a> an immutable "
+ + "list of the arguments for the command line to be executed. Note that "
+ + "for shell actions the first two arguments will be the shell path "
+ + "and <code>\"-c\"</code>.",
+ structField = true,
+ allowReturnNones = true
+ )
+ public SkylarkList<String> getSkylarkArgv() throws EvalException;
+
+ @SkylarkCallable(
+ name = "content",
+ doc =
+ "For actions created by <a href=\"actions.html#write\">ctx.actions.write()</a> or "
+ + "<a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a>,"
+ + " the contents of the file to be written.",
+ structField = true,
+ allowReturnNones = true)
+ public String getSkylarkContent() throws IOException;
+
+ @SkylarkCallable(
+ name = "substitutions",
+ doc =
+ "For actions created by "
+ + "<a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a>,"
+ + " an immutable dict holding the substitution mapping.",
+ structField = true,
+ allowReturnNones = true)
+ public SkylarkDict<String, String> getSkylarkSubstitutions();
+
+ @SkylarkCallable(
+ name = "env",
+ structField = true,
+ doc =
+ "The 'fixed' environment variables for this action. This includes only environment "
+ + "settings which are explicitly set by the action definition, and thus omits settings "
+ + "which are only pre-set in the execution environment.")
+ public SkylarkDict<String, String> getEnv();
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/CommandLineArgsApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/CommandLineArgsApi.java
new file mode 100644
index 0000000000..6d6ba657a8
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/CommandLineArgsApi.java
@@ -0,0 +1,520 @@
+// Copyright 2018 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.skylarkbuildapi;
+
+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.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.Runtime;
+import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+
+/** Command line args module. */
+@SkylarkModule(
+ name = "Args",
+ category = SkylarkModuleCategory.BUILTIN,
+ doc =
+ "An object that encapsulates, in a memory-efficient way, the data needed to build part or "
+ + "all of a command line."
+ + ""
+ + "<p>It often happens that an action requires a large command line containing values "
+ + "accumulated from transitive dependencies. For example, a linker command line might "
+ + "list every object file needed by all of the libraries being linked. It is best "
+ + "practice to store such transitive data in <a href='depset.html'><code>depset"
+ + "</code></a>s, so that they can be shared by multiple targets. However, if the rule "
+ + "author had to convert these depsets into lists of strings in order to construct an "
+ + "action command line, it would defeat this memory-sharing optimization."
+ + ""
+ + "<p>For this reason, the action-constructing functions accept <code>Args</code> "
+ + "objects in addition to strings. Each <code>Args</code> object represents a "
+ + "concatenation of strings and depsets, with optional transformations for "
+ + "manipulating the data. <code>Args</code> objects do not process the depsets they "
+ + "encapsulate until the execution phase, when it comes time to calculate the command "
+ + "line. This helps defer any expensive copying until after the analysis phase is "
+ + "complete. See the <a href='../performance.$DOC_EXT'>Optimizing Performance</a> page "
+ + "for more information."
+ + ""
+ + "<p><code>Args</code> are constructed by calling <a href='actions.html#args'><code>"
+ + "ctx.actions.args()</code></a>. They can be passed as the <code>arguments</code> "
+ + "parameter of <a href='actions.html#run'><code>ctx.actions.run()</code></a> or "
+ + "<a href='actions.html#run_shell'><code>ctx.actions.run_shell()</code></a>. Each "
+ + "mutation of an <code>Args</code> object appends values to the eventual command "
+ + "line."
+ + ""
+ + "<p>The <code>map_each</code> feature allows you to customize how items are "
+ + "transformed into strings. If you do not provide a <code>map_each</code> function, "
+ + "the standard conversion is as follows: "
+ + "<ul>"
+ + "<li>Values that are already strings are left as-is."
+ + "<li><a href='File.html'><code>File</code></a> objects are turned into their "
+ + " <code>File.path</code> values."
+ + "<li>All other types are turned into strings in an <i>unspecified</i> manner. For "
+ + " this reason, you should avoid passing values that are not of string or "
+ + " <code>File</code> type to <code>add()</code>, and if you pass them to "
+ + " <code>add_all()</code> or <code>add_joined()</code> then you should provide a "
+ + " <code>map_each</code> function."
+ + "</ul>"
+ + ""
+ + "<p>When using string formatting (<code>format</code>, <code>format_each</code>, and "
+ + "<code>format_joined</code> params of the <code>add*()</code> methods), the format "
+ + "template is interpreted in the same way as <code>%</code>-substitution on strings, "
+ + "except that the template must have exactly one substitution placeholder and it must "
+ + "be <code>%s</code>. Literal percents may be escaped as <code>%%</code>. Formatting "
+ + "is applied after the value is converted to a string as per the above."
+ + ""
+ + "<p>Each of the <code>add*()</code> methods have an alternate form that accepts an "
+ + "extra positional parameter, an \"arg name\" string to insert before the rest of the "
+ + "arguments. For <code>add_all</code> and <code>add_joined</code> the extra string "
+ + "will not be added if the sequence turns out to be empty. "
+ + "For instance, the same usage can add either <code>--foo val1 val2 val3 --bar"
+ + "</code> or just <code>--bar</code> to the command line, depending on whether the "
+ + "given sequence contains <code>val1..val3</code> or is empty."
+ + ""
+ + "<p>If the size of the command line can grow longer than the maximum size allowed by "
+ + "the system, the arguments can be spilled over into parameter files. See "
+ + "<a href='#use_param_file'><code>use_param_file()</code></a> and "
+ + "<a href='#set_param_file_format'><code>set_param_file_format()</code></a>."
+ + ""
+ + "<p>Example: Suppose we wanted to generate the command line: "
+ + "<pre>\n"
+ + "--foo foo1.txt foo2.txt ... fooN.txt --bar bar1.txt,bar2.txt,...,barM.txt --baz\n"
+ + "</pre>"
+ + "We could use the following <code>Args</code> object: "
+ + "<pre class=language-python>\n"
+ + "# foo_deps and bar_deps are depsets containing\n"
+ + "# File objects for the foo and bar .txt files.\n"
+ + "args = ctx.actions.args()\n"
+ + "args.add_all(\"--foo\", foo_deps)\n"
+ + "args.add_joined(\"--bar\", bar_deps, join_with=\",\")\n"
+ + "args.add(\"--baz\")\n"
+ + "ctx.actions.run(\n"
+ + " ...\n"
+ + " arguments = [args],\n"
+ + " ...\n"
+ + ")\n"
+ + "</pre>"
+)
+public interface CommandLineArgsApi extends SkylarkValue {
+ @SkylarkCallable(
+ name = "add",
+ doc =
+ "Appends an argument to this command line."
+ + ""
+ + "<p><b>Deprecation note:</b> The <code>before_each</code>, <code>join_with</code> "
+ + "and <code>map_fn</code> params are replaced by the <a href='#add_all'><code>"
+ + "add_all()</code></a> and <a href='#add_joined'><code>add_joined()</code></a> "
+ + "methods. These parameters will be removed, and are currently disallowed if the "
+ + "<a href='../backward-compatibility.$DOC_EXT#new-args-api'><code>"
+ + "--incompatible_disallow_old_style_args_add</code></a> flag is set. Likewise, "
+ + "<code>value</code> should now be a scalar value, not a list, tuple, or depset of "
+ + "items.",
+ parameters = {
+ @Param(
+ name = "arg_name_or_value",
+ doc =
+ "If two positional parameters are passed this is interpreted as the arg name. "
+ + "The arg name is added before the value without any processing. "
+ + "If only one positional parameter is passed, it is interpreted as "
+ + "<code>value</code> (see below)."),
+ @Param(
+ name = "value",
+ defaultValue = "unbound",
+ doc =
+ "The object to append. It will be converted to a string using the standard "
+ + "conversion mentioned above. Since there is no <code>map_each</code> parameter "
+ + "for this function, <code>value</code> should be either a string or a <code>"
+ + "File</code>."
+ + ""
+ + "<p><i>Deprecated behavior:</i> <code>value</code> may also be a list, tuple, "
+ + "or depset of multiple items to append."),
+ @Param(
+ name = "format",
+ type = String.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc =
+ "A format string pattern, to be applied to the stringified version of <code>value"
+ + "</code>."
+ + ""
+ + "<p><i>Deprecated behavior:</i> If <code>value</code> is a list or depset, "
+ + "formatting is applied to each item."),
+ @Param(
+ name = "before_each",
+ type = String.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc =
+ "<i>Deprecated:</i> Only supported when <code>value</code> is a list, tuple, or "
+ + "depset. This string will be appended prior to appending each item."),
+ @Param(
+ name = "join_with",
+ type = String.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc =
+ "<i>Deprecated:</i> Only supported when <code>value</code> is a list, tuple, or "
+ + "depset. All items will be joined together using this string to form a single "
+ + "arg to append."),
+ @Param(
+ name = "map_fn",
+ type = BaseFunction.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc =
+ "<i>Deprecated:</i> Only supported when <code>value</code> is a list, tuple, or "
+ + "depset. This is a function that transforms the sequence of items into a list "
+ + "of strings. The sequence of items is given as a positional argument -- the "
+ + "function must not take any other parameters -- and the returned list's length "
+ + "must equal the number of items. Use <code>map_each</code> of <code>add_all"
+ + "</code> or <code>add_joined</code> instead.")
+ },
+ useLocation = true
+ )
+ public Runtime.NoneType addArgument(
+ Object argNameOrValue,
+ Object value,
+ Object format,
+ Object beforeEach,
+ Object joinWith,
+ Object mapFn,
+ Location loc)
+ throws EvalException;
+
+ @SkylarkCallable(
+ name = "add_all",
+ doc =
+ "Appends multiple arguments to this command line. For depsets, the items are "
+ + "evaluated lazily during the execution phase."
+ + ""
+ + "<p>Most of the processing occurs over a list of arguments to be appended, as per "
+ + "the following steps:"
+ + "<ol>"
+ + "<li>If <code>map_each</code> is given, it is applied to each input item, and the "
+ + " resulting lists of strings are concatenated to form the initial argument "
+ + " list. Otherwise, the initial argument list is the result of applying the "
+ + " standard conversion to each item."
+ + "<li>Each argument in the list is formatted with <code>format_each</code>, if "
+ + " present."
+ + "<li>If <code>uniquify</code> is true, duplicate arguments are removed. The first "
+ + " occurrence is the one that remains."
+ + "<li>If a <code>before_each</code> string is given, it is inserted as a new "
+ + " argument before each existing argument in the list. This effectively doubles "
+ + " the number of arguments to be appended by this point."
+ + "<li>Except in the case that the list is empty and <code>omit_if_empty</code> is "
+ + " true (the default), the arg name and <code>terminate_with</code> are "
+ + " inserted as the first and last arguments, respectively, if they are given."
+ + "</ol>"
+ + "Note that empty strings are valid arguments that are subject to all these "
+ + "processing steps.",
+ parameters = {
+ @Param(
+ name = "arg_name_or_values",
+ doc =
+ "If two positional parameters are passed this is interpreted as the arg name. "
+ + "The arg name is added before the <code>values</code> without any processing. "
+ + "This arg name will not be added if <code>omit_if_empty</code> is true "
+ + "(the default) and no other items are appended (as happens if "
+ + "<code>values</code> is empty or all of its items are filtered). "
+ + "If only one positional parameter is passed, it is interpreted as "
+ + "<code>values</code> (see below)."
+ ),
+ @Param(
+ name = "values",
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ @ParamType(type = SkylarkNestedSet.class),
+ },
+ defaultValue = "unbound",
+ doc = "The list, tuple, or depset whose items will be appended."
+ ),
+ @Param(
+ name = "map_each",
+ type = BaseFunction.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc =
+ "A function that converts each item to zero or more strings, which may be further "
+ + "processed before appending. If this param is not provided, the standard "
+ + "conversion is used."
+ + ""
+ + "<p>The function takes in the item as a positional parameter and must have no "
+ + "other parameters. The return value's type depends on how many arguments "
+ + "are to be produced for the item:"
+ + "<ul>"
+ + "<li>In the common case when each item turns into one string, the function "
+ + " should return that string."
+ + "<li>If the item is to be filtered out entirely, the function should return "
+ + " <code>None</code>."
+ + "<li>If the item turns into multiple strings, the function returns a list of "
+ + " those strings."
+ + "</ul>"
+ + "Returning a single string or <code>None</code> has the same effect as "
+ + "returning a list of length 1 or length 0 respectively. However, it is more "
+ + "efficient and readable to avoid creating a list where it is not needed."
+ + ""
+ + "<p><i>Warning:</i> <a href='globals.html#print'><code>print()</code></a> "
+ + "statements that are executed during the call to <code>map_each</code> will "
+ + "not produce any visible output."
+ ),
+ @Param(
+ name = "format_each",
+ type = String.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc =
+ "An optional format string pattern, applied to each string returned by the "
+ + "<code>map_each</code> function. "
+ + "The format string must have exactly one '%s' placeholder."
+ ),
+ @Param(
+ name = "before_each",
+ type = String.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc =
+ "An optional string to append before each argument derived from <code>values</code> "
+ + "is appended."
+ ),
+ @Param(
+ name = "omit_if_empty",
+ type = Boolean.class,
+ named = true,
+ positional = false,
+ defaultValue = "True",
+ doc =
+ "If true, if there are no arguments derived from <code>values</code> to be "
+ + "appended, then all further processing is suppressed and the command line will "
+ + "be unchanged. If false, the arg name and <code>terminate_with</code>, "
+ + "if provided, will still be appended regardless of whether or not there are "
+ + "other arguments."
+ ),
+ @Param(
+ name = "uniquify",
+ type = Boolean.class,
+ named = true,
+ positional = false,
+ defaultValue = "False",
+ doc =
+ "If true, duplicate arguments that are derived from <code>values</code> will be "
+ + "omitted. Only the first occurrence of each argument will remain. Usually this "
+ + "feature is not needed because depsets already omit duplicates, but it can be "
+ + "useful if <code>map_each</code> emits the same string for multiple items."
+ ),
+ @Param(
+ name = "terminate_with",
+ type = String.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc =
+ "An optional string to append after all other arguments. This string will not be "
+ + "added if <code>omit_if_empty</code> is true (the default) and no other items "
+ + "are appended (as happens if <code>values</code> is empty or all of its items "
+ + "are filtered)."
+ ),
+ },
+ useLocation = true
+ )
+ public Runtime.NoneType addAll(
+ Object argNameOrValue,
+ Object values,
+ Object mapEach,
+ Object formatEach,
+ Object beforeEach,
+ Boolean omitIfEmpty,
+ Boolean uniquify,
+ Object terminateWith,
+ Location loc)
+ throws EvalException;
+
+ @SkylarkCallable(
+ name = "add_joined",
+ doc =
+ "Appends an argument to this command line by concatenating together multiple values "
+ + "using a separator. For depsets, the items are evaluated lazily during the "
+ + "execution phase."
+ + ""
+ + "<p>Processing is similar to <a href='#add_all'><code>add_all()</code></a>, but "
+ + "the list of arguments derived from <code>values</code> is combined into a single "
+ + "argument as if by <code>join_with.join(...)</code>, and then formatted using the "
+ + "given <code>format_joined</code> string template. Unlike <code>add_all()</code>, "
+ + "there is no <code>before_each</code> or <code>terminate_with</code> parameter "
+ + "since these are not generally useful when the items are combined into a single "
+ + "argument."
+ + ""
+ + "<p>If after filtering there are no strings to join into an argument, and if "
+ + "<code>omit_if_empty</code> is true (the default), no processing is done. "
+ + "Otherwise if there are no strings to join but <code>omit_if_empty</code> is "
+ + "false, the joined string will be an empty string.",
+ parameters = {
+ @Param(
+ name = "arg_name_or_values",
+ doc =
+ "If two positional parameters are passed this is interpreted as the arg name. "
+ + "The arg name is added before <code>values</code> without any processing. "
+ + "This arg will not be added if <code>omit_if_empty</code> is true "
+ + "(the default) and there are no strings derived from <code>values</code> "
+ + "to join together (which can happen if <code>values</code> is empty "
+ + "or all of its items are filtered)."
+ + "If only one positional parameter is passed, it is interpreted as "
+ + "<code>values</code> (see below)."),
+ @Param(
+ name = "values",
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ @ParamType(type = SkylarkNestedSet.class),
+ },
+ defaultValue = "unbound",
+ doc = "The list, tuple, or depset whose items will be joined."),
+ @Param(
+ name = "join_with",
+ type = String.class,
+ named = true,
+ positional = false,
+ doc =
+ "A delimiter string used to join together the strings obtained from applying "
+ + "<code>map_each</code> and <code>format_each</code>, in the same manner as "
+ + "<a href='string.html#join'><code>string.join()</code></a>."),
+ @Param(
+ name = "map_each",
+ type = BaseFunction.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc = "Same as for <a href='#add_all.map_each'><code>add_all</code></a>."),
+ @Param(
+ name = "format_each",
+ type = String.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc = "Same as for <a href='#add_all.format_each'><code>add_all</code></a>."
+ ),
+ @Param(
+ name = "format_joined",
+ type = String.class,
+ named = true,
+ positional = false,
+ defaultValue = "None",
+ noneable = true,
+ doc =
+ "An optional format string pattern applied to the joined string. "
+ + "The format string must have exactly one '%s' placeholder."
+ ),
+ @Param(
+ name = "omit_if_empty",
+ type = Boolean.class,
+ named = true,
+ positional = false,
+ defaultValue = "True",
+ doc =
+ "If true, if there are no strings to join together (either because <code>values"
+ + "</code> is empty or all its items are filtered), then all further processing "
+ + "is suppressed and the command line will be unchanged. If false, then even if "
+ + "there are no strings to join together, two arguments will be appended: "
+ + "the arg name followed by an empty string (which is the logical join "
+ + "of zero strings)."
+ ),
+ @Param(
+ name = "uniquify",
+ type = Boolean.class,
+ named = true,
+ positional = false,
+ defaultValue = "False",
+ doc = "Same as for <a href='#add_all.uniquify'><code>add_all</code></a>."
+ )
+ },
+ useLocation = true
+ )
+ public Runtime.NoneType addJoined(
+ Object argNameOrValue,
+ Object values,
+ String joinWith,
+ Object mapEach,
+ Object formatEach,
+ Object formatJoined,
+ Boolean omitIfEmpty,
+ Boolean uniquify,
+ Location loc)
+ throws EvalException;
+
+ @SkylarkCallable(
+ name = "use_param_file",
+ doc =
+ "Spills the args to a params file, replacing them with a pointer to the param file. "
+ + "Use when your args may be too large for the system's command length limits ",
+ parameters = {
+ @Param(
+ name = "param_file_arg",
+ type = String.class,
+ named = true,
+ doc =
+ "A format string with a single \"%s\". "
+ + "If the args are spilled to a params file then they are replaced "
+ + "with an argument consisting of this string formatted with "
+ + "the path of the params file."),
+ @Param(
+ name = "use_always",
+ type = Boolean.class,
+ named = true,
+ positional = false,
+ defaultValue = "False",
+ doc =
+ "Whether to always spill the args to a params file. If false, "
+ + "bazel will decide whether the arguments need to be spilled "
+ + "based on your system and arg length.")
+ })
+ public void useParamsFile(String paramFileArg, Boolean useAlways) throws EvalException;
+
+ @SkylarkCallable(
+ name = "set_param_file_format",
+ doc = "Sets the format of the param file when written to disk",
+ parameters = {
+ @Param(
+ name = "format",
+ type = String.class,
+ named = true,
+ doc =
+ "The format of the param file. Must be one of:<br>"
+ + "\"shell\": All arguments are shell quoted and separated by whitespace<br>"
+ + "\"multiline\": All arguments are unquoted and separated by newline characters"
+ + "The format defaults to \"shell\" if not called.")
+ }
+ )
+ public void setParamFileFormat(String format) throws EvalException;
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkActionFactoryApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkActionFactoryApi.java
new file mode 100644
index 0000000000..25a3218bc6
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkActionFactoryApi.java
@@ -0,0 +1,523 @@
+// Copyright 2018 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.skylarkbuildapi;
+
+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.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
+import com.google.devtools.build.lib.syntax.Environment;
+import com.google.devtools.build.lib.syntax.EvalException;
+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.SkylarkNestedSet;
+
+/** Module providing functions to create actions. */
+@SkylarkModule(
+ name = "actions",
+ category = SkylarkModuleCategory.BUILTIN,
+ doc =
+ "Module providing functions to create actions. "
+ + "Access this module using <a href=\"ctx.html#actions\"><code>ctx.actions</code></a>.")
+public interface SkylarkActionFactoryApi extends SkylarkValue {
+
+ @SkylarkCallable(
+ name = "declare_file",
+ doc =
+ "Declares that the rule or aspect creates a file with the given filename. "
+ + "If <code>sibling</code> is not specified, the file name is relative to the package"
+ + "directory, otherwise the file is in the same directory as <code>sibling</code>."
+ + "Files cannot be created outside of the current package."
+ + "<p>Remember that in addition to declaring a file, you must separately create an "
+ + "action that emits the file. Creating that action will require passing the returned "
+ + "<code>File</code> object to the action's construction function."
+ + "<p>Note that <a href='../rules.$DOC_EXT#files'>predeclared output files</a> do not "
+ + "need to be (and cannot be) declared using this function. You can obtain their "
+ + "<code>File</code> objects from <a href=\"ctx.html#outputs\"><code>ctx.outputs</code>"
+ + "</a> instead. "
+ + "<a href=\"https://github.com/bazelbuild/examples/tree/master/rules/"
+ + "computed_dependencies/hash.bzl\">See example of use</a>",
+ parameters = {
+ @Param(
+ name = "filename",
+ type = String.class,
+ doc =
+ "If no 'sibling' provided, path of the new file, relative "
+ + "to the current package. Otherwise a base name for a file "
+ + "('sibling' determines a directory)."
+ ),
+ @Param(
+ name = "sibling",
+ doc =
+ "A file that lives in the same directory as the newly created file. "
+ + "The file must be in the current package.",
+ type = FileApi.class,
+ noneable = true,
+ positional = false,
+ named = true,
+ defaultValue = "None"
+ )
+ }
+ )
+ public FileApi declareFile(String filename, Object sibling) throws EvalException;
+
+ @SkylarkCallable(
+ name = "declare_directory",
+ doc =
+ "Declares that rule or aspect create a directory with the given name, in the "
+ + "current package. You must create an action that generates the directory.",
+ parameters = {
+ @Param(
+ name = "filename",
+ type = String.class,
+ doc =
+ "If no 'sibling' provided, path of the new directory, relative "
+ + "to the current package. Otherwise a base name for a file "
+ + "('sibling' defines a directory)."),
+ @Param(
+ name = "sibling",
+ doc = "A file that lives in the same directory as the newly declared directory.",
+ type = FileApi.class,
+ noneable = true,
+ positional = false,
+ named = true,
+ defaultValue = "None")
+ })
+ public FileApi declareDirectory(String filename, Object sibling) throws EvalException;
+
+ @SkylarkCallable(
+ name = "do_nothing",
+ doc =
+ "Creates an empty action that neither executes a command nor produces any "
+ + "output, but that is useful for inserting 'extra actions'.",
+ parameters = {
+ @Param(
+ name = "mnemonic",
+ type = String.class,
+ named = true,
+ positional = false,
+ doc = "A one-word description of the action, for example, CppCompile or GoLink."),
+ @Param(
+ name = "inputs",
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ @ParamType(type = SkylarkNestedSet.class),
+ },
+ generic1 = FileApi.class,
+ named = true,
+ positional = false,
+ defaultValue = "[]",
+ doc = "List of the input files of the action."),
+ })
+ public void doNothing(String mnemonic, Object inputs) throws EvalException;
+
+ @SkylarkCallable(
+ name = "write",
+ doc =
+ "Creates a file write action. When the action is executed, it will write the given content "
+ + "to a file. This is used to generate files using information available in the "
+ + "analysis phase. If the file is large and with a lot of static content, consider "
+ + "using <a href=\"#expand_template\"><code>expand_template</code></a>.",
+ parameters = {
+ @Param(name = "output", type = FileApi.class, doc = "The output file.", named = true),
+ @Param(
+ name = "content",
+ type = Object.class,
+ allowedTypes = {
+ @ParamType(type = String.class),
+ @ParamType(type = CommandLineArgsApi.class)
+ },
+ doc =
+ "the contents of the file. "
+ + "May be a either a string or an "
+ + "<a href=\"actions.html#args\"><code>actions.args()</code></a> object.",
+ named = true
+ ),
+ @Param(
+ name = "is_executable",
+ type = Boolean.class,
+ defaultValue = "False",
+ doc = "Whether the output file should be executable.",
+ named = true
+ )
+ }
+ )
+ public void write(FileApi output, Object content, Boolean isExecutable) throws EvalException;
+
+ @SkylarkCallable(
+ name = "run",
+ doc =
+ "Creates an action that runs an executable. "
+ + "<a href=\"https://github.com/bazelbuild/examples/tree/master/rules/"
+ + "actions_run/execute.bzl\">See example of use</a>",
+ parameters = {
+ @Param(
+ name = "outputs",
+ type = SkylarkList.class,
+ generic1 = FileApi.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 = FileApi.class,
+ defaultValue = "[]",
+ named = true,
+ positional = false,
+ doc = "List or depset of the input files of the action."
+ ),
+ @Param(
+ name = "executable",
+ type = Object.class,
+ allowedTypes = {
+ @ParamType(type = FileApi.class),
+ @ParamType(type = String.class),
+ },
+ named = true,
+ positional = false,
+ doc = "The executable file to be called by the action."
+ ),
+ @Param(
+ name = "tools",
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ @ParamType(type = SkylarkNestedSet.class),
+ },
+ generic1 = FileApi.class,
+ defaultValue = "unbound",
+ named = true,
+ positional = false,
+ doc =
+ "List or depset of any tools needed by the action. Tools are inputs with additional "
+ + "runfiles that are automatically made available to the action."
+ ),
+ @Param(
+ name = "arguments",
+ type = Object.class,
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ },
+ defaultValue = "[]",
+ named = true,
+ positional = false,
+ doc =
+ "Command line arguments of the action. "
+ + "Must be a list of strings or "
+ + "<a href=\"actions.html#args\"><code>actions.args()</code></a> objects."
+ ),
+ @Param(
+ name = "mnemonic",
+ type = String.class,
+ noneable = true,
+ defaultValue = "None",
+ named = true,
+ positional = false,
+ doc = "A one-word description of the action, for example, CppCompile or GoLink."
+ ),
+ @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, "
+ + "for example, \"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
+ )
+ public void run(
+ SkylarkList outputs,
+ Object inputs,
+ Object executableUnchecked,
+ Object toolsUnchecked,
+ Object arguments,
+ Object mnemonicUnchecked,
+ Object progressMessage,
+ Boolean useDefaultShellEnv,
+ Object envUnchecked,
+ Object executionRequirementsUnchecked,
+ Object inputManifestsUnchecked,
+ Location location)
+ throws EvalException;
+
+ @SkylarkCallable(
+ name = "run_shell",
+ doc =
+ "Creates an action that runs a shell command. "
+ + "<a href=\"https://github.com/bazelbuild/examples/tree/master/rules/"
+ + "shell_command/size.bzl\">See example of use</a>",
+ parameters = {
+ @Param(
+ name = "outputs",
+ type = SkylarkList.class,
+ generic1 = FileApi.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 = FileApi.class,
+ defaultValue = "[]",
+ named = true,
+ positional = false,
+ doc = "List or depset of the input files of the action."
+ ),
+ @Param(
+ name = "tools",
+ allowedTypes = {
+ @ParamType(type = SkylarkList.class),
+ @ParamType(type = SkylarkNestedSet.class),
+ },
+ generic1 = FileApi.class,
+ defaultValue = "unbound",
+ named = true,
+ positional = false,
+ doc =
+ "List or depset of any tools needed by the action. Tools are inputs with additional "
+ + "runfiles that are automatically made available to 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 "
+ + "<a href=\"actions.html#args\"><code>actions.args()</code></a> objects.<br>"
+ + "Blaze passes the elements in this attribute as arguments to the command."
+ + "The command can access these arguments as <code>$1</code>, <code>$2</code>, etc."
+ ),
+ @Param(
+ name = "mnemonic",
+ type = String.class,
+ noneable = true,
+ defaultValue = "None",
+ named = true,
+ positional = false,
+ doc = "A one-word description of the action, for example, 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),
+ },
+ named = true,
+ positional = false,
+ doc =
+ "Shell command to execute.<br><br>"
+ + "<b>Passing a sequence of strings to this attribute is deprecated and Blaze may "
+ + "stop accepting such values in the future.</b><br><br>"
+ + "The command can access the elements of the <code>arguments</code> object via "
+ + "<code>$1</code>, <code>$2</code>, etc.<br>"
+ + "When this argument is a string, it must be a valid shell command. For example: "
+ + "\"<code>echo foo > $1</code>\". Blaze uses the same shell to execute the "
+ + "command as it does for genrules."
+ ),
+ @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, "
+ + "for example, \"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
+ )
+ public void runShell(
+ SkylarkList outputs,
+ Object inputs,
+ Object toolsUnchecked,
+ Object arguments,
+ Object mnemonicUnchecked,
+ Object commandUnchecked,
+ Object progressMessage,
+ Boolean useDefaultShellEnv,
+ Object envUnchecked,
+ Object executionRequirementsUnchecked,
+ Object inputManifestsUnchecked,
+ Location location)
+ throws EvalException;
+
+ @SkylarkCallable(
+ name = "expand_template",
+ doc =
+ "Creates a template expansion action. When the action is executed, it will "
+ + "generate a file based on a template. Parts of the template will be replaced "
+ + "using the <code>substitutions</code> dictionary. Whenever a key of the "
+ + "dictionary appears in the template, it is replaced with the associated value. "
+ + "There is no special syntax for the keys. You may, for example, use curly braces "
+ + "to avoid conflicts (for example, <code>{KEY}</code>). "
+ + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/expand_template/hello.bzl\">"
+ + "See example of use</a>",
+ parameters = {
+ @Param(
+ name = "template",
+ type = FileApi.class,
+ named = true,
+ positional = false,
+ doc = "The template file, which is a UTF-8 encoded text file."
+ ),
+ @Param(
+ name = "output",
+ type = FileApi.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 = "is_executable",
+ type = Boolean.class,
+ defaultValue = "False",
+ named = true,
+ positional = false,
+ doc = "Whether the output file should be executable."
+ )
+ }
+ )
+ public void expandTemplate(
+ FileApi template,
+ FileApi output,
+ SkylarkDict<?, ?> substitutionsUnchecked,
+ Boolean executable)
+ throws EvalException;
+
+ @SkylarkCallable(
+ name = "args",
+ doc = "Returns an Args object that can be used to build memory-efficient command lines.",
+ useEnvironment = true
+ )
+ public CommandLineArgsApi args(Environment env);
+}