aboutsummaryrefslogtreecommitdiffhomepage
path: root/site
diff options
context:
space:
mode:
authorGravatar Han-Wen Nienhuys <hanwen@google.com>2016-01-15 15:54:12 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-01-15 22:29:37 +0000
commit67e6f98d7659ac41154f93c39e548ba0ecc43c80 (patch)
treeaa1804d5058d3e0d53c58ab1af4e6301da1fd190 /site
parent8cc0541da1ec912568c8df2fc13a9b72b668cda2 (diff)
Add native.rule(NAME), which returns the attributes of a previously defined rule.
Add native.rules(), which returns all previously defined rules. These primitives can be used to write Skylark extensions that aggregate over the contents of a BUILD file, eg. def instantiate_if_needed(name): n = name + "_wrapped" if not native.rule(n): py_test(name = n , ... ) def archive_cc_src_files(tag): all_src = [] for r in native.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"]) RELNOTES: Support aggregation over existing rules in Skylark extensions through native.rules and native.rule. -- MOS_MIGRATED_REVID=112249050
Diffstat (limited to 'site')
-rw-r--r--site/docs/skylark/cookbook.md70
1 files changed, 70 insertions, 0 deletions
diff --git a/site/docs/skylark/cookbook.md b/site/docs/skylark/cookbook.md
index 4952d91a20..c4f718faea 100644
--- a/site/docs/skylark/cookbook.md
+++ b/site/docs/skylark/cookbook.md
@@ -59,6 +59,76 @@ load("/pkg/extension", "macro")
macro(name = "myrule")
```
+## <a name="conditional-instantiation"></a>Conditional instantiation.</a>
+
+Macros can look at previously instantiated rules. This is done with
+`native.rule`, which returns information on a single rule defined in the same
+`BUILD` file, eg.,
+
+```python
+native.rule("descriptor_proto")
+```
+
+This is useful to avoid instantiating the same rule twice, which is an
+error. For example, the following rule will simulate a test suite, instantiating
+tests for diverse flavors of the same test.
+
+`extension.bzl`:
+
+```python
+def system_test(test_file, flavor):
+ n = "system_test_%s_%s_test" % (test_file, flavor)
+ if native.rule(n) == None:
+ native.py_test(
+ name = n,
+ srcs = [ "test_driver.py", test_file ],
+ args = [ "--flavor=" + flavor])
+ return n
+
+def system_test_suite(name, flavors=["default"], test_files):
+ ts = []
+ for flavor in flavors:
+ for test in test_files:
+ ts.append(system_test(name, flavor, test))
+ native.test_suite(name = name, tests = ts)
+```
+
+In the following BUILD file, note how `(fast, basic_test.py)` is emitted for
+both the `smoke` test suite and the `thorough` test suite.
+
+```python
+load("/pkg/extension", "system_test_suite")
+
+# Run all files through the 'fast' flavor.
+system_test_suite("smoke", flavors=["fast"], glob(["*_test.py"]))
+
+# Run the basic test through all flavors.
+system_test_suite("thorough", flavors=["fast", "debug", "opt"], ["basic_test.py"])
+```
+
+
+## <a name="aggregation"></a>Aggregating over the BUILD file.</a>
+
+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
+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`.
+
+```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():
+ 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
+calling it repeatedly within BUILD file.
+
## <a name="empty"></a>Empty rule
Minimalist example of a rule that does nothing. If you build it, the target will