You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(pip_repository): Support pip parse cycles (#1166)
This patch reworks the `pip_repository` machinery to allow users to
manually annotate groups of libraries which form packaging cycles in
PyPi and must be simultaneously installed.
The strategy here is to transform any dependencies `A` and `B` which
have dependencies and are mutually dependent
```mermaid
graph LR;
A-->B;
A-->D;
A-->E;
B-->A;
B-->F;
B-->G;
```
into a new "dependency group" `C` which has `A*` and `B*` as
dependencies, defined as `A` and `B` less any direct dependencies which
are members of the group. This is viable _for python_ because Python
files just need to be emplaced into a runfiles directory for the
interpreter. We don't actually have a true hard dependency between the
build definition of `A` requiring the build product `B` be available
which requires that the build product of `A` be available.
```mermaid
graph LR
C-->A*;
A*-->D;
A*-->E;
C-->B*;
B*-->F;
B*-->G;
```
This gets us most of the way there, as a user can now safely write
`requirement("A")` and we can provide them with `C`, which has the
desired effect of pulling in `A`, `B` and their respective transitives.
There is one remaining problem - a user writing `deps =
[requirement("A"), requirement("B")]` will take a double direct
dependency on `C`. So we need to insert a layer of indirection,
generating `C_A` and `C_B` which serve only as unique aliases for `C` so
that we can support the double dependency. Our final dependency graph
then is as follows
```mermaid
graph LR
C_A-->C;
C_B-->C;
C-->A*;
A*-->D;
A*-->E;
C-->B*;
B*-->F;
B*-->G;
```
Addresses #1076, #1188
## To do
- [x] Get rebased
- [x] Get re-validated manually
- [x] Buildifier
- [x] Get CI happy
- [x] Update documentation
- [x] Update changelog
---------
Co-authored-by: Ignas Anikevicius <240938+aignas@users.noreply.github.com>
Copy file name to clipboardExpand all lines: docs/sphinx/pypi-dependencies.md
+80Lines changed: 80 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -130,6 +130,86 @@ Any 'extras' specified in the requirements lock file will be automatically added
130
130
as transitive dependencies of the package. In the example above, you'd just put
131
131
`requirement("useful_dep")`.
132
132
133
+
### Packaging cycles
134
+
135
+
Sometimes PyPi packages contain dependency cycles -- for instance `sphinx`
136
+
depends on `sphinxcontrib-serializinghtml`. When using them as `requirement()`s,
137
+
ala
138
+
139
+
```
140
+
py_binary(
141
+
name = "doctool",
142
+
...
143
+
deps = [
144
+
requirement("sphinx"),
145
+
]
146
+
)
147
+
```
148
+
149
+
Bazel will protest because it doesn't support cycles in the build graph --
150
+
151
+
```
152
+
ERROR: .../external/pypi_sphinxcontrib_serializinghtml/BUILD.bazel:44:6: in alias rule @pypi_sphinxcontrib_serializinghtml//:pkg: cycle in dependency graph:
0 commit comments