// 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 ctx.actions.") public interface SkylarkActionFactoryApi extends SkylarkValue { @SkylarkCallable( name = "declare_file", doc = "Declares that the rule or aspect creates a file with the given filename. " + "If sibling is not specified, the file name is relative to the " + "package " + "directory, otherwise the file is in the same directory as sibling. " + "Files cannot be created outside of the current package." + "

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 File object to the action's construction function." + "

Note that predeclared output files do " + "not " + "need to be (and cannot be) declared using this function. You can obtain their " + "File objects from " + "ctx.outputs instead. " + "See example of use.", 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 expand_template.", 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 " + "actions.args() 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. " + "See example of use.", 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 " + "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, 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 " + "tags " + "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. " + "See example of use.", 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 " + "actions.args() objects.
" + "Blaze passes the elements in this attribute as arguments to the command." + "The command can access these arguments as $1, $2, " + "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.

" + "Passing a sequence of strings to this attribute is deprecated and Blaze" + "may " + "stop accepting such values in the future.

" + "The command can access the elements of the arguments object " + "via " + "$1, $2, etc.
" + "When this argument is a string, it must be a valid shell command. For " + "example: " + "\"echo foo > $1\". 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 " + "tags " + "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 substitutions dictionary, in the order the substitutions " + "are specified. Whenever a key of the dictionary appears in the template (or a " + "result of a previous substitution), 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, {KEY}). " + "" + "See example of use.", 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); }