diff options
Diffstat (limited to 'src/main/java/com/google/devtools/build')
10 files changed, 1198 insertions, 827 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java index 51cf588714..1ba598474d 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java @@ -24,10 +24,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.packages.RequiredProviders; import com.google.devtools.build.lib.skyframe.BuildConfigurationValue; -import com.google.devtools.build.lib.skylarkinterface.Param; -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.TransitiveInfoCollectionApi; import com.google.devtools.build.lib.syntax.SkylarkIndexable; import com.google.devtools.build.lib.syntax.SkylarkNestedSet; import javax.annotation.Nullable; @@ -47,37 +44,10 @@ import javax.annotation.Nullable; * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory * @see TransitiveInfoProvider */ -@SkylarkModule( - name = "Target", - category = SkylarkModuleCategory.BUILTIN, - doc = - "A BUILD target. It is essentially a <code>struct</code> with the following fields:" - + "<ul>" - + "<li><h3 id=\"modules.Target.label\">label</h3><code><a class=\"anchor\" " - + "href=\"Label.html\">Label</a> Target.label</code><br>The identifier of the " - + "target.</li>" - + "<li><h3 id=\"modules.Target.files\">files</h3><code><a class=\"anchor\" " - + "href=\"depset.html\">depset</a> Target.files </code><br>The set of " - + "<a class=\"anchor\" href=\"File.html\">File</a>s produced directly by this " - + "target.</li>" - + "<li><h3 id=\"modules.Target.aspect_ids\">aspect_ids</h3><code><a class=\"anchor\"" - + "href=\"list.html\">list</a> Target.aspect_ids </code><br>The list of " - + "<a class=\"anchor\" href=\"ctx.html#aspect_id\">aspect_id</a>s applied to this " - + "target.</li>" - + "<li><h3 id=\"modules.Target.extraproviders\">Extra providers</h3>For rule targets all " - + "additional providers provided by this target are accessible as <code>struct</code> " - + "fields. These extra providers are defined in the <code>struct</code> returned by the " - + "rule implementation function.</li>" - + "</ul>" -) -public interface TransitiveInfoCollection extends SkylarkIndexable, SkylarkProviderCollection { +public interface TransitiveInfoCollection + extends SkylarkIndexable, SkylarkProviderCollection, TransitiveInfoCollectionApi { - @SkylarkCallable(name = "output_group", - documented = false, // TODO(dslomov): document. - parameters = { - @Param(name = "group_name", type = String.class, doc = "Output group name", named = true) - } - ) + @Override default SkylarkNestedSet outputGroup(String group) { OutputGroupInfo provider = OutputGroupInfo.get(this); NestedSet<Artifact> result = provider != null diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java index afd1735f62..93646419fb 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java @@ -51,10 +51,9 @@ import com.google.devtools.build.lib.packages.RuleClassProvider; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.packages.TestTimeout; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; -import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; +import com.google.devtools.build.lib.skylarkbuildapi.BuildConfigurationApi; import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; import com.google.devtools.build.lib.util.OS; import com.google.devtools.build.lib.util.RegexFilter; import com.google.devtools.build.lib.vfs.Path; @@ -102,18 +101,10 @@ import javax.annotation.Nullable; * * <pre>c1.equals(c2) <=> c1==c2.</pre> */ -@SkylarkModule( - name = "configuration", - category = SkylarkModuleCategory.BUILTIN, - doc = - "This object holds information about the environment in which the build is running. See " - + "the <a href='../rules.$DOC_EXT#configurations'>Rules page</a> for more on the general " - + "concept of configurations." -) // TODO(janakr): If overhead of fragments class names is too high, add constructor that just takes // fragments and gets names from them. @AutoCodec -public class BuildConfiguration { +public class BuildConfiguration implements BuildConfigurationApi { /** * Sorts fragments by class name. This produces a stable order which, e.g., facilitates consistent * output from buildMnemonic. @@ -1453,8 +1444,7 @@ public class BuildConfiguration { } /** Returns the bin directory for this build configuration. */ - @SkylarkCallable(name = "bin_dir", structField = true, documented = false) - @Deprecated + @Override public ArtifactRoot getBinDirectory() { return getBinDirectory(RepositoryName.MAIN); } @@ -1488,8 +1478,7 @@ public class BuildConfiguration { } /** Returns the genfiles directory for this build configuration. */ - @SkylarkCallable(name = "genfiles_dir", structField = true, documented = false) - @Deprecated + @Override public ArtifactRoot getGenfilesDirectory() { return getGenfilesDirectory(RepositoryName.MAIN); } @@ -1538,8 +1527,7 @@ public class BuildConfiguration { * not match the host platform. You should only use this when invoking tools that are known to use * the native path separator, i.e., the path separator for the machine that they run on. */ - @SkylarkCallable(name = "host_path_separator", structField = true, - doc = "Returns the separator for PATH environment variable, which is ':' on Unix.") + @Override public String getHostPathSeparator() { // TODO(bazel-team): Maybe do this in the constructor instead? This isn't serialization-safe. return OS.getCurrent() == OS.WINDOWS ? ";" : ":"; @@ -1578,13 +1566,6 @@ public class BuildConfiguration { return actionEnv; } - @SkylarkCallable( - name = "default_shell_env", - structField = true, - doc = - "A dictionary representing the static local shell environment. It maps variables " - + "to their values (strings)." - ) /** * Return the "fixed" part of the actions' environment variables. * @@ -1596,7 +1577,7 @@ public class BuildConfiguration { * <p>Since values of the "fixed" variables are already known at analysis phase, it is returned * here as a map. */ - @Deprecated // Use getActionEnvironment instead. + @Override public ImmutableMap<String, String> getLocalShellEnvironment() { return actionEnv.getFixedEnv(); } @@ -1749,14 +1730,7 @@ public class BuildConfiguration { * Returns user-specified test environment variables and their values, as set by the --test_env * options. */ - @Deprecated - @SkylarkCallable( - name = "test_env", - structField = true, - doc = - "A dictionary containing user-specified test environment variables and their values, " - + "as set by the --test_env options. DO NOT USE! This is not the complete environment!" - ) + @Override public ImmutableMap<String, String> getTestEnv() { return testEnv.getFixedEnv(); } @@ -1785,11 +1759,7 @@ public class BuildConfiguration { return options.deferParamFiles; } - @SkylarkCallable(name = "coverage_enabled", structField = true, - doc = "A boolean that tells whether code coverage is enabled for this run. Note that this " - + "does not compute whether a specific rule should be instrumented for code coverage " - + "data collection. For that, see the <a href=\"ctx.html#coverage_instrumented\"><code>" - + "ctx.coverage_instrumented</code></a> function.") + @Override public boolean isCodeCoverageEnabled() { return options.collectCodeCoverage; } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java index bd053f4fb5..d396bcc174 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/config/FragmentCollection.java @@ -18,26 +18,13 @@ import com.google.common.collect.ImmutableCollection; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; -import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; -import com.google.devtools.build.lib.syntax.ClassObject; +import com.google.devtools.build.lib.skylarkbuildapi.FragmentCollectionApi; import javax.annotation.Nullable; -/** - * Represents a collection of configuration fragments in Skylark. - */ +/** Represents a collection of configuration fragments in Skylark. */ // Documentation can be found at ctx.fragments @Immutable -@SkylarkModule(name = "fragments", - category = SkylarkModuleCategory.NONE, - doc = "Possible fields are " - + "<a href=\"apple.html\">apple</a>, <a href=\"cpp.html\">cpp</a>, " - + "<a href=\"java.html\">java</a>, <a href=\"jvm.html\">jvm</a> and " - + "<a href=\"objc.html\">objc</a>, <a href=\"android.html\">android</a>. " - + "Access a specific fragment by its field name ex:</p><code>ctx.fragments.apple</code></p>" - + "Note that rules have to declare their required fragments in order to access them " - + "(see <a href=\"../rules.md#fragments\">here</a>).") -public class FragmentCollection implements ClassObject { +public class FragmentCollection implements FragmentCollectionApi { private final RuleContext ruleContext; private final ConfigurationTransition transition; diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java index 6821129be6..ae13ebf460 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkAttributesCollection.java @@ -24,11 +24,8 @@ import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.Info; import com.google.devtools.build.lib.packages.NativeProvider; -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.SkylarkAttributesCollectionApi; import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; -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; @@ -41,12 +38,8 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -@SkylarkModule( - name = "rule_attributes", - category = SkylarkModuleCategory.NONE, - doc = "Information about attributes of a rule an aspect is applied to." -) -class SkylarkAttributesCollection implements SkylarkValue { +/** Information about attributes of a rule an aspect is applied to. */ +class SkylarkAttributesCollection implements SkylarkAttributesCollectionApi { private final SkylarkRuleContext skylarkRuleContext; private final Info attrObject; private final Info executableObject; @@ -91,35 +84,31 @@ class SkylarkAttributesCollection implements SkylarkValue { skylarkRuleContext.checkMutable("rule." + attrName); } - @SkylarkCallable(name = "attr", structField = true, doc = SkylarkRuleContext.ATTR_DOC) + @Override public Info getAttr() throws EvalException { checkMutable("attr"); return attrObject; } - @SkylarkCallable(name = "executable", structField = true, doc = SkylarkRuleContext.EXECUTABLE_DOC) + @Override public Info getExecutable() throws EvalException { checkMutable("executable"); return executableObject; } - @SkylarkCallable(name = "file", structField = true, doc = SkylarkRuleContext.FILE_DOC) + @Override public Info getFile() throws EvalException { checkMutable("file"); return fileObject; } - @SkylarkCallable(name = "files", structField = true, doc = SkylarkRuleContext.FILES_DOC) + @Override public Info getFiles() throws EvalException { checkMutable("files"); return filesObject; } - @SkylarkCallable( - name = "kind", - structField = true, - doc = "The kind of a rule, such as 'cc_library'" - ) + @Override public String getRuleClassName() throws EvalException { checkMutable("kind"); return ruleClassName; diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java index 0614e1e33e..75e4f635d3 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java @@ -13,7 +13,7 @@ // limitations under the License. package com.google.devtools.build.lib.analysis.skylark; - + import com.google.common.base.Function; import com.google.common.base.Optional; import com.google.common.base.Preconditions; @@ -43,7 +43,6 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.FragmentCollection; import com.google.devtools.build.lib.analysis.config.HostTransition; import com.google.devtools.build.lib.analysis.config.transitions.NoTransition; -import com.google.devtools.build.lib.analysis.configuredtargets.AbstractConfiguredTarget; import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.stringtemplate.ExpansionException; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesCollector; @@ -64,11 +63,9 @@ import com.google.devtools.build.lib.packages.Provider; import com.google.devtools.build.lib.packages.RawAttributeMapper; import com.google.devtools.build.lib.shell.ShellUtils; import com.google.devtools.build.lib.shell.ShellUtils.TokenizationException; -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.skylarkbuildapi.FileApi; +import com.google.devtools.build.lib.skylarkbuildapi.FileRootApi; +import com.google.devtools.build.lib.skylarkbuildapi.SkylarkRuleContextApi; import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; import com.google.devtools.build.lib.syntax.ClassObject; @@ -99,108 +96,17 @@ import java.util.Map; import java.util.Set; import javax.annotation.Nullable; -/** A Skylark API for the ruleContext. +/** + * A Skylark API for the ruleContext. * - * "This object becomes featureless once the rule implementation function that it was created for + * <p>"This object becomes featureless once the rule implementation function that it was created for * has completed. To achieve this, the {@link #nullify()} should be called once the evaluation of * the function is completed. The method both frees memory by deleting all significant fields of the * object and makes it impossible to accidentally use this object where it's not supposed to be used * (such attempts will result in {@link EvalException}s). */ -@SkylarkModule( - name = "ctx", - category = SkylarkModuleCategory.BUILTIN, - doc = - "The context of the rule containing helper functions and " - + "information about attributes, depending targets and outputs. " - + "You get a ctx object as an argument to the <code>implementation</code> function when " - + "you create a rule." -) -public final class SkylarkRuleContext implements SkylarkValue { - - private static final String DOC_NEW_FILE_TAIL = "Does not actually create a file on the file " - + "system, just declares that some action will do so. You must create an action that " - + "generates the file. If the file should be visible to other rules, declare a rule output " - + "instead when possible. Doing so enables Blaze to associate a label with the file that " - + "rules can refer to (allowing finer dependency control) instead of referencing the whole " - + "rule."; - public static final String EXECUTABLE_DOC = - "A <code>struct</code> containing executable files defined in label type " - + "attributes marked as <code>executable=True</code>. The struct fields correspond " - + "to the attribute names. Each value in the struct is either a <code>file</code> or " - + "<code>None</code>. If an optional attribute is not specified in the rule " - + "then the corresponding struct value is <code>None</code>. If a label type is not " - + "marked as <code>executable=True</code>, no corresponding struct field is generated. " - + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/actions_run/" - + "execute.bzl\">See example of use</a>."; - public static final String FILES_DOC = - "A <code>struct</code> containing files defined in label or label list " - + "type attributes. The struct fields correspond to the attribute names. The struct " - + "values are <code>list</code> of <code>file</code>s. " - + "It is a shortcut for:" - + "<pre class=language-python>[f for t in ctx.attr.<ATTR> for f in t.files]</pre> " - + "In other words, use <code>files</code> to access the " - + "<a href=\"../rules.$DOC_EXT#requesting-output-files\">default outputs</a> of a " - + "dependency. " - + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/depsets/foo.bzl\">" - + "See example of use</a>."; - public static final String FILE_DOC = - "A <code>struct</code> containing files defined in label type " - + "attributes marked as <code>allow_single_file</code>. The struct fields correspond " - + "to the attribute names. The struct value is always a <code>file</code> or " - + "<code>None</code>. If an optional attribute is not specified in the rule " - + "then the corresponding struct value is <code>None</code>. If a label type is not " - + "marked as <code>allow_single_file</code>, no corresponding struct field is generated. " - + "It is a shortcut for:" - + "<pre class=language-python>list(ctx.attr.<ATTR>.files)[0]</pre>" - + "In other words, use <code>file</code> to access the (singular) " - + "<a href=\"../rules.$DOC_EXT#requesting-output-files\">default output</a> of a " - + "dependency. " - + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/expand_template/" - + "hello.bzl\">See example of use</a>."; - public static final String ATTR_DOC = - "A struct to access the values of the attributes. The values are provided by " - + "the user (if not, a default value is used). The attributes of the struct and the " - + "types of their values correspond to the keys and values of the <code>attrs</code> " - + "dict provided to the <code>rule</code> function. " - + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/attributes/" - + "printer.bzl\">See example of use</a>."; - public static final String SPLIT_ATTR_DOC = - "A struct to access the values of attributes with split configurations. If the attribute is " - + "a label list, the value of split_attr is a dict of the keys of the split (as strings) " - + "to lists of the ConfiguredTargets in that branch of the split. If the attribute is a " - + "label, then the value of split_attr is a dict of the keys of the split (as strings) " - + "to single ConfiguredTargets. Attributes with split configurations still appear in the " - + "attr struct, but their values will be single lists with all the branches of the split " - + "merged together."; - public static final String OUTPUTS_DOC = - "A pseudo-struct containing all the predeclared output files, represented by " - + "<a href='File.html'><code>File</code></a> objects. See the " - + "<a href='../rules.$DOC_EXT#files'>Rules page</a> for more information and examples." - + "<p>This field does not exist on aspect contexts, since aspects do not have " - + "predeclared outputs." - + "<p>The fields of this object are defined as follows. It is an error if two outputs " - + "produce the same field name or have the same label." - + "<ul>" - + "<li>If the rule declares an <a href='globals.html#rule.outputs'><code>outputs</code>" - + "</a> dict, then for every entry in the dict, there is a field whose name is the key " - + "and whose value is the corresponding <code>File</code>." - + "<li>For every attribute of type <a href='attr.html#output'><code>attr.output</code>" - + "</a> that the rule declares, there is a field whose name is the attribute's name. " - + "If the target specified a label for that attribute, then the field value is the " - + "corresponding <code>File</code>; otherwise the field value is <code>None</code>." - + "<li>For every attribute of type <a href='attr.html#output_list'><code>attr.output_list" - + "</code></a> that the rule declares, there is a field whose name is the attribute's " - + "name. The field value is a list of <code>File</code> objects corresponding to the " - + "labels given for that attribute in the target, or an empty list if the attribute was " - + "not specified in the target." - + "<li><b>(Deprecated)</b> If the rule is marked <a href='globals.html#rule.executable'>" - + "<code>executable</code></a> or <a href='globals.html#rule.test'><code>test</code></a>," - + "there is a field named <code>\"executable\"</code>, which is the default executable. " - + "It is recommended that instead of using this, you pass another file (either " - + "predeclared or not) to the <code>executable</code> arg of " - + "<a href='globals.html#DefaultInfo'><code>DefaultInfo</code></a>." - + "</ul>"; +public final class SkylarkRuleContext implements SkylarkRuleContextApi { + public static final Function<Attribute, Object> ATTRIBUTE_VALUE_EXTRACTOR_FOR_ASPECT = new Function<Attribute, Object>() { @Nullable @@ -573,34 +479,17 @@ public final class SkylarkRuleContext implements SkylarkValue { return ruleContext; } - @SkylarkCallable( - name = "default_provider", - structField = true, - doc = "Deprecated. Use <a href=\"globals.html#DefaultInfo\">DefaultInfo</a> instead." - ) - public static Provider getDefaultProvider() { + @Override + public Provider getDefaultProvider() { return DefaultInfo.PROVIDER; } - @SkylarkCallable( - name = "actions", - structField = true, - doc = "Functions to declare files and create actions." - ) + @Override public SkylarkActionFactory actions() { return actionFactory; } - @SkylarkCallable(name = "created_actions", - doc = "For rules with <a href=\"globals.html#rule._skylark_testable\">_skylark_testable" - + "</a> set to <code>True</code>, this returns an " - + "<a href=\"globals.html#Actions\">Actions</a> provider representing all actions " - + "created so far for the current rule. For all other rules, returns <code>None</code>. " - + "Note that the provider is not updated when subsequent actions are created, so you " - + "will have to call this function again if you wish to inspect them. " - + "<br/><br/>" - + "This is intended to help write tests for rule-implementation helper functions, which " - + "may take in a <code>ctx</code> object and create actions on it.") + @Override public SkylarkValue createdActions() throws EvalException { checkMutable("created_actions"); if (ruleContext.getRule().getRuleClassObject().isSkylarkTestable()) { @@ -611,13 +500,13 @@ public final class SkylarkRuleContext implements SkylarkValue { } } - @SkylarkCallable(name = "attr", structField = true, doc = ATTR_DOC) + @Override public Info getAttr() throws EvalException { checkMutable("attr"); return attributesCollection.getAttr(); } - @SkylarkCallable(name = "split_attr", structField = true, doc = SPLIT_ATTR_DOC) + @Override public Info getSplitAttr() throws EvalException { checkMutable("split_attr"); if (splitAttributes == null) { @@ -628,88 +517,63 @@ public final class SkylarkRuleContext implements SkylarkValue { } /** See {@link RuleContext#getExecutablePrerequisite(String, Mode)}. */ - @SkylarkCallable(name = "executable", structField = true, doc = EXECUTABLE_DOC) + @Override public Info getExecutable() throws EvalException { checkMutable("executable"); return attributesCollection.getExecutable(); } /** See {@link RuleContext#getPrerequisiteArtifact(String, Mode)}. */ - @SkylarkCallable(name = "file", structField = true, doc = FILE_DOC) + @Override public Info getFile() throws EvalException { checkMutable("file"); return attributesCollection.getFile(); } /** See {@link RuleContext#getPrerequisiteArtifacts(String, Mode)}. */ - @SkylarkCallable(name = "files", structField = true, doc = FILES_DOC) + @Override public Info getFiles() throws EvalException { checkMutable("files"); return attributesCollection.getFiles(); } - @SkylarkCallable(name = "workspace_name", structField = true, - doc = "Returns the workspace name as defined in the WORKSPACE file.") + @Override public String getWorkspaceName() throws EvalException { checkMutable("workspace_name"); return ruleContext.getWorkspaceName(); } - @SkylarkCallable(name = "label", structField = true, doc = "The label of this rule.") + @Override public Label getLabel() throws EvalException { checkMutable("label"); return ruleContext.getLabel(); } - @SkylarkCallable(name = "fragments", structField = true, - doc = "Allows access to configuration fragments in target configuration.") + @Override public FragmentCollection getFragments() throws EvalException { checkMutable("fragments"); return fragments; } - @SkylarkCallable(name = "host_fragments", structField = true, - doc = "Allows access to configuration fragments in host configuration.") + @Override public FragmentCollection getHostFragments() throws EvalException { checkMutable("host_fragments"); return hostFragments; } - @SkylarkCallable(name = "configuration", structField = true, - doc = "Returns the default configuration. See the <a href=\"configuration.html\">" - + "configuration</a> type for more details.") + @Override public BuildConfiguration getConfiguration() throws EvalException { checkMutable("configuration"); return ruleContext.getConfiguration(); } - @SkylarkCallable(name = "host_configuration", structField = true, - doc = "Returns the host configuration. See the <a href=\"configuration.html\">" - + "configuration</a> type for more details.") + @Override public BuildConfiguration getHostConfiguration() throws EvalException { checkMutable("host_configuration"); return ruleContext.getHostConfiguration(); } - @SkylarkCallable(name = "coverage_instrumented", - doc = "Returns whether code coverage instrumentation should be generated when performing " - + "compilation actions for this rule or, if <code>target</code> is provided, the rule " - + "specified by that Target. (If a non-rule or a Skylark rule Target is provided, this " - + "returns False.) Checks if the sources of the current rule (if no Target is provided) or" - + "the sources of Target should be instrumented based on the --instrumentation_filter and" - + "--instrument_test_targets config settings. " - + "This differs from <code>coverage_enabled</code> in the <a href=\"configuration.html\">" - + "configuration</a>, which notes whether coverage data collection is enabled for the " - + "entire run, but not whether a specific target should be instrumented.", - parameters = { - @Param( - name = "target", - type = TransitiveInfoCollection.class, - defaultValue = "None", - noneable = true, - named = true, - doc = "A Target specifying a rule. If not provided, defaults to the current rule.") - }) + @Override public boolean instrumentCoverage(Object targetUnchecked) throws EvalException { checkMutable("coverage_instrumented"); BuildConfiguration config = ruleContext.getConfiguration(); @@ -724,35 +588,25 @@ public final class SkylarkRuleContext implements SkylarkValue { && InstrumentedFilesCollector.shouldIncludeLocalSources(config, target); } - @SkylarkCallable(name = "features", structField = true, - doc = "Returns the set of features that are enabled for this rule." - ) + @Override public ImmutableList<String> getFeatures() throws EvalException { checkMutable("features"); return ImmutableList.copyOf(ruleContext.getFeatures()); } - @SkylarkCallable( - name = "bin_dir", - structField = true, - doc = "The root corresponding to bin directory." - ) + @Override public ArtifactRoot getBinDirectory() throws EvalException { checkMutable("bin_dir"); return getConfiguration().getBinDirectory(ruleContext.getRule().getRepository()); } - @SkylarkCallable( - name = "genfiles_dir", - structField = true, - doc = "The root corresponding to genfiles directory." - ) + @Override public ArtifactRoot getGenfilesDirectory() throws EvalException { checkMutable("genfiles_dir"); return getConfiguration().getGenfilesDirectory(ruleContext.getRule().getRepository()); } - @SkylarkCallable(structField = true, doc = OUTPUTS_DOC) + @Override public ClassObject outputs() throws EvalException { checkMutable("outputs"); if (outputsObject == null) { @@ -761,12 +615,7 @@ public final class SkylarkRuleContext implements SkylarkValue { return outputsObject; } - @SkylarkCallable( - structField = true, - doc = - "Returns rule attributes descriptor for the rule that aspect is applied to." - + " Only available in aspect implementation functions." - ) + @Override public SkylarkAttributesCollection rule() throws EvalException { checkMutable("rule"); if (!isForAspect) { @@ -776,10 +625,7 @@ public final class SkylarkRuleContext implements SkylarkValue { return ruleAttributesCollection; } - @SkylarkCallable(structField = true, - name = "aspect_ids", - doc = "Returns a list ids for all aspects applied to the target." - + " Only available in aspect implementation functions.") + @Override public ImmutableList<String> aspectIds() throws EvalException { checkMutable("aspect_ids"); if (!isForAspect) { @@ -794,16 +640,13 @@ public final class SkylarkRuleContext implements SkylarkValue { return result.build(); } - @SkylarkCallable( - structField = true, - doc = "Dictionary (String to String) of configuration variables." - ) + @Override public SkylarkDict<String, String> var() throws EvalException { checkMutable("var"); return makeVariables; } - @SkylarkCallable(structField = true, doc = "Toolchains required for this rule.") + @Override public SkylarkIndexable toolchains() throws EvalException { checkMutable("toolchains"); return ruleContext.getToolchainContext().getResolvedToolchainProviders(); @@ -814,7 +657,7 @@ public final class SkylarkRuleContext implements SkylarkValue { return ruleLabelCanonicalName; } - @SkylarkCallable(doc = "Splits a shell command to a list of tokens.", documented = false) + @Override public SkylarkList<String> tokenize(String optionString) throws FuncallException, EvalException { checkMutable("tokenize"); List<String> options = new ArrayList<>(); @@ -826,13 +669,7 @@ public final class SkylarkRuleContext implements SkylarkValue { return SkylarkList.createImmutable(options); } - @SkylarkCallable( - doc = - "Expands all references to labels embedded within a string for all files using a mapping " - + "from definition labels (i.e. the label in the output type attribute) to files. " - + "Deprecated.", - documented = false - ) + @Override public String expand( @Nullable String expression, SkylarkList<Object> artifacts, Label labelResolver) throws EvalException, FuncallException { @@ -852,20 +689,7 @@ public final class SkylarkRuleContext implements SkylarkValue { return isForAspect; } - @SkylarkCallable( - name = "new_file", - doc = - "DEPRECATED. Use <a href=\"actions.html#declare_file\">ctx.actions.declare_file</a>. <br>" - + "Creates a file object with the given filename, in the current package. " - + DOC_NEW_FILE_TAIL, - parameters = { - @Param( - name = "filename", - type = String.class, - doc = "The path of the new file, relative to the current package." - ) - } - ) + @Override public Artifact newFile(String filename) throws EvalException { checkDeprecated("ctx.actions.declare_file", "ctx.new_file", null, skylarkSemantics); checkMutable("new_file"); @@ -873,60 +697,30 @@ public final class SkylarkRuleContext implements SkylarkValue { } // Kept for compatibility with old code. - @SkylarkCallable(documented = false) - public Artifact newFile(ArtifactRoot root, String filename) throws EvalException { + @Override + public Artifact newFile(FileRootApi root, String filename) throws EvalException { checkMutable("new_file"); - return ruleContext.getPackageRelativeArtifact(filename, root); + return ruleContext.getPackageRelativeArtifact(filename, (ArtifactRoot) root); } - @SkylarkCallable( - name = "new_file", - doc = - "Creates a new file object in the same directory as the original file. " - + DOC_NEW_FILE_TAIL, - parameters = { - @Param( - name = "sibling_file", - type = Artifact.class, - doc = "A file that lives in the same directory as the newly created file." - ), - @Param( - name = "basename", - type = String.class, - doc = "The base name of the newly created file." - ) - } - ) - public Artifact newFile(Artifact baseArtifact, String newBaseName) throws EvalException { + @Override + public Artifact newFile(FileApi baseArtifact, String newBaseName) throws EvalException { checkDeprecated("ctx.actions.declare_file", "ctx.new_file", null, skylarkSemantics); checkMutable("new_file"); return actionFactory.declareFile(newBaseName, baseArtifact); } // Kept for compatibility with old code. - @SkylarkCallable(documented = false) - public Artifact newFile(ArtifactRoot root, Artifact baseArtifact, String suffix) + @Override + public Artifact newFile(FileRootApi root, FileApi baseArtifact, String suffix) throws EvalException { checkMutable("new_file"); - PathFragment original = baseArtifact.getRootRelativePath(); + PathFragment original = ((Artifact) baseArtifact).getRootRelativePath(); PathFragment fragment = original.replaceName(original.getBaseName() + suffix); - return ruleContext.getDerivedArtifact(fragment, root); + return ruleContext.getDerivedArtifact(fragment, (ArtifactRoot) root); } - @SkylarkCallable( - name = "experimental_new_directory", - documented = false, - parameters = { - @Param(name = "name", type = String.class), - @Param( - name = "sibling", - type = Artifact.class, - defaultValue = "None", - noneable = true, - named = true - ) - } - ) + @Override public Artifact newDirectory(String name, Object siblingArtifactUnchecked) throws EvalException { checkDeprecated( "ctx.actions.declare_directory", "ctx.experimental_new_directory", null, skylarkSemantics); @@ -934,7 +728,7 @@ public final class SkylarkRuleContext implements SkylarkValue { return actionFactory.declareDirectory(name, siblingArtifactUnchecked); } - @SkylarkCallable(documented = false) + @Override public boolean checkPlaceholders(String template, SkylarkList<Object> allowedPlaceholders) throws EvalException { checkMutable("check_placeholders"); @@ -950,26 +744,10 @@ public final class SkylarkRuleContext implements SkylarkValue { return true; } - @SkylarkCallable(doc = - "<b>Deprecated.</b> Use <code>ctx.var</code> to access the variables instead.<br>" - + "Returns a string after expanding all references to \"Make variables\". The variables " - + "must have the following format: <code>$(VAR_NAME)</code>. Also, <code>$$VAR_NAME" - + "</code> expands to <code>$VAR_NAME</code>. Parameters:" - + "<ul><li>The name of the attribute (<code>string</code>). It's only used for error " - + "reporting.</li>\n" - + "<li>The expression to expand (<code>string</code>). It can contain references to " - + "\"Make variables\".</li>\n" - + "<li>A mapping of additional substitutions (<code>dict</code> of <code>string</code> : " - + "<code>string</code>).</li></ul>\n" - + "Examples:" - + "<pre class=language-python>\n" - + "ctx.expand_make_variables(\"cmd\", \"$(MY_VAR)\", {\"MY_VAR\": \"Hi\"}) # == \"Hi\"\n" - + "ctx.expand_make_variables(\"cmd\", \"$$PWD\", {}) # == \"$PWD\"\n" - + "</pre>" - + "Additional variables may come from other places, such as configurations. Note that " - + "this function is experimental.") - public String expandMakeVariables(String attributeName, String command, - final Map<String, String> additionalSubstitutions) throws EvalException { + @Override + public String expandMakeVariables( + String attributeName, String command, final Map<String, String> additionalSubstitutions) + throws EvalException { checkMutable("expand_make_variables"); ConfigurationMakeVariableContext makeVariableContext = new ConfigurationMakeVariableContext( @@ -995,38 +773,19 @@ public final class SkylarkRuleContext implements SkylarkValue { return attributesCollection.getExecutableRunfilesMap().get(executable); } - @SkylarkCallable( - name = "info_file", - structField = true, - documented = false, - doc = - "Returns the file that is used to hold the non-volatile workspace status for the " - + "current build request." - ) + @Override public Artifact getStableWorkspaceStatus() throws InterruptedException, EvalException { checkMutable("info_file"); return ruleContext.getAnalysisEnvironment().getStableWorkspaceStatusArtifact(); } - @SkylarkCallable( - name = "version_file", - structField = true, - documented = false, - doc = - "Returns the file that is used to hold the volatile workspace status for the " - + "current build request." - ) + @Override public Artifact getVolatileWorkspaceStatus() throws InterruptedException, EvalException { checkMutable("version_file"); return ruleContext.getAnalysisEnvironment().getVolatileWorkspaceStatusArtifact(); } - @SkylarkCallable( - name = "build_file_path", - structField = true, - documented = true, - doc = "Returns path to the BUILD file for this rule, relative to the source root." - ) + @Override public String getBuildFileRelativePath() throws EvalException { checkMutable("build_file_path"); Package pkg = ruleContext.getRule().getPackage(); @@ -1039,161 +798,7 @@ public final class SkylarkRuleContext implements SkylarkValue { * executable = executable, arguments = [argument1, argument2, ...], mnemonic = 'Mnemonic', * command = 'command', ) */ - @SkylarkCallable( - name = "action", - doc = - "DEPRECATED. Use <a href=\"actions.html#run\">ctx.actions.run()</a> or" - + " <a href=\"actions.html#run_shell\">ctx.actions.run_shell()</a>. <br>" - + "Creates an action that runs an executable or a shell command." - + " You must specify either <code>command</code> or <code>executable</code>.\n" - + "Actions and genrules are very similar, but have different use cases. Actions are " - + "used inside rules, and genrules are used inside macros. Genrules also have make " - + "variable expansion.", - 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 of the input files of the action." - ), - @Param( - name = "executable", - type = Object.class, - allowedTypes = { - @ParamType(type = Artifact.class), - @ParamType(type = String.class), - @ParamType(type = Runtime.NoneType.class), - }, - noneable = true, - defaultValue = "None", - 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 of the 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." - ), - @Param( - name = "mnemonic", - type = String.class, - noneable = true, - defaultValue = "None", - named = true, - positional = false, - doc = "A one-word description of the action, e.g. CppCompile or GoLink." - ), - @Param( - name = "command", - type = Object.class, - allowedTypes = { - @ParamType(type = String.class), - @ParamType(type = SkylarkList.class, generic1 = String.class), - @ParamType(type = Runtime.NoneType.class), - }, - noneable = true, - defaultValue = "None", - named = true, - positional = false, - doc = - "Shell command to execute. It is usually preferable to " - + "use <code>executable</code> instead. " - + "Arguments are available with <code>$1</code>, <code>$2</code>, etc." - ), - @Param( - name = "progress_message", - type = String.class, - noneable = true, - defaultValue = "None", - named = true, - positional = false, - doc = - "Progress message to show to the user during the build, " - + "e.g. \"Compiling foo.cc to create foo.o\"." - ), - @Param( - name = "use_default_shell_env", - type = Boolean.class, - defaultValue = "False", - named = true, - positional = false, - doc = "Whether the action should use the built in shell environment or not." - ), - @Param( - name = "env", - type = SkylarkDict.class, - noneable = true, - defaultValue = "None", - named = true, - positional = false, - doc = "Sets the dictionary of environment variables." - ), - @Param( - name = "execution_requirements", - type = SkylarkDict.class, - noneable = true, - defaultValue = "None", - named = true, - positional = false, - doc = - "Information for scheduling the action. See " - + "<a href=\"$BE_ROOT/common-definitions.html#common.tags\">tags</a> " - + "for useful keys." - ), - @Param( - // TODO(bazel-team): The name here isn't accurate anymore. This is technically experimental, - // so folks shouldn't be too attached, but consider renaming to be more accurate/opaque. - name = "input_manifests", - type = SkylarkList.class, - noneable = true, - defaultValue = "None", - named = true, - positional = false, - doc = - "(Experimental) sets the input runfiles metadata; " - + "they are typically generated by resolve_command." - ) - }, - allowReturnNones = true, - useLocation = true, - useEnvironment = true - ) + @Override public Runtime.NoneType action( SkylarkList outputs, Object inputs, @@ -1252,33 +857,7 @@ public final class SkylarkRuleContext implements SkylarkValue { return Runtime.NONE; } - @SkylarkCallable( - name = "expand_location", - doc = - "Expands all <code>$(location ...)</code> templates in the given string by replacing " - + "<code>$(location //x)</code> with the path of the output file of target //x. " - + "Expansion only works for labels that point to direct dependencies of this rule or " - + "that are explicitly listed in the optional argument <code>targets</code>. " - + "<br/><br/>" - + "<code>$(location ...)</code> will cause an error if the referenced target has " - + "multiple outputs. In this case, please use <code>$(locations ...)</code> since it " - + "produces a space-separated list of output paths. It can be safely used for a " - + "single output file, too.", - parameters = { - @Param(name = "input", type = String.class, doc = "String to be expanded."), - @Param( - name = "targets", - type = SkylarkList.class, - generic1 = AbstractConfiguredTarget.class, - defaultValue = "[]", - named = true, - doc = "List of targets for additional lookup information." - ), - }, - allowReturnNones = true, - useLocation = true, - useEnvironment = true - ) + @Override public String expandLocation(String input, SkylarkList targets, Location loc, Environment env) throws EvalException { checkMutable("expand_location"); @@ -1292,33 +871,9 @@ public final class SkylarkRuleContext implements SkylarkValue { } } - @SkylarkCallable( - name = "file_action", - doc = - "DEPRECATED. Use <a href =\"actions.html#write\">ctx.actions.write</a> instead. <br>" - + "Creates a file write action.", - parameters = { - @Param(name = "output", type = Artifact.class, named = true, doc = "The output file."), - @Param( - name = "content", - type = String.class, - named = true, - doc = "The contents of the file." - ), - @Param( - name = "executable", - type = Boolean.class, - defaultValue = "False", - named = true, - doc = "Whether the output file should be executable (default is False)." - ) - }, - allowReturnNones = true, - useLocation = true, - useEnvironment = true - ) + @Override public Runtime.NoneType fileAction( - Artifact output, String content, Boolean executable, Location loc, Environment env) + FileApi output, String content, Boolean executable, Location loc, Environment env) throws EvalException { checkDeprecated("ctx.actions.write", "ctx.file_action", loc, env.getSemantics()); checkMutable("file_action"); @@ -1326,38 +881,7 @@ public final class SkylarkRuleContext implements SkylarkValue { return Runtime.NONE; } - @SkylarkCallable( - name = "empty_action", - doc = - "DEPRECATED. Use <a href=\"actions.html#do_nothing\">ctx.actions.do_nothing</a> instead." - + " <br>" - + "Creates an empty action that neither executes a command nor produces any " - + "output, but that is useful for inserting 'extra actions'.", - parameters = { - @Param( - name = "mnemonic", - type = String.class, - named = true, - positional = false, - doc = "A one-word description of the action, e.g. CppCompile or GoLink." - ), - @Param( - name = "inputs", - allowedTypes = { - @ParamType(type = SkylarkList.class), - @ParamType(type = SkylarkNestedSet.class), - }, - generic1 = Artifact.class, - named = true, - positional = false, - defaultValue = "[]", - doc = "List of the input files of the action." - ), - }, - allowReturnNones = true, - useLocation = true, - useEnvironment = true - ) + @Override public Runtime.NoneType emptyAction(String mnemonic, Object inputs, Location loc, Environment env) throws EvalException { checkDeprecated("ctx.actions.do_nothing", "ctx.empty_action", loc, env.getSemantics()); @@ -1366,50 +890,10 @@ public final class SkylarkRuleContext implements SkylarkValue { return Runtime.NONE; } - @SkylarkCallable( - name = "template_action", - doc = - "DEPRECATED. " - + "Use <a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a> " - + "instead. <br>Creates a template expansion action.", - 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 = "executable", - type = Boolean.class, - defaultValue = "False", - named = true, - positional = false, - doc = "Whether the output file should be executable (default is False)." - ) - }, - allowReturnNones = true, - useLocation = true, - useEnvironment = true - ) + @Override public Runtime.NoneType templateAction( - Artifact template, - Artifact output, + FileApi template, + FileApi output, SkylarkDict<?, ?> substitutionsUnchecked, Boolean executable, Location loc, @@ -1421,67 +905,7 @@ public final class SkylarkRuleContext implements SkylarkValue { return Runtime.NONE; } - @SkylarkCallable( - name = "runfiles", - doc = "Creates a runfiles object.", - parameters = { - @Param( - name = "files", - type = SkylarkList.class, - generic1 = Artifact.class, - named = true, - defaultValue = "[]", - doc = "The list of files to be added to the runfiles." - ), - // TODO(bazel-team): If we have a memory efficient support for lazy list containing - // NestedSets we can remove this and just use files = [file] + list(set) - // Also, allow empty set for init - @Param( - name = "transitive_files", - type = SkylarkNestedSet.class, - generic1 = Artifact.class, - noneable = true, - defaultValue = "None", - named = true, - doc = - "The (transitive) set of files to be added to the runfiles. The depset should " - + "use the `default` order (which, as the name implies, is the default)." - ), - @Param( - name = "collect_data", - type = Boolean.class, - defaultValue = "False", - named = true, - doc = - "Whether to collect the data " - + "runfiles from the dependencies in srcs, data and deps attributes." - ), - @Param( - name = "collect_default", - type = Boolean.class, - defaultValue = "False", - named = true, - doc = - "Whether to collect the default " - + "runfiles from the dependencies in srcs, data and deps attributes." - ), - @Param( - name = "symlinks", - type = SkylarkDict.class, - defaultValue = "{}", - named = true, - doc = "The map of symlinks to be added to the runfiles, prefixed by workspace name." - ), - @Param( - name = "root_symlinks", - type = SkylarkDict.class, - defaultValue = "{}", - named = true, - doc = "The map of symlinks to be added to the runfiles." - ) - }, - useLocation = true - ) + @Override public Runfiles runfiles( SkylarkList files, Object transitiveFiles, @@ -1530,87 +954,7 @@ public final class SkylarkRuleContext implements SkylarkValue { return runfiles; } - @SkylarkCallable( - name = "resolve_command", - // TODO(bazel-team): The naming here isn't entirely accurate (input_manifests is no longer - // manifests), but this is experimental/should be opaque to the end user. - doc = - "<i>(Experimental)</i> " - + "Returns a tuple <code>(inputs, command, input_manifests)</code> of the list of " - + "resolved inputs, the argv list for the resolved command, and the runfiles metadata" - + "required to run the command, all of them suitable for passing as the same-named " - + "arguments of the <code>ctx.action</code> method.", - parameters = { - @Param( - name = "command", - type = String.class, // string - defaultValue = "''", - named = true, - positional = false, - doc = "Command to resolve." - ), - @Param( - name = "attribute", - type = String.class, // string - defaultValue = "None", - noneable = true, - named = true, - positional = false, - doc = "Name of the associated attribute for which to issue an error, or None." - ), - @Param( - name = "expand_locations", - type = Boolean.class, - defaultValue = "False", - named = true, - positional = false, - doc = - "Shall we expand $(location) variables? " - + "See <a href=\"#expand_location\">ctx.expand_location()</a> for more details." - ), - @Param( - name = "make_variables", - type = SkylarkDict.class, // dict(string, string) - noneable = true, - defaultValue = "None", - named = true, - positional = false, - doc = "Make variables to expand, or None." - ), - @Param( - name = "tools", - defaultValue = "[]", - type = SkylarkList.class, - generic1 = TransitiveInfoCollection.class, - named = true, - positional = false, - doc = "List of tools (list of targets)." - ), - @Param( - name = "label_dict", - type = SkylarkDict.class, - defaultValue = "{}", - named = true, - positional = false, - doc = - "Dictionary of resolved labels and the corresponding list of Files " - + "(a dict of Label : list of Files)." - ), - @Param( - name = "execution_requirements", - type = SkylarkDict.class, - defaultValue = "{}", - named = true, - positional = false, - doc = - "Information for scheduling the action to resolve this command. See " - + "<a href=\"$BE_ROOT/common-definitions.html#common.tags\">tags</a> " - + "for useful keys." - ), - }, - useLocation = true, - useEnvironment = true - ) + @Override public Tuple<Object> resolveCommand( String command, Object attributeUnchecked, diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/BuildConfigurationApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/BuildConfigurationApi.java new file mode 100644 index 0000000000..ad73c80e88 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/BuildConfigurationApi.java @@ -0,0 +1,69 @@ +// 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.common.collect.ImmutableMap; +import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; + +/** Interface for a configuration object which holds information about the build environment. */ +@SkylarkModule( + name = "configuration", + category = SkylarkModuleCategory.BUILTIN, + doc = "This object holds information about the environment in which the build is running. See " + + "the <a href='../rules.$DOC_EXT#configurations'>Rules page</a> for more on the general " + + "concept of configurations." +) +public interface BuildConfigurationApi { + + @SkylarkCallable(name = "bin_dir", structField = true, documented = false) + @Deprecated + public FileRootApi getBinDirectory(); + + @SkylarkCallable(name = "genfiles_dir", structField = true, documented = false) + @Deprecated + public FileRootApi getGenfilesDirectory(); + + @SkylarkCallable(name = "host_path_separator", structField = true, + doc = "Returns the separator for PATH environment variable, which is ':' on Unix.") + public String getHostPathSeparator(); + + @SkylarkCallable( + name = "default_shell_env", + structField = true, + doc = + "A dictionary representing the static local shell environment. It maps variables " + + "to their values (strings)." + ) + @Deprecated // Use getActionEnvironment instead. + public ImmutableMap<String, String> getLocalShellEnvironment(); + + @SkylarkCallable( + name = "test_env", + structField = true, + doc = + "A dictionary containing user-specified test environment variables and their values, " + + "as set by the --test_env options. DO NOT USE! This is not the complete environment!" + ) + public ImmutableMap<String, String> getTestEnv(); + + @SkylarkCallable(name = "coverage_enabled", structField = true, + doc = "A boolean that tells whether code coverage is enabled for this run. Note that this " + + "does not compute whether a specific rule should be instrumented for code coverage " + + "data collection. For that, see the <a href=\"ctx.html#coverage_instrumented\"><code>" + + "ctx.coverage_instrumented</code></a> function.") + public boolean isCodeCoverageEnabled(); +} diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/FragmentCollectionApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/FragmentCollectionApi.java new file mode 100644 index 0000000000..5ddc5da973 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/FragmentCollectionApi.java @@ -0,0 +1,34 @@ +// 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.SkylarkModule; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; +import com.google.devtools.build.lib.syntax.ClassObject; + +/** Represents a collection of configuration fragments in Skylark. */ +@SkylarkModule( + name = "fragments", + category = SkylarkModuleCategory.NONE, + doc = + "Possible fields are " + + "<a href=\"android.html\">android</a>, <a href=\"apple.html\">apple</a>, " + + "<a href=\"cpp.html\">cpp</a>, <a href=\"java.html\">java</a>, " + + "<a href=\"jvm.html\">jvm</a>, and <a href=\"objc.html\">objc</a>. " + + "Access a specific fragment by its field name " + + "ex:</p><code>ctx.fragments.apple</code></p>" + + "Note that rules have to declare their required fragments in order to access them " + + "(see <a href=\"../rules.md#fragments\">here</a>).") +public interface FragmentCollectionApi extends ClassObject {} diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttributesCollectionApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttributesCollectionApi.java new file mode 100644 index 0000000000..7092b70338 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttributesCollectionApi.java @@ -0,0 +1,54 @@ +// 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; + +/** + * Interface for a type containing information about the attributes of a rule. + */ +@SkylarkModule( + name = "rule_attributes", + category = SkylarkModuleCategory.NONE, + doc = "Information about attributes of a rule an aspect is applied to." +) +public interface SkylarkAttributesCollectionApi extends SkylarkValue { + + @SkylarkCallable(name = "attr", structField = true, doc = SkylarkRuleContextApi.ATTR_DOC) + public StructApi getAttr() throws EvalException; + + @SkylarkCallable( + name = "executable", + structField = true, + doc = SkylarkRuleContextApi.EXECUTABLE_DOC) + public StructApi getExecutable() throws EvalException; + + @SkylarkCallable(name = "file", structField = true, doc = SkylarkRuleContextApi.FILE_DOC) + public StructApi getFile() throws EvalException; + + @SkylarkCallable(name = "files", structField = true, doc = SkylarkRuleContextApi.FILES_DOC) + public StructApi getFiles() throws EvalException; + + @SkylarkCallable( + name = "kind", + structField = true, + doc = "The kind of a rule, such as 'cc_library'" + ) + public String getRuleClassName() throws EvalException; +} diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java new file mode 100644 index 0000000000..64b50ebdb5 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java @@ -0,0 +1,896 @@ +// 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.common.collect.ImmutableList; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.events.Location; +import com.google.devtools.build.lib.skylarkinterface.Param; +import com.google.devtools.build.lib.skylarkinterface.ParamType; +import com.google.devtools.build.lib.skylarkinterface.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.ClassObject; +import com.google.devtools.build.lib.syntax.Environment; +import com.google.devtools.build.lib.syntax.EvalException; +import com.google.devtools.build.lib.syntax.FuncallExpression.FuncallException; +import com.google.devtools.build.lib.syntax.Runtime; +import com.google.devtools.build.lib.syntax.SkylarkDict; +import com.google.devtools.build.lib.syntax.SkylarkIndexable; +import com.google.devtools.build.lib.syntax.SkylarkList; +import com.google.devtools.build.lib.syntax.SkylarkList.Tuple; +import com.google.devtools.build.lib.syntax.SkylarkNestedSet; +import java.util.Map; +import javax.annotation.Nullable; + +/** Interface for a context object given to rule implementation functions. */ +@SkylarkModule( + name = "ctx", + category = SkylarkModuleCategory.BUILTIN, + doc = "The context of the rule containing helper functions and " + + "information about attributes, depending targets and outputs. " + + "You get a ctx object as an argument to the <code>implementation</code> function when " + + "you create a rule.") +public interface SkylarkRuleContextApi extends SkylarkValue { + + public static final String DOC_NEW_FILE_TAIL = "Does not actually create a file on the file " + + "system, just declares that some action will do so. You must create an action that " + + "generates the file. If the file should be visible to other rules, declare a rule output " + + "instead when possible. Doing so enables Blaze to associate a label with the file that " + + "rules can refer to (allowing finer dependency control) instead of referencing the whole " + + "rule."; + public static final String EXECUTABLE_DOC = + "A <code>struct</code> containing executable files defined in label type " + + "attributes marked as <code>executable=True</code>. The struct fields correspond " + + "to the attribute names. Each value in the struct is either a <code>file</code> or " + + "<code>None</code>. If an optional attribute is not specified in the rule " + + "then the corresponding struct value is <code>None</code>. If a label type is not " + + "marked as <code>executable=True</code>, no corresponding struct field is generated. " + + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/actions_run/" + + "execute.bzl\">See example of use</a>."; + public static final String FILES_DOC = + "A <code>struct</code> containing files defined in label or label list " + + "type attributes. The struct fields correspond to the attribute names. The struct " + + "values are <code>list</code> of <code>file</code>s. " + + "It is a shortcut for:" + + "<pre class=language-python>[f for t in ctx.attr.<ATTR> for f in t.files]</pre> " + + "In other words, use <code>files</code> to access the " + + "<a href=\"../rules.$DOC_EXT#requesting-output-files\">default outputs</a> of a " + + "dependency. " + + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/depsets/foo.bzl\">" + + "See example of use</a>."; + public static final String FILE_DOC = + "A <code>struct</code> containing files defined in label type " + + "attributes marked as <code>allow_single_file</code>. The struct fields correspond " + + "to the attribute names. The struct value is always a <code>file</code> or " + + "<code>None</code>. If an optional attribute is not specified in the rule " + + "then the corresponding struct value is <code>None</code>. If a label type is not " + + "marked as <code>allow_single_file</code>, no corresponding struct field is generated. " + + "It is a shortcut for:" + + "<pre class=language-python>list(ctx.attr.<ATTR>.files)[0]</pre>" + + "In other words, use <code>file</code> to access the (singular) " + + "<a href=\"../rules.$DOC_EXT#requesting-output-files\">default output</a> of a " + + "dependency. " + + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/expand_template/" + + "hello.bzl\">See example of use</a>."; + public static final String ATTR_DOC = + "A struct to access the values of the attributes. The values are provided by " + + "the user (if not, a default value is used). The attributes of the struct and the " + + "types of their values correspond to the keys and values of the <code>attrs</code> " + + "dict provided to the <code>rule</code> function. " + + "<a href=\"https://github.com/bazelbuild/examples/blob/master/rules/attributes/" + + "printer.bzl\">See example of use</a>."; + public static final String SPLIT_ATTR_DOC = + "A struct to access the values of attributes with split configurations. If the attribute is " + + "a label list, the value of split_attr is a dict of the keys of the split (as strings) " + + "to lists of the ConfiguredTargets in that branch of the split. If the attribute is a " + + "label, then the value of split_attr is a dict of the keys of the split (as strings) " + + "to single ConfiguredTargets. Attributes with split configurations still appear in the " + + "attr struct, but their values will be single lists with all the branches of the split " + + "merged together."; + public static final String OUTPUTS_DOC = + "A pseudo-struct containing all the predeclared output files, represented by " + + "<a href='File.html'><code>File</code></a> objects. See the " + + "<a href='../rules.$DOC_EXT#files'>Rules page</a> for more information and examples." + + "<p>This field does not exist on aspect contexts, since aspects do not have " + + "predeclared outputs." + + "<p>The fields of this object are defined as follows. It is an error if two outputs " + + "produce the same field name or have the same label." + + "<ul>" + + "<li>If the rule declares an <a href='globals.html#rule.outputs'><code>outputs</code>" + + "</a> dict, then for every entry in the dict, there is a field whose name is the key " + + "and whose value is the corresponding <code>File</code>." + + "<li>For every attribute of type <a href='attr.html#output'><code>attr.output</code>" + + "</a> that the rule declares, there is a field whose name is the attribute's name. " + + "If the target specified a label for that attribute, then the field value is the " + + "corresponding <code>File</code>; otherwise the field value is <code>None</code>." + + "<li>For every attribute of type <a href='attr.html#output_list'><code>attr.output_list" + + "</code></a> that the rule declares, there is a field whose name is the attribute's " + + "name. The field value is a list of <code>File</code> objects corresponding to the " + + "labels given for that attribute in the target, or an empty list if the attribute was " + + "not specified in the target." + + "<li><b>(Deprecated)</b> If the rule is marked <a href='globals.html#rule.executable'>" + + "<code>executable</code></a> or <a href='globals.html#rule.test'><code>test</code></a>," + + "there is a field named <code>\"executable\"</code>, which is the default executable. " + + "It is recommended that instead of using this, you pass another file (either " + + "predeclared or not) to the <code>executable</code> arg of " + + "<a href='globals.html#DefaultInfo'><code>DefaultInfo</code></a>." + + "</ul>"; + + @SkylarkCallable( + name = "default_provider", + structField = true, + doc = "Deprecated. Use <a href=\"globals.html#DefaultInfo\">DefaultInfo</a> instead." + ) + public ProviderApi getDefaultProvider(); + + @SkylarkCallable( + name = "actions", + structField = true, + doc = "Functions to declare files and create actions." + ) + public SkylarkActionFactoryApi actions(); + + @SkylarkCallable( + name = "created_actions", + doc = "For rules with <a href=\"globals.html#rule._skylark_testable\">_skylark_testable" + + "</a> set to <code>True</code>, this returns an " + + "<a href=\"globals.html#Actions\">Actions</a> provider representing all actions " + + "created so far for the current rule. For all other rules, returns <code>None</code>. " + + "Note that the provider is not updated when subsequent actions are created, so you " + + "will have to call this function again if you wish to inspect them. " + + "<br/><br/>" + + "This is intended to help write tests for rule-implementation helper functions, which " + + "may take in a <code>ctx</code> object and create actions on it.") + public SkylarkValue createdActions() throws EvalException; + + @SkylarkCallable(name = "attr", structField = true, doc = ATTR_DOC) + public StructApi getAttr() throws EvalException; + + @SkylarkCallable(name = "split_attr", structField = true, doc = SPLIT_ATTR_DOC) + public StructApi getSplitAttr() throws EvalException; + + @SkylarkCallable(name = "executable", structField = true, doc = EXECUTABLE_DOC) + public StructApi getExecutable() throws EvalException; + + @SkylarkCallable(name = "file", structField = true, doc = FILE_DOC) + public StructApi getFile() throws EvalException; + + @SkylarkCallable(name = "files", structField = true, doc = FILES_DOC) + public StructApi getFiles() throws EvalException; + + @SkylarkCallable( + name = "workspace_name", + structField = true, + doc = "Returns the workspace name as defined in the WORKSPACE file." + ) + public String getWorkspaceName() throws EvalException; + + @SkylarkCallable(name = "label", structField = true, doc = "The label of this rule.") + public Label getLabel() throws EvalException; + + @SkylarkCallable( + name = "fragments", + structField = true, + doc = "Allows access to configuration fragments in target configuration." + ) + public FragmentCollectionApi getFragments() throws EvalException; + + @SkylarkCallable( + name = "host_fragments", + structField = true, + doc = "Allows access to configuration fragments in host configuration." + ) + public FragmentCollectionApi getHostFragments() throws EvalException; + + @SkylarkCallable( + name = "configuration", + structField = true, + doc = + "Returns the default configuration. See the <a href=\"configuration.html\">" + + "configuration</a> type for more details." + ) + public BuildConfigurationApi getConfiguration() throws EvalException; + + @SkylarkCallable( + name = "host_configuration", + structField = true, + doc = + "Returns the host configuration. See the <a href=\"configuration.html\">" + + "configuration</a> type for more details." + ) + public BuildConfigurationApi getHostConfiguration() throws EvalException; + + @SkylarkCallable( + name = "coverage_instrumented", + doc = "Returns whether code coverage instrumentation should be generated when performing " + + "compilation actions for this rule or, if <code>target</code> is provided, the rule " + + "specified by that Target. (If a non-rule or a Skylark rule Target is provided, this " + + "returns False.) Checks if the sources of the current rule (if no Target is provided) or" + + "the sources of Target should be instrumented based on the --instrumentation_filter and" + + "--instrument_test_targets config settings. " + + "This differs from <code>coverage_enabled</code> in the <a href=\"configuration.html\">" + + "configuration</a>, which notes whether coverage data collection is enabled for the " + + "entire run, but not whether a specific target should be instrumented.", + parameters = { + @Param( + name = "target", + type = TransitiveInfoCollectionApi.class, + defaultValue = "None", + noneable = true, + named = true, + doc = "A Target specifying a rule. If not provided, defaults to the current rule.") + } + ) + public boolean instrumentCoverage(Object targetUnchecked) throws EvalException; + + @SkylarkCallable( + name = "features", + structField = true, + doc = "Returns the set of features that are enabled for this rule." + ) + public ImmutableList<String> getFeatures() throws EvalException; + + @SkylarkCallable( + name = "bin_dir", + structField = true, + doc = "The root corresponding to bin directory." + ) + public FileRootApi getBinDirectory() throws EvalException; + + @SkylarkCallable( + name = "genfiles_dir", + structField = true, + doc = "The root corresponding to genfiles directory." + ) + public FileRootApi getGenfilesDirectory() throws EvalException; + + @SkylarkCallable(structField = true, doc = OUTPUTS_DOC) + public ClassObject outputs() throws EvalException; + + @SkylarkCallable( + structField = true, + doc = + "Returns rule attributes descriptor for the rule that aspect is applied to." + + " Only available in aspect implementation functions." + ) + public SkylarkAttributesCollectionApi rule() throws EvalException; + + @SkylarkCallable( + structField = true, + name = "aspect_ids", + doc = + "Returns a list ids for all aspects applied to the target." + + " Only available in aspect implementation functions." + ) + public ImmutableList<String> aspectIds() throws EvalException; + + @SkylarkCallable( + structField = true, + doc = "Dictionary (String to String) of configuration variables." + ) + public SkylarkDict<String, String> var() throws EvalException; + + @SkylarkCallable(structField = true, doc = "Toolchains required for this rule.") + public SkylarkIndexable toolchains() throws EvalException; + + @SkylarkCallable(doc = "Splits a shell command to a list of tokens.", documented = false) + public SkylarkList<String> tokenize(String optionString) throws FuncallException, EvalException; + + @SkylarkCallable( + doc = + "Expands all references to labels embedded within a string for all files using a mapping " + + "from definition labels (i.e. the label in the output type attribute) to files. " + + "Deprecated.", + documented = false + ) + public String expand( + @Nullable String expression, SkylarkList<Object> artifacts, Label labelResolver) + throws EvalException, FuncallException; + + @SkylarkCallable( + name = "new_file", + doc = + "DEPRECATED. Use <a href=\"actions.html#declare_file\">ctx.actions.declare_file</a>. <br>" + + "Creates a file object with the given filename, in the current package. " + + DOC_NEW_FILE_TAIL, + parameters = { + @Param( + name = "filename", + type = String.class, + doc = "The path of the new file, relative to the current package." + ) + } + ) + public FileApi newFile(String filename) throws EvalException; + + @SkylarkCallable(documented = false) + public FileApi newFile(FileRootApi root, String filename) throws EvalException; + + @SkylarkCallable( + name = "new_file", + doc = + "Creates a new file object in the same directory as the original file. " + + DOC_NEW_FILE_TAIL, + parameters = { + @Param( + name = "sibling_file", + type = FileApi.class, + doc = "A file that lives in the same directory as the newly created file." + ), + @Param( + name = "basename", + type = String.class, + doc = "The base name of the newly created file." + ) + } + ) + public FileApi newFile(FileApi baseArtifact, String newBaseName) throws EvalException; + + @SkylarkCallable(documented = false) + public FileApi newFile(FileRootApi root, FileApi baseArtifact, String suffix) + throws EvalException; + + @SkylarkCallable( + name = "experimental_new_directory", + documented = false, + parameters = { + @Param(name = "name", type = String.class), + @Param( + name = "sibling", + type = FileApi.class, + defaultValue = "None", + noneable = true, + named = true + ) + } + ) + public FileApi newDirectory(String name, Object siblingArtifactUnchecked) throws EvalException; + + @SkylarkCallable(documented = false) + public boolean checkPlaceholders(String template, SkylarkList<Object> allowedPlaceholders) + throws EvalException; + + @SkylarkCallable( + doc = "<b>Deprecated.</b> Use <code>ctx.var</code> to access the variables instead.<br>" + + "Returns a string after expanding all references to \"Make variables\". The variables " + + "must have the following format: <code>$(VAR_NAME)</code>. Also, <code>$$VAR_NAME" + + "</code> expands to <code>$VAR_NAME</code>. Parameters:" + + "<ul><li>The name of the attribute (<code>string</code>). It's only used for error " + + "reporting.</li>\n" + + "<li>The expression to expand (<code>string</code>). It can contain references to " + + "\"Make variables\".</li>\n" + + "<li>A mapping of additional substitutions (<code>dict</code> of <code>string</code> : " + + "<code>string</code>).</li></ul>\n" + + "Examples:" + + "<pre class=language-python>\n" + + "ctx.expand_make_variables(\"cmd\", \"$(MY_VAR)\", {\"MY_VAR\": \"Hi\"}) # == \"Hi\"\n" + + "ctx.expand_make_variables(\"cmd\", \"$$PWD\", {}) # == \"$PWD\"\n" + + "</pre>" + + "Additional variables may come from other places, such as configurations. Note that " + + "this function is experimental.") + public String expandMakeVariables( + String attributeName, String command, final Map<String, String> additionalSubstitutions) + throws EvalException; + + @SkylarkCallable( + name = "info_file", + structField = true, + documented = false, + doc = + "Returns the file that is used to hold the non-volatile workspace status for the " + + "current build request." + ) + public FileApi getStableWorkspaceStatus() throws InterruptedException, EvalException; + + @SkylarkCallable( + name = "version_file", + structField = true, + documented = false, + doc = + "Returns the file that is used to hold the volatile workspace status for the " + + "current build request." + ) + public FileApi getVolatileWorkspaceStatus() throws InterruptedException, EvalException; + + @SkylarkCallable( + name = "build_file_path", + structField = true, + documented = true, + doc = "Returns path to the BUILD file for this rule, relative to the source root." + ) + public String getBuildFileRelativePath() throws EvalException; + + @SkylarkCallable( + name = "action", + doc = + "DEPRECATED. Use <a href=\"actions.html#run\">ctx.actions.run()</a> or" + + " <a href=\"actions.html#run_shell\">ctx.actions.run_shell()</a>. <br>" + + "Creates an action that runs an executable or a shell command." + + " You must specify either <code>command</code> or <code>executable</code>.\n" + + "Actions and genrules are very similar, but have different use cases. Actions are " + + "used inside rules, and genrules are used inside macros. Genrules also have make " + + "variable expansion.", + 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 of the input files of the action." + ), + @Param( + name = "executable", + type = Object.class, + allowedTypes = { + @ParamType(type = FileApi.class), + @ParamType(type = String.class), + @ParamType(type = Runtime.NoneType.class), + }, + noneable = true, + defaultValue = "None", + 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 of the 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." + ), + @Param( + name = "mnemonic", + type = String.class, + noneable = true, + defaultValue = "None", + named = true, + positional = false, + doc = "A one-word description of the action, e.g. CppCompile or GoLink." + ), + @Param( + name = "command", + type = Object.class, + allowedTypes = { + @ParamType(type = String.class), + @ParamType(type = SkylarkList.class, generic1 = String.class), + @ParamType(type = Runtime.NoneType.class), + }, + noneable = true, + defaultValue = "None", + named = true, + positional = false, + doc = + "Shell command to execute. It is usually preferable to " + + "use <code>executable</code> instead. " + + "Arguments are available with <code>$1</code>, <code>$2</code>, etc." + ), + @Param( + name = "progress_message", + type = String.class, + noneable = true, + defaultValue = "None", + named = true, + positional = false, + doc = + "Progress message to show to the user during the build, " + + "e.g. \"Compiling foo.cc to create foo.o\"." + ), + @Param( + name = "use_default_shell_env", + type = Boolean.class, + defaultValue = "False", + named = true, + positional = false, + doc = "Whether the action should use the built in shell environment or not." + ), + @Param( + name = "env", + type = SkylarkDict.class, + noneable = true, + defaultValue = "None", + named = true, + positional = false, + doc = "Sets the dictionary of environment variables." + ), + @Param( + name = "execution_requirements", + type = SkylarkDict.class, + noneable = true, + defaultValue = "None", + named = true, + positional = false, + doc = + "Information for scheduling the action. See " + + "<a href=\"$BE_ROOT/common-definitions.html#common.tags\">tags</a> " + + "for useful keys." + ), + @Param( + // TODO(bazel-team): The name here isn't accurate anymore. This is technically experimental, + // so folks shouldn't be too attached, but consider renaming to be more accurate/opaque. + name = "input_manifests", + type = SkylarkList.class, + noneable = true, + defaultValue = "None", + named = true, + positional = false, + doc = + "(Experimental) sets the input runfiles metadata; " + + "they are typically generated by resolve_command." + ) + }, + allowReturnNones = true, + useLocation = true, + useEnvironment = true + ) + public Runtime.NoneType action( + SkylarkList outputs, + Object inputs, + Object executableUnchecked, + Object toolsUnchecked, + Object arguments, + Object mnemonicUnchecked, + Object commandUnchecked, + Object progressMessage, + Boolean useDefaultShellEnv, + Object envUnchecked, + Object executionRequirementsUnchecked, + Object inputManifestsUnchecked, + Location loc, + Environment env) + throws EvalException; + + @SkylarkCallable( + name = "expand_location", + doc = + "Expands all <code>$(location ...)</code> templates in the given string by replacing " + + "<code>$(location //x)</code> with the path of the output file of target //x. " + + "Expansion only works for labels that point to direct dependencies of this rule or " + + "that are explicitly listed in the optional argument <code>targets</code>. " + + "<br/><br/>" + + "<code>$(location ...)</code> will cause an error if the referenced target has " + + "multiple outputs. In this case, please use <code>$(locations ...)</code> since it " + + "produces a space-separated list of output paths. It can be safely used for a " + + "single output file, too.", + parameters = { + @Param(name = "input", type = String.class, doc = "String to be expanded."), + @Param( + name = "targets", + type = SkylarkList.class, + generic1 = TransitiveInfoCollectionApi.class, + defaultValue = "[]", + named = true, + doc = "List of targets for additional lookup information." + ), + }, + allowReturnNones = true, + useLocation = true, + useEnvironment = true + ) + public String expandLocation(String input, SkylarkList targets, Location loc, Environment env) + throws EvalException; + + @SkylarkCallable( + name = "file_action", + doc = + "DEPRECATED. Use <a href =\"actions.html#write\">ctx.actions.write</a> instead. <br>" + + "Creates a file write action.", + parameters = { + @Param(name = "output", type = FileApi.class, named = true, doc = "The output file."), + @Param( + name = "content", + type = String.class, + named = true, + doc = "The contents of the file." + ), + @Param( + name = "executable", + type = Boolean.class, + defaultValue = "False", + named = true, + doc = "Whether the output file should be executable (default is False)." + ) + }, + allowReturnNones = true, + useLocation = true, + useEnvironment = true + ) + public Runtime.NoneType fileAction( + FileApi output, String content, Boolean executable, Location loc, Environment env) + throws EvalException; + + @SkylarkCallable( + name = "empty_action", + doc = + "DEPRECATED. Use <a href=\"actions.html#do_nothing\">ctx.actions.do_nothing</a> instead." + + " <br>" + + "Creates an empty action that neither executes a command nor produces any " + + "output, but that is useful for inserting 'extra actions'.", + parameters = { + @Param( + name = "mnemonic", + type = String.class, + named = true, + positional = false, + doc = "A one-word description of the action, e.g. CppCompile or GoLink." + ), + @Param( + name = "inputs", + allowedTypes = { + @ParamType(type = SkylarkList.class), + @ParamType(type = SkylarkNestedSet.class), + }, + generic1 = FileApi.class, + named = true, + positional = false, + defaultValue = "[]", + doc = "List of the input files of the action." + ), + }, + allowReturnNones = true, + useLocation = true, + useEnvironment = true + ) + public Runtime.NoneType emptyAction(String mnemonic, Object inputs, Location loc, Environment env) + throws EvalException; + + @SkylarkCallable( + name = "template_action", + doc = + "DEPRECATED. " + + "Use <a href=\"actions.html#expand_template\">ctx.actions.expand_template()</a> " + + "instead. <br>Creates a template expansion action.", + 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 = "executable", + type = Boolean.class, + defaultValue = "False", + named = true, + positional = false, + doc = "Whether the output file should be executable (default is False)." + ) + }, + allowReturnNones = true, + useLocation = true, + useEnvironment = true + ) + public Runtime.NoneType templateAction( + FileApi template, + FileApi output, + SkylarkDict<?, ?> substitutionsUnchecked, + Boolean executable, + Location loc, + Environment env) + throws EvalException; + + @SkylarkCallable( + name = "runfiles", + doc = "Creates a runfiles object.", + parameters = { + @Param( + name = "files", + type = SkylarkList.class, + generic1 = FileApi.class, + named = true, + defaultValue = "[]", + doc = "The list of files to be added to the runfiles." + ), + // TODO(bazel-team): If we have a memory efficient support for lazy list containing + // NestedSets we can remove this and just use files = [file] + list(set) + // Also, allow empty set for init + @Param( + name = "transitive_files", + type = SkylarkNestedSet.class, + generic1 = FileApi.class, + noneable = true, + defaultValue = "None", + named = true, + doc = + "The (transitive) set of files to be added to the runfiles. The depset should " + + "use the `default` order (which, as the name implies, is the default)." + ), + @Param( + name = "collect_data", + type = Boolean.class, + defaultValue = "False", + named = true, + doc = + "Whether to collect the data " + + "runfiles from the dependencies in srcs, data and deps attributes." + ), + @Param( + name = "collect_default", + type = Boolean.class, + defaultValue = "False", + named = true, + doc = + "Whether to collect the default " + + "runfiles from the dependencies in srcs, data and deps attributes." + ), + @Param( + name = "symlinks", + type = SkylarkDict.class, + defaultValue = "{}", + named = true, + doc = "The map of symlinks to be added to the runfiles, prefixed by workspace name." + ), + @Param( + name = "root_symlinks", + type = SkylarkDict.class, + defaultValue = "{}", + named = true, + doc = "The map of symlinks to be added to the runfiles." + ) + }, + useLocation = true + ) + public RunfilesApi runfiles( + SkylarkList files, + Object transitiveFiles, + Boolean collectData, + Boolean collectDefault, + SkylarkDict<?, ?> symlinks, + SkylarkDict<?, ?> rootSymlinks, + Location loc) + throws EvalException; + + @SkylarkCallable( + name = "resolve_command", + // TODO(bazel-team): The naming here isn't entirely accurate (input_manifests is no longer + // manifests), but this is experimental/should be opaque to the end user. + doc = + "<i>(Experimental)</i> " + + "Returns a tuple <code>(inputs, command, input_manifests)</code> of the list of " + + "resolved inputs, the argv list for the resolved command, and the runfiles metadata" + + "required to run the command, all of them suitable for passing as the same-named " + + "arguments of the <code>ctx.action</code> method.", + parameters = { + @Param( + name = "command", + type = String.class, // string + defaultValue = "''", + named = true, + positional = false, + doc = "Command to resolve." + ), + @Param( + name = "attribute", + type = String.class, // string + defaultValue = "None", + noneable = true, + named = true, + positional = false, + doc = "Name of the associated attribute for which to issue an error, or None." + ), + @Param( + name = "expand_locations", + type = Boolean.class, + defaultValue = "False", + named = true, + positional = false, + doc = + "Shall we expand $(location) variables? " + + "See <a href=\"#expand_location\">ctx.expand_location()</a> for more details." + ), + @Param( + name = "make_variables", + type = SkylarkDict.class, // dict(string, string) + noneable = true, + defaultValue = "None", + named = true, + positional = false, + doc = "Make variables to expand, or None." + ), + @Param( + name = "tools", + defaultValue = "[]", + type = SkylarkList.class, + generic1 = TransitiveInfoCollectionApi.class, + named = true, + positional = false, + doc = "List of tools (list of targets)." + ), + @Param( + name = "label_dict", + type = SkylarkDict.class, + defaultValue = "{}", + named = true, + positional = false, + doc = + "Dictionary of resolved labels and the corresponding list of Files " + + "(a dict of Label : list of Files)." + ), + @Param( + name = "execution_requirements", + type = SkylarkDict.class, + defaultValue = "{}", + named = true, + positional = false, + doc = + "Information for scheduling the action to resolve this command. See " + + "<a href=\"$BE_ROOT/common-definitions.html#common.tags\">tags</a> " + + "for useful keys." + ), + }, + useLocation = true, + useEnvironment = true + ) + public Tuple<Object> resolveCommand( + String command, + Object attributeUnchecked, + Boolean expandLocations, + Object makeVariablesUnchecked, + SkylarkList tools, + SkylarkDict<?, ?> labelDictUnchecked, + SkylarkDict<?, ?> executionRequirementsUnchecked, + Location loc, + Environment env) + throws EvalException; +} diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/TransitiveInfoCollectionApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/TransitiveInfoCollectionApi.java new file mode 100644 index 0000000000..3b3d1ce034 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/TransitiveInfoCollectionApi.java @@ -0,0 +1,58 @@ +// 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.Param; +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.syntax.SkylarkNestedSet; + +/** + * Interface for a build target. + */ +@SkylarkModule( + name = "Target", + category = SkylarkModuleCategory.BUILTIN, + doc = + "A BUILD target. It is essentially a <code>struct</code> with the following fields:" + + "<ul>" + + "<li><h3 id=\"modules.Target.label\">label</h3><code><a class=\"anchor\" " + + "href=\"Label.html\">Label</a> Target.label</code><br>The identifier of the " + + "target.</li>" + + "<li><h3 id=\"modules.Target.files\">files</h3><code><a class=\"anchor\" " + + "href=\"depset.html\">depset</a> Target.files </code><br>The set of " + + "<a class=\"anchor\" href=\"File.html\">File</a>s produced directly by this " + + "target.</li>" + + "<li><h3 id=\"modules.Target.aspect_ids\">aspect_ids</h3><code><a class=\"anchor\"" + + "href=\"list.html\">list</a> Target.aspect_ids </code><br>The list of " + + "<a class=\"anchor\" href=\"ctx.html#aspect_id\">aspect_id</a>s applied to this " + + "target.</li>" + + "<li><h3 id=\"modules.Target.extraproviders\">Extra providers</h3>For rule targets all " + + "additional providers provided by this target are accessible as <code>struct</code> " + + "fields. These extra providers are defined in the <code>struct</code> returned by the " + + "rule implementation function.</li>" + + "</ul>" +) +public interface TransitiveInfoCollectionApi { + + @SkylarkCallable( + name = "output_group", + documented = false, // TODO(dslomov): document. + parameters = { + @Param(name = "group_name", type = String.class, doc = "Output group name", named = true) + }) + SkylarkNestedSet outputGroup(String group); +} |