Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 389431b

Browse filesBrowse files
authored
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 #1647
1 parent 5a8f6c4 commit 389431b
Copy full SHA for 389431b
Expand file treeCollapse file tree

22 files changed

+3238
-547
lines changed

‎docs/BUILD.bazel

Copy file name to clipboardExpand all lines: docs/BUILD.bazel
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,14 @@ sphinx_stardocs(
103103
"//python/cc:py_cc_toolchain_bzl",
104104
"//python/cc:py_cc_toolchain_info_bzl",
105105
"//python/entry_points:py_console_script_binary_bzl",
106+
"//python/private:attr_builders_bzl",
107+
"//python/private:builders_util_bzl",
106108
"//python/private:py_binary_rule_bzl",
107109
"//python/private:py_cc_toolchain_rule_bzl",
108110
"//python/private:py_library_rule_bzl",
109111
"//python/private:py_runtime_rule_bzl",
110112
"//python/private:py_test_rule_bzl",
113+
"//python/private:rule_builders_bzl",
111114
"//python/private/api:py_common_api_bzl",
112115
"//python/private/pypi:config_settings_bzl",
113116
"//python/private/pypi:pkg_aliases_bzl",

‎docs/_includes/field_kwargs_doc.md

Copy file name to clipboard
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
:::{field} kwargs
2+
:type: dict[str, Any]
3+
4+
Additional kwargs to use when building. This is to allow manipulations that
5+
aren't directly supported by the builder's API. The state of this dict
6+
may or may not reflect prior API calls, and subsequent API calls may
7+
modify this dict. The general contract is that modifications to this will
8+
be respected when `build()` is called, assuming there were no API calls
9+
in between.
10+
:::
11+

‎python/private/BUILD.bazel

Copy file name to clipboardExpand all lines: python/private/BUILD.bazel
+32Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,20 @@ filegroup(
5151
visibility = ["//python:__pkg__"],
5252
)
5353

54+
bzl_library(
55+
name = "attr_builders_bzl",
56+
srcs = ["attr_builders.bzl"],
57+
deps = [
58+
":builders_util_bzl",
59+
"@bazel_skylib//lib:types",
60+
],
61+
)
62+
5463
bzl_library(
5564
name = "attributes_bzl",
5665
srcs = ["attributes.bzl"],
5766
deps = [
67+
":attr_builders_bzl",
5868
":common_bzl",
5969
":enum_bzl",
6070
":flags_bzl",
@@ -92,6 +102,14 @@ bzl_library(
92102
],
93103
)
94104

105+
bzl_library(
106+
name = "builders_util_bzl",
107+
srcs = ["builders_util.bzl"],
108+
deps = [
109+
"@bazel_skylib//lib:types",
110+
],
111+
)
112+
95113
bzl_library(
96114
name = "bzlmod_enabled_bzl",
97115
srcs = ["bzlmod_enabled.bzl"],
@@ -283,6 +301,7 @@ bzl_library(
283301
deps = [
284302
":attributes_bzl",
285303
":py_executable_bzl",
304+
":rule_builders_bzl",
286305
":semantics_bzl",
287306
"@bazel_skylib//lib:dicts",
288307
],
@@ -410,6 +429,7 @@ bzl_library(
410429
":flags_bzl",
411430
":py_cc_link_params_info_bzl",
412431
":py_internal_bzl",
432+
":rule_builders_bzl",
413433
":toolchain_types_bzl",
414434
"@bazel_skylib//lib:dicts",
415435
"@bazel_skylib//rules:common_settings",
@@ -475,6 +495,7 @@ bzl_library(
475495
":py_internal_bzl",
476496
":py_runtime_info_bzl",
477497
":reexports_bzl",
498+
":rule_builders_bzl",
478499
":util_bzl",
479500
"@bazel_skylib//lib:dicts",
480501
"@bazel_skylib//lib:paths",
@@ -515,6 +536,7 @@ bzl_library(
515536
":attributes_bzl",
516537
":common_bzl",
517538
":py_executable_bzl",
539+
":rule_builders_bzl",
518540
":semantics_bzl",
519541
"@bazel_skylib//lib:dicts",
520542
],
@@ -563,6 +585,16 @@ bzl_library(
563585
srcs = ["repo_utils.bzl"],
564586
)
565587

588+
bzl_library(
589+
name = "rule_builders_bzl",
590+
srcs = ["rule_builders.bzl"],
591+
deps = [
592+
":builders_bzl",
593+
":builders_util_bzl",
594+
"@bazel_skylib//lib:types",
595+
],
596+
)
597+
566598
bzl_library(
567599
name = "semver_bzl",
568600
srcs = ["semver.bzl"],

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.