refactor: API for deriving customized versions of the base rules (#2610)
This implements a "builder style" API to allow arbitrary modification of
rule, attr, etc
objects used when defining a rule. The net effect is users are able to
use the base
definition for our rules, but define their own with the modifications
they need, without
having to copy/paste portions our implementation, load private files, or
patch source.
The basic way it works is a mutable object ("builder") holds the args
and state that would
be used to create the immutable Bazel object. When `build()` is called,
the immutable
Bazel object (e.g. `attr.string()`) is created. Builders are implemented
for most objects
and their settings (rule, attrs, and supporting objects).
This design is necessary because of three Bazel behaviors:
* attr etc objects are immutable, which means we must keep our own state
* attr etc objects aren't inspectable, which means we must store the
arguments for
creating the immutable objects.
* Starlark objects are frozen after initial bzl file evaluation, which
means creation
of any mutable object must be done at the point of use.
The resulting API resembles the builder APIs common in other languages:
```
r = create_py_binary_rule_builder()
r.attrs.get("srcs").set_mandatory(True)
r.attrs.get("deps").aspects().append(my_aspect)
my_py_binary = r.build()
```
Most objects are thin wrappers for managing a kwargs dict. As such, and
because they're
wrapping a foreign API, they aren't strict in enforcing their internal
state and the
kwargs dict is publicly exposed as an escape hatch.
As of this PR, no public API for e.g. `create_py_binary_rule_builder()`
is exposed. That'll come in a separate PR (to add public access points
under python/api).
Work towards https://github.com/bazelbuild/rules_python/issues/1647This repository is the home of the core Python rules -- py_library, py_binary, py_test, py_proto_library, and related symbols that provide the basis for Python support in Bazel. It also contains package installation rules for integrating with PyPI and other indices.
Documentation for rules_python is at https://rules-python.readthedocs.io and in the Bazel Build Encyclopedia.
Examples live in the examples directory.
The core rules are stable. Their implementation is subject to Bazel's backward compatibility policy. This repository aims to follow semantic versioning.
The Bazel community maintains this repository. Neither Google nor the Bazel team provides support for the code. However, this repository is part of the test suite used to vet new Bazel releases. See How to contribute page for information on our development workflow.
For detailed documentation, see https://rules-python.readthedocs.io
See Bzlmod support for more details.