Skip to content

Commit 388e1d8

Browse files
committed
docs: rewrite multi-version dependency track guide using custom platforms
Updated the monorepo multi-version dependency sharing documentation to reflect bzlmod extension capabilities, migrating from manual Starlark select() routing on library targets to single-hub configurations utilizing custom platform settings. Work towards #3671.
1 parent f130aea commit 388e1d8

1 file changed

Lines changed: 85 additions & 31 deletions

File tree

Lines changed: 85 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,100 @@
11
(common-deps-with-multiple-pypi-versions)=
22
# How to use a common set of dependencies with multiple PyPI versions
33

4-
In this guide, we show how to handle a situation common to monorepos
5-
that extensively share code: How does a common library refer to the correct
6-
`@pypi_<name>` hub when binaries may have their own requirements (and thus
7-
PyPI hub name)? Stated as code, this situation:
4+
In this guide, we show how to handle a situation common to monorepos that
5+
extensively share code: How do multiple binaries utilize distinct requirements
6+
files while pulling from shared internal libraries, without requiring
7+
manually-maintained `select()` logic inside dependency targets?
88

9-
```bzl
9+
Stated as code, consider this example:
1010

11+
```bzl
12+
# When building bin_alpha, requests and more_itertools should resolve
13+
# from requirements_alpha.txt
1114
py_binary(
12-
name = "bin_alpha",
13-
deps = ["@pypi_alpha//requests", ":common"],
15+
name = "bin_alpha",
16+
deps = [
17+
"@pypi//requests",
18+
":common",
19+
],
1420
)
21+
22+
# When building bin_beta, requests and more_itertools should resolve
23+
# from requirements_beta.txt
1524
py_binary(
16-
name = "bin_beta",
17-
deps = ["@pypi_beta//requests", ":common"],
25+
name = "bin_beta",
26+
deps = [
27+
"@pypi//requests",
28+
":common",
29+
],
1830
)
1931

32+
# Transitive dependencies like more_itertools are requested here, but
33+
# must automatically match whichever dependency track is active for the binary.
2034
py_library(
21-
name = "common",
22-
deps = ["@pypi_???//more_itertools"] # <-- Which @pypi repo?
35+
name = "common",
36+
deps = ["@pypi//more_itertools"],
2337
)
2438
```
2539

26-
## Using flags to pick a hub
40+
## Defining dependency tracks via custom platforms
2741

28-
The basic trick to make `:common` pick the appropriate `@pypi_<name>` is to use
29-
`select()` to choose one based on build flags. To help this process, `py_binary`
30-
et al allow forcing particular build flags to be used, and custom flags can be
31-
registered to allow `py_binary` et al to set them.
42+
The solution involves defining custom "platforms" mapped to separate
43+
dependency tracks inside `MODULE.bazel`. Using custom platforms via
44+
{obj}`pip.default` and associating requirements files to them through the
45+
`requirements_by_platform` attribute on {obj}`pip.parse` instructs
46+
`rules_python` to generate `select()` logic behind a unified hub.
3247

33-
In this example, we create a custom string flag named `//:pypi_hub`,
34-
register it to allow using it with `py_binary` directly, then use `select()`
35-
to pick different dependencies.
48+
Binaries configure their execution requirements by forcing flag transition
49+
attributes using custom build setting flags.
3650

37-
```bzl
51+
In this example, we define custom string flag named `//:pypi_hub`, setup
52+
distinct custom platforms for `"alpha"` and `"beta"` profiles, and register
53+
associated requirements lock files grouped inside the `@pypi` hub.
54+
55+
```starlark
3856
# File: MODULE.bazel
3957

58+
rules_python_config = use_extension(
59+
"@rules_python//python/extensions:config.bzl",
60+
"config",
61+
)
4062
rules_python_config.add_transition_setting(
4163
setting = "//:pypi_hub",
4264
)
4365

66+
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
67+
68+
pip.default(
69+
platform = "alpha",
70+
config_settings = ["@//:is_pypi_alpha"],
71+
)
72+
73+
pip.default(
74+
platform = "beta",
75+
config_settings = ["@//:is_pypi_beta"],
76+
)
77+
78+
pip.parse(
79+
hub_name = "pypi",
80+
python_version = "3.14",
81+
requirements_by_platform = {
82+
"//:requirements_alpha.txt": "alpha",
83+
"//:requirements_beta.txt": "beta",
84+
},
85+
)
86+
87+
use_repo(pip, "pypi")
88+
```
89+
90+
```starlark
4491
# File: BUILD.bazel
4592

4693
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
4794

4895
string_flag(
4996
name = "pypi_hub",
97+
build_setting_default = "none",
5098
)
5199

52100
config_setting(
@@ -56,7 +104,7 @@ config_setting(
56104

57105
config_setting(
58106
name = "is_pypi_beta",
59-
flag_values = {"//:pypi_hub": "beta"}
107+
flag_values = {"//:pypi_hub": "beta"},
60108
)
61109

62110
py_binary(
@@ -65,26 +113,32 @@ py_binary(
65113
config_settings = {
66114
"//:pypi_hub": "alpha",
67115
},
68-
deps = ["@pypi_alpha//requests", ":common"],
116+
deps = [
117+
"@pypi//requests",
118+
":common",
119+
],
69120
)
121+
70122
py_binary(
71123
name = "bin_beta",
72124
srcs = ["bin_beta.py"],
73125
config_settings = {
74126
"//:pypi_hub": "beta",
75127
},
76-
deps = ["@pypi_beta//requests", ":common"],
128+
deps = [
129+
"@pypi//requests",
130+
":common",
131+
],
77132
)
133+
78134
py_library(
79135
name = "common",
80-
deps = select({
81-
":is_pypi_alpha": ["@pypi_alpha//more_itertools"],
82-
":is_pypi_beta": ["@pypi_beta//more_itertools"],
83-
}),
136+
deps = ["@pypi//more_itertools"],
84137
)
85138
```
86139

87-
When `bin_alpha` and `bin_beta` are built, they will have the `pypi_hub`
88-
flag force to their respective value. When `:common` is evaluated, it sees
89-
the flag value of the binary that is consuming it, and the `select()` resolves
90-
appropriately.
140+
When building `bin_alpha` or `bin_beta`, they set `//:pypi_hub` via target
141+
transitions. The generated aliased dependencies inside the `@pypi` hub will
142+
evaluate that Bazel configuration, automatically delivering corresponding
143+
Python wheels from targeted lock files.
144+

0 commit comments

Comments
 (0)