diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index 1a73e6347..3f9274bf1 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -4770,7 +4770,13 @@ pub struct BuildOptionsArgs { /// /// The given packages will be built and installed from source. The resolver will still use /// pre-built wheels to extract package metadata, if available. - #[arg(long, overrides_with("binary"), help_heading = "Build options")] + #[arg( + long, + env = EnvVars::UV_NO_BINARY, + overrides_with("binary"), + value_parser = clap::builder::BoolishValueParser::new(), + help_heading = "Build options" + )] pub no_binary: bool, #[arg( @@ -4782,7 +4788,7 @@ pub struct BuildOptionsArgs { pub binary: bool, /// Don't install pre-built wheels for a specific package. - #[arg(long, help_heading = "Build options")] + #[arg(long, help_heading = "Build options", env = EnvVars::UV_NO_BINARY_PACKAGE, value_delimiter = ' ')] pub no_binary_package: Vec, } diff --git a/crates/uv-static/src/env_vars.rs b/crates/uv-static/src/env_vars.rs index aa35eb162..36085c828 100644 --- a/crates/uv-static/src/env_vars.rs +++ b/crates/uv-static/src/env_vars.rs @@ -142,6 +142,15 @@ impl EnvVars { /// will compile Python source files to bytecode after installation. pub const UV_COMPILE_BYTECODE: &'static str = "UV_COMPILE_BYTECODE"; + /// Equivalent to the `--no-binary` command-line argument. If set, uv will install + /// all packages from source. The resolver will still use pre-built wheels to + /// extract package metadata, if available. + pub const UV_NO_BINARY: &'static str = "UV_NO_BINARY"; + + /// Equivalent to the `--no-binary-package` command line argument. If set, uv will + /// not use pre-built wheels for the given space-delimited list of packages. + pub const UV_NO_BINARY_PACKAGE: &'static str = "UV_NO_BINARY_PACKAGE"; + /// Equivalent to the `--publish-url` command-line argument. The URL of the upload /// endpoint of the index to use with `uv publish`. pub const UV_PUBLISH_URL: &'static str = "UV_PUBLISH_URL"; diff --git a/crates/uv/tests/it/pip_install.rs b/crates/uv/tests/it/pip_install.rs index e898db13e..af4c3a753 100644 --- a/crates/uv/tests/it/pip_install.rs +++ b/crates/uv/tests/it/pip_install.rs @@ -2279,6 +2279,83 @@ fn install_no_binary_overrides_only_binary_all() { context.assert_command("import anyio").success(); } +/// Disable binaries with an environment variable +/// TODO(zanieb): This is not yet implemented +#[test] +fn install_no_binary_env() { + let context = TestContext::new("3.12"); + + let mut command = context.pip_install(); + command.arg("anyio").env("UV_NO_BINARY", "1"); + uv_snapshot!( + command, + @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 3 packages in [TIME] + Prepared 3 packages in [TIME] + Installed 3 packages in [TIME] + + anyio==4.3.0 + + idna==3.6 + + sniffio==1.3.1 + "### + ); + + let mut command = context.pip_install(); + command + .arg("anyio") + .arg("--reinstall") + .env("UV_NO_BINARY", "anyio"); + uv_snapshot!( + command, + @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 3 packages in [TIME] + Prepared 3 packages in [TIME] + Uninstalled 3 packages in [TIME] + Installed 3 packages in [TIME] + ~ anyio==4.3.0 + ~ idna==3.6 + ~ sniffio==1.3.1 + "### + ); + + context.assert_command("import anyio").success(); + + let mut command = context.pip_install(); + command + .arg("anyio") + .arg("--reinstall") + .arg("idna") + .env("UV_NO_BINARY_PACKAGE", "idna"); + uv_snapshot!( + command, + @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 3 packages in [TIME] + Prepared 3 packages in [TIME] + Uninstalled 3 packages in [TIME] + Installed 3 packages in [TIME] + ~ anyio==4.3.0 + ~ idna==3.6 + ~ sniffio==1.3.1 + "### + ); + + context.assert_command("import idna").success(); +} + /// Overlapping usage of `--no-binary` and `--only-binary` #[test] fn install_only_binary_overrides_no_binary_all() { diff --git a/crates/uv/tests/it/sync.rs b/crates/uv/tests/it/sync.rs index 5bc88fc30..008a54c64 100644 --- a/crates/uv/tests/it/sync.rs +++ b/crates/uv/tests/it/sync.rs @@ -3963,6 +3963,56 @@ fn no_binary() -> Result<()> { assert!(context.temp_dir.child("uv.lock").exists()); + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").arg("--no-binary"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 2 packages in [TIME] + Prepared 1 package in [TIME] + Uninstalled 1 package in [TIME] + Installed 1 package in [TIME] + ~ iniconfig==2.0.0 + "###); + + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BINARY_PACKAGE", "iniconfig"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 2 packages in [TIME] + Prepared 1 package in [TIME] + Uninstalled 1 package in [TIME] + Installed 1 package in [TIME] + ~ iniconfig==2.0.0 + "###); + + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BINARY", "1"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 2 packages in [TIME] + Prepared 1 package in [TIME] + Uninstalled 1 package in [TIME] + Installed 1 package in [TIME] + ~ iniconfig==2.0.0 + "###); + + uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BINARY", "iniconfig"), @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + error: invalid value 'iniconfig' for '--no-binary': value was not a boolean + + For more information, try '--help'. + "###); + Ok(()) } diff --git a/docs/configuration/environment.md b/docs/configuration/environment.md index 46cd28950..a64fb48e0 100644 --- a/docs/configuration/environment.md +++ b/docs/configuration/environment.md @@ -178,6 +178,17 @@ Equivalent to the `--locked` command-line argument. If set, uv will assert that Equivalent to the `--native-tls` command-line argument. If set to `true`, uv will use the system's trust store instead of the bundled `webpki-roots` crate. +### `UV_NO_BINARY` + +Equivalent to the `--no-binary` command-line argument. If set, uv will install +all packages from source. The resolver will still use pre-built wheels to +extract package metadata, if available. + +### `UV_NO_BINARY_PACKAGE` + +Equivalent to the `--no-binary-package` command line argument. If set, uv will +not use pre-built wheels for the given space-delimited list of packages. + ### `UV_NO_BUILD_ISOLATION` Equivalent to the `--no-build-isolation` command-line argument. If set, uv will diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 18f2fb04b..46af8841b 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -299,8 +299,10 @@ uv run [OPTIONS] [COMMAND]

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.

@@ -958,8 +960,10 @@ uv add [OPTIONS] >

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.

@@ -1319,8 +1323,10 @@ uv remove [OPTIONS] ...

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.

@@ -1692,8 +1698,10 @@ uv sync [OPTIONS]

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.

@@ -2059,8 +2067,10 @@ uv lock [OPTIONS]

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.

@@ -2404,8 +2414,10 @@ uv export [OPTIONS]

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.

@@ -2782,8 +2794,10 @@ uv tree [OPTIONS]

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.

@@ -3255,8 +3269,10 @@ uv tool run [OPTIONS] [COMMAND]

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.

@@ -3584,8 +3600,10 @@ uv tool install [OPTIONS]

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.

@@ -3907,8 +3925,10 @@ uv tool upgrade [OPTIONS] ...

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.

@@ -8349,8 +8369,10 @@ uv build [OPTIONS] [SRC]

The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.

+

May also be set with the UV_NO_BINARY environment variable.

--no-binary-package no-binary-package

Don’t install pre-built wheels for a specific package

+

May also be set with the UV_NO_BINARY_PACKAGE environment variable.

--no-build

Don’t build source distributions.

When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.