mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-23 12:56:47 +00:00
Use a global flags instance for wheel check (#16047)
Some checks failed
CI / Determine changes (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / cargo shear (push) Has been cancelled
CI / typos (push) Has been cancelled
CI / mkdocs (push) Has been cancelled
zizmor / Run zizmor (push) Has been cancelled
CI / cargo clippy | ubuntu (push) Has been cancelled
CI / cargo clippy | windows (push) Has been cancelled
CI / cargo dev generate-all (push) Has been cancelled
CI / cargo test | ubuntu (push) Has been cancelled
CI / cargo test | macos (push) Has been cancelled
CI / cargo test | windows (push) Has been cancelled
CI / check windows trampoline | aarch64 (push) Has been cancelled
CI / check windows trampoline | i686 (push) Has been cancelled
CI / check windows trampoline | x86_64 (push) Has been cancelled
CI / test windows trampoline | aarch64 (push) Has been cancelled
CI / test windows trampoline | i686 (push) Has been cancelled
CI / test windows trampoline | x86_64 (push) Has been cancelled
CI / build binary | linux libc (push) Has been cancelled
CI / build binary | linux aarch64 (push) Has been cancelled
CI / build binary | linux musl (push) Has been cancelled
CI / build binary | macos aarch64 (push) Has been cancelled
CI / build binary | macos x86_64 (push) Has been cancelled
CI / build binary | windows x86_64 (push) Has been cancelled
CI / build binary | windows aarch64 (push) Has been cancelled
CI / build binary | msrv (push) Has been cancelled
CI / build binary | freebsd (push) Has been cancelled
CI / ecosystem test | pydantic/pydantic-core (push) Has been cancelled
CI / ecosystem test | prefecthq/prefect (push) Has been cancelled
CI / ecosystem test | pallets/flask (push) Has been cancelled
CI / smoke test | linux (push) Has been cancelled
CI / smoke test | linux aarch64 (push) Has been cancelled
CI / check system | alpine (push) Has been cancelled
CI / smoke test | macos (push) Has been cancelled
CI / smoke test | windows x86_64 (push) Has been cancelled
CI / smoke test | windows aarch64 (push) Has been cancelled
CI / integration test | activate nushell venv (push) Has been cancelled
CI / integration test | conda on ubuntu (push) Has been cancelled
CI / integration test | deadsnakes python3.9 on ubuntu (push) Has been cancelled
CI / integration test | free-threaded on windows (push) Has been cancelled
CI / integration test | aarch64 windows implicit (push) Has been cancelled
CI / integration test | aarch64 windows explicit (push) Has been cancelled
CI / integration test | pypy on ubuntu (push) Has been cancelled
CI / integration test | pypy on windows (push) Has been cancelled
CI / integration test | graalpy on ubuntu (push) Has been cancelled
CI / integration test | graalpy on windows (push) Has been cancelled
CI / integration test | pyodide on ubuntu (push) Has been cancelled
CI / integration test | github actions (push) Has been cancelled
CI / integration test | free-threaded python on github actions (push) Has been cancelled
CI / integration test | pyenv on wsl x86-64 (push) Has been cancelled
CI / integration test | determine publish changes (push) Has been cancelled
CI / integration test | registries (push) Has been cancelled
CI / integration test | uv publish (push) Has been cancelled
CI / integration test | uv_build (push) Has been cancelled
CI / check cache | ubuntu (push) Has been cancelled
CI / check cache | macos aarch64 (push) Has been cancelled
CI / check system | python on debian (push) Has been cancelled
CI / check system | python on fedora (push) Has been cancelled
CI / check system | python on ubuntu (push) Has been cancelled
CI / check system | python on rocky linux 8 (push) Has been cancelled
CI / check system | python on rocky linux 9 (push) Has been cancelled
CI / check system | graalpy on ubuntu (push) Has been cancelled
CI / check system | pypy on ubuntu (push) Has been cancelled
CI / check system | pyston (push) Has been cancelled
CI / check system | python on macos aarch64 (push) Has been cancelled
CI / check system | homebrew python on macos aarch64 (push) Has been cancelled
CI / check system | x86-64 python on macos aarch64 (push) Has been cancelled
CI / check system | python on macos x86-64 (push) Has been cancelled
CI / check system | python3.10 on windows x86-64 (push) Has been cancelled
CI / check system | python3.10 on windows x86 (push) Has been cancelled
CI / check system | python3.13 on windows x86-64 (push) Has been cancelled
CI / check system | x86-64 python3.13 on windows aarch64 (push) Has been cancelled
CI / check system | aarch64 python3.13 on windows aarch64 (push) Has been cancelled
CI / check system | windows registry (push) Has been cancelled
CI / check system | python3.12 via chocolatey (push) Has been cancelled
CI / check system | python3.9 via pyenv (push) Has been cancelled
CI / check system | python3.13 (push) Has been cancelled
CI / check system | conda3.11 on macos aarch64 (push) Has been cancelled
CI / check system | conda3.8 on macos aarch64 (push) Has been cancelled
CI / check system | conda3.11 on linux x86-64 (push) Has been cancelled
CI / check system | conda3.8 on linux x86-64 (push) Has been cancelled
CI / check system | conda3.11 on windows x86-64 (push) Has been cancelled
CI / check system | conda3.8 on windows x86-64 (push) Has been cancelled
CI / check system | amazonlinux (push) Has been cancelled
CI / check system | embedded python3.10 on windows x86-64 (push) Has been cancelled
CI / benchmarks | walltime aarch64 linux (push) Has been cancelled
CI / benchmarks | instrumented (push) Has been cancelled
Some checks failed
CI / Determine changes (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / cargo shear (push) Has been cancelled
CI / typos (push) Has been cancelled
CI / mkdocs (push) Has been cancelled
zizmor / Run zizmor (push) Has been cancelled
CI / cargo clippy | ubuntu (push) Has been cancelled
CI / cargo clippy | windows (push) Has been cancelled
CI / cargo dev generate-all (push) Has been cancelled
CI / cargo test | ubuntu (push) Has been cancelled
CI / cargo test | macos (push) Has been cancelled
CI / cargo test | windows (push) Has been cancelled
CI / check windows trampoline | aarch64 (push) Has been cancelled
CI / check windows trampoline | i686 (push) Has been cancelled
CI / check windows trampoline | x86_64 (push) Has been cancelled
CI / test windows trampoline | aarch64 (push) Has been cancelled
CI / test windows trampoline | i686 (push) Has been cancelled
CI / test windows trampoline | x86_64 (push) Has been cancelled
CI / build binary | linux libc (push) Has been cancelled
CI / build binary | linux aarch64 (push) Has been cancelled
CI / build binary | linux musl (push) Has been cancelled
CI / build binary | macos aarch64 (push) Has been cancelled
CI / build binary | macos x86_64 (push) Has been cancelled
CI / build binary | windows x86_64 (push) Has been cancelled
CI / build binary | windows aarch64 (push) Has been cancelled
CI / build binary | msrv (push) Has been cancelled
CI / build binary | freebsd (push) Has been cancelled
CI / ecosystem test | pydantic/pydantic-core (push) Has been cancelled
CI / ecosystem test | prefecthq/prefect (push) Has been cancelled
CI / ecosystem test | pallets/flask (push) Has been cancelled
CI / smoke test | linux (push) Has been cancelled
CI / smoke test | linux aarch64 (push) Has been cancelled
CI / check system | alpine (push) Has been cancelled
CI / smoke test | macos (push) Has been cancelled
CI / smoke test | windows x86_64 (push) Has been cancelled
CI / smoke test | windows aarch64 (push) Has been cancelled
CI / integration test | activate nushell venv (push) Has been cancelled
CI / integration test | conda on ubuntu (push) Has been cancelled
CI / integration test | deadsnakes python3.9 on ubuntu (push) Has been cancelled
CI / integration test | free-threaded on windows (push) Has been cancelled
CI / integration test | aarch64 windows implicit (push) Has been cancelled
CI / integration test | aarch64 windows explicit (push) Has been cancelled
CI / integration test | pypy on ubuntu (push) Has been cancelled
CI / integration test | pypy on windows (push) Has been cancelled
CI / integration test | graalpy on ubuntu (push) Has been cancelled
CI / integration test | graalpy on windows (push) Has been cancelled
CI / integration test | pyodide on ubuntu (push) Has been cancelled
CI / integration test | github actions (push) Has been cancelled
CI / integration test | free-threaded python on github actions (push) Has been cancelled
CI / integration test | pyenv on wsl x86-64 (push) Has been cancelled
CI / integration test | determine publish changes (push) Has been cancelled
CI / integration test | registries (push) Has been cancelled
CI / integration test | uv publish (push) Has been cancelled
CI / integration test | uv_build (push) Has been cancelled
CI / check cache | ubuntu (push) Has been cancelled
CI / check cache | macos aarch64 (push) Has been cancelled
CI / check system | python on debian (push) Has been cancelled
CI / check system | python on fedora (push) Has been cancelled
CI / check system | python on ubuntu (push) Has been cancelled
CI / check system | python on rocky linux 8 (push) Has been cancelled
CI / check system | python on rocky linux 9 (push) Has been cancelled
CI / check system | graalpy on ubuntu (push) Has been cancelled
CI / check system | pypy on ubuntu (push) Has been cancelled
CI / check system | pyston (push) Has been cancelled
CI / check system | python on macos aarch64 (push) Has been cancelled
CI / check system | homebrew python on macos aarch64 (push) Has been cancelled
CI / check system | x86-64 python on macos aarch64 (push) Has been cancelled
CI / check system | python on macos x86-64 (push) Has been cancelled
CI / check system | python3.10 on windows x86-64 (push) Has been cancelled
CI / check system | python3.10 on windows x86 (push) Has been cancelled
CI / check system | python3.13 on windows x86-64 (push) Has been cancelled
CI / check system | x86-64 python3.13 on windows aarch64 (push) Has been cancelled
CI / check system | aarch64 python3.13 on windows aarch64 (push) Has been cancelled
CI / check system | windows registry (push) Has been cancelled
CI / check system | python3.12 via chocolatey (push) Has been cancelled
CI / check system | python3.9 via pyenv (push) Has been cancelled
CI / check system | python3.13 (push) Has been cancelled
CI / check system | conda3.11 on macos aarch64 (push) Has been cancelled
CI / check system | conda3.8 on macos aarch64 (push) Has been cancelled
CI / check system | conda3.11 on linux x86-64 (push) Has been cancelled
CI / check system | conda3.8 on linux x86-64 (push) Has been cancelled
CI / check system | conda3.11 on windows x86-64 (push) Has been cancelled
CI / check system | conda3.8 on windows x86-64 (push) Has been cancelled
CI / check system | amazonlinux (push) Has been cancelled
CI / check system | embedded python3.10 on windows x86-64 (push) Has been cancelled
CI / benchmarks | walltime aarch64 linux (push) Has been cancelled
CI / benchmarks | instrumented (push) Has been cancelled
## Summary This stands up the idea proposed in https://github.com/astral-sh/uv/pull/16046/files#r2384395797.
This commit is contained in:
parent
7d9ea797b0
commit
ab2f394019
13 changed files with 179 additions and 114 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
|
@ -5351,6 +5351,7 @@ dependencies = [
|
|||
"uv-distribution-filename",
|
||||
"uv-distribution-types",
|
||||
"uv-extract",
|
||||
"uv-flags",
|
||||
"uv-fs",
|
||||
"uv-git",
|
||||
"uv-git-types",
|
||||
|
|
@ -5982,6 +5983,13 @@ dependencies = [
|
|||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uv-flags"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uv-fs"
|
||||
version = "0.0.1"
|
||||
|
|
@ -6085,13 +6093,13 @@ dependencies = [
|
|||
"thiserror 2.0.16",
|
||||
"tracing",
|
||||
"uv-distribution-filename",
|
||||
"uv-flags",
|
||||
"uv-fs",
|
||||
"uv-normalize",
|
||||
"uv-pep440",
|
||||
"uv-preview",
|
||||
"uv-pypi-types",
|
||||
"uv-shell",
|
||||
"uv-static",
|
||||
"uv-trampoline-builder",
|
||||
"uv-warnings",
|
||||
"walkdir",
|
||||
|
|
@ -6559,6 +6567,7 @@ dependencies = [
|
|||
"uv-distribution",
|
||||
"uv-distribution-filename",
|
||||
"uv-distribution-types",
|
||||
"uv-flags",
|
||||
"uv-fs",
|
||||
"uv-git",
|
||||
"uv-git-types",
|
||||
|
|
@ -6621,6 +6630,7 @@ dependencies = [
|
|||
"uv-configuration",
|
||||
"uv-dirs",
|
||||
"uv-distribution-types",
|
||||
"uv-flags",
|
||||
"uv-fs",
|
||||
"uv-install-wheel",
|
||||
"uv-macros",
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ uv-distribution = { path = "crates/uv-distribution" }
|
|||
uv-distribution-filename = { path = "crates/uv-distribution-filename" }
|
||||
uv-distribution-types = { path = "crates/uv-distribution-types" }
|
||||
uv-extract = { path = "crates/uv-extract" }
|
||||
uv-flags = { path = "crates/uv-flags" }
|
||||
uv-fs = { path = "crates/uv-fs", features = ["serde", "tokio"] }
|
||||
uv-git = { path = "crates/uv-git" }
|
||||
uv-git-types = { path = "crates/uv-git-types" }
|
||||
|
|
|
|||
24
crates/uv-flags/Cargo.toml
Normal file
24
crates/uv-flags/Cargo.toml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
[package]
|
||||
name = "uv-flags"
|
||||
version = "0.0.1"
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
documentation = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
bitflags = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
[features]
|
||||
default = []
|
||||
21
crates/uv-flags/src/lib.rs
Normal file
21
crates/uv-flags/src/lib.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
use std::sync::OnceLock;
|
||||
|
||||
static FLAGS: OnceLock<EnvironmentFlags> = OnceLock::new();
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub struct EnvironmentFlags: u32 {
|
||||
const SKIP_WHEEL_FILENAME_CHECK = 1 << 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the environment flags.
|
||||
#[allow(clippy::result_unit_err)]
|
||||
pub fn init(flags: EnvironmentFlags) -> Result<(), ()> {
|
||||
FLAGS.set(flags).map_err(|_| ())
|
||||
}
|
||||
|
||||
/// Check if a specific environment flag is set.
|
||||
pub fn contains(flag: EnvironmentFlags) -> bool {
|
||||
FLAGS.get_or_init(EnvironmentFlags::default).contains(flag)
|
||||
}
|
||||
|
|
@ -22,13 +22,13 @@ name = "uv_install_wheel"
|
|||
|
||||
[dependencies]
|
||||
uv-distribution-filename = { workspace = true }
|
||||
uv-flags = { workspace = true }
|
||||
uv-fs = { workspace = true }
|
||||
uv-normalize = { workspace = true }
|
||||
uv-pep440 = { workspace = true }
|
||||
uv-preview = { workspace = true }
|
||||
uv-pypi-types = { workspace = true }
|
||||
uv-shell = { workspace = true }
|
||||
uv-static = { workspace = true }
|
||||
uv-trampoline-builder = { workspace = true }
|
||||
uv-warnings = { workspace = true }
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ use tracing::{instrument, trace};
|
|||
use uv_distribution_filename::WheelFilename;
|
||||
use uv_pep440::Version;
|
||||
use uv_pypi_types::{DirectUrl, Metadata10};
|
||||
use uv_static::{EnvVars, parse_boolish_environment_variable};
|
||||
|
||||
use crate::linker::{LinkMode, Locks};
|
||||
use crate::wheel::{
|
||||
|
|
@ -49,25 +48,15 @@ pub fn install_wheel<Cache: serde::Serialize, Build: serde::Serialize>(
|
|||
let version = Version::from_str(&version)?;
|
||||
|
||||
// Validate the wheel name and version.
|
||||
{
|
||||
if !uv_flags::contains(uv_flags::EnvironmentFlags::SKIP_WHEEL_FILENAME_CHECK) {
|
||||
if name != filename.name {
|
||||
if !matches!(
|
||||
parse_boolish_environment_variable(EnvVars::UV_SKIP_WHEEL_FILENAME_CHECK),
|
||||
Ok(Some(true))
|
||||
) {
|
||||
return Err(Error::MismatchedName(name, filename.name.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
if version != filename.version && version != filename.version.clone().without_local() {
|
||||
if !matches!(
|
||||
parse_boolish_environment_variable(EnvVars::UV_SKIP_WHEEL_FILENAME_CHECK),
|
||||
Ok(Some(true))
|
||||
) {
|
||||
return Err(Error::MismatchedVersion(version, filename.version.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We're going step by step though
|
||||
// https://packaging.python.org/en/latest/specifications/binary-distribution-format/#installing-a-wheel-distribution-1-0-py32-none-any-whl
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ uv-configuration = { workspace = true }
|
|||
uv-distribution = { workspace = true }
|
||||
uv-distribution-filename = { workspace = true }
|
||||
uv-distribution-types = { workspace = true }
|
||||
uv-flags = { workspace = true }
|
||||
uv-fs = { workspace = true, features = ["serde"] }
|
||||
uv-git = { workspace = true }
|
||||
uv-git-types = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ use uv_pypi_types::{
|
|||
};
|
||||
use uv_redacted::DisplaySafeUrl;
|
||||
use uv_small_str::SmallString;
|
||||
use uv_static::{EnvVars, parse_boolish_environment_variable};
|
||||
use uv_types::{BuildContext, HashStrategy};
|
||||
use uv_workspace::{Editability, WorkspaceMember};
|
||||
|
||||
|
|
@ -3241,15 +3240,12 @@ impl PackageWire {
|
|||
unambiguous_package_ids: &FxHashMap<PackageName, PackageId>,
|
||||
) -> Result<Package, LockError> {
|
||||
// Consistency check
|
||||
if !uv_flags::contains(uv_flags::EnvironmentFlags::SKIP_WHEEL_FILENAME_CHECK) {
|
||||
if let Some(version) = &self.id.version {
|
||||
for wheel in &self.wheels {
|
||||
if *version != wheel.filename.version
|
||||
&& *version != wheel.filename.version.clone().without_local()
|
||||
{
|
||||
if !matches!(
|
||||
parse_boolish_environment_variable(EnvVars::UV_SKIP_WHEEL_FILENAME_CHECK),
|
||||
Ok(Some(true))
|
||||
) {
|
||||
return Err(LockError::from(LockErrorKind::InconsistentVersions {
|
||||
name: self.id.name,
|
||||
version: version.clone(),
|
||||
|
|
@ -3257,10 +3253,10 @@ impl PackageWire {
|
|||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
// We can't check the source dist version since it does not need to contain the version
|
||||
// in the filename.
|
||||
}
|
||||
}
|
||||
|
||||
let unwire_deps = |deps: Vec<DependencyWire>| -> Result<Vec<Dependency>, LockError> {
|
||||
deps.into_iter()
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ uv-cache-info = { workspace = true, features = ["schemars"] }
|
|||
uv-configuration = { workspace = true, features = ["schemars", "clap"] }
|
||||
uv-dirs = { workspace = true }
|
||||
uv-distribution-types = { workspace = true, features = ["schemars"] }
|
||||
uv-flags = { workspace = true }
|
||||
uv-fs = { workspace = true }
|
||||
uv-install-wheel = { workspace = true, features = ["schemars", "clap"] }
|
||||
uv-macros = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ use std::ops::Deref;
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use uv_dirs::{system_config_file, user_config_dir};
|
||||
use uv_flags::EnvironmentFlags;
|
||||
use uv_fs::Simplified;
|
||||
use uv_static::{EnvVars, parse_boolish_environment_variable, parse_string_environment_variable};
|
||||
use uv_static::EnvVars;
|
||||
use uv_warnings::warn_user;
|
||||
|
||||
pub use crate::combine::*;
|
||||
|
|
@ -554,8 +555,12 @@ pub enum Error {
|
|||
#[error("Failed to parse: `{}`. The `{}` field is not allowed in a `uv.toml` file. `{}` is only applicable in the context of a project, and should be placed in a `pyproject.toml` file instead.", _0.user_display(), _1, _1)]
|
||||
PyprojectOnlyField(PathBuf, &'static str),
|
||||
|
||||
#[error("{0}")]
|
||||
InvalidEnvironmentVariable(String),
|
||||
#[error("Failed to parse environment variable `{name}` with invalid value `{value}`: {err}")]
|
||||
InvalidEnvironmentVariable {
|
||||
name: String,
|
||||
value: String,
|
||||
err: String,
|
||||
},
|
||||
}
|
||||
|
||||
/// Options loaded from environment variables.
|
||||
|
|
@ -564,6 +569,7 @@ pub enum Error {
|
|||
/// the CLI level, however there are limited semantics in that context.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EnvironmentOptions {
|
||||
pub skip_wheel_filename_check: Option<bool>,
|
||||
pub python_install_bin: Option<bool>,
|
||||
pub python_install_registry: Option<bool>,
|
||||
pub install_mirrors: PythonInstallMirrors,
|
||||
|
|
@ -574,28 +580,109 @@ impl EnvironmentOptions {
|
|||
/// Create a new [`EnvironmentOptions`] from environment variables.
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
python_install_bin: parse_boolish_environment_variable(EnvVars::UV_PYTHON_INSTALL_BIN)
|
||||
.map_err(Error::InvalidEnvironmentVariable)?,
|
||||
skip_wheel_filename_check: parse_boolish_environment_variable(
|
||||
EnvVars::UV_SKIP_WHEEL_FILENAME_CHECK,
|
||||
)?,
|
||||
python_install_bin: parse_boolish_environment_variable(EnvVars::UV_PYTHON_INSTALL_BIN)?,
|
||||
python_install_registry: parse_boolish_environment_variable(
|
||||
EnvVars::UV_PYTHON_INSTALL_REGISTRY,
|
||||
)
|
||||
.map_err(Error::InvalidEnvironmentVariable)?,
|
||||
)?,
|
||||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: parse_string_environment_variable(
|
||||
EnvVars::UV_PYTHON_INSTALL_MIRROR,
|
||||
)
|
||||
.map_err(Error::InvalidEnvironmentVariable)?,
|
||||
)?,
|
||||
pypy_install_mirror: parse_string_environment_variable(
|
||||
EnvVars::UV_PYPY_INSTALL_MIRROR,
|
||||
)
|
||||
.map_err(Error::InvalidEnvironmentVariable)?,
|
||||
)?,
|
||||
python_downloads_json_url: parse_string_environment_variable(
|
||||
EnvVars::UV_PYTHON_DOWNLOADS_JSON_URL,
|
||||
)
|
||||
.map_err(Error::InvalidEnvironmentVariable)?,
|
||||
)?,
|
||||
},
|
||||
log_context: parse_boolish_environment_variable(EnvVars::UV_LOG_CONTEXT)
|
||||
.map_err(Error::InvalidEnvironmentVariable)?,
|
||||
log_context: parse_boolish_environment_variable(EnvVars::UV_LOG_CONTEXT)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a boolean environment variable.
|
||||
///
|
||||
/// Adapted from Clap's `BoolishValueParser` which is dual licensed under the MIT and Apache-2.0.
|
||||
fn parse_boolish_environment_variable(name: &'static str) -> Result<Option<bool>, Error> {
|
||||
// See `clap_builder/src/util/str_to_bool.rs`
|
||||
// We want to match Clap's accepted values
|
||||
|
||||
// True values are `y`, `yes`, `t`, `true`, `on`, and `1`.
|
||||
const TRUE_LITERALS: [&str; 6] = ["y", "yes", "t", "true", "on", "1"];
|
||||
|
||||
// False values are `n`, `no`, `f`, `false`, `off`, and `0`.
|
||||
const FALSE_LITERALS: [&str; 6] = ["n", "no", "f", "false", "off", "0"];
|
||||
|
||||
// Converts a string literal representation of truth to true or false.
|
||||
//
|
||||
// `false` values are `n`, `no`, `f`, `false`, `off`, and `0` (case insensitive).
|
||||
//
|
||||
// Any other value will be considered as `true`.
|
||||
fn str_to_bool(val: impl AsRef<str>) -> Option<bool> {
|
||||
let pat: &str = &val.as_ref().to_lowercase();
|
||||
if TRUE_LITERALS.contains(&pat) {
|
||||
Some(true)
|
||||
} else if FALSE_LITERALS.contains(&pat) {
|
||||
Some(false)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let Some(value) = std::env::var_os(name) else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let Some(value) = value.to_str() else {
|
||||
return Err(Error::InvalidEnvironmentVariable {
|
||||
name: name.to_string(),
|
||||
value: value.to_string_lossy().to_string(),
|
||||
err: "expected a valid UTF-8 string".to_string(),
|
||||
});
|
||||
};
|
||||
|
||||
let Some(value) = str_to_bool(value) else {
|
||||
return Err(Error::InvalidEnvironmentVariable {
|
||||
name: name.to_string(),
|
||||
value: value.to_string(),
|
||||
err: "expected a boolish value".to_string(),
|
||||
});
|
||||
};
|
||||
|
||||
Ok(Some(value))
|
||||
}
|
||||
|
||||
/// Parse a string environment variable.
|
||||
fn parse_string_environment_variable(name: &'static str) -> Result<Option<String>, Error> {
|
||||
match std::env::var(name) {
|
||||
Ok(v) => {
|
||||
if v.is_empty() {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(v))
|
||||
}
|
||||
}
|
||||
Err(e) => match e {
|
||||
std::env::VarError::NotPresent => Ok(None),
|
||||
std::env::VarError::NotUnicode(err) => Err(Error::InvalidEnvironmentVariable {
|
||||
name: name.to_string(),
|
||||
value: err.to_string_lossy().to_string(),
|
||||
err: "expected a valid UTF-8 string".to_string(),
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Populate the [`EnvironmentFlags`] from the given [`EnvironmentOptions`].
|
||||
impl From<&EnvironmentOptions> for EnvironmentFlags {
|
||||
fn from(options: &EnvironmentOptions) -> Self {
|
||||
let mut flags = Self::empty();
|
||||
if options.skip_wheel_filename_check == Some(true) {
|
||||
flags.insert(Self::SKIP_WHEEL_FILENAME_CHECK);
|
||||
}
|
||||
flags
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,74 +1,3 @@
|
|||
pub use env_vars::*;
|
||||
|
||||
mod env_vars;
|
||||
|
||||
/// Parse a boolean environment variable.
|
||||
///
|
||||
/// Adapted from Clap's `BoolishValueParser` which is dual licensed under the MIT and Apache-2.0.
|
||||
pub fn parse_boolish_environment_variable(name: &'static str) -> Result<Option<bool>, String> {
|
||||
// See `clap_builder/src/util/str_to_bool.rs`
|
||||
// We want to match Clap's accepted values
|
||||
|
||||
// True values are `y`, `yes`, `t`, `true`, `on`, and `1`.
|
||||
const TRUE_LITERALS: [&str; 6] = ["y", "yes", "t", "true", "on", "1"];
|
||||
|
||||
// False values are `n`, `no`, `f`, `false`, `off`, and `0`.
|
||||
const FALSE_LITERALS: [&str; 6] = ["n", "no", "f", "false", "off", "0"];
|
||||
|
||||
// Converts a string literal representation of truth to true or false.
|
||||
//
|
||||
// `false` values are `n`, `no`, `f`, `false`, `off`, and `0` (case insensitive).
|
||||
//
|
||||
// Any other value will be considered as `true`.
|
||||
fn str_to_bool(val: impl AsRef<str>) -> Option<bool> {
|
||||
let pat: &str = &val.as_ref().to_lowercase();
|
||||
if TRUE_LITERALS.contains(&pat) {
|
||||
Some(true)
|
||||
} else if FALSE_LITERALS.contains(&pat) {
|
||||
Some(false)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
let Some(value) = std::env::var_os(name) else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let Some(value) = value.to_str() else {
|
||||
return Err(format!(
|
||||
"Failed to parse environment variable `{}` with invalid value `{}`: expected a valid UTF-8 string",
|
||||
name,
|
||||
value.to_string_lossy()
|
||||
));
|
||||
};
|
||||
|
||||
let Some(value) = str_to_bool(value) else {
|
||||
return Err(format!(
|
||||
"Failed to parse environment variable `{name}` with invalid value `{value}`: expected a boolish value"
|
||||
));
|
||||
};
|
||||
|
||||
Ok(Some(value))
|
||||
}
|
||||
|
||||
/// Parse a string environment variable.
|
||||
pub fn parse_string_environment_variable(name: &'static str) -> Result<Option<String>, String> {
|
||||
match std::env::var(name) {
|
||||
Ok(v) => {
|
||||
if v.is_empty() {
|
||||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(v))
|
||||
}
|
||||
}
|
||||
Err(e) => match e {
|
||||
std::env::VarError::NotPresent => Ok(None),
|
||||
std::env::VarError::NotUnicode(err) => Err(format!(
|
||||
"Failed to parse environment variable `{}` with invalid value `{}`: expected a valid UTF-8 string",
|
||||
name,
|
||||
err.to_string_lossy()
|
||||
)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ uv-distribution = { workspace = true }
|
|||
uv-distribution-filename = { workspace = true }
|
||||
uv-distribution-types = { workspace = true }
|
||||
uv-extract = { workspace = true }
|
||||
uv-flags = { workspace = true }
|
||||
uv-fs = { workspace = true }
|
||||
uv-git = { workspace = true }
|
||||
uv-git-types = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ use uv_cli::{
|
|||
};
|
||||
use uv_client::BaseClientBuilder;
|
||||
use uv_configuration::min_stack_size;
|
||||
use uv_flags::EnvironmentFlags;
|
||||
use uv_fs::{CWD, Simplified};
|
||||
#[cfg(feature = "self-update")]
|
||||
use uv_pep440::release_specifiers_to_ranges;
|
||||
|
|
@ -314,6 +315,10 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
// Resolve the cache settings.
|
||||
let cache_settings = CacheSettings::resolve(*cli.top_level.cache_args, filesystem.as_ref());
|
||||
|
||||
// Set the global flags.
|
||||
uv_flags::init(EnvironmentFlags::from(&environment))
|
||||
.map_err(|()| anyhow::anyhow!("Flags are already initialized"))?;
|
||||
|
||||
// Enforce the required version.
|
||||
if let Some(required_version) = globals.required_version.as_ref() {
|
||||
let package_version = uv_pep440::Version::from_str(uv_version::version())?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue