blob: 202349116adf83d89199d7f6d1bf60c9305b6f62 [file] [log] [blame] [view] [edit]
# rules_uv
Bazel rules to enable use of [uv](https://github.com/astral-sh/uv) to compile pip requirements and generate virtual envs.
## Usage
Installing with bzlmod, add to MODULE.bazel (adjust version as appropriate):
```starlark
bazel_dep(name = "rules_uv", version = "<version>")
```
**Note**: rules_uv requires a Python toolchain to be available. One can be obtained by having [rules_python](https://github.com/bazelbuild/rules_python) installed using:
```starlark
bazel_dep(name = "rules_python", version = "<rules_python version>")
```
### pip_compile
Create a requirements.in or pyproject.toml -> requirements.txt compilation target and diff test:
```starlark
load("@rules_uv//uv:pip.bzl", "pip_compile")
pip_compile(
name = "generate_requirements_txt",
requirements_in = "//:requirements.in", # default
requirements_txt = "//:requirements.txt", # default
)
```
Ensure both requirements.in and requirements.txt exist (the latter must exist but may be empty).
Run the compilation step with `bazel run //:generate_requirements_txt`.
This will automatically register a diff test with name `[name]_test`.
Additionally, you can specify the following optional args:
- `python_platform`: the `uv pip compile` compatible `--python-platform` value to pass to uv
- `args`: override the default arguments passed to uv (`--generate-hashes`, `--emit-index-url` and `--no-strip-extras`)
- `data`: pass additional files to be present when generating and testing requirements txt files (see also [examples/multiple-inputs](examples/multiple-inputs/))
- `tags`: tags to apply to the test target
- `target_compatible_with`: restrict targets to running on the specified Bazel platform
- `requirements_overrides`: a label for the file that is used to override dependencies (passed to uv via `--overrides`)
### create_venv
Create a virtual environment creation target:
```starlark
load("@rules_uv//uv:venv.bzl", "create_venv")
create_venv(
name = "create_venv",
requirements_txt = "//:requirements.txt", # default
)
```
Create a virtual environment with default path `venv` by running `bazel run //:create_venv`. The generated script accepts a single, optional argument to define the virtual environment path.
The created venv will use the default Python 3 runtime defined in rules_python.
## Multi-platform setup
`uv` supports generating platform-specific requirements files, and `rules_uv` exposes this configuration, and a multi-platform setup might look like this:
```starlark
load("@rules_multirun//:defs.bzl", "multirun")
load("@rules_uv//uv:pip.bzl", "pip_compile")
load("@rules_uv//uv:venv.bzl", "create_venv")
pip_compile(
name = "generate_requirements_linux_txt",
python_platform = "x86_64-unknown-linux-gnu",
requirements_txt = "requirements_linux.txt",
)
pip_compile(
name = "generate_requirements_macos_txt",
python_platform = "aarch64-apple-darwin",
requirements_txt = "requirements_macos.txt",
)
multirun(
name = "generate_requirements_lock",
commands = [
":generate_requirements_linux_txt",
":generate_requirements_macos_txt",
],
# Running in a single threaded mode allows consecutive `uv` invocations to benefit
# from the `uv` cache from the first run.
jobs = 1,
)
create_venv(
name = "create_venv",
requirements_txt = select({
"@platforms//os:linux": ":requirements_linux.txt",
"@platforms//os:osx": ":requirements_macos.txt",
}),
)
```
This makes use of the excellent [rules_multirun](https://github.com/keith/rules_multirun).
To match up with `rules_python`, a bzlmod config will look something like:
```starlark
pip.parse(
hub_name = "pip",
python_version = "3.11",
requirements_darwin = "//:requirements_macos.txt",
requirements_linux = "//:requirements_linux.txt",
)
```