Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bzlmod): cross-platform builds without experimental_index_url #2325

Merged
merged 42 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
4eb639e
feat: reuse the render_pkg_aliases for when filename is not known but…
aignas Oct 22, 2024
ab8b2f0
feat: support generating the extra config settings required
aignas Oct 22, 2024
645885c
feat: get_whl_flag_versions now generates extra args for the rules
aignas Oct 22, 2024
1d33f49
feat: make lock file generation the same irrespective of the host pla…
aignas Oct 22, 2024
9544386
test: add an extra test with multiple requirements files
aignas Oct 22, 2024
b81f86e
doc: CHANGELOG
aignas Oct 22, 2024
9b296d2
bring back code used in workspace
aignas Oct 22, 2024
77754c2
fixup the generation of the config settings
aignas Oct 22, 2024
d9a0d3b
Update python/private/pypi/extension.bzl
aignas Oct 22, 2024
fdfa1de
wip
aignas Oct 22, 2024
f7051ab
wip
aignas Oct 22, 2024
0c058a1
Update CHANGELOG.md
aignas Oct 22, 2024
e5b0190
test: check that parse_requirements handles multiple files with downl…
aignas Oct 23, 2024
0400154
ensure that we can support multi-platform setups with the legacy pip
aignas Oct 23, 2024
c75039d
fix: make the names of the repos more user friendly
aignas Oct 23, 2024
bf4f644
revert docs about cross-platform building
aignas Oct 23, 2024
4de5a45
Revert "revert docs about cross-platform building"
aignas Oct 23, 2024
0d468df
fix the docs to fully document what is possible today
aignas Oct 23, 2024
8d418f4
adjust the code so that the experimental_target_platforms is set in d…
aignas Oct 23, 2024
cfcc8c5
Merge branch 'main' into fix/lockfile-inconsistency
aignas Oct 23, 2024
cf76913
wip
aignas Oct 23, 2024
ecf5a5b
Merge branch 'main' into fix/lockfile-inconsistency
aignas Oct 23, 2024
c4fceb9
fixup test
aignas Oct 23, 2024
9482a13
fixup test
aignas Oct 23, 2024
a520e29
Merge branch 'main' into fix/lockfile-inconsistency
aignas Oct 26, 2024
8578b02
merge conflicts
aignas Oct 26, 2024
de98a02
fix integration tests
aignas Oct 26, 2024
5025f90
Merge branch 'main' into fix/lockfile-inconsistency
aignas Nov 1, 2024
e90d257
fixup! Merge branch 'main' into fix/lockfile-inconsistency
aignas Nov 1, 2024
8835d02
use a different scheme inspired by #2366
aignas Nov 1, 2024
e2c07ae
one more try
aignas Nov 1, 2024
74383f3
fix the tests
aignas Nov 1, 2024
4120c15
simplify
aignas Nov 2, 2024
b4dad40
Merge branch 'main' into fix/lockfile-inconsistency
aignas Nov 3, 2024
7582d5b
revert: start making the change in behaviour opt in
aignas Nov 3, 2024
e5d2ff4
add a flag to use all requirements to make the extension lock file en…
aignas Nov 4, 2024
5c45b4a
fixup! add a flag to use all requirements to make the extension lock …
aignas Nov 4, 2024
58e7a6c
fixup! fixup! add a flag to use all requirements to make the extensio…
aignas Nov 4, 2024
c0fe195
fixup tests
aignas Nov 4, 2024
1ffb52c
wip
aignas Nov 4, 2024
b7577ff
Merge branch 'main' into fix/lockfile-inconsistency
aignas Nov 5, 2024
a2b8b52
wip
aignas Nov 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ A brief description of the categories of changes:
[`pip.parse#extra_pip_args`](https://rules-python.readthedocs.io/en/latest/api/rules_python/python/extensions/pip.html#pip.parse.extra_pip_args)
* (pip.parse) {attr}`pip.parse.whl_modifications` now normalizes the given whl names
and now `pyyaml` and `PyYAML` will both work.
* (bzlmod) `pip.parse` spoke repository naming will be changed in an upcoming
release in places where the users specify different package versions per
platform in the same hub repository. The naming of the spoke repos is considered
an implementation detail and we advise the users to use the `hub` repository
directly to avoid such breakage in the future. If `rules_python` is missing
features to allow one to do that, please raise tickets.

{#v0-0-0-fixed}
### Fixed
Expand All @@ -51,6 +57,12 @@ A brief description of the categories of changes:
pass the `extra_pip_args` value when building an `sdist`.
* (pypi) The patched wheel filenames from now on are using local version specifiers
which fixes usage of the said wheels using standard package managers.
* (bzlmod) The extension evaluation has been adjusted to always generate the
same lock file irrespective if `experimental_index_url` is set by any module
or not. Fixes
[#2268](https://github.com/bazelbuild/rules_python/issues/2268). A known
issue is that it may break `bazel query` and in these use cases it is
advisable to use `cquery` or switch to `download_only = True`

{#v0-0-0-added}
### Added
Expand All @@ -63,6 +75,11 @@ A brief description of the categories of changes:
* (pip.parse) {attr}`pip.parse.extra_hub_aliases` can now be used to expose extra
targets created by annotations in whl repositories.
Fixes [#2187](https://github.com/bazelbuild/rules_python/issues/2187).
* (bzlmod) `pip.parse` now supports `whl-only` setup using
`download_only = True` where users can specify multiple requirements files
and use the `pip` backend to do the downloading. This was only available for
users setting {bzl:obj}`pip.parse.experimental_index_url`, but now users have
more options whilst we continue to work on stabilizing the experimental feature.

{#v0-0-0-removed}
### Removed
Expand Down
13 changes: 10 additions & 3 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ register_toolchains("@pythons_hub//:all")

pip = use_extension("//python/private/pypi:pip.bzl", "pip_internal")
pip.parse(
# NOTE @aignas 2024-10-26: We have an integration test that depends on us
# being able to build sdists for this hub, so explicitly set this to False.
download_only = False,
experimental_index_url = "https://pypi.org/simple",
hub_name = "rules_python_publish_deps",
python_version = "3.11",
requirements_by_platform = {
Expand Down Expand Up @@ -90,17 +94,20 @@ dev_python.override(
)

dev_pip = use_extension(
"//python/private/pypi:pip.bzl",
"pip_internal",
"//python/extensions:pip.bzl",
"pip",
dev_dependency = True,
)
dev_pip.parse(
download_only = True, # this will not add the `sdist` values to the transitive closures at all.
download_only = True,
experimental_index_url = "https://pypi.org/simple",
hub_name = "dev_pip",
python_version = "3.11",
requirements_lock = "//docs:requirements.txt",
)
dev_pip.parse(
download_only = True,
experimental_index_url = "https://pypi.org/simple",
hub_name = "pypiserver",
python_version = "3.11",
requirements_lock = "//examples/wheel:requirements_server.txt",
Expand Down
53 changes: 53 additions & 0 deletions docs/pypi-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,59 @@ leg of the dependency manually. For instance by making
perhaps `apache-airflow-providers-common-sql`.


(bazel-downloader)=
### Multi-platform support

Multi-platform support of cross-building the wheels can be done in two ways - either
using {bzl:attr}`experimental_index_url` for the {bzl:obj}`pip.parse` bzlmod tag class
or by using the {bzl:attr}`pip.parse.download_only` setting. In this section we
are going to outline quickly how one can use the latter option.

Let's say you have 2 requirements files:
```
# requirements.linux_x86_64.txt
--platform=manylinux_2_17_x86_64
--python-version=39
--implementation=cp
--abi=cp39

foo==0.0.1 --hash=sha256:deadbeef
bar==0.0.1 --hash=sha256:deadb00f
```

```
# requirements.osx_aarch64.txt contents
--platform=macosx_10_9_arm64
--python-version=39
--implementation=cp
--abi=cp39

foo==0.0.3 --hash=sha256:deadbaaf
```

With these 2 files your {bzl:obj}`pip.parse` could look like:
```
pip.parse(
hub_name = "pip",
python_version = "3.9",
# Tell `pip` to ignore sdists
download_only = True,
requirements_by_platform = {
"requirements.linux_x86_64.txt": "linux_x86_64",
"requirements.osx_aarch64.txt": "osx_aarch64",
},
)
```

With this, the `pip.parse` will create a hub repository that is going to
support only two platforms - `cp39_osx_aarch64` and `cp39_linux_x86_64` and it
will only use `wheels` and ignore any sdists that it may find on the PyPI
compatible indexes.

```{note}
This is only supported on `bzlmd`.
```

(bazel-downloader)=
### Bazel downloader and multi-platform wheel hub repository.

Expand Down
3 changes: 3 additions & 0 deletions examples/bzlmod/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,9 @@ pip.parse(
"host",
],
hub_name = "pip",
# Parse all requirements files for the same lock file on all OSes, this will
# become the default with 1.0 release
parse_all_requirements_files = True,
python_version = "3.10",
# The requirements files for each platform that we want to support.
requirements_by_platform = {
Expand Down
8 changes: 4 additions & 4 deletions examples/bzlmod/MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion python/private/pypi/config_settings.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ def config_settings(
)

def _dist_config_settings(*, suffix, plat_flag_values, **kwargs):
if kwargs.get("constraint_values"):
# Add python version + platform config settings
_dist_config_setting(
name = suffix.strip("_"),
**kwargs
)

flag_values = {_flags.dist: ""}

# First create an sdist, we will be building upon the flag values, which
Expand Down Expand Up @@ -277,7 +284,7 @@ def _plat_flag_values(os, cpu, osx_versions, glibc_versions, muslc_versions):

return ret

def _dist_config_setting(*, name, is_pip_whl, is_python, python_version, native = native, **kwargs):
def _dist_config_setting(*, name, is_python, python_version, is_pip_whl = None, native = native, **kwargs):
"""A macro to create a target that matches is_pip_whl_auto and one more value.

Args:
Expand Down Expand Up @@ -310,6 +317,10 @@ def _dist_config_setting(*, name, is_pip_whl, is_python, python_version, native
# `python_version` setting.
return

if not is_pip_whl:
native.config_setting(name = _name, **kwargs)
return

config_setting_name = _name + "_setting"
native.config_setting(name = config_setting_name, **kwargs)

Expand Down
Loading