Skip to content

Commit

Permalink
Rename native.rule and native.rules to {existing_rule,existing_rules}
Browse files Browse the repository at this point in the history
This is to avoid confusion between rule(), which declares a new build
rules, and native.rule(), which can only be used in macros to inspect
the BUILD file processed so far.

native.{rule,rules} is maintained and marked deprecated to smooth the
transition for early adopters.

--
MOS_MIGRATED_REVID=113250194
  • Loading branch information
hanwen authored and kchodorow committed Jan 28, 2016
1 parent c63b90f commit de435f4
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 18 deletions.
14 changes: 7 additions & 7 deletions site/docs/skylark/cookbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ macro(name = "myrule")
## <a name="conditional-instantiation"></a>Conditional instantiation.

Macros can look at previously instantiated rules. This is done with
`native.rule`, which returns information on a single rule defined in the same
`native.existing_rule`, which returns information on a single rule defined in the same
`BUILD` file, eg.,

```python
native.rule("descriptor_proto")
native.existing_rule("descriptor_proto")
```

This is useful to avoid instantiating the same rule twice, which is an
Expand All @@ -82,7 +82,7 @@ tests for diverse flavors of the same test.
```python
def system_test(test_file, flavor):
n = "system_test_%s_%s_test" % (test_file, flavor)
if native.rule(n) == None:
if native.existing_rule(n) == None:
native.py_test(
name = n,
srcs = [ "test_driver.py", test_file ],
Expand Down Expand Up @@ -115,22 +115,22 @@ system_test_suite("thorough", flavors=["fast", "debug", "opt"], ["basic_test.py"

Macros can collect information from the BUILD file as processed so far. We call
this aggregation. The typical example is collecting data from all rules of a
certain kind. This is done by calling `native.rules`, which returns a
certain kind. This is done by calling `native.existing_rules`, which returns a
dictionary representing all rules defined so far in the current BUILD file. The
dictionary has entries of the form `name` => `rule`, with the values using the
same format as `native.rule`.
same format as `native.existing_rule`.

```python
def archive_cc_src_files(tag):
"""Create an archive of all C++ sources that have the given tag."""
all_src = []
for r in native.rules().values():
for r in native.existing_rules().values():
if tag in r["tags"] and r["kind"] == "cc_library":
all_src.append(r["srcs"])
native.genrule(cmd = "zip $@ $^", srcs = all_src, outs = ["out.zip"])
```

Since `native.rules` constructs a potentially large dictionary, you should avoid
Since `native.existing_rules` constructs a potentially large dictionary, you should avoid
calling it repeatedly within BUILD file.

## <a name="empty"></a>Empty rule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,12 @@ public SkylarkList invoke(
}
};

@Deprecated
@SkylarkSignature(
name = "rule",
objectType = SkylarkNativeModule.class,
returnType = Object.class,
doc =
"Returns a dictionary representing the attributes of a previously defined rule, "
+ "or None if the rule does not exist.",
doc = "Deprecated. Use existing_rule instead.",
mandatoryPositionals = {
@Param(name = "name", type = String.class, doc = "The name of the rule.")
},
Expand All @@ -122,12 +121,58 @@ public Object invoke(String name, FuncallExpression ast, Environment env)
}
};

@SkylarkSignature(
name = "existing_rule",
objectType = SkylarkNativeModule.class,
returnType = Object.class,
doc =
"Returns a dictionary representing the attributes of a previously defined rule, "
+ "or None if the rule does not exist.",
mandatoryPositionals = {
@Param(name = "name", type = String.class, doc = "The name of the rule.")
},
useAst = true,
useEnvironment = true
)
private static final BuiltinFunction existingRule =
new BuiltinFunction("existing_rule") {
public Object invoke(String name, FuncallExpression ast, Environment env)
throws EvalException, InterruptedException {
env.checkLoadingPhase("native.existing_rule", ast.getLocation());
Map<String, Object> rule = PackageFactory.callGetRuleFunction(name, ast, env);
if (rule != null) {
return rule;
}

return Runtime.NONE;
}
};

@Deprecated
@SkylarkSignature(
name = "rules",
objectType = SkylarkNativeModule.class,
returnType = Map.class,
doc = "Deprecated. Use existing_rules instead.",
mandatoryPositionals = {},
useAst = true,
useEnvironment = true
)
private static final BuiltinFunction getRules =
new BuiltinFunction("rules") {
public Map<?, ?> invoke(FuncallExpression ast, Environment env)
throws EvalException, InterruptedException {
env.checkLoadingPhase("native.rules", ast.getLocation());
return PackageFactory.callGetRulesFunction(ast, env);
}
};

/*
If necessary, we could allow filtering by tag (anytag, alltags), name (regexp?), kind ?
For now, we ignore this, since users can implement it in Skylark.
*/
@SkylarkSignature(
name = "rules",
name = "existing_rules",
objectType = SkylarkNativeModule.class,
returnType = Map.class,
doc =
Expand All @@ -138,11 +183,11 @@ If necessary, we could allow filtering by tag (anytag, alltags), name (regexp?),
useAst = true,
useEnvironment = true
)
private static final BuiltinFunction getRules =
new BuiltinFunction("rules") {
public Map invoke(FuncallExpression ast, Environment env)
private static final BuiltinFunction existingRules =
new BuiltinFunction("existing_rules") {
public Map<?, ?> invoke(FuncallExpression ast, Environment env)
throws EvalException, InterruptedException {
env.checkLoadingPhase("native.rules", ast.getLocation());
env.checkLoadingPhase("native.existing_rules", ast.getLocation());
return PackageFactory.callGetRulesFunction(ast, env);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,8 @@ public void testGetRuleAttributeListType() throws Exception {
@Test
public void testGetRuleSelect() throws Exception {
scratch.file("test/skylark/BUILD");
scratch.file("test/skylark/rulestr.bzl", "def rule_dict(name):", " return native.rule(name)");
scratch.file(
"test/skylark/rulestr.bzl", "def rule_dict(name):", " return native.existing_rule(name)");

scratch.file(
"test/getrule/BUILD",
Expand All @@ -376,9 +377,9 @@ public void testGetRule() throws Exception {
scratch.file(
"test/skylark/rulestr.bzl",
"def rule_dict(name):",
" return native.rule(name)",
" return native.existing_rule(name)",
"def rules_dict():",
" return native.rules()",
" return native.existing_rules()",
"def nop(ctx):",
" pass",
"nop_rule = rule(attrs = {'x': attr.label()}, implementation = nop)",
Expand Down

0 comments on commit de435f4

Please sign in to comment.