From abbb9002c41bbd53588e7249756aab236f6fcb4b Mon Sep 17 00:00:00 2001 From: cparsons Date: Fri, 11 May 2018 11:54:17 -0700 Subject: Migrate SkylarkRuleContext (and a few dependencies) to the build API RELNOTES: None. PiperOrigin-RevId: 196287081 --- .../lib/analysis/TransitiveInfoCollection.java | 38 +- .../lib/analysis/config/BuildConfiguration.java | 46 +- .../lib/analysis/config/FragmentCollection.java | 19 +- .../skylark/SkylarkAttributesCollection.java | 27 +- .../lib/analysis/skylark/SkylarkRuleContext.java | 784 ++---------------- .../lib/skylarkbuildapi/BuildConfigurationApi.java | 69 ++ .../lib/skylarkbuildapi/FragmentCollectionApi.java | 34 + .../SkylarkAttributesCollectionApi.java | 54 ++ .../lib/skylarkbuildapi/SkylarkRuleContextApi.java | 896 +++++++++++++++++++++ .../TransitiveInfoCollectionApi.java | 58 ++ 10 files changed, 1198 insertions(+), 827 deletions(-) create mode 100644 src/main/java/com/google/devtools/build/lib/skylarkbuildapi/BuildConfigurationApi.java create mode 100644 src/main/java/com/google/devtools/build/lib/skylarkbuildapi/FragmentCollectionApi.java create mode 100644 src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkAttributesCollectionApi.java create mode 100644 src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java create mode 100644 src/main/java/com/google/devtools/build/lib/skylarkbuildapi/TransitiveInfoCollectionApi.java (limited to 'src/main/java') 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 struct with the following fields:" - + "" -) -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 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; * *
c1.equals(c2) <=> c1==c2.
*/ -@SkylarkModule( - name = "configuration", - category = SkylarkModuleCategory.BUILTIN, - doc = - "This object holds information about the environment in which the build is running. See " - + "the Rules page 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 { *

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 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 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 " - + "ctx.coverage_instrumented 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 " - + "apple, cpp, " - + "java, jvm and " - + "objc, android. " - + "Access a specific fragment by its field name ex:

ctx.fragments.apple

" - + "Note that rules have to declare their required fragments in order to access them " - + "(see here).") -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 + *

"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 implementation 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 struct containing executable files defined in label type " - + "attributes marked as executable=True. The struct fields correspond " - + "to the attribute names. Each value in the struct is either a file or " - + "None. If an optional attribute is not specified in the rule " - + "then the corresponding struct value is None. If a label type is not " - + "marked as executable=True, no corresponding struct field is generated. " - + "See example of use."; - public static final String FILES_DOC = - "A struct containing files defined in label or label list " - + "type attributes. The struct fields correspond to the attribute names. The struct " - + "values are list of files. " - + "It is a shortcut for:" - + "

[f for t in ctx.attr.<ATTR> for f in t.files]
" - + "In other words, use files to access the " - + "default outputs of a " - + "dependency. " - + "" - + "See example of use."; - public static final String FILE_DOC = - "A struct containing files defined in label type " - + "attributes marked as allow_single_file. The struct fields correspond " - + "to the attribute names. The struct value is always a file or " - + "None. If an optional attribute is not specified in the rule " - + "then the corresponding struct value is None. If a label type is not " - + "marked as allow_single_file, no corresponding struct field is generated. " - + "It is a shortcut for:" - + "
list(ctx.attr.<ATTR>.files)[0]
" - + "In other words, use file to access the (singular) " - + "default output of a " - + "dependency. " - + "See example of use."; - 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 attrs " - + "dict provided to the rule function. " - + "See example of use."; - 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 " - + "File objects. See the " - + "Rules page for more information and examples." - + "

This field does not exist on aspect contexts, since aspects do not have " - + "predeclared outputs." - + "

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." - + "

"; +public final class SkylarkRuleContext implements SkylarkRuleContextApi { + public static final Function ATTRIBUTE_VALUE_EXTRACTOR_FOR_ASPECT = new Function() { @Nullable @@ -573,34 +479,17 @@ public final class SkylarkRuleContext implements SkylarkValue { return ruleContext; } - @SkylarkCallable( - name = "default_provider", - structField = true, - doc = "Deprecated. Use DefaultInfo 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 _skylark_testable" - + " set to True, this returns an " - + "Actions provider representing all actions " - + "created so far for the current rule. For all other rules, returns None. " - + "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. " - + "

" - + "This is intended to help write tests for rule-implementation helper functions, which " - + "may take in a ctx 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 " - + "configuration 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 " - + "configuration 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 target 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 coverage_enabled in the " - + "configuration, 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 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 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 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 tokenize(String optionString) throws FuncallException, EvalException { checkMutable("tokenize"); List 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 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 ctx.actions.declare_file.
" - + "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 allowedPlaceholders) throws EvalException { checkMutable("check_placeholders"); @@ -950,26 +744,10 @@ public final class SkylarkRuleContext implements SkylarkValue { return true; } - @SkylarkCallable(doc = - "Deprecated. Use ctx.var to access the variables instead.
" - + "Returns a string after expanding all references to \"Make variables\". The variables " - + "must have the following format: $(VAR_NAME). Also, $$VAR_NAME" - + " expands to $VAR_NAME. Parameters:" - + "
  • The name of the attribute (string). It's only used for error " - + "reporting.
  • \n" - + "
  • The expression to expand (string). It can contain references to " - + "\"Make variables\".
  • \n" - + "
  • A mapping of additional substitutions (dict of string : " - + "string).
\n" - + "Examples:" - + "
\n"
-      + "ctx.expand_make_variables(\"cmd\", \"$(MY_VAR)\", {\"MY_VAR\": \"Hi\"})  # == \"Hi\"\n"
-      + "ctx.expand_make_variables(\"cmd\", \"$$PWD\", {})  # == \"$PWD\"\n"
-      + "
" - + "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 additionalSubstitutions) throws EvalException { + @Override + public String expandMakeVariables( + String attributeName, String command, final Map 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 ctx.actions.run() or" - + " ctx.actions.run_shell().
" - + "Creates an action that runs an executable or a shell command." - + " You must specify either command or executable.\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 executable instead. " - + "Arguments are available with $1, $2, 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 " - + "tags " - + "for useful keys." - ), - @Param( - // TODO(bazel-team): The name here isn't accurate anymore. This is technically experimental, - // so folks shouldn't be too attached, but consider renaming to be more accurate/opaque. - name = "input_manifests", - type = SkylarkList.class, - noneable = true, - defaultValue = "None", - named = true, - positional = false, - doc = - "(Experimental) sets the input runfiles metadata; " - + "they are typically generated by resolve_command." - ) - }, - 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 $(location ...) templates in the given string by replacing " - + "$(location //x) 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 targets. " - + "

" - + "$(location ...) will cause an error if the referenced target has " - + "multiple outputs. In this case, please use $(locations ...) 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 ctx.actions.write instead.
" - + "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 ctx.actions.do_nothing instead." - + "
" - + "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 ctx.actions.expand_template() " - + "instead.
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 = - "(Experimental) " - + "Returns a tuple (inputs, command, input_manifests) 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 ctx.action 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 ctx.expand_location() 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 " - + "tags " - + "for useful keys." - ), - }, - useLocation = true, - useEnvironment = true - ) + @Override public Tuple 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 Rules page 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 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 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 " + + "ctx.coverage_instrumented 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 " + + "android, apple, " + + "cpp, java, " + + "jvm, and objc. " + + "Access a specific fragment by its field name " + + "ex:

ctx.fragments.apple

" + + "Note that rules have to declare their required fragments in order to access them " + + "(see here).") +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 implementation 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 struct containing executable files defined in label type " + + "attributes marked as executable=True. The struct fields correspond " + + "to the attribute names. Each value in the struct is either a file or " + + "None. If an optional attribute is not specified in the rule " + + "then the corresponding struct value is None. If a label type is not " + + "marked as executable=True, no corresponding struct field is generated. " + + "See example of use."; + public static final String FILES_DOC = + "A struct containing files defined in label or label list " + + "type attributes. The struct fields correspond to the attribute names. The struct " + + "values are list of files. " + + "It is a shortcut for:" + + "
[f for t in ctx.attr.<ATTR> for f in t.files]
" + + "In other words, use files to access the " + + "default outputs of a " + + "dependency. " + + "" + + "See example of use."; + public static final String FILE_DOC = + "A struct containing files defined in label type " + + "attributes marked as allow_single_file. The struct fields correspond " + + "to the attribute names. The struct value is always a file or " + + "None. If an optional attribute is not specified in the rule " + + "then the corresponding struct value is None. If a label type is not " + + "marked as allow_single_file, no corresponding struct field is generated. " + + "It is a shortcut for:" + + "
list(ctx.attr.<ATTR>.files)[0]
" + + "In other words, use file to access the (singular) " + + "default output of a " + + "dependency. " + + "See example of use."; + 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 attrs " + + "dict provided to the rule function. " + + "See example of use."; + 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 " + + "File objects. See the " + + "Rules page for more information and examples." + + "

This field does not exist on aspect contexts, since aspects do not have " + + "predeclared outputs." + + "

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." + + "

    " + + "
  • If the rule declares an outputs" + + " dict, then for every entry in the dict, there is a field whose name is the key " + + "and whose value is the corresponding File." + + "
  • For every attribute of type attr.output" + + " 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 File; otherwise the field value is None." + + "
  • For every attribute of type attr.output_list" + + " that the rule declares, there is a field whose name is the attribute's " + + "name. The field value is a list of File 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." + + "
  • (Deprecated) If the rule is marked " + + "executable or test," + + "there is a field named \"executable\", which is the default executable. " + + "It is recommended that instead of using this, you pass another file (either " + + "predeclared or not) to the executable arg of " + + "DefaultInfo." + + "
"; + + @SkylarkCallable( + name = "default_provider", + structField = true, + doc = "Deprecated. Use DefaultInfo 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 _skylark_testable" + + " set to True, this returns an " + + "Actions provider representing all actions " + + "created so far for the current rule. For all other rules, returns None. " + + "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. " + + "

" + + "This is intended to help write tests for rule-implementation helper functions, which " + + "may take in a ctx 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 " + + "configuration type for more details." + ) + public BuildConfigurationApi getConfiguration() throws EvalException; + + @SkylarkCallable( + name = "host_configuration", + structField = true, + doc = + "Returns the host configuration. See the " + + "configuration 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 target 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 coverage_enabled in the " + + "configuration, 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 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 aspectIds() throws EvalException; + + @SkylarkCallable( + structField = true, + doc = "Dictionary (String to String) of configuration variables." + ) + public SkylarkDict 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 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 artifacts, Label labelResolver) + throws EvalException, FuncallException; + + @SkylarkCallable( + name = "new_file", + doc = + "DEPRECATED. Use ctx.actions.declare_file.
" + + "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 allowedPlaceholders) + throws EvalException; + + @SkylarkCallable( + doc = "Deprecated. Use ctx.var to access the variables instead.
" + + "Returns a string after expanding all references to \"Make variables\". The variables " + + "must have the following format: $(VAR_NAME). Also, $$VAR_NAME" + + " expands to $VAR_NAME. Parameters:" + + "
  • The name of the attribute (string). It's only used for error " + + "reporting.
  • \n" + + "
  • The expression to expand (string). It can contain references to " + + "\"Make variables\".
  • \n" + + "
  • A mapping of additional substitutions (dict of string : " + + "string).
\n" + + "Examples:" + + "
\n"
+        + "ctx.expand_make_variables(\"cmd\", \"$(MY_VAR)\", {\"MY_VAR\": \"Hi\"})  # == \"Hi\"\n"
+        + "ctx.expand_make_variables(\"cmd\", \"$$PWD\", {})  # == \"$PWD\"\n"
+        + "
" + + "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 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 ctx.actions.run() or" + + " ctx.actions.run_shell().
" + + "Creates an action that runs an executable or a shell command." + + " You must specify either command or executable.\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 executable instead. " + + "Arguments are available with $1, $2, 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 " + + "tags " + + "for useful keys." + ), + @Param( + // TODO(bazel-team): The name here isn't accurate anymore. This is technically experimental, + // so folks shouldn't be too attached, but consider renaming to be more accurate/opaque. + name = "input_manifests", + type = SkylarkList.class, + noneable = true, + defaultValue = "None", + named = true, + positional = false, + doc = + "(Experimental) sets the input runfiles metadata; " + + "they are typically generated by resolve_command." + ) + }, + 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 $(location ...) templates in the given string by replacing " + + "$(location //x) 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 targets. " + + "

" + + "$(location ...) will cause an error if the referenced target has " + + "multiple outputs. In this case, please use $(locations ...) 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 ctx.actions.write instead.
" + + "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 ctx.actions.do_nothing instead." + + "
" + + "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 ctx.actions.expand_template() " + + "instead.
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 = + "(Experimental) " + + "Returns a tuple (inputs, command, input_manifests) 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 ctx.action 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 ctx.expand_location() 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 " + + "tags " + + "for useful keys." + ), + }, + useLocation = true, + useEnvironment = true + ) + public Tuple 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 struct with the following fields:" + + "
    " + + "
  • label

    Label Target.label
    The identifier of the " + + "target.
  • " + + "
  • files

    depset Target.files
    The set of " + + "Files produced directly by this " + + "target.
  • " + + "
  • aspect_ids

    list Target.aspect_ids
    The list of " + + "aspect_ids applied to this " + + "target.
  • " + + "
  • Extra providers

    For rule targets all " + + "additional providers provided by this target are accessible as struct " + + "fields. These extra providers are defined in the struct returned by the " + + "rule implementation function.
  • " + + "
" +) +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); +} -- cgit v1.2.3