mirror of
https://github.com/astral-sh/uv
synced 2026-01-20 21:10:10 -05:00
Manually parse and reconcile Boolean environment variables (#17321)
## Summary This gives us more flexibility since we can avoid erroring on "conflicts" when one option is disabled (e.g., `UV_FROZEN=0 uv lock --check`). Closes https://github.com/astral-sh/uv/issues/13385. Closes https://github.com/astral-sh/uv/issues/13316. --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
18
clippy.toml
18
clippy.toml
@@ -9,6 +9,24 @@ doc-valid-idents = [
|
||||
"ROCm",
|
||||
"XPU",
|
||||
"PowerShell",
|
||||
"UV_DEV",
|
||||
"UV_FROZEN",
|
||||
"UV_ISOLATED",
|
||||
"UV_LOCKED",
|
||||
"UV_MANAGED_PYTHON",
|
||||
"UV_NATIVE_TLS",
|
||||
"UV_NO_DEV",
|
||||
"UV_NO_EDITABLE",
|
||||
"UV_NO_ENV_FILE",
|
||||
"UV_NO_INSTALLER_METADATA",
|
||||
"UV_NO_MANAGED_PYTHON",
|
||||
"UV_NO_PROGRESS",
|
||||
"UV_NO_SYNC",
|
||||
"UV_OFFLINE",
|
||||
"UV_PREVIEW",
|
||||
"UV_SHOW_RESOLUTION",
|
||||
"UV_VENV_CLEAR",
|
||||
"UV_VENV_SEED",
|
||||
".." # Include the defaults
|
||||
]
|
||||
|
||||
|
||||
@@ -165,33 +165,27 @@ pub struct GlobalArgs {
|
||||
)]
|
||||
pub python_preference: Option<PythonPreference>,
|
||||
|
||||
/// Require use of uv-managed Python versions.
|
||||
/// Require use of uv-managed Python versions [env: UV_MANAGED_PYTHON=]
|
||||
///
|
||||
/// By default, uv prefers using Python versions it manages. However, it
|
||||
/// will use system Python versions if a uv-managed Python is not
|
||||
/// installed. This option disables use of system Python versions.
|
||||
/// By default, uv prefers using Python versions it manages. However, it will use system Python
|
||||
/// versions if a uv-managed Python is not installed. This option disables use of system Python
|
||||
/// versions.
|
||||
#[arg(
|
||||
global = true,
|
||||
long,
|
||||
help_heading = "Python options",
|
||||
env = EnvVars::UV_MANAGED_PYTHON,
|
||||
value_parser = clap::builder::BoolishValueParser::new(),
|
||||
overrides_with = "no_managed_python",
|
||||
conflicts_with = "python_preference"
|
||||
overrides_with = "no_managed_python"
|
||||
)]
|
||||
pub managed_python: bool,
|
||||
|
||||
/// Disable use of uv-managed Python versions.
|
||||
/// Disable use of uv-managed Python versions [env: UV_NO_MANAGED_PYTHON=]
|
||||
///
|
||||
/// Instead, uv will search for a suitable Python version on the system.
|
||||
#[arg(
|
||||
global = true,
|
||||
long,
|
||||
help_heading = "Python options",
|
||||
env = EnvVars::UV_NO_MANAGED_PYTHON,
|
||||
value_parser = clap::builder::BoolishValueParser::new(),
|
||||
overrides_with = "managed_python",
|
||||
conflicts_with = "python_preference"
|
||||
overrides_with = "managed_python"
|
||||
)]
|
||||
pub no_managed_python: bool,
|
||||
|
||||
@@ -241,7 +235,7 @@ pub struct GlobalArgs {
|
||||
)]
|
||||
pub color: Option<ColorChoice>,
|
||||
|
||||
/// Whether to load TLS certificates from the platform's native certificate store.
|
||||
/// Whether to load TLS certificates from the platform's native store [env: UV_NATIVE_TLS=]
|
||||
///
|
||||
/// By default, uv loads certificates from the bundled `webpki-roots` crate. The
|
||||
/// `webpki-roots` are a reliable set of trust roots from Mozilla, and including them in uv
|
||||
@@ -250,16 +244,16 @@ pub struct GlobalArgs {
|
||||
/// However, in some cases, you may want to use the platform's native certificate store,
|
||||
/// especially if you're relying on a corporate trust root (e.g., for a mandatory proxy) that's
|
||||
/// included in your system's certificate store.
|
||||
#[arg(global = true, long, env = EnvVars::UV_NATIVE_TLS, value_parser = clap::builder::BoolishValueParser::new(), overrides_with("no_native_tls"))]
|
||||
#[arg(global = true, long, value_parser = clap::builder::BoolishValueParser::new(), overrides_with("no_native_tls"))]
|
||||
pub native_tls: bool,
|
||||
|
||||
#[arg(global = true, long, overrides_with("native_tls"), hide = true)]
|
||||
pub no_native_tls: bool,
|
||||
|
||||
/// Disable network access.
|
||||
/// Disable network access [env: UV_OFFLINE=]
|
||||
///
|
||||
/// When disabled, uv will only use locally cached data and locally available files.
|
||||
#[arg(global = true, long, overrides_with("no_offline"), env = EnvVars::UV_OFFLINE, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(global = true, long, overrides_with("no_offline"))]
|
||||
pub offline: bool,
|
||||
|
||||
#[arg(global = true, long, overrides_with("offline"), hide = true)]
|
||||
@@ -286,10 +280,10 @@ pub struct GlobalArgs {
|
||||
)]
|
||||
pub allow_insecure_host: Option<Vec<Maybe<TrustedHost>>>,
|
||||
|
||||
/// Whether to enable all experimental preview features.
|
||||
/// Whether to enable all experimental preview features [env: UV_PREVIEW=]
|
||||
///
|
||||
/// Preview features may change without warning.
|
||||
#[arg(global = true, long, hide = true, env = EnvVars::UV_PREVIEW, value_parser = clap::builder::BoolishValueParser::new(), overrides_with("no_preview"))]
|
||||
#[arg(global = true, long, hide = true, value_parser = clap::builder::BoolishValueParser::new(), overrides_with("no_preview"))]
|
||||
pub preview: bool,
|
||||
|
||||
#[arg(global = true, long, overrides_with("preview"), hide = true)]
|
||||
@@ -314,13 +308,13 @@ pub struct GlobalArgs {
|
||||
)]
|
||||
pub preview_features: Vec<PreviewFeatures>,
|
||||
|
||||
/// Avoid discovering a `pyproject.toml` or `uv.toml` file.
|
||||
/// Avoid discovering a `pyproject.toml` or `uv.toml` file [env: UV_ISOLATED=]
|
||||
///
|
||||
/// Normally, configuration files are discovered in the current directory,
|
||||
/// parent directories, or user configuration directories.
|
||||
///
|
||||
/// This option is deprecated in favor of `--no-config`.
|
||||
#[arg(global = true, long, hide = true, env = EnvVars::UV_ISOLATED, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(global = true, long, hide = true, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub isolated: bool,
|
||||
|
||||
/// Show the resolved settings for the current command.
|
||||
@@ -329,14 +323,15 @@ pub struct GlobalArgs {
|
||||
#[arg(global = true, long, hide = true)]
|
||||
pub show_settings: bool,
|
||||
|
||||
/// Hide all progress outputs.
|
||||
/// Hide all progress outputs [env: UV_NO_PROGRESS=]
|
||||
///
|
||||
/// For example, spinners or progress bars.
|
||||
#[arg(global = true, long, env = EnvVars::UV_NO_PROGRESS, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(global = true, long, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_progress: bool,
|
||||
|
||||
/// Skip writing `uv` installer metadata files (e.g., `INSTALLER`, `REQUESTED`, and `direct_url.json`) to site-packages `.dist-info` directories.
|
||||
#[arg(global = true, long, hide = true, env = EnvVars::UV_NO_INSTALLER_METADATA, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
/// Skip writing `uv` installer metadata files (e.g., `INSTALLER`, `REQUESTED`, and
|
||||
/// `direct_url.json`) to site-packages `.dist-info` directories [env: UV_NO_INSTALLER_METADATA=]
|
||||
#[arg(global = true, long, hide = true, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_installer_metadata: bool,
|
||||
|
||||
/// Change to the given directory prior to running the command.
|
||||
@@ -612,8 +607,8 @@ pub struct VersionArgs {
|
||||
#[arg(long, value_enum, default_value = "text")]
|
||||
pub output_format: VersionFormat,
|
||||
|
||||
/// Avoid syncing the virtual environment after re-locking the project.
|
||||
#[arg(long, env = EnvVars::UV_NO_SYNC, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with = "frozen")]
|
||||
/// Avoid syncing the virtual environment after re-locking the project [env: UV_NO_SYNC=]
|
||||
#[arg(long)]
|
||||
pub no_sync: bool,
|
||||
|
||||
/// Prefer the active virtual environment over the project's virtual environment.
|
||||
@@ -629,17 +624,17 @@ pub struct VersionArgs {
|
||||
#[arg(long, overrides_with = "active", hide = true)]
|
||||
pub no_active: bool,
|
||||
|
||||
/// Assert that the `uv.lock` will remain unchanged.
|
||||
/// Assert that the `uv.lock` will remain unchanged [env: UV_LOCKED=]
|
||||
///
|
||||
/// Requires that the lockfile is up-to-date. If the lockfile is missing or needs to be updated,
|
||||
/// uv will exit with an error.
|
||||
#[arg(long, env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["frozen", "upgrade"])]
|
||||
#[arg(long, conflicts_with_all = ["frozen", "upgrade"])]
|
||||
pub locked: bool,
|
||||
|
||||
/// Update the version without re-locking the project.
|
||||
/// Update the version without re-locking the project [env: UV_FROZEN=]
|
||||
///
|
||||
/// The project environment will not be synced.
|
||||
#[arg(long, env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
#[arg(long, conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
pub frozen: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
@@ -3088,18 +3083,19 @@ pub struct VenvArgs {
|
||||
#[arg(long, alias = "no-workspace")]
|
||||
pub no_project: bool,
|
||||
|
||||
/// Install seed packages (one or more of: `pip`, `setuptools`, and `wheel`) into the virtual environment.
|
||||
/// Install seed packages (one or more of: `pip`, `setuptools`, and `wheel`) into the virtual
|
||||
/// environment [env: UV_VENV_SEED=]
|
||||
///
|
||||
/// Note that `setuptools` and `wheel` are not included in Python 3.12+ environments.
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_VENV_SEED)]
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub seed: bool,
|
||||
|
||||
/// Remove any existing files or directories at the target path.
|
||||
/// Remove any existing files or directories at the target path [env: UV_VENV_CLEAR=]
|
||||
///
|
||||
/// By default, `uv venv` will exit with an error if the given path is non-empty. The
|
||||
/// `--clear` option will instead clear a non-empty path before creating a new virtual
|
||||
/// environment.
|
||||
#[clap(long, short, overrides_with = "allow_existing", value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_VENV_CLEAR)]
|
||||
#[clap(long, short, overrides_with = "allow_existing", value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub clear: bool,
|
||||
|
||||
/// Fail without prompting if any existing files or directories are present at the target path.
|
||||
@@ -3481,7 +3477,7 @@ pub struct RunArgs {
|
||||
#[arg(long, overrides_with("all_extras"), hide = true)]
|
||||
pub no_all_extras: bool,
|
||||
|
||||
/// Include the development dependency group.
|
||||
/// Include the development dependency group [env: UV_DEV=]
|
||||
///
|
||||
/// Development dependencies are defined via `dependency-groups.dev` or
|
||||
/// `tool.uv.dev-dependencies` in a `pyproject.toml`.
|
||||
@@ -3489,16 +3485,16 @@ pub struct RunArgs {
|
||||
/// This option is an alias for `--group dev`.
|
||||
///
|
||||
/// This option is only available when running in a project.
|
||||
#[arg(long, overrides_with("no_dev"), hide = true, env = EnvVars::UV_DEV, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, overrides_with("no_dev"), hide = true, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub dev: bool,
|
||||
|
||||
/// Disable the development dependency group.
|
||||
/// Disable the development dependency group [env: UV_NO_DEV=]
|
||||
///
|
||||
/// This option is an alias of `--no-group dev`.
|
||||
/// See `--no-default-groups` to disable all default groups instead.
|
||||
///
|
||||
/// This option is only available when running in a project.
|
||||
#[arg(long, overrides_with("dev"), env = EnvVars::UV_NO_DEV, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, overrides_with("dev"), value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_dev: bool,
|
||||
|
||||
/// Include dependencies from the specified dependency group.
|
||||
@@ -3557,8 +3553,8 @@ pub struct RunArgs {
|
||||
pub editable: bool,
|
||||
|
||||
/// Install any editable dependencies, including the project and any workspace members, as
|
||||
/// non-editable.
|
||||
#[arg(long, overrides_with = "editable", value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_NO_EDITABLE)]
|
||||
/// non-editable [env: UV_NO_EDITABLE=]
|
||||
#[arg(long, overrides_with = "editable", value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_editable: bool,
|
||||
|
||||
/// Do not remove extraneous packages present in the environment.
|
||||
@@ -3579,8 +3575,8 @@ pub struct RunArgs {
|
||||
#[arg(long, env = EnvVars::UV_ENV_FILE, value_hint = ValueHint::FilePath)]
|
||||
pub env_file: Vec<String>,
|
||||
|
||||
/// Avoid reading environment variables from a `.env` file.
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_NO_ENV_FILE)]
|
||||
/// Avoid reading environment variables from a `.env` file [env: UV_NO_ENV_FILE=]
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_env_file: bool,
|
||||
|
||||
/// The command to run.
|
||||
@@ -3617,7 +3613,7 @@ pub struct RunArgs {
|
||||
#[arg(long, value_delimiter = ',', value_parser = parse_maybe_file_path, value_hint = ValueHint::FilePath)]
|
||||
pub with_requirements: Vec<Maybe<PathBuf>>,
|
||||
|
||||
/// Run the command in an isolated virtual environment.
|
||||
/// Run the command in an isolated virtual environment [env: UV_ISOLATED=]
|
||||
///
|
||||
/// Usually, the project environment is reused for performance. This option forces a fresh
|
||||
/// environment to be used for the project, enforcing strict isolation between dependencies and
|
||||
@@ -3627,7 +3623,7 @@ pub struct RunArgs {
|
||||
///
|
||||
/// When used with `--with` or `--with-requirements`, the additional dependencies will still be
|
||||
/// layered in a second environment.
|
||||
#[arg(long, env = EnvVars::UV_ISOLATED, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub isolated: bool,
|
||||
|
||||
/// Prefer the active virtual environment over the project's virtual environment.
|
||||
@@ -3643,27 +3639,27 @@ pub struct RunArgs {
|
||||
#[arg(long, overrides_with = "active", hide = true)]
|
||||
pub no_active: bool,
|
||||
|
||||
/// Avoid syncing the virtual environment.
|
||||
/// Avoid syncing the virtual environment [env: UV_NO_SYNC=]
|
||||
///
|
||||
/// Implies `--frozen`, as the project dependencies will be ignored (i.e., the lockfile will not
|
||||
/// be updated, since the environment will not be synced regardless).
|
||||
#[arg(long, env = EnvVars::UV_NO_SYNC, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_sync: bool,
|
||||
|
||||
/// Assert that the `uv.lock` will remain unchanged.
|
||||
/// Assert that the `uv.lock` will remain unchanged [env: UV_LOCKED=]
|
||||
///
|
||||
/// Requires that the lockfile is up-to-date. If the lockfile is missing or
|
||||
/// needs to be updated, uv will exit with an error.
|
||||
#[arg(long, env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["frozen", "upgrade"])]
|
||||
#[arg(long, conflicts_with_all = ["frozen", "upgrade"])]
|
||||
pub locked: bool,
|
||||
|
||||
/// Run without updating the `uv.lock` file.
|
||||
/// Run without updating the `uv.lock` file [env: UV_FROZEN=]
|
||||
///
|
||||
/// Instead of checking if the lockfile is up-to-date, uses the versions in the lockfile as the
|
||||
/// source of truth. If the lockfile is missing, uv will exit with an error. If the
|
||||
/// `pyproject.toml` includes changes to dependencies that have not been included in the
|
||||
/// lockfile yet, they will not be present in the environment.
|
||||
#[arg(long, env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
#[arg(long, conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
pub frozen: bool,
|
||||
|
||||
/// Run the given path as a Python script.
|
||||
@@ -3731,10 +3727,11 @@ pub struct RunArgs {
|
||||
)]
|
||||
pub python: Option<Maybe<String>>,
|
||||
|
||||
/// Whether to show resolver and installer output from any environment modifications.
|
||||
/// Whether to show resolver and installer output from any environment modifications [env:
|
||||
/// UV_SHOW_RESOLUTION=]
|
||||
///
|
||||
/// By default, environment modifications are omitted, but enabled under `--verbose`.
|
||||
#[arg(long, env = EnvVars::UV_SHOW_RESOLUTION, value_parser = clap::builder::BoolishValueParser::new(), hide = true)]
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new(), hide = true)]
|
||||
pub show_resolution: bool,
|
||||
|
||||
/// Number of times that `uv run` will allow recursive invocations.
|
||||
@@ -3813,17 +3810,17 @@ pub struct SyncArgs {
|
||||
#[arg(long, overrides_with("all_extras"), hide = true)]
|
||||
pub no_all_extras: bool,
|
||||
|
||||
/// Include the development dependency group.
|
||||
/// Include the development dependency group [env: UV_DEV=]
|
||||
///
|
||||
/// This option is an alias for `--group dev`.
|
||||
#[arg(long, overrides_with("no_dev"), hide = true, env = EnvVars::UV_DEV, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, overrides_with("no_dev"), hide = true, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub dev: bool,
|
||||
|
||||
/// Disable the development dependency group.
|
||||
/// Disable the development dependency group [env: UV_NO_DEV=]
|
||||
///
|
||||
/// This option is an alias of `--no-group dev`.
|
||||
/// See `--no-default-groups` to disable all default groups instead.
|
||||
#[arg(long, overrides_with("dev"), env = EnvVars::UV_NO_DEV, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, overrides_with("dev"), value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_dev: bool,
|
||||
|
||||
/// Only include the development dependency group.
|
||||
@@ -3879,8 +3876,8 @@ pub struct SyncArgs {
|
||||
pub editable: bool,
|
||||
|
||||
/// Install any editable dependencies, including the project and any workspace members, as
|
||||
/// non-editable.
|
||||
#[arg(long, overrides_with = "editable", value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_NO_EDITABLE)]
|
||||
/// non-editable [env: UV_NO_EDITABLE=]
|
||||
#[arg(long, overrides_with = "editable", value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_editable: bool,
|
||||
|
||||
/// Do not remove extraneous packages present in the environment.
|
||||
@@ -3972,20 +3969,20 @@ pub struct SyncArgs {
|
||||
#[arg(long, conflicts_with = "no_install_package", hide = true, value_hint = ValueHint::Other)]
|
||||
pub only_install_package: Vec<PackageName>,
|
||||
|
||||
/// Assert that the `uv.lock` will remain unchanged.
|
||||
/// Assert that the `uv.lock` will remain unchanged [env: UV_LOCKED=]
|
||||
///
|
||||
/// Requires that the lockfile is up-to-date. If the lockfile is missing or needs to be updated,
|
||||
/// uv will exit with an error.
|
||||
#[arg(long, env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["frozen", "upgrade"])]
|
||||
#[arg(long, conflicts_with_all = ["frozen", "upgrade"])]
|
||||
pub locked: bool,
|
||||
|
||||
/// Sync without updating the `uv.lock` file.
|
||||
/// Sync without updating the `uv.lock` file [env: UV_FROZEN=]
|
||||
///
|
||||
/// Instead of checking if the lockfile is up-to-date, uses the versions in the lockfile as the
|
||||
/// source of truth. If the lockfile is missing, uv will exit with an error. If the
|
||||
/// `pyproject.toml` includes changes to dependencies that have not been included in the
|
||||
/// lockfile yet, they will not be present in the environment.
|
||||
#[arg(long, env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
#[arg(long, conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
pub frozen: bool,
|
||||
|
||||
/// Perform a dry run, without writing the lockfile or modifying the project environment.
|
||||
@@ -4114,19 +4111,19 @@ pub struct LockArgs {
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["check_exists", "upgrade"], overrides_with = "check")]
|
||||
pub check: bool,
|
||||
|
||||
/// Check if the lockfile is up-to-date.
|
||||
/// Check if the lockfile is up-to-date [env: UV_LOCKED=]
|
||||
///
|
||||
/// Asserts that the `uv.lock` would remain unchanged after a resolution. If the lockfile is
|
||||
/// missing or needs to be updated, uv will exit with an error.
|
||||
///
|
||||
/// Equivalent to `--check`.
|
||||
#[arg(long, env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["check_exists", "upgrade"], hide = true)]
|
||||
#[arg(long, conflicts_with_all = ["check_exists", "upgrade"], hide = true)]
|
||||
pub locked: bool,
|
||||
|
||||
/// Assert that a `uv.lock` exists without checking if it is up-to-date.
|
||||
/// Assert that a `uv.lock` exists without checking if it is up-to-date [env: UV_FROZEN=]
|
||||
///
|
||||
/// Equivalent to `--frozen`.
|
||||
#[arg(long, alias = "frozen", env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["check", "locked"])]
|
||||
#[arg(long, alias = "frozen", conflicts_with_all = ["check", "locked"])]
|
||||
pub check_exists: bool,
|
||||
|
||||
/// Perform a dry run, without writing the lockfile.
|
||||
@@ -4221,7 +4218,7 @@ pub struct AddArgs {
|
||||
#[arg(long, short, value_parser = MarkerTree::from_str, value_hint = ValueHint::Other)]
|
||||
pub marker: Option<MarkerTree>,
|
||||
|
||||
/// Add the requirements to the development dependency group.
|
||||
/// Add the requirements to the development dependency group [env: UV_DEV=]
|
||||
///
|
||||
/// This option is an alias for `--group dev`.
|
||||
#[arg(
|
||||
@@ -4229,7 +4226,6 @@ pub struct AddArgs {
|
||||
conflicts_with("optional"),
|
||||
conflicts_with("group"),
|
||||
conflicts_with("script"),
|
||||
env = EnvVars::UV_DEV,
|
||||
value_parser = clap::builder::BoolishValueParser::new()
|
||||
)]
|
||||
pub dev: bool,
|
||||
@@ -4258,7 +4254,8 @@ pub struct AddArgs {
|
||||
#[arg(long, overrides_with = "no_editable")]
|
||||
pub editable: bool,
|
||||
|
||||
#[arg(long, overrides_with = "editable", hide = true, value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_NO_EDITABLE)]
|
||||
/// Don't add the requirements as editable [env: UV_NO_EDITABLE=]
|
||||
#[arg(long, overrides_with = "editable", hide = true, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_editable: bool,
|
||||
|
||||
/// Add a dependency as provided.
|
||||
@@ -4317,21 +4314,21 @@ pub struct AddArgs {
|
||||
#[arg(long, value_hint = ValueHint::Other)]
|
||||
pub extra: Option<Vec<ExtraName>>,
|
||||
|
||||
/// Avoid syncing the virtual environment.
|
||||
#[arg(long, env = EnvVars::UV_NO_SYNC, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with = "frozen")]
|
||||
/// Avoid syncing the virtual environment [env: UV_NO_SYNC=]
|
||||
#[arg(long)]
|
||||
pub no_sync: bool,
|
||||
|
||||
/// Assert that the `uv.lock` will remain unchanged.
|
||||
/// Assert that the `uv.lock` will remain unchanged [env: UV_LOCKED=]
|
||||
///
|
||||
/// Requires that the lockfile is up-to-date. If the lockfile is missing or needs to be updated,
|
||||
/// uv will exit with an error.
|
||||
#[arg(long, env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["frozen", "upgrade"])]
|
||||
#[arg(long, conflicts_with_all = ["frozen", "upgrade"])]
|
||||
pub locked: bool,
|
||||
|
||||
/// Add dependencies without re-locking the project.
|
||||
/// Add dependencies without re-locking the project [env: UV_FROZEN=]
|
||||
///
|
||||
/// The project environment will not be synced.
|
||||
#[arg(long, env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
#[arg(long, conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
pub frozen: bool,
|
||||
|
||||
/// Prefer the active virtual environment over the project's virtual environment.
|
||||
@@ -4523,10 +4520,10 @@ pub struct RemoveArgs {
|
||||
#[arg(required = true, value_hint = ValueHint::Other)]
|
||||
pub packages: Vec<Requirement<VerbatimParsedUrl>>,
|
||||
|
||||
/// Remove the packages from the development dependency group.
|
||||
/// Remove the packages from the development dependency group [env: UV_DEV=]
|
||||
///
|
||||
/// This option is an alias for `--group dev`.
|
||||
#[arg(long, conflicts_with("optional"), conflicts_with("group"), env = EnvVars::UV_DEV, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, conflicts_with("optional"), conflicts_with("group"), value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub dev: bool,
|
||||
|
||||
/// Remove the packages from the project's optional dependencies for the specified extra.
|
||||
@@ -4549,8 +4546,8 @@ pub struct RemoveArgs {
|
||||
)]
|
||||
pub group: Option<GroupName>,
|
||||
|
||||
/// Avoid syncing the virtual environment after re-locking the project.
|
||||
#[arg(long, env = EnvVars::UV_NO_SYNC, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with = "frozen")]
|
||||
/// Avoid syncing the virtual environment after re-locking the project [env: UV_NO_SYNC=]
|
||||
#[arg(long)]
|
||||
pub no_sync: bool,
|
||||
|
||||
/// Prefer the active virtual environment over the project's virtual environment.
|
||||
@@ -4566,17 +4563,17 @@ pub struct RemoveArgs {
|
||||
#[arg(long, overrides_with = "active", hide = true)]
|
||||
pub no_active: bool,
|
||||
|
||||
/// Assert that the `uv.lock` will remain unchanged.
|
||||
/// Assert that the `uv.lock` will remain unchanged [env: UV_LOCKED=]
|
||||
///
|
||||
/// Requires that the lockfile is up-to-date. If the lockfile is missing or needs to be updated,
|
||||
/// uv will exit with an error.
|
||||
#[arg(long, env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["frozen", "upgrade"])]
|
||||
#[arg(long, conflicts_with_all = ["frozen", "upgrade"])]
|
||||
pub locked: bool,
|
||||
|
||||
/// Remove dependencies without re-locking the project.
|
||||
/// Remove dependencies without re-locking the project [env: UV_FROZEN=]
|
||||
///
|
||||
/// The project environment will not be synced.
|
||||
#[arg(long, env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
#[arg(long, conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
pub frozen: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
@@ -4628,13 +4625,13 @@ pub struct TreeArgs {
|
||||
#[command(flatten)]
|
||||
pub tree: DisplayTreeArgs,
|
||||
|
||||
/// Include the development dependency group.
|
||||
/// Include the development dependency group [env: UV_DEV=]
|
||||
///
|
||||
/// Development dependencies are defined via `dependency-groups.dev` or
|
||||
/// `tool.uv.dev-dependencies` in a `pyproject.toml`.
|
||||
///
|
||||
/// This option is an alias for `--group dev`.
|
||||
#[arg(long, overrides_with("no_dev"), hide = true, env = EnvVars::UV_DEV, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, overrides_with("no_dev"), hide = true, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub dev: bool,
|
||||
|
||||
/// Only include the development dependency group.
|
||||
@@ -4645,11 +4642,11 @@ pub struct TreeArgs {
|
||||
#[arg(long, conflicts_with_all = ["group", "all_groups", "no_dev"])]
|
||||
pub only_dev: bool,
|
||||
|
||||
/// Disable the development dependency group.
|
||||
/// Disable the development dependency group [env: UV_NO_DEV=]
|
||||
///
|
||||
/// This option is an alias of `--no-group dev`.
|
||||
/// See `--no-default-groups` to disable all default groups instead.
|
||||
#[arg(long, overrides_with("dev"), env = EnvVars::UV_NO_DEV, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, overrides_with("dev"), value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_dev: bool,
|
||||
|
||||
/// Include dependencies from the specified dependency group.
|
||||
@@ -4688,17 +4685,17 @@ pub struct TreeArgs {
|
||||
#[arg(long, conflicts_with_all = ["only_group", "only_dev"])]
|
||||
pub all_groups: bool,
|
||||
|
||||
/// Assert that the `uv.lock` will remain unchanged.
|
||||
/// Assert that the `uv.lock` will remain unchanged [env: UV_LOCKED=]
|
||||
///
|
||||
/// Requires that the lockfile is up-to-date. If the lockfile is missing or needs to be updated,
|
||||
/// uv will exit with an error.
|
||||
#[arg(long, env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["frozen", "upgrade"])]
|
||||
#[arg(long, conflicts_with_all = ["frozen", "upgrade"])]
|
||||
pub locked: bool,
|
||||
|
||||
/// Display the requirements without locking the project.
|
||||
/// Display the requirements without locking the project [env: UV_FROZEN=]
|
||||
///
|
||||
/// If the lockfile is missing, uv will exit with an error.
|
||||
#[arg(long, env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
#[arg(long, conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
pub frozen: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
@@ -4808,17 +4805,17 @@ pub struct ExportArgs {
|
||||
#[arg(long, overrides_with("all_extras"), hide = true)]
|
||||
pub no_all_extras: bool,
|
||||
|
||||
/// Include the development dependency group.
|
||||
/// Include the development dependency group [env: UV_DEV=]
|
||||
///
|
||||
/// This option is an alias for `--group dev`.
|
||||
#[arg(long, overrides_with("no_dev"), hide = true, env = EnvVars::UV_DEV, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, overrides_with("no_dev"), hide = true, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub dev: bool,
|
||||
|
||||
/// Disable the development dependency group.
|
||||
/// Disable the development dependency group [env: UV_NO_DEV=]
|
||||
///
|
||||
/// This option is an alias of `--no-group dev`.
|
||||
/// See `--no-default-groups` to disable all default groups instead.
|
||||
#[arg(long, overrides_with("dev"), env = EnvVars::UV_NO_DEV, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
#[arg(long, overrides_with("dev"), value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_dev: bool,
|
||||
|
||||
/// Only include the development dependency group.
|
||||
@@ -4885,8 +4882,8 @@ pub struct ExportArgs {
|
||||
pub editable: bool,
|
||||
|
||||
/// Export any editable dependencies, including the project and any workspace members, as
|
||||
/// non-editable.
|
||||
#[arg(long, overrides_with = "editable", value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_NO_EDITABLE)]
|
||||
/// non-editable [env: UV_NO_EDITABLE=]
|
||||
#[arg(long, overrides_with = "editable", value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_editable: bool,
|
||||
|
||||
/// Include hashes for all dependencies.
|
||||
@@ -4994,17 +4991,17 @@ pub struct ExportArgs {
|
||||
)]
|
||||
pub only_emit_package: Vec<PackageName>,
|
||||
|
||||
/// Assert that the `uv.lock` will remain unchanged.
|
||||
/// Assert that the `uv.lock` will remain unchanged [env: UV_LOCKED=]
|
||||
///
|
||||
/// Requires that the lockfile is up-to-date. If the lockfile is missing or needs to be updated,
|
||||
/// uv will exit with an error.
|
||||
#[arg(long, env = EnvVars::UV_LOCKED, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["frozen", "upgrade"])]
|
||||
#[arg(long, conflicts_with_all = ["frozen", "upgrade"])]
|
||||
pub locked: bool,
|
||||
|
||||
/// Do not update the `uv.lock` before exporting.
|
||||
/// Do not update the `uv.lock` before exporting [env: UV_FROZEN=]
|
||||
///
|
||||
/// If a `uv.lock` does not exist, uv will exit with an error.
|
||||
#[arg(long, env = EnvVars::UV_FROZEN, value_parser = clap::builder::BoolishValueParser::new(), conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
#[arg(long, conflicts_with_all = ["locked", "upgrade", "no_sources"])]
|
||||
pub frozen: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
@@ -5302,8 +5299,9 @@ pub struct ToolRunArgs {
|
||||
)]
|
||||
pub overrides: Vec<Maybe<PathBuf>>,
|
||||
|
||||
/// Run the tool in an isolated virtual environment, ignoring any already-installed tools.
|
||||
#[arg(long, env = EnvVars::UV_ISOLATED, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
/// Run the tool in an isolated virtual environment, ignoring any already-installed tools [env:
|
||||
/// UV_ISOLATED=]
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub isolated: bool,
|
||||
|
||||
/// Load environment variables from a `.env` file.
|
||||
@@ -5313,8 +5311,8 @@ pub struct ToolRunArgs {
|
||||
#[arg(long, value_delimiter = ' ', env = EnvVars::UV_ENV_FILE, value_hint = ValueHint::FilePath)]
|
||||
pub env_file: Vec<PathBuf>,
|
||||
|
||||
/// Avoid reading environment variables from a `.env` file.
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new(), env = EnvVars::UV_NO_ENV_FILE)]
|
||||
/// Avoid reading environment variables from a `.env` file [env: UV_NO_ENV_FILE=]
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new())]
|
||||
pub no_env_file: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
@@ -5344,10 +5342,11 @@ pub struct ToolRunArgs {
|
||||
)]
|
||||
pub python: Option<Maybe<String>>,
|
||||
|
||||
/// Whether to show resolver and installer output from any environment modifications.
|
||||
/// Whether to show resolver and installer output from any environment modifications [env:
|
||||
/// UV_SHOW_RESOLUTION=]
|
||||
///
|
||||
/// By default, environment modifications are omitted, but enabled under `--verbose`.
|
||||
#[arg(long, env = EnvVars::UV_SHOW_RESOLUTION, value_parser = clap::builder::BoolishValueParser::new(), hide = true)]
|
||||
#[arg(long, value_parser = clap::builder::BoolishValueParser::new(), hide = true)]
|
||||
pub show_resolution: bool,
|
||||
|
||||
/// The platform for which requirements should be installed.
|
||||
@@ -6649,17 +6648,11 @@ pub struct IndexArgs {
|
||||
#[derive(Args)]
|
||||
pub struct RefreshArgs {
|
||||
/// Refresh all cached data.
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with("offline"),
|
||||
overrides_with("no_refresh"),
|
||||
help_heading = "Cache options"
|
||||
)]
|
||||
#[arg(long, overrides_with("no_refresh"), help_heading = "Cache options")]
|
||||
pub refresh: bool,
|
||||
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with("offline"),
|
||||
overrides_with("refresh"),
|
||||
hide = true,
|
||||
help_heading = "Cache options"
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
use std::fmt;
|
||||
|
||||
use anstream::eprintln;
|
||||
|
||||
use uv_cache::Refresh;
|
||||
use uv_configuration::{BuildIsolation, Reinstall, Upgrade};
|
||||
use uv_distribution_types::{ConfigSettings, PackageConfigSettings, Requirement};
|
||||
use uv_resolver::{ExcludeNewer, ExcludeNewerPackage, PrereleaseMode};
|
||||
use uv_settings::{Combine, PipOptions, ResolverInstallerOptions, ResolverOptions};
|
||||
use uv_settings::{Combine, EnvFlag, PipOptions, ResolverInstallerOptions, ResolverOptions};
|
||||
use uv_warnings::owo_colors::OwoColorize;
|
||||
|
||||
use crate::{
|
||||
@@ -37,6 +39,150 @@ pub fn flag(yes: bool, no: bool, name: &str) -> Option<bool> {
|
||||
}
|
||||
}
|
||||
|
||||
/// The source of a boolean flag value.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum FlagSource {
|
||||
/// The flag was set via command-line argument.
|
||||
Cli,
|
||||
/// The flag was set via environment variable.
|
||||
Env(&'static str),
|
||||
/// The flag was set via workspace/project configuration.
|
||||
Config,
|
||||
}
|
||||
|
||||
impl fmt::Display for FlagSource {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::Cli => write!(f, "command-line argument"),
|
||||
Self::Env(name) => write!(f, "environment variable `{name}`"),
|
||||
Self::Config => write!(f, "workspace configuration"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A boolean flag value with its source.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Flag {
|
||||
/// The flag is not set.
|
||||
Disabled,
|
||||
/// The flag is enabled with a known source.
|
||||
Enabled {
|
||||
source: FlagSource,
|
||||
/// The CLI flag name (e.g., "locked" for `--locked`).
|
||||
name: &'static str,
|
||||
},
|
||||
}
|
||||
|
||||
impl Flag {
|
||||
/// Create a flag that is explicitly disabled.
|
||||
pub const fn disabled() -> Self {
|
||||
Self::Disabled
|
||||
}
|
||||
|
||||
/// Create an enabled flag from a CLI argument.
|
||||
pub const fn from_cli(name: &'static str) -> Self {
|
||||
Self::Enabled {
|
||||
source: FlagSource::Cli,
|
||||
name,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an enabled flag from workspace/project configuration.
|
||||
pub const fn from_config(name: &'static str) -> Self {
|
||||
Self::Enabled {
|
||||
source: FlagSource::Config,
|
||||
name,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the flag is set.
|
||||
pub fn is_enabled(self) -> bool {
|
||||
matches!(self, Self::Enabled { .. })
|
||||
}
|
||||
|
||||
/// Returns the source of the flag, if it is set.
|
||||
pub fn source(self) -> Option<FlagSource> {
|
||||
match self {
|
||||
Self::Disabled => None,
|
||||
Self::Enabled { source, .. } => Some(source),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the CLI flag name, if the flag is enabled.
|
||||
pub fn name(self) -> Option<&'static str> {
|
||||
match self {
|
||||
Self::Disabled => None,
|
||||
Self::Enabled { name, .. } => Some(name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Flag> for bool {
|
||||
fn from(flag: Flag) -> Self {
|
||||
flag.is_enabled()
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve a boolean flag from CLI arguments and an environment variable.
|
||||
///
|
||||
/// The CLI argument takes precedence over the environment variable. Returns a [`Flag`] with the
|
||||
/// resolved value and source.
|
||||
pub fn resolve_flag(cli_flag: bool, name: &'static str, env_flag: EnvFlag) -> Flag {
|
||||
if cli_flag {
|
||||
Flag::Enabled {
|
||||
source: FlagSource::Cli,
|
||||
name,
|
||||
}
|
||||
} else if env_flag.value == Some(true) {
|
||||
Flag::Enabled {
|
||||
source: FlagSource::Env(env_flag.env_var),
|
||||
name,
|
||||
}
|
||||
} else {
|
||||
Flag::Disabled
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if two flags conflict and exit with an error if they do.
|
||||
///
|
||||
/// This function checks if both flags are enabled (truthy) and reports an error if so, including
|
||||
/// the source of each flag (CLI or environment variable) in the error message.
|
||||
pub fn check_conflicts(flag_a: Flag, flag_b: Flag) {
|
||||
if let (
|
||||
Flag::Enabled {
|
||||
source: source_a,
|
||||
name: name_a,
|
||||
},
|
||||
Flag::Enabled {
|
||||
source: source_b,
|
||||
name: name_b,
|
||||
},
|
||||
) = (flag_a, flag_b)
|
||||
{
|
||||
let display_a = match source_a {
|
||||
FlagSource::Cli => format!("`--{name_a}`"),
|
||||
FlagSource::Env(env) => format!("`{env}` (environment variable)"),
|
||||
FlagSource::Config => format!("`{name_a}` (workspace configuration)"),
|
||||
};
|
||||
let display_b = match source_b {
|
||||
FlagSource::Cli => format!("`--{name_b}`"),
|
||||
FlagSource::Env(env) => format!("`{env}` (environment variable)"),
|
||||
FlagSource::Config => format!("`{name_b}` (workspace configuration)"),
|
||||
};
|
||||
eprintln!(
|
||||
"{}{} the argument {} cannot be used with {}",
|
||||
"error".bold().red(),
|
||||
":".bold(),
|
||||
display_a.green(),
|
||||
display_b.green(),
|
||||
);
|
||||
#[allow(clippy::exit)]
|
||||
{
|
||||
std::process::exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RefreshArgs> for Refresh {
|
||||
fn from(value: RefreshArgs) -> Self {
|
||||
let RefreshArgs {
|
||||
|
||||
@@ -594,6 +594,25 @@ pub struct Concurrency {
|
||||
pub installs: Option<NonZeroUsize>,
|
||||
}
|
||||
|
||||
/// A boolean flag parsed from an environment variable.
|
||||
///
|
||||
/// Stores both the value and the environment variable name for use in error messages.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct EnvFlag {
|
||||
pub value: Option<bool>,
|
||||
pub env_var: &'static str,
|
||||
}
|
||||
|
||||
impl EnvFlag {
|
||||
/// Create a new [`EnvFlag`] by parsing the given environment variable.
|
||||
pub fn new(env_var: &'static str) -> Result<Self, Error> {
|
||||
Ok(Self {
|
||||
value: parse_boolish_environment_variable(env_var)?,
|
||||
env_var,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Options loaded from environment variables.
|
||||
///
|
||||
/// This is currently a subset of all respected environment variables, most are parsed via Clap at
|
||||
@@ -613,6 +632,24 @@ pub struct EnvironmentOptions {
|
||||
pub concurrency: Concurrency,
|
||||
#[cfg(feature = "tracing-durations-export")]
|
||||
pub tracing_durations_file: Option<PathBuf>,
|
||||
pub frozen: EnvFlag,
|
||||
pub locked: EnvFlag,
|
||||
pub offline: EnvFlag,
|
||||
pub no_sync: EnvFlag,
|
||||
pub managed_python: EnvFlag,
|
||||
pub no_managed_python: EnvFlag,
|
||||
pub native_tls: EnvFlag,
|
||||
pub preview: EnvFlag,
|
||||
pub isolated: EnvFlag,
|
||||
pub no_progress: EnvFlag,
|
||||
pub no_installer_metadata: EnvFlag,
|
||||
pub dev: EnvFlag,
|
||||
pub no_dev: EnvFlag,
|
||||
pub show_resolution: EnvFlag,
|
||||
pub no_editable: EnvFlag,
|
||||
pub no_env_file: EnvFlag,
|
||||
pub venv_seed: EnvFlag,
|
||||
pub venv_clear: EnvFlag,
|
||||
}
|
||||
|
||||
impl EnvironmentOptions {
|
||||
@@ -667,6 +704,24 @@ impl EnvironmentOptions {
|
||||
tracing_durations_file: parse_path_environment_variable(
|
||||
EnvVars::TRACING_DURATIONS_FILE,
|
||||
),
|
||||
frozen: EnvFlag::new(EnvVars::UV_FROZEN)?,
|
||||
locked: EnvFlag::new(EnvVars::UV_LOCKED)?,
|
||||
offline: EnvFlag::new(EnvVars::UV_OFFLINE)?,
|
||||
no_sync: EnvFlag::new(EnvVars::UV_NO_SYNC)?,
|
||||
managed_python: EnvFlag::new(EnvVars::UV_MANAGED_PYTHON)?,
|
||||
no_managed_python: EnvFlag::new(EnvVars::UV_NO_MANAGED_PYTHON)?,
|
||||
native_tls: EnvFlag::new(EnvVars::UV_NATIVE_TLS)?,
|
||||
preview: EnvFlag::new(EnvVars::UV_PREVIEW)?,
|
||||
isolated: EnvFlag::new(EnvVars::UV_ISOLATED)?,
|
||||
no_progress: EnvFlag::new(EnvVars::UV_NO_PROGRESS)?,
|
||||
no_installer_metadata: EnvFlag::new(EnvVars::UV_NO_INSTALLER_METADATA)?,
|
||||
dev: EnvFlag::new(EnvVars::UV_DEV)?,
|
||||
no_dev: EnvFlag::new(EnvVars::UV_NO_DEV)?,
|
||||
show_resolution: EnvFlag::new(EnvVars::UV_SHOW_RESOLUTION)?,
|
||||
no_editable: EnvFlag::new(EnvVars::UV_NO_EDITABLE)?,
|
||||
no_env_file: EnvFlag::new(EnvVars::UV_NO_ENV_FILE)?,
|
||||
venv_seed: EnvFlag::new(EnvVars::UV_VENV_SEED)?,
|
||||
venv_clear: EnvFlag::new(EnvVars::UV_VENV_CLEAR)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,18 @@ pub(crate) fn help(query: &[String], printer: Printer, no_pager: bool) -> Result
|
||||
.render_long_help()
|
||||
};
|
||||
|
||||
// Reformat inline [env: VAR=] annotations to their own line.
|
||||
let help_plain = if is_root {
|
||||
help.to_string()
|
||||
} else {
|
||||
reformat_env_annotations(&help.to_string())
|
||||
};
|
||||
let help_ansi = if is_root {
|
||||
help.ansi().to_string()
|
||||
} else {
|
||||
reformat_env_annotations(&help.ansi().to_string())
|
||||
};
|
||||
|
||||
let want_color = match anstream::Stdout::choice(&std::io::stdout()) {
|
||||
ColorChoice::Always | ColorChoice::AlwaysAnsi => true,
|
||||
ColorChoice::Never => false,
|
||||
@@ -83,21 +95,156 @@ pub(crate) fn help(query: &[String], printer: Printer, no_pager: bool) -> Result
|
||||
if should_page && let Some(pager) = Pager::try_from_env() {
|
||||
let query = query.join(" ");
|
||||
if want_color && pager.supports_colors() {
|
||||
pager.spawn(format!("{}: {query}", "uv help".bold()), help.ansi())?;
|
||||
pager.spawn(format!("{}: {query}", "uv help".bold()), &help_ansi)?;
|
||||
} else {
|
||||
pager.spawn(format!("uv help: {query}"), help)?;
|
||||
pager.spawn(format!("uv help: {query}"), &help_plain)?;
|
||||
}
|
||||
} else {
|
||||
if want_color {
|
||||
writeln!(printer.stdout(), "{}", help.ansi())?;
|
||||
writeln!(printer.stdout(), "{help_ansi}")?;
|
||||
} else {
|
||||
writeln!(printer.stdout(), "{help}")?;
|
||||
writeln!(printer.stdout(), "{help_plain}")?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ExitStatus::Success)
|
||||
}
|
||||
|
||||
/// Get the first non-ANSI character starting at a given byte position.
|
||||
///
|
||||
/// Returns `None` if the rest of the string is empty or only contains ANSI sequences.
|
||||
fn first_non_ansi_char(s: &str, start: usize) -> Option<char> {
|
||||
let mut chars = s[start..].chars().peekable();
|
||||
while let Some(c) = chars.next() {
|
||||
if c == '\x1b' {
|
||||
// Skip ANSI escape sequences.
|
||||
if chars.peek() == Some(&'[') {
|
||||
chars.next();
|
||||
for c in chars.by_ref() {
|
||||
if c.is_ascii_alphabetic() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Some(c);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Reformat `[env: VAR=]` annotations in long help output.
|
||||
///
|
||||
/// Moves inline `[env: VAR=]` annotations to their own line at the end of each
|
||||
/// argument's description, matching clap's native formatting for environment vars.
|
||||
fn reformat_env_annotations(help: &str) -> String {
|
||||
let mut result = String::new();
|
||||
let mut pending_env: Option<String> = None;
|
||||
|
||||
let lines: Vec<&str> = help.lines().collect();
|
||||
let mut i = 0;
|
||||
|
||||
while i < lines.len() {
|
||||
let line = lines[i];
|
||||
|
||||
// Classify the line type based on clap's help formatting:
|
||||
// - Argument lines: 6 spaces + `-` or `<` (e.g., " --offline", " <PACKAGE>")
|
||||
// - Description lines: 10 spaces + text (e.g., " Disable network access")
|
||||
// - Section headers: no leading spaces, ends with `:` (e.g., "Options:")
|
||||
//
|
||||
// Leading spaces never contain ANSI codes, but argument names may be colored,
|
||||
// so we skip ANSI sequences when checking the first content character.
|
||||
let indent = line.len() - line.trim_start().len();
|
||||
let first_char = first_non_ansi_char(line, indent);
|
||||
let is_arg_line = indent == 6 && matches!(first_char, Some('-' | '<'));
|
||||
let is_section_header = indent == 0 && line.ends_with(':');
|
||||
let is_description_line = indent == 10;
|
||||
|
||||
// Flush pending env before starting a new argument or section.
|
||||
if is_arg_line || is_section_header {
|
||||
if let Some(env) = pending_env.take() {
|
||||
// Remove trailing blank lines; add exactly one blank line before the environment variable.
|
||||
while result.ends_with("\n\n") {
|
||||
result.pop();
|
||||
}
|
||||
if !result.ends_with('\n') {
|
||||
result.push('\n');
|
||||
}
|
||||
result.push('\n');
|
||||
let _ = write!(result, " {env}\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Check for inline environment annotations on description lines.
|
||||
if is_description_line {
|
||||
if let Some((env_annotation, new_line)) = extract_env_annotation(line) {
|
||||
pending_env = Some(env_annotation);
|
||||
if !new_line.trim().is_empty() {
|
||||
result.push_str(&new_line);
|
||||
// Add a period, if the line doesn't end with punctuation.
|
||||
if !new_line.ends_with('.') && !new_line.ends_with(':') {
|
||||
result.push('.');
|
||||
}
|
||||
result.push('\n');
|
||||
}
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
result.push_str(line);
|
||||
result.push('\n');
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// Flush any remaining pending environment variables at the end of the help.
|
||||
if let Some(env) = pending_env {
|
||||
while result.ends_with("\n\n") {
|
||||
result.pop();
|
||||
}
|
||||
if !result.ends_with('\n') {
|
||||
result.push('\n');
|
||||
}
|
||||
result.push('\n');
|
||||
let _ = writeln!(result, " {env}");
|
||||
}
|
||||
|
||||
if result.ends_with('\n') {
|
||||
result.pop();
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Extract an inline `[env: VAR=]` annotation from a line.
|
||||
///
|
||||
/// Returns the annotation and the line with the annotation removed, or `None` if no
|
||||
/// annotation is found.
|
||||
fn extract_env_annotation(line: &str) -> Option<(String, String)> {
|
||||
// Look for the pattern: " [env: SOMETHING=]"
|
||||
let start = line.find(" [env: ")?;
|
||||
let rest = &line[start + " [env: ".len()..];
|
||||
let end_offset = rest.find("=]")?;
|
||||
|
||||
// Validate that the environment variable name contains only uppercase letters and underscores.
|
||||
let env_name = &rest[..end_offset];
|
||||
if !env_name.chars().all(|c| c.is_ascii_uppercase() || c == '_') {
|
||||
return None;
|
||||
}
|
||||
|
||||
let annotation_end = start + " [env: ".len() + end_offset + "=]".len();
|
||||
let annotation = line[start + " ".len()..annotation_end].to_string();
|
||||
let new_line = format!("{}{}", &line[..start], &line[annotation_end..]);
|
||||
|
||||
// Only extract if there's actual text remaining (not just whitespace).
|
||||
// If the line is just the annotation (clap-generated), leave it alone.
|
||||
if new_line.trim().is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some((annotation, new_line))
|
||||
}
|
||||
|
||||
/// Find the command corresponding to a set of arguments, e.g., `["uv", "pip", "install"]`.
|
||||
///
|
||||
/// If the command cannot be found, the nearest command is returned.
|
||||
|
||||
@@ -57,14 +57,14 @@ use crate::commands::project::{
|
||||
use crate::commands::reporters::{PythonDownloadReporter, ResolverReporter};
|
||||
use crate::commands::{ExitStatus, ScriptPath, diagnostics, project};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::{LockCheck, ResolverInstallerSettings};
|
||||
use crate::settings::{FrozenSource, LockCheck, ResolverInstallerSettings};
|
||||
|
||||
/// Add one or more packages to the project requirements.
|
||||
#[allow(clippy::fn_params_excessive_bools)]
|
||||
pub(crate) async fn add(
|
||||
project_dir: &Path,
|
||||
lock_check: LockCheck,
|
||||
frozen: bool,
|
||||
frozen: Option<FrozenSource>,
|
||||
active: Option<bool>,
|
||||
no_sync: bool,
|
||||
no_install_project: bool,
|
||||
@@ -187,7 +187,7 @@ pub(crate) async fn add(
|
||||
"`{lock_check}` is a no-op for Python scripts with inline metadata, which always run in isolation"
|
||||
);
|
||||
}
|
||||
if frozen {
|
||||
if frozen.is_some() {
|
||||
warn_user_once!(
|
||||
"`--frozen` is a no-op for Python scripts with inline metadata, which always run in isolation"
|
||||
);
|
||||
@@ -291,7 +291,7 @@ pub(crate) async fn add(
|
||||
defaulted_groups =
|
||||
groups.with_defaults(default_dependency_groups(project.pyproject_toml())?);
|
||||
|
||||
if frozen || no_sync {
|
||||
if frozen.is_some() || no_sync {
|
||||
// Discover the interpreter.
|
||||
let interpreter = ProjectInterpreter::discover(
|
||||
project.workspace(),
|
||||
@@ -706,7 +706,7 @@ pub(crate) async fn add(
|
||||
|
||||
// If `--frozen`, exit early. There's no reason to lock and sync, since we don't need a `uv.lock`
|
||||
// to exist at all.
|
||||
if frozen {
|
||||
if frozen.is_some() {
|
||||
return Ok(ExitStatus::Success);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,12 @@ use crate::commands::project::install_target::InstallTarget;
|
||||
use crate::commands::project::lock::{LockMode, LockOperation};
|
||||
use crate::commands::project::lock_target::LockTarget;
|
||||
use crate::commands::project::{
|
||||
MissingLockfileSource, ProjectError, ProjectInterpreter, ScriptInterpreter, UniversalState,
|
||||
default_dependency_groups, detect_conflicts,
|
||||
ProjectError, ProjectInterpreter, ScriptInterpreter, UniversalState, default_dependency_groups,
|
||||
detect_conflicts,
|
||||
};
|
||||
use crate::commands::{ExitStatus, OutputWriter, diagnostics};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::{LockCheck, ResolverSettings};
|
||||
use crate::settings::{FrozenSource, LockCheck, ResolverSettings};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
@@ -68,7 +68,7 @@ pub(crate) async fn export(
|
||||
groups: DependencyGroups,
|
||||
editable: Option<EditableMode>,
|
||||
lock_check: LockCheck,
|
||||
frozen: bool,
|
||||
frozen: Option<FrozenSource>,
|
||||
include_annotations: bool,
|
||||
include_header: bool,
|
||||
script: Option<Pep723Script>,
|
||||
@@ -90,7 +90,7 @@ pub(crate) async fn export(
|
||||
let target = if let Some(script) = script {
|
||||
ExportTarget::Script(script)
|
||||
} else {
|
||||
let project = if frozen {
|
||||
let project = if frozen.is_some() {
|
||||
VirtualProject::discover(
|
||||
project_dir,
|
||||
&DiscoveryOptions {
|
||||
@@ -142,7 +142,7 @@ pub(crate) async fn export(
|
||||
let extras = extras.with_defaults(default_extras);
|
||||
|
||||
// Find an interpreter for the project, unless `--frozen` is set.
|
||||
let interpreter = if frozen {
|
||||
let interpreter = if frozen.is_some() {
|
||||
None
|
||||
} else {
|
||||
Some(match &target {
|
||||
@@ -184,8 +184,8 @@ pub(crate) async fn export(
|
||||
};
|
||||
|
||||
// Determine the lock mode.
|
||||
let mode = if frozen {
|
||||
LockMode::Frozen(MissingLockfileSource::frozen())
|
||||
let mode = if let Some(frozen_source) = frozen {
|
||||
LockMode::Frozen(frozen_source.into())
|
||||
} else if let LockCheck::Enabled(lock_check) = lock_check {
|
||||
LockMode::Locked(interpreter.as_ref().unwrap(), lock_check)
|
||||
} else if matches!(target, ExportTarget::Script(_))
|
||||
|
||||
@@ -49,7 +49,7 @@ use crate::commands::project::{
|
||||
use crate::commands::reporters::{PythonDownloadReporter, ResolverReporter};
|
||||
use crate::commands::{ExitStatus, ScriptPath, diagnostics, pip};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::{LockCheck, LockCheckSource, ResolverSettings};
|
||||
use crate::settings::{FrozenSource, LockCheck, LockCheckSource, ResolverSettings};
|
||||
|
||||
/// The result of running a lock operation.
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -82,7 +82,7 @@ impl LockResult {
|
||||
pub(crate) async fn lock(
|
||||
project_dir: &Path,
|
||||
lock_check: LockCheck,
|
||||
frozen: bool,
|
||||
frozen: Option<FrozenSource>,
|
||||
dry_run: DryRun,
|
||||
refresh: Refresh,
|
||||
python: Option<String>,
|
||||
@@ -136,8 +136,8 @@ pub(crate) async fn lock(
|
||||
|
||||
// Determine the lock mode.
|
||||
let interpreter;
|
||||
let mode = if frozen {
|
||||
LockMode::Frozen(MissingLockfileSource::frozen())
|
||||
let mode = if let Some(frozen_source) = frozen {
|
||||
LockMode::Frozen(frozen_source.into())
|
||||
} else {
|
||||
interpreter = match target {
|
||||
LockTarget::Workspace(workspace) => ProjectInterpreter::discover(
|
||||
|
||||
@@ -41,7 +41,7 @@ use uv_resolver::{
|
||||
ResolverEnvironment, ResolverOutput,
|
||||
};
|
||||
use uv_scripts::Pep723ItemRef;
|
||||
use uv_settings::{PythonInstallMirrors, parse_boolish_environment_variable};
|
||||
use uv_settings::PythonInstallMirrors;
|
||||
use uv_static::EnvVars;
|
||||
use uv_torch::{TorchSource, TorchStrategy};
|
||||
use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy};
|
||||
@@ -58,7 +58,8 @@ use crate::commands::reporters::{PythonDownloadReporter, ResolverReporter};
|
||||
use crate::commands::{capitalize, conjunction, pip};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::{
|
||||
InstallerSettingsRef, LockCheckSource, ResolverInstallerSettings, ResolverSettings,
|
||||
FrozenSource, InstallerSettingsRef, LockCheckSource, ResolverInstallerSettings,
|
||||
ResolverSettings,
|
||||
};
|
||||
|
||||
pub(crate) mod add;
|
||||
@@ -82,10 +83,14 @@ pub(crate) enum MissingLockfileSource {
|
||||
Frozen,
|
||||
/// The `UV_FROZEN` environment variable was set.
|
||||
FrozenEnv,
|
||||
/// The `frozen` option was set via workspace configuration.
|
||||
FrozenConfiguration,
|
||||
/// The `--locked` flag was provided.
|
||||
Locked,
|
||||
/// The `UV_LOCKED` environment variable was set.
|
||||
LockedEnv,
|
||||
/// The `locked` option was set via workspace configuration.
|
||||
LockedConfiguration,
|
||||
/// The `--check` flag was provided.
|
||||
Check,
|
||||
}
|
||||
@@ -95,8 +100,10 @@ impl std::fmt::Display for MissingLockfileSource {
|
||||
match self {
|
||||
Self::Frozen => write!(f, "`--frozen`"),
|
||||
Self::FrozenEnv => write!(f, "`UV_FROZEN=1`"),
|
||||
Self::FrozenConfiguration => write!(f, "`frozen` (workspace configuration)"),
|
||||
Self::Locked => write!(f, "`--locked`"),
|
||||
Self::LockedEnv => write!(f, "`UV_LOCKED=1`"),
|
||||
Self::LockedConfiguration => write!(f, "`locked` (workspace configuration)"),
|
||||
Self::Check => write!(f, "`--check`"),
|
||||
}
|
||||
}
|
||||
@@ -105,38 +112,20 @@ impl std::fmt::Display for MissingLockfileSource {
|
||||
impl From<LockCheckSource> for MissingLockfileSource {
|
||||
fn from(source: LockCheckSource) -> Self {
|
||||
match source {
|
||||
LockCheckSource::Locked => {
|
||||
// TODO(charlie): Track the source (flag vs. environment variable) when resolving
|
||||
// settings, rather than checking after-the-fact.
|
||||
if matches!(
|
||||
parse_boolish_environment_variable(EnvVars::UV_LOCKED),
|
||||
Ok(Some(true))
|
||||
) {
|
||||
Self::LockedEnv
|
||||
} else {
|
||||
Self::Locked
|
||||
}
|
||||
}
|
||||
LockCheckSource::LockedCli => Self::Locked,
|
||||
LockCheckSource::LockedEnv => Self::LockedEnv,
|
||||
LockCheckSource::LockedConfiguration => Self::LockedConfiguration,
|
||||
LockCheckSource::Check => Self::Check,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MissingLockfileSource {
|
||||
/// Determine the source of the frozen flag.
|
||||
///
|
||||
/// If `UV_FROZEN` is set to a truthy value in the environment, the source is the environment
|
||||
/// variable. Otherwise, the source is the `--frozen` flag.
|
||||
pub(crate) fn frozen() -> Self {
|
||||
// TODO(charlie): Track the source (flag vs. environment variable) when resolving
|
||||
// settings, rather than checking after-the-fact.
|
||||
if matches!(
|
||||
parse_boolish_environment_variable(EnvVars::UV_FROZEN),
|
||||
Ok(Some(true))
|
||||
) {
|
||||
Self::FrozenEnv
|
||||
} else {
|
||||
Self::Frozen
|
||||
impl From<FrozenSource> for MissingLockfileSource {
|
||||
fn from(source: FrozenSource) -> Self {
|
||||
match source {
|
||||
FrozenSource::Cli => Self::Frozen,
|
||||
FrozenSource::Env => Self::FrozenEnv,
|
||||
FrozenSource::Configuration => Self::FrozenConfiguration,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ use crate::commands::project::{
|
||||
};
|
||||
use crate::commands::{ExitStatus, diagnostics, project};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::{LockCheck, ResolverInstallerSettings};
|
||||
use crate::settings::{FrozenSource, LockCheck, ResolverInstallerSettings};
|
||||
|
||||
/// Remove one or more packages from the project requirements.
|
||||
#[allow(clippy::fn_params_excessive_bools)]
|
||||
pub(crate) async fn remove(
|
||||
project_dir: &Path,
|
||||
lock_check: LockCheck,
|
||||
frozen: bool,
|
||||
frozen: Option<FrozenSource>,
|
||||
active: Option<bool>,
|
||||
no_sync: bool,
|
||||
packages: Vec<PackageName>,
|
||||
@@ -75,7 +75,7 @@ pub(crate) async fn remove(
|
||||
"`{lock_check}` is a no-op for Python scripts with inline metadata, which always run in isolation",
|
||||
);
|
||||
}
|
||||
if frozen {
|
||||
if frozen.is_some() {
|
||||
warn_user_once!(
|
||||
"`--frozen` is a no-op for Python scripts with inline metadata, which always run in isolation"
|
||||
);
|
||||
@@ -184,7 +184,7 @@ pub(crate) async fn remove(
|
||||
|
||||
// If `--frozen`, exit early. There's no reason to lock and sync, since we don't need a `uv.lock`
|
||||
// to exist at all.
|
||||
if frozen {
|
||||
if frozen.is_some() {
|
||||
return Ok(ExitStatus::Success);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,15 +65,15 @@ use crate::commands::project::install_target::InstallTarget;
|
||||
use crate::commands::project::lock::LockMode;
|
||||
use crate::commands::project::lock_target::LockTarget;
|
||||
use crate::commands::project::{
|
||||
EnvironmentSpecification, MissingLockfileSource, PreferenceLocation, ProjectEnvironment,
|
||||
ProjectError, ScriptEnvironment, ScriptInterpreter, UniversalState, WorkspacePython,
|
||||
EnvironmentSpecification, PreferenceLocation, ProjectEnvironment, ProjectError,
|
||||
ScriptEnvironment, ScriptInterpreter, UniversalState, WorkspacePython,
|
||||
default_dependency_groups, script_extra_build_requires, script_specification,
|
||||
update_environment, validate_project_requires_python,
|
||||
};
|
||||
use crate::commands::reporters::PythonDownloadReporter;
|
||||
use crate::commands::{ExitStatus, diagnostics, project};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::{LockCheck, ResolverInstallerSettings, ResolverSettings};
|
||||
use crate::settings::{FrozenSource, LockCheck, ResolverInstallerSettings, ResolverSettings};
|
||||
|
||||
/// Run a command.
|
||||
#[allow(clippy::fn_params_excessive_bools)]
|
||||
@@ -84,7 +84,7 @@ pub(crate) async fn run(
|
||||
requirements: Vec<RequirementsSource>,
|
||||
show_resolution: bool,
|
||||
lock_check: LockCheck,
|
||||
frozen: bool,
|
||||
frozen: Option<FrozenSource>,
|
||||
active: Option<bool>,
|
||||
no_sync: bool,
|
||||
isolated: bool,
|
||||
@@ -262,8 +262,8 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
|
||||
.ok();
|
||||
|
||||
// Determine the lock mode.
|
||||
let mode = if frozen {
|
||||
LockMode::Frozen(MissingLockfileSource::frozen())
|
||||
let mode = if let Some(frozen_source) = frozen {
|
||||
LockMode::Frozen(frozen_source.into())
|
||||
} else if let LockCheck::Enabled(lock_check) = lock_check {
|
||||
LockMode::Locked(environment.interpreter(), lock_check)
|
||||
} else {
|
||||
@@ -364,7 +364,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
|
||||
"uv lock --script".green(),
|
||||
);
|
||||
}
|
||||
if frozen {
|
||||
if frozen.is_some() {
|
||||
warn_user!(
|
||||
"No lockfile found for Python script (ignoring `--frozen`); run `{}` to generate a lockfile",
|
||||
"uv lock --script".green(),
|
||||
@@ -601,7 +601,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
|
||||
if let LockCheck::Enabled(lock_check) = lock_check {
|
||||
warn_user!("`{lock_check}` has no effect when used alongside `--no-project`");
|
||||
}
|
||||
if frozen {
|
||||
if frozen.is_some() {
|
||||
warn_user!("`--frozen` has no effect when used alongside `--no-project`");
|
||||
}
|
||||
if no_sync {
|
||||
@@ -748,8 +748,8 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
|
||||
.ok();
|
||||
|
||||
// Determine the lock mode.
|
||||
let mode = if frozen {
|
||||
LockMode::Frozen(MissingLockfileSource::frozen())
|
||||
let mode = if let Some(frozen_source) = frozen {
|
||||
LockMode::Frozen(frozen_source.into())
|
||||
} else if let LockCheck::Enabled(lock_check) = lock_check {
|
||||
LockMode::Locked(venv.interpreter(), lock_check)
|
||||
} else if isolated {
|
||||
|
||||
@@ -44,14 +44,15 @@ use crate::commands::project::install_target::InstallTarget;
|
||||
use crate::commands::project::lock::{LockMode, LockOperation, LockResult};
|
||||
use crate::commands::project::lock_target::LockTarget;
|
||||
use crate::commands::project::{
|
||||
EnvironmentUpdate, MissingLockfileSource, PlatformState, ProjectEnvironment, ProjectError,
|
||||
ScriptEnvironment, UniversalState, default_dependency_groups, detect_conflicts,
|
||||
script_extra_build_requires, script_specification, update_environment,
|
||||
EnvironmentUpdate, PlatformState, ProjectEnvironment, ProjectError, ScriptEnvironment,
|
||||
UniversalState, default_dependency_groups, detect_conflicts, script_extra_build_requires,
|
||||
script_specification, update_environment,
|
||||
};
|
||||
use crate::commands::{ExitStatus, diagnostics};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::{
|
||||
InstallerSettingsRef, LockCheck, LockCheckSource, ResolverInstallerSettings, ResolverSettings,
|
||||
FrozenSource, InstallerSettingsRef, LockCheck, LockCheckSource, ResolverInstallerSettings,
|
||||
ResolverSettings,
|
||||
};
|
||||
|
||||
/// Sync the project environment.
|
||||
@@ -59,7 +60,7 @@ use crate::settings::{
|
||||
pub(crate) async fn sync(
|
||||
project_dir: &Path,
|
||||
lock_check: LockCheck,
|
||||
frozen: bool,
|
||||
frozen: Option<FrozenSource>,
|
||||
dry_run: DryRun,
|
||||
active: Option<bool>,
|
||||
all_packages: bool,
|
||||
@@ -99,7 +100,7 @@ pub(crate) async fn sync(
|
||||
SyncTarget::Script(script)
|
||||
} else {
|
||||
// Identify the project.
|
||||
let project = if frozen {
|
||||
let project = if frozen.is_some() {
|
||||
VirtualProject::discover(
|
||||
project_dir,
|
||||
&DiscoveryOptions {
|
||||
@@ -225,7 +226,7 @@ pub(crate) async fn sync(
|
||||
if let SyncTarget::Script(script) = &target {
|
||||
let lockfile = LockTarget::from(script).lock_path();
|
||||
if !lockfile.is_file() {
|
||||
if frozen {
|
||||
if frozen.is_some() {
|
||||
return Err(anyhow::anyhow!(
|
||||
"`uv sync --frozen` requires a script lockfile; run `{}` to lock the script",
|
||||
format!("uv lock --script {}", script.path.user_display()).green(),
|
||||
@@ -329,8 +330,8 @@ pub(crate) async fn sync(
|
||||
let state = UniversalState::default();
|
||||
|
||||
// Determine the lock mode.
|
||||
let mode = if frozen {
|
||||
LockMode::Frozen(MissingLockfileSource::frozen())
|
||||
let mode = if let Some(frozen_source) = frozen {
|
||||
LockMode::Frozen(frozen_source.into())
|
||||
} else if let LockCheck::Enabled(lock_check) = lock_check {
|
||||
LockMode::Locked(environment.interpreter(), lock_check)
|
||||
} else if dry_run.enabled() {
|
||||
|
||||
@@ -24,12 +24,12 @@ use crate::commands::pip::resolution_markers;
|
||||
use crate::commands::project::lock::{LockMode, LockOperation};
|
||||
use crate::commands::project::lock_target::LockTarget;
|
||||
use crate::commands::project::{
|
||||
MissingLockfileSource, ProjectError, ProjectInterpreter, ScriptInterpreter, UniversalState,
|
||||
default_dependency_groups,
|
||||
ProjectError, ProjectInterpreter, ScriptInterpreter, UniversalState, default_dependency_groups,
|
||||
};
|
||||
use crate::commands::reporters::LatestVersionReporter;
|
||||
use crate::commands::{ExitStatus, diagnostics};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::FrozenSource;
|
||||
use crate::settings::LockCheck;
|
||||
use crate::settings::ResolverSettings;
|
||||
|
||||
@@ -39,7 +39,7 @@ pub(crate) async fn tree(
|
||||
project_dir: &Path,
|
||||
groups: DependencyGroups,
|
||||
lock_check: LockCheck,
|
||||
frozen: bool,
|
||||
frozen: Option<FrozenSource>,
|
||||
universal: bool,
|
||||
depth: u8,
|
||||
prune: Vec<PackageName>,
|
||||
@@ -83,7 +83,7 @@ pub(crate) async fn tree(
|
||||
let groups = groups.with_defaults(default_groups);
|
||||
|
||||
// Find an interpreter for the project, unless `--frozen` and `--universal` are both set.
|
||||
let interpreter = if frozen && universal {
|
||||
let interpreter = if frozen.is_some() && universal {
|
||||
None
|
||||
} else {
|
||||
Some(match target {
|
||||
@@ -125,8 +125,8 @@ pub(crate) async fn tree(
|
||||
};
|
||||
|
||||
// Determine the lock mode.
|
||||
let mode = if frozen {
|
||||
LockMode::Frozen(MissingLockfileSource::frozen())
|
||||
let mode = if let Some(frozen_source) = frozen {
|
||||
LockMode::Frozen(frozen_source.into())
|
||||
} else if let LockCheck::Enabled(lock_check) = lock_check {
|
||||
LockMode::Locked(interpreter.as_ref().unwrap(), lock_check)
|
||||
} else if matches!(target, LockTarget::Script(_)) && !target.lock_path().is_file() {
|
||||
|
||||
@@ -34,12 +34,11 @@ use crate::commands::project::add::{AddTarget, PythonTarget};
|
||||
use crate::commands::project::install_target::InstallTarget;
|
||||
use crate::commands::project::lock::LockMode;
|
||||
use crate::commands::project::{
|
||||
MissingLockfileSource, ProjectEnvironment, ProjectError, ProjectInterpreter, UniversalState,
|
||||
default_dependency_groups,
|
||||
ProjectEnvironment, ProjectError, ProjectInterpreter, UniversalState, default_dependency_groups,
|
||||
};
|
||||
use crate::commands::{ExitStatus, diagnostics, project};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::{LockCheck, ResolverInstallerSettings};
|
||||
use crate::settings::{FrozenSource, LockCheck, ResolverInstallerSettings};
|
||||
|
||||
/// Display version information for uv itself (`uv self version`)
|
||||
pub(crate) fn self_version(
|
||||
@@ -65,7 +64,7 @@ pub(crate) async fn project_version(
|
||||
explicit_project: bool,
|
||||
dry_run: bool,
|
||||
lock_check: LockCheck,
|
||||
frozen: bool,
|
||||
frozen: Option<FrozenSource>,
|
||||
active: Option<bool>,
|
||||
no_sync: bool,
|
||||
python: Option<String>,
|
||||
@@ -94,27 +93,30 @@ pub(crate) async fn project_version(
|
||||
|
||||
// Short-circuit early for a frozen read
|
||||
let is_read_only = value.is_none() && bump.is_empty();
|
||||
if frozen && is_read_only {
|
||||
return Box::pin(print_frozen_version(
|
||||
project,
|
||||
&name,
|
||||
project_dir,
|
||||
active,
|
||||
python,
|
||||
install_mirrors,
|
||||
&settings,
|
||||
client_builder,
|
||||
python_preference,
|
||||
python_downloads,
|
||||
concurrency,
|
||||
no_config,
|
||||
cache,
|
||||
short,
|
||||
output_format,
|
||||
printer,
|
||||
preview,
|
||||
))
|
||||
.await;
|
||||
if let Some(frozen_source) = frozen {
|
||||
if is_read_only {
|
||||
return Box::pin(print_frozen_version(
|
||||
project,
|
||||
&name,
|
||||
project_dir,
|
||||
frozen_source,
|
||||
active,
|
||||
python,
|
||||
install_mirrors,
|
||||
&settings,
|
||||
client_builder,
|
||||
python_preference,
|
||||
python_downloads,
|
||||
concurrency,
|
||||
no_config,
|
||||
cache,
|
||||
short,
|
||||
output_format,
|
||||
printer,
|
||||
preview,
|
||||
))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
let mut toml = PyProjectTomlMut::from_toml(
|
||||
@@ -422,6 +424,7 @@ async fn print_frozen_version(
|
||||
project: VirtualProject,
|
||||
name: &PackageName,
|
||||
project_dir: &Path,
|
||||
frozen_source: FrozenSource,
|
||||
active: Option<bool>,
|
||||
python: Option<String>,
|
||||
install_mirrors: PythonInstallMirrors,
|
||||
@@ -465,7 +468,7 @@ async fn print_frozen_version(
|
||||
// Lock and sync the environment, if necessary.
|
||||
let lock = match Box::pin(
|
||||
project::lock::LockOperation::new(
|
||||
LockMode::Frozen(MissingLockfileSource::frozen()),
|
||||
LockMode::Frozen(frozen_source.into()),
|
||||
&settings.resolver,
|
||||
&client_builder,
|
||||
&state,
|
||||
@@ -518,7 +521,7 @@ async fn lock_and_sync(
|
||||
project: VirtualProject,
|
||||
project_dir: &Path,
|
||||
lock_check: LockCheck,
|
||||
frozen: bool,
|
||||
frozen: Option<FrozenSource>,
|
||||
active: Option<bool>,
|
||||
no_sync: bool,
|
||||
python: Option<String>,
|
||||
@@ -535,7 +538,7 @@ async fn lock_and_sync(
|
||||
preview: Preview,
|
||||
) -> Result<ExitStatus> {
|
||||
// If frozen, don't touch the lock or sync at all
|
||||
if frozen {
|
||||
if frozen.is_some() {
|
||||
return Ok(ExitStatus::Success);
|
||||
}
|
||||
|
||||
|
||||
@@ -567,6 +567,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||
let args = PipCompileSettings::resolve(args, filesystem, environment);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -677,6 +682,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||
let args = PipSyncSettings::resolve(args, filesystem, environment);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -840,6 +850,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||
}
|
||||
}
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -1101,6 +1116,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||
let args = settings::BuildSettings::resolve(args, filesystem, environment);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -1162,6 +1182,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||
let args = settings::VenvSettings::resolve(args, filesystem, environment);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -1325,6 +1350,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||
);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -1410,6 +1440,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||
let args = settings::ToolInstallSettings::resolve(args, filesystem, environment);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -1951,6 +1986,11 @@ async fn run_project(
|
||||
let args = settings::RunSettings::resolve(args, filesystem, environment);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -2015,6 +2055,11 @@ async fn run_project(
|
||||
let args = settings::SyncSettings::resolve(args, filesystem, environment);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -2065,6 +2110,11 @@ async fn run_project(
|
||||
let args = settings::LockSettings::resolve(args, filesystem, environment);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -2177,6 +2227,11 @@ async fn run_project(
|
||||
}
|
||||
}
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -2240,6 +2295,11 @@ async fn run_project(
|
||||
let args = settings::RemoveSettings::resolve(args, filesystem, environment);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
@@ -2284,6 +2344,11 @@ async fn run_project(
|
||||
let args = settings::VersionSettings::resolve(args, filesystem, environment);
|
||||
show_settings!(args);
|
||||
|
||||
// Check for conflicts between offline and refresh.
|
||||
globals
|
||||
.network_settings
|
||||
.check_refresh_conflict(&args.refresh);
|
||||
|
||||
// Initialize the cache.
|
||||
let cache = cache.init().await?.with_refresh(
|
||||
args.refresh
|
||||
|
||||
@@ -21,7 +21,10 @@ use uv_cli::{
|
||||
use uv_cli::{
|
||||
AuthorFrom, BuildArgs, ExportArgs, FormatArgs, PublishArgs, PythonDirArgs,
|
||||
ResolverInstallerArgs, ToolUpgradeArgs,
|
||||
options::{flag, resolver_installer_options, resolver_options},
|
||||
options::{
|
||||
Flag, FlagSource, check_conflicts, flag, resolve_flag, resolver_installer_options,
|
||||
resolver_options,
|
||||
},
|
||||
};
|
||||
use uv_client::Connectivity;
|
||||
use uv_configuration::{
|
||||
@@ -87,7 +90,7 @@ impl GlobalSettings {
|
||||
environment: &EnvironmentOptions,
|
||||
) -> Self {
|
||||
let network_settings = NetworkSettings::resolve(args, workspace, environment);
|
||||
let python_preference = resolve_python_preference(args, workspace);
|
||||
let python_preference = resolve_python_preference(args, workspace, environment);
|
||||
Self {
|
||||
required_version: workspace
|
||||
.and_then(|workspace| workspace.globals.required_version.clone()),
|
||||
@@ -140,9 +143,7 @@ impl GlobalSettings {
|
||||
},
|
||||
show_settings: args.show_settings,
|
||||
preview: Preview::from_args(
|
||||
flag(args.preview, args.no_preview, "preview")
|
||||
.combine(workspace.and_then(|workspace| workspace.globals.preview))
|
||||
.unwrap_or(false),
|
||||
resolve_preview(args, workspace, environment),
|
||||
args.no_preview,
|
||||
&args.preview_features,
|
||||
),
|
||||
@@ -158,8 +159,15 @@ impl GlobalSettings {
|
||||
.unwrap_or_default(),
|
||||
// Disable the progress bar with `RUST_LOG` to avoid progress fragments interleaving
|
||||
// with log messages.
|
||||
no_progress: args.no_progress || std::env::var_os(EnvVars::RUST_LOG).is_some(),
|
||||
installer_metadata: !args.no_installer_metadata,
|
||||
no_progress: resolve_flag(args.no_progress, "no-progress", environment.no_progress)
|
||||
.is_enabled()
|
||||
|| std::env::var_os(EnvVars::RUST_LOG).is_some(),
|
||||
installer_metadata: !resolve_flag(
|
||||
args.no_installer_metadata,
|
||||
"no-installer-metadata",
|
||||
environment.no_installer_metadata,
|
||||
)
|
||||
.is_enabled(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,10 +175,33 @@ impl GlobalSettings {
|
||||
fn resolve_python_preference(
|
||||
args: &GlobalArgs,
|
||||
workspace: Option<&FilesystemOptions>,
|
||||
environment: &EnvironmentOptions,
|
||||
) -> PythonPreference {
|
||||
if args.managed_python {
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let managed_python = resolve_flag(
|
||||
args.managed_python,
|
||||
"managed-python",
|
||||
environment.managed_python,
|
||||
);
|
||||
let no_managed_python = resolve_flag(
|
||||
args.no_managed_python,
|
||||
"no-managed-python",
|
||||
environment.no_managed_python,
|
||||
);
|
||||
|
||||
// Check for conflicts between managed_python and python_preference.
|
||||
if managed_python.is_enabled() && args.python_preference.is_some() {
|
||||
check_conflicts(managed_python, Flag::from_cli("python-preference"));
|
||||
}
|
||||
|
||||
// Check for conflicts between no_managed_python and python_preference.
|
||||
if no_managed_python.is_enabled() && args.python_preference.is_some() {
|
||||
check_conflicts(no_managed_python, Flag::from_cli("python-preference"));
|
||||
}
|
||||
|
||||
if managed_python.is_enabled() {
|
||||
PythonPreference::OnlyManaged
|
||||
} else if args.no_managed_python {
|
||||
} else if no_managed_python.is_enabled() {
|
||||
PythonPreference::OnlySystem
|
||||
} else {
|
||||
args.python_preference
|
||||
@@ -179,10 +210,34 @@ fn resolve_python_preference(
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve the preview setting from CLI, environment, and workspace config.
|
||||
fn resolve_preview(
|
||||
args: &GlobalArgs,
|
||||
workspace: Option<&FilesystemOptions>,
|
||||
environment: &EnvironmentOptions,
|
||||
) -> bool {
|
||||
// CLI takes precedence
|
||||
match flag(args.preview, args.no_preview, "preview") {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
// Check environment variable
|
||||
if environment.preview.value == Some(true) {
|
||||
true
|
||||
} else {
|
||||
// Fall back to workspace config
|
||||
workspace
|
||||
.and_then(|workspace| workspace.globals.preview)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The resolved network settings to use for any invocation of the CLI.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct NetworkSettings {
|
||||
pub(crate) connectivity: Connectivity,
|
||||
pub(crate) offline: Flag,
|
||||
pub(crate) native_tls: bool,
|
||||
pub(crate) http_proxy: Option<ProxyUrl>,
|
||||
pub(crate) https_proxy: Option<ProxyUrl>,
|
||||
@@ -198,17 +253,45 @@ impl NetworkSettings {
|
||||
workspace: Option<&FilesystemOptions>,
|
||||
environment: &EnvironmentOptions,
|
||||
) -> Self {
|
||||
let connectivity = if flag(args.offline, args.no_offline, "offline")
|
||||
.combine(workspace.and_then(|workspace| workspace.globals.offline))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
// Resolve offline flag from CLI, environment variable, and workspace config.
|
||||
// Precedence: CLI > Env var > Workspace config > default (false).
|
||||
let offline = match flag(args.offline, args.no_offline, "offline") {
|
||||
Some(true) => Flag::from_cli("offline"),
|
||||
Some(false) => Flag::disabled(),
|
||||
None => {
|
||||
// CLI didn't provide a value, check environment variable.
|
||||
let env_flag = resolve_flag(false, "offline", environment.offline);
|
||||
if env_flag.is_enabled() {
|
||||
env_flag
|
||||
} else if workspace
|
||||
.and_then(|workspace| workspace.globals.offline)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
// Workspace config enabled offline mode.
|
||||
Flag::from_config("offline")
|
||||
} else {
|
||||
Flag::disabled()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let connectivity = if offline.is_enabled() {
|
||||
Connectivity::Offline
|
||||
} else {
|
||||
Connectivity::Online
|
||||
};
|
||||
let native_tls = flag(args.native_tls, args.no_native_tls, "native-tls")
|
||||
.combine(workspace.and_then(|workspace| workspace.globals.native_tls))
|
||||
.unwrap_or(false);
|
||||
let native_tls = match flag(args.native_tls, args.no_native_tls, "native-tls") {
|
||||
Some(value) => value,
|
||||
None => {
|
||||
if environment.native_tls.value == Some(true) {
|
||||
true
|
||||
} else {
|
||||
workspace
|
||||
.and_then(|workspace| workspace.globals.native_tls)
|
||||
.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
};
|
||||
let allow_insecure_host = args
|
||||
.allow_insecure_host
|
||||
.as_ref()
|
||||
@@ -232,6 +315,7 @@ impl NetworkSettings {
|
||||
|
||||
Self {
|
||||
connectivity,
|
||||
offline,
|
||||
native_tls,
|
||||
http_proxy,
|
||||
https_proxy,
|
||||
@@ -241,6 +325,19 @@ impl NetworkSettings {
|
||||
retries: environment.http_retries,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if offline mode conflicts with a refresh request.
|
||||
///
|
||||
/// This should be called when a command uses refresh functionality to ensure
|
||||
/// offline mode and refresh are not both enabled.
|
||||
pub(crate) fn check_refresh_conflict(&self, refresh: &Refresh) {
|
||||
if !matches!(refresh, Refresh::None(_)) {
|
||||
// TODO(charlie): `Refresh` isn't a `Flag`, so we create a synthetic one here
|
||||
// (which matches Clap's representation). Consider a dedicated helper for
|
||||
// conflicts with CLI-only arguments.
|
||||
check_conflicts(self.offline, Flag::from_cli("refresh"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The resolved cache settings to use for any invocation of the CLI.
|
||||
@@ -363,7 +460,11 @@ impl InitSettings {
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub(crate) enum LockCheckSource {
|
||||
/// The user invoked `uv <command> --locked`
|
||||
Locked,
|
||||
LockedCli,
|
||||
/// The `UV_LOCKED` environment variable was set.
|
||||
LockedEnv,
|
||||
/// The `locked` option was set via workspace configuration.
|
||||
LockedConfiguration,
|
||||
/// The user invoked `uv <command> --check`
|
||||
Check,
|
||||
}
|
||||
@@ -371,7 +472,9 @@ pub(crate) enum LockCheckSource {
|
||||
impl std::fmt::Display for LockCheckSource {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Locked => write!(f, "--locked"),
|
||||
Self::LockedCli => write!(f, "--locked"),
|
||||
Self::LockedEnv => write!(f, "UV_LOCKED=1"),
|
||||
Self::LockedConfiguration => write!(f, "locked (workspace configuration)"),
|
||||
Self::Check => write!(f, "--check"),
|
||||
}
|
||||
}
|
||||
@@ -386,11 +489,48 @@ pub(crate) enum LockCheck {
|
||||
Disabled,
|
||||
}
|
||||
|
||||
/// The source of the frozen flag.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub(crate) enum FrozenSource {
|
||||
/// The `--frozen` flag was provided on CLI.
|
||||
Cli,
|
||||
/// The `UV_FROZEN` environment variable was set.
|
||||
Env,
|
||||
/// The `frozen` option was set via workspace configuration.
|
||||
Configuration,
|
||||
}
|
||||
|
||||
/// Convert a resolved flag to an optional frozen source.
|
||||
fn resolve_frozen(flag: Flag) -> Option<FrozenSource> {
|
||||
if flag.is_enabled() {
|
||||
Some(match flag.source() {
|
||||
Some(FlagSource::Cli) | None => FrozenSource::Cli,
|
||||
Some(FlagSource::Env(_)) => FrozenSource::Env,
|
||||
Some(FlagSource::Config) => FrozenSource::Configuration,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a resolved flag to a lock check.
|
||||
fn resolve_lock_check(flag: Flag) -> LockCheck {
|
||||
if flag.is_enabled() {
|
||||
LockCheck::Enabled(match flag.source() {
|
||||
Some(FlagSource::Cli) | None => LockCheckSource::LockedCli,
|
||||
Some(FlagSource::Env(_)) => LockCheckSource::LockedEnv,
|
||||
Some(FlagSource::Config) => LockCheckSource::LockedConfiguration,
|
||||
})
|
||||
} else {
|
||||
LockCheck::Disabled
|
||||
}
|
||||
}
|
||||
|
||||
/// The resolved settings to use for a `run` invocation.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct RunSettings {
|
||||
pub(crate) lock_check: LockCheck,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) frozen: Option<FrozenSource>,
|
||||
pub(crate) extras: ExtrasSpecification,
|
||||
pub(crate) groups: DependencyGroups,
|
||||
pub(crate) editable: Option<EditableMode>,
|
||||
@@ -477,13 +617,24 @@ impl RunSettings {
|
||||
.map(|fs| fs.install_mirrors.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let locked = resolve_flag(locked, "locked", environment.locked);
|
||||
let frozen = resolve_flag(frozen, "frozen", environment.frozen);
|
||||
|
||||
// Check for conflicts between locked and frozen.
|
||||
check_conflicts(locked, frozen);
|
||||
|
||||
let dev = dev || environment.dev.value == Some(true);
|
||||
let no_dev = no_dev || environment.no_dev.value == Some(true);
|
||||
|
||||
let no_editable = no_editable || environment.no_editable.value == Some(true);
|
||||
let isolated = isolated || environment.isolated.value == Some(true);
|
||||
let show_resolution = show_resolution || environment.show_resolution.value == Some(true);
|
||||
let no_env_file = no_env_file || environment.no_env_file.value == Some(true);
|
||||
|
||||
Self {
|
||||
lock_check: if locked {
|
||||
LockCheck::Enabled(LockCheckSource::Locked)
|
||||
} else {
|
||||
LockCheck::Disabled
|
||||
},
|
||||
frozen,
|
||||
lock_check: resolve_lock_check(locked),
|
||||
frozen: resolve_frozen(frozen),
|
||||
extras: ExtrasSpecification::from_args(
|
||||
extra.unwrap_or_default(),
|
||||
no_extra,
|
||||
@@ -646,6 +797,11 @@ impl ToolRunSettings {
|
||||
}
|
||||
let lfs = GitLfsSetting::new(lfs.then_some(true), environment.lfs);
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let isolated = isolated || environment.isolated.value == Some(true);
|
||||
let show_resolution = show_resolution || environment.show_resolution.value == Some(true);
|
||||
let no_env_file = no_env_file || environment.no_env_file.value == Some(true);
|
||||
|
||||
Self {
|
||||
command,
|
||||
from,
|
||||
@@ -1387,7 +1543,7 @@ impl PythonPinSettings {
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct SyncSettings {
|
||||
pub(crate) lock_check: LockCheck,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) frozen: Option<FrozenSource>,
|
||||
pub(crate) dry_run: DryRun,
|
||||
pub(crate) script: Option<PathBuf>,
|
||||
pub(crate) active: Option<bool>,
|
||||
@@ -1472,16 +1628,22 @@ impl SyncSettings {
|
||||
} else {
|
||||
DryRun::from_args(dry_run)
|
||||
};
|
||||
let lock_check = if locked {
|
||||
LockCheck::Enabled(LockCheckSource::Locked)
|
||||
} else {
|
||||
LockCheck::Disabled
|
||||
};
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let locked = resolve_flag(locked, "locked", environment.locked);
|
||||
let frozen = resolve_flag(frozen, "frozen", environment.frozen);
|
||||
|
||||
// Check for conflicts between locked and frozen.
|
||||
check_conflicts(locked, frozen);
|
||||
|
||||
let dev = dev || environment.dev.value == Some(true);
|
||||
let no_dev = no_dev || environment.no_dev.value == Some(true);
|
||||
let no_editable = no_editable || environment.no_editable.value == Some(true);
|
||||
|
||||
Self {
|
||||
output_format,
|
||||
lock_check,
|
||||
frozen,
|
||||
lock_check: resolve_lock_check(locked),
|
||||
frozen: resolve_frozen(frozen),
|
||||
dry_run,
|
||||
script,
|
||||
active: flag(active, no_active, "active"),
|
||||
@@ -1538,7 +1700,7 @@ impl SyncSettings {
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct LockSettings {
|
||||
pub(crate) lock_check: LockCheck,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) frozen: Option<FrozenSource>,
|
||||
pub(crate) dry_run: DryRun,
|
||||
pub(crate) script: Option<PathBuf>,
|
||||
pub(crate) python: Option<String>,
|
||||
@@ -1572,17 +1734,22 @@ impl LockSettings {
|
||||
.map(|fs| fs.install_mirrors.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let locked = resolve_flag(locked, "locked", environment.locked);
|
||||
let frozen = resolve_flag(check_exists, "frozen", environment.frozen);
|
||||
|
||||
// Check for conflicts between locked and frozen.
|
||||
check_conflicts(locked, frozen);
|
||||
|
||||
let lock_check = if check {
|
||||
LockCheck::Enabled(LockCheckSource::Check)
|
||||
} else if locked {
|
||||
LockCheck::Enabled(LockCheckSource::Locked)
|
||||
} else {
|
||||
LockCheck::Disabled
|
||||
resolve_lock_check(locked)
|
||||
};
|
||||
|
||||
Self {
|
||||
lock_check,
|
||||
frozen: check_exists,
|
||||
frozen: resolve_frozen(frozen),
|
||||
dry_run: DryRun::from_args(dry_run),
|
||||
script,
|
||||
python: python.and_then(Maybe::into_option),
|
||||
@@ -1600,7 +1767,7 @@ impl LockSettings {
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct AddSettings {
|
||||
pub(crate) lock_check: LockCheck,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) frozen: Option<FrozenSource>,
|
||||
pub(crate) active: Option<bool>,
|
||||
pub(crate) no_sync: bool,
|
||||
pub(crate) packages: Vec<String>,
|
||||
@@ -1682,6 +1849,10 @@ impl AddSettings {
|
||||
only_install_package,
|
||||
} = args;
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let dev = dev || environment.dev.value == Some(true);
|
||||
let no_editable = no_editable || environment.no_editable.value == Some(true);
|
||||
|
||||
let dependency_type = if let Some(extra) = optional {
|
||||
DependencyType::Optional(extra)
|
||||
} else if let Some(group) = group {
|
||||
@@ -1760,15 +1931,22 @@ impl AddSettings {
|
||||
let bounds = bounds.or(filesystem.as_ref().and_then(|fs| fs.add.add_bounds));
|
||||
let lfs = GitLfsSetting::new(lfs.then_some(true), environment.lfs);
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let locked = resolve_flag(locked, "locked", environment.locked);
|
||||
let frozen = resolve_flag(frozen, "frozen", environment.frozen);
|
||||
let no_sync = resolve_flag(no_sync, "no-sync", environment.no_sync);
|
||||
|
||||
// Check for conflicts between locked and frozen.
|
||||
check_conflicts(locked, frozen);
|
||||
|
||||
// Check for conflicts between no_sync and frozen.
|
||||
check_conflicts(no_sync, frozen);
|
||||
|
||||
Self {
|
||||
lock_check: if locked {
|
||||
LockCheck::Enabled(LockCheckSource::Locked)
|
||||
} else {
|
||||
LockCheck::Disabled
|
||||
},
|
||||
frozen,
|
||||
lock_check: resolve_lock_check(locked),
|
||||
frozen: resolve_frozen(frozen),
|
||||
active: flag(active, no_active, "active"),
|
||||
no_sync,
|
||||
no_sync: no_sync.is_enabled(),
|
||||
packages,
|
||||
requirements,
|
||||
constraints: constraints
|
||||
@@ -1815,7 +1993,7 @@ impl AddSettings {
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct RemoveSettings {
|
||||
pub(crate) lock_check: LockCheck,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) frozen: Option<FrozenSource>,
|
||||
pub(crate) active: Option<bool>,
|
||||
pub(crate) no_sync: bool,
|
||||
pub(crate) packages: Vec<PackageName>,
|
||||
@@ -1854,6 +2032,9 @@ impl RemoveSettings {
|
||||
python,
|
||||
} = args;
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let dev = dev || environment.dev.value == Some(true);
|
||||
|
||||
let dependency_type = if let Some(extra) = optional {
|
||||
DependencyType::Optional(extra)
|
||||
} else if let Some(group) = group {
|
||||
@@ -1874,15 +2055,22 @@ impl RemoveSettings {
|
||||
.map(|requirement| requirement.name)
|
||||
.collect();
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let locked = resolve_flag(locked, "locked", environment.locked);
|
||||
let frozen = resolve_flag(frozen, "frozen", environment.frozen);
|
||||
let no_sync = resolve_flag(no_sync, "no-sync", environment.no_sync);
|
||||
|
||||
// Check for conflicts between locked and frozen.
|
||||
check_conflicts(locked, frozen);
|
||||
|
||||
// Check for conflicts between no_sync and frozen.
|
||||
check_conflicts(no_sync, frozen);
|
||||
|
||||
Self {
|
||||
lock_check: if locked {
|
||||
LockCheck::Enabled(LockCheckSource::Locked)
|
||||
} else {
|
||||
LockCheck::Disabled
|
||||
},
|
||||
frozen,
|
||||
lock_check: resolve_lock_check(locked),
|
||||
frozen: resolve_frozen(frozen),
|
||||
active: flag(active, no_active, "active"),
|
||||
no_sync,
|
||||
no_sync: no_sync.is_enabled(),
|
||||
packages,
|
||||
dependency_type,
|
||||
package,
|
||||
@@ -1910,7 +2098,7 @@ pub(crate) struct VersionSettings {
|
||||
pub(crate) output_format: VersionFormat,
|
||||
pub(crate) dry_run: bool,
|
||||
pub(crate) lock_check: LockCheck,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) frozen: Option<FrozenSource>,
|
||||
pub(crate) active: Option<bool>,
|
||||
pub(crate) no_sync: bool,
|
||||
pub(crate) package: Option<PackageName>,
|
||||
@@ -1951,20 +2139,27 @@ impl VersionSettings {
|
||||
.map(|fs| fs.install_mirrors.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let locked = resolve_flag(locked, "locked", environment.locked);
|
||||
let frozen = resolve_flag(frozen, "frozen", environment.frozen);
|
||||
let no_sync = resolve_flag(no_sync, "no-sync", environment.no_sync);
|
||||
|
||||
// Check for conflicts between locked and frozen.
|
||||
check_conflicts(locked, frozen);
|
||||
|
||||
// Check for conflicts between no_sync and frozen.
|
||||
check_conflicts(no_sync, frozen);
|
||||
|
||||
Self {
|
||||
value,
|
||||
bump,
|
||||
short,
|
||||
output_format,
|
||||
dry_run,
|
||||
lock_check: if locked {
|
||||
LockCheck::Enabled(LockCheckSource::Locked)
|
||||
} else {
|
||||
LockCheck::Disabled
|
||||
},
|
||||
frozen,
|
||||
lock_check: resolve_lock_check(locked),
|
||||
frozen: resolve_frozen(frozen),
|
||||
active: flag(active, no_active, "active"),
|
||||
no_sync,
|
||||
no_sync: no_sync.is_enabled(),
|
||||
package,
|
||||
python: python.and_then(Maybe::into_option),
|
||||
refresh: Refresh::from(refresh),
|
||||
@@ -1984,7 +2179,7 @@ impl VersionSettings {
|
||||
pub(crate) struct TreeSettings {
|
||||
pub(crate) groups: DependencyGroups,
|
||||
pub(crate) lock_check: LockCheck,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) frozen: Option<FrozenSource>,
|
||||
pub(crate) universal: bool,
|
||||
pub(crate) depth: u8,
|
||||
pub(crate) prune: Vec<PackageName>,
|
||||
@@ -2035,6 +2230,16 @@ impl TreeSettings {
|
||||
.map(|fs| fs.install_mirrors.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let locked = resolve_flag(locked, "locked", environment.locked);
|
||||
let frozen = resolve_flag(frozen, "frozen", environment.frozen);
|
||||
|
||||
// Check for conflicts between locked and frozen.
|
||||
check_conflicts(locked, frozen);
|
||||
|
||||
let dev = dev || environment.dev.value == Some(true);
|
||||
let no_dev = no_dev || environment.no_dev.value == Some(true);
|
||||
|
||||
Self {
|
||||
groups: DependencyGroups::from_args(
|
||||
dev,
|
||||
@@ -2046,12 +2251,8 @@ impl TreeSettings {
|
||||
only_group,
|
||||
all_groups,
|
||||
),
|
||||
lock_check: if locked {
|
||||
LockCheck::Enabled(LockCheckSource::Locked)
|
||||
} else {
|
||||
LockCheck::Disabled
|
||||
},
|
||||
frozen,
|
||||
lock_check: resolve_lock_check(locked),
|
||||
frozen: resolve_frozen(frozen),
|
||||
universal,
|
||||
depth: tree.depth,
|
||||
prune: tree.prune,
|
||||
@@ -2087,7 +2288,7 @@ pub(crate) struct ExportSettings {
|
||||
pub(crate) install_options: InstallOptions,
|
||||
pub(crate) output_file: Option<PathBuf>,
|
||||
pub(crate) lock_check: LockCheck,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) frozen: Option<FrozenSource>,
|
||||
pub(crate) include_annotations: bool,
|
||||
pub(crate) include_header: bool,
|
||||
pub(crate) script: Option<PathBuf>,
|
||||
@@ -2140,7 +2341,7 @@ impl ExportSettings {
|
||||
no_emit_package,
|
||||
only_emit_package,
|
||||
locked,
|
||||
frozen,
|
||||
frozen: frozen_cli,
|
||||
resolver,
|
||||
build,
|
||||
refresh,
|
||||
@@ -2152,6 +2353,17 @@ impl ExportSettings {
|
||||
.map(|fs| fs.install_mirrors.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let locked = resolve_flag(locked, "locked", environment.locked);
|
||||
let frozen = resolve_flag(frozen_cli, "frozen", environment.frozen);
|
||||
|
||||
// Check for conflicts between locked and frozen.
|
||||
check_conflicts(locked, frozen);
|
||||
|
||||
let dev = dev || environment.dev.value == Some(true);
|
||||
let no_dev = no_dev || environment.no_dev.value == Some(true);
|
||||
let no_editable = no_editable || environment.no_editable.value == Some(true);
|
||||
|
||||
Self {
|
||||
format,
|
||||
all_packages,
|
||||
@@ -2189,12 +2401,8 @@ impl ExportSettings {
|
||||
only_emit_package,
|
||||
),
|
||||
output_file,
|
||||
lock_check: if locked {
|
||||
LockCheck::Enabled(LockCheckSource::Locked)
|
||||
} else {
|
||||
LockCheck::Disabled
|
||||
},
|
||||
frozen,
|
||||
lock_check: resolve_lock_check(locked),
|
||||
frozen: resolve_frozen(frozen),
|
||||
include_annotations: flag(annotate, no_annotate, "annotate").unwrap_or(true),
|
||||
include_header: flag(header, no_header, "header").unwrap_or(true),
|
||||
script,
|
||||
@@ -2250,7 +2458,7 @@ pub(crate) struct PipCompileSettings {
|
||||
pub(crate) build_constraints: Vec<PathBuf>,
|
||||
pub(crate) constraints_from_workspace: Vec<Requirement>,
|
||||
pub(crate) overrides_from_workspace: Vec<Requirement>,
|
||||
pub(crate) excludes_from_workspace: Vec<uv_normalize::PackageName>,
|
||||
pub(crate) excludes_from_workspace: Vec<PackageName>,
|
||||
pub(crate) build_constraints_from_workspace: Vec<Requirement>,
|
||||
pub(crate) environments: SupportedEnvironments,
|
||||
pub(crate) refresh: Refresh,
|
||||
@@ -2566,7 +2774,7 @@ pub(crate) struct PipInstallSettings {
|
||||
pub(crate) dry_run: DryRun,
|
||||
pub(crate) constraints_from_workspace: Vec<Requirement>,
|
||||
pub(crate) overrides_from_workspace: Vec<Requirement>,
|
||||
pub(crate) excludes_from_workspace: Vec<uv_normalize::PackageName>,
|
||||
pub(crate) excludes_from_workspace: Vec<PackageName>,
|
||||
pub(crate) build_constraints_from_workspace: Vec<Requirement>,
|
||||
pub(crate) modifications: Modifications,
|
||||
pub(crate) refresh: Refresh,
|
||||
@@ -3169,6 +3377,10 @@ impl VenvSettings {
|
||||
exclude_newer_package,
|
||||
} = args;
|
||||
|
||||
// Resolve flags from CLI and environment variables.
|
||||
let seed = seed || environment.venv_seed.value == Some(true);
|
||||
let clear = clear || environment.venv_clear.value == Some(true);
|
||||
|
||||
Self {
|
||||
seed,
|
||||
allow_existing,
|
||||
|
||||
@@ -57,8 +57,7 @@ fn help() {
|
||||
--color <COLOR_CHOICE>
|
||||
Control the use of color in output [possible values: auto, always, never]
|
||||
--native-tls
|
||||
Whether to load TLS certificates from the platform's native certificate store [env:
|
||||
UV_NATIVE_TLS=]
|
||||
Whether to load TLS certificates from the platform's native store [env: UV_NATIVE_TLS=]
|
||||
--offline
|
||||
Disable network access [env: UV_OFFLINE=]
|
||||
--allow-insecure-host <ALLOW_INSECURE_HOST>
|
||||
@@ -138,8 +137,7 @@ fn help_flag() {
|
||||
--color <COLOR_CHOICE>
|
||||
Control the use of color in output [possible values: auto, always, never]
|
||||
--native-tls
|
||||
Whether to load TLS certificates from the platform's native certificate store [env:
|
||||
UV_NATIVE_TLS=]
|
||||
Whether to load TLS certificates from the platform's native store [env: UV_NATIVE_TLS=]
|
||||
--offline
|
||||
Disable network access [env: UV_OFFLINE=]
|
||||
--allow-insecure-host <ALLOW_INSECURE_HOST>
|
||||
@@ -218,8 +216,7 @@ fn help_short_flag() {
|
||||
--color <COLOR_CHOICE>
|
||||
Control the use of color in output [possible values: auto, always, never]
|
||||
--native-tls
|
||||
Whether to load TLS certificates from the platform's native certificate store [env:
|
||||
UV_NATIVE_TLS=]
|
||||
Whether to load TLS certificates from the platform's native store [env: UV_NATIVE_TLS=]
|
||||
--offline
|
||||
Disable network access [env: UV_OFFLINE=]
|
||||
--allow-insecure-host <ALLOW_INSECURE_HOST>
|
||||
@@ -331,14 +328,14 @@ fn help_subcommand() {
|
||||
By default, uv prefers using Python versions it manages. However, it will use system
|
||||
Python versions if a uv-managed Python is not installed. This option disables use of
|
||||
system Python versions.
|
||||
|
||||
|
||||
[env: UV_MANAGED_PYTHON=]
|
||||
|
||||
--no-managed-python
|
||||
Disable use of uv-managed Python versions.
|
||||
|
||||
Instead, uv will search for a suitable Python version on the system.
|
||||
|
||||
|
||||
[env: UV_NO_MANAGED_PYTHON=]
|
||||
|
||||
--no-python-downloads
|
||||
@@ -369,7 +366,7 @@ fn help_subcommand() {
|
||||
- never: Disables colored output
|
||||
|
||||
--native-tls
|
||||
Whether to load TLS certificates from the platform's native certificate store.
|
||||
Whether to load TLS certificates from the platform's native store.
|
||||
|
||||
By default, uv loads certificates from the bundled `webpki-roots` crate. The
|
||||
`webpki-roots` are a reliable set of trust roots from Mozilla, and including them in uv
|
||||
@@ -378,14 +375,14 @@ fn help_subcommand() {
|
||||
However, in some cases, you may want to use the platform's native certificate store,
|
||||
especially if you're relying on a corporate trust root (e.g., for a mandatory proxy)
|
||||
that's included in your system's certificate store.
|
||||
|
||||
|
||||
[env: UV_NATIVE_TLS=]
|
||||
|
||||
--offline
|
||||
Disable network access.
|
||||
|
||||
When disabled, uv will only use locally cached data and locally available files.
|
||||
|
||||
|
||||
[env: UV_OFFLINE=]
|
||||
|
||||
--allow-insecure-host <ALLOW_INSECURE_HOST>
|
||||
@@ -406,7 +403,7 @@ fn help_subcommand() {
|
||||
Hide all progress outputs.
|
||||
|
||||
For example, spinners or progress bars.
|
||||
|
||||
|
||||
[env: UV_NO_PROGRESS=]
|
||||
|
||||
--directory <DIRECTORY>
|
||||
@@ -455,7 +452,6 @@ fn help_subcommand() {
|
||||
|
||||
Use `uv help python <command>` for more information on a specific command.
|
||||
|
||||
|
||||
----- stderr -----
|
||||
"#);
|
||||
}
|
||||
@@ -604,14 +600,14 @@ fn help_subsubcommand() {
|
||||
By default, uv prefers using Python versions it manages. However, it will use system
|
||||
Python versions if a uv-managed Python is not installed. This option disables use of
|
||||
system Python versions.
|
||||
|
||||
|
||||
[env: UV_MANAGED_PYTHON=]
|
||||
|
||||
--no-managed-python
|
||||
Disable use of uv-managed Python versions.
|
||||
|
||||
Instead, uv will search for a suitable Python version on the system.
|
||||
|
||||
|
||||
[env: UV_NO_MANAGED_PYTHON=]
|
||||
|
||||
--no-python-downloads
|
||||
@@ -642,7 +638,7 @@ fn help_subsubcommand() {
|
||||
- never: Disables colored output
|
||||
|
||||
--native-tls
|
||||
Whether to load TLS certificates from the platform's native certificate store.
|
||||
Whether to load TLS certificates from the platform's native store.
|
||||
|
||||
By default, uv loads certificates from the bundled `webpki-roots` crate. The
|
||||
`webpki-roots` are a reliable set of trust roots from Mozilla, and including them in uv
|
||||
@@ -651,14 +647,14 @@ fn help_subsubcommand() {
|
||||
However, in some cases, you may want to use the platform's native certificate store,
|
||||
especially if you're relying on a corporate trust root (e.g., for a mandatory proxy)
|
||||
that's included in your system's certificate store.
|
||||
|
||||
|
||||
[env: UV_NATIVE_TLS=]
|
||||
|
||||
--offline
|
||||
Disable network access.
|
||||
|
||||
When disabled, uv will only use locally cached data and locally available files.
|
||||
|
||||
|
||||
[env: UV_OFFLINE=]
|
||||
|
||||
--allow-insecure-host <ALLOW_INSECURE_HOST>
|
||||
@@ -679,7 +675,7 @@ fn help_subsubcommand() {
|
||||
Hide all progress outputs.
|
||||
|
||||
For example, spinners or progress bars.
|
||||
|
||||
|
||||
[env: UV_NO_PROGRESS=]
|
||||
|
||||
--directory <DIRECTORY>
|
||||
@@ -726,7 +722,6 @@ fn help_subsubcommand() {
|
||||
-h, --help
|
||||
Display the concise help for this command
|
||||
|
||||
|
||||
----- stderr -----
|
||||
"#);
|
||||
}
|
||||
@@ -772,8 +767,7 @@ fn help_flag_subcommand() {
|
||||
--color <COLOR_CHOICE>
|
||||
Control the use of color in output [possible values: auto, always, never]
|
||||
--native-tls
|
||||
Whether to load TLS certificates from the platform's native certificate store [env:
|
||||
UV_NATIVE_TLS=]
|
||||
Whether to load TLS certificates from the platform's native store [env: UV_NATIVE_TLS=]
|
||||
--offline
|
||||
Disable network access [env: UV_OFFLINE=]
|
||||
--allow-insecure-host <ALLOW_INSECURE_HOST>
|
||||
@@ -853,8 +847,7 @@ fn help_flag_subsubcommand() {
|
||||
--color <COLOR_CHOICE>
|
||||
Control the use of color in output [possible values: auto, always, never]
|
||||
--native-tls
|
||||
Whether to load TLS certificates from the platform's native certificate store [env:
|
||||
UV_NATIVE_TLS=]
|
||||
Whether to load TLS certificates from the platform's native store [env: UV_NATIVE_TLS=]
|
||||
--offline
|
||||
Disable network access [env: UV_OFFLINE=]
|
||||
--allow-insecure-host <ALLOW_INSECURE_HOST>
|
||||
@@ -1015,8 +1008,7 @@ fn help_with_global_option() {
|
||||
--color <COLOR_CHOICE>
|
||||
Control the use of color in output [possible values: auto, always, never]
|
||||
--native-tls
|
||||
Whether to load TLS certificates from the platform's native certificate store [env:
|
||||
UV_NATIVE_TLS=]
|
||||
Whether to load TLS certificates from the platform's native store [env: UV_NATIVE_TLS=]
|
||||
--offline
|
||||
Disable network access [env: UV_OFFLINE=]
|
||||
--allow-insecure-host <ALLOW_INSECURE_HOST>
|
||||
@@ -1138,8 +1130,7 @@ fn help_with_no_pager() {
|
||||
--color <COLOR_CHOICE>
|
||||
Control the use of color in output [possible values: auto, always, never]
|
||||
--native-tls
|
||||
Whether to load TLS certificates from the platform's native certificate store [env:
|
||||
UV_NATIVE_TLS=]
|
||||
Whether to load TLS certificates from the platform's native store [env: UV_NATIVE_TLS=]
|
||||
--offline
|
||||
Disable network access [env: UV_OFFLINE=]
|
||||
--allow-insecure-host <ALLOW_INSECURE_HOST>
|
||||
|
||||
@@ -12273,6 +12273,25 @@ fn conflicting_flags_clap_bug() {
|
||||
);
|
||||
}
|
||||
|
||||
/// Test that `--offline` and `--refresh` conflict.
|
||||
#[test]
|
||||
fn offline_refresh_conflict() {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
uv_snapshot!(context.filters(), context.pip_install()
|
||||
.arg("tqdm")
|
||||
.arg("--offline")
|
||||
.arg("--refresh"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: the argument `--offline` cannot be used with `--refresh`
|
||||
"
|
||||
);
|
||||
}
|
||||
|
||||
/// Test that shebang arguments are stripped when installing scripts
|
||||
#[test]
|
||||
#[cfg(unix)]
|
||||
|
||||
@@ -64,6 +64,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -270,6 +271,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -477,6 +479,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -716,6 +719,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -924,6 +928,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -1108,6 +1113,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -1341,6 +1347,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -1582,6 +1589,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -1881,6 +1889,7 @@ fn resolve_find_links() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -2111,6 +2120,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -2300,6 +2310,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -2539,6 +2550,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -2801,6 +2813,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -2980,6 +2993,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -3159,6 +3173,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -3340,6 +3355,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -3540,6 +3556,7 @@ fn resolve_tool() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -3734,6 +3751,7 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -3947,6 +3965,7 @@ fn resolve_both() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -4199,6 +4218,7 @@ fn resolve_both_special_fields() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -4530,6 +4550,7 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -4836,6 +4857,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -5018,6 +5040,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -5208,6 +5231,7 @@ fn allow_insecure_host() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -5412,6 +5436,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -5653,6 +5678,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -5900,6 +5926,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -6142,6 +6169,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -6391,6 +6419,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -6633,6 +6662,7 @@ fn index_priority() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -6888,6 +6918,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -7060,6 +7091,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -7230,6 +7262,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -7402,6 +7435,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -7572,6 +7606,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -7743,6 +7778,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -7929,6 +7965,7 @@ fn preview_features() {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -7966,7 +8003,7 @@ fn preview_features() {
|
||||
output_format: Text,
|
||||
dry_run: false,
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
active: None,
|
||||
no_sync: false,
|
||||
package: None,
|
||||
@@ -8047,6 +8084,7 @@ fn preview_features() {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -8084,7 +8122,7 @@ fn preview_features() {
|
||||
output_format: Text,
|
||||
dry_run: false,
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
active: None,
|
||||
no_sync: false,
|
||||
package: None,
|
||||
@@ -8165,6 +8203,7 @@ fn preview_features() {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -8202,7 +8241,7 @@ fn preview_features() {
|
||||
output_format: Text,
|
||||
dry_run: false,
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
active: None,
|
||||
no_sync: false,
|
||||
package: None,
|
||||
@@ -8283,6 +8322,7 @@ fn preview_features() {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -8320,7 +8360,7 @@ fn preview_features() {
|
||||
output_format: Text,
|
||||
dry_run: false,
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
active: None,
|
||||
no_sync: false,
|
||||
package: None,
|
||||
@@ -8401,6 +8441,7 @@ fn preview_features() {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -8438,7 +8479,7 @@ fn preview_features() {
|
||||
output_format: Text,
|
||||
dry_run: false,
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
active: None,
|
||||
no_sync: false,
|
||||
package: None,
|
||||
@@ -8521,6 +8562,7 @@ fn preview_features() {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -8558,7 +8600,7 @@ fn preview_features() {
|
||||
output_format: Text,
|
||||
dry_run: false,
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
active: None,
|
||||
no_sync: false,
|
||||
package: None,
|
||||
@@ -8660,6 +8702,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -8840,6 +8883,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -9043,6 +9087,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -9221,6 +9266,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -9393,6 +9439,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -9566,6 +9613,7 @@ fn upgrade_pip_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -9804,6 +9852,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -9836,7 +9885,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
}
|
||||
LockSettings {
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
dry_run: Disabled,
|
||||
script: None,
|
||||
python: None,
|
||||
@@ -9927,6 +9976,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -9959,7 +10009,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
}
|
||||
LockSettings {
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
dry_run: Disabled,
|
||||
script: None,
|
||||
python: None,
|
||||
@@ -10073,6 +10123,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -10105,7 +10156,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
}
|
||||
LockSettings {
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
dry_run: Disabled,
|
||||
script: None,
|
||||
python: None,
|
||||
@@ -10194,6 +10245,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -10226,7 +10278,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
}
|
||||
LockSettings {
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
dry_run: Disabled,
|
||||
script: None,
|
||||
python: None,
|
||||
@@ -10305,6 +10357,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -10337,7 +10390,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
}
|
||||
LockSettings {
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
dry_run: Disabled,
|
||||
script: None,
|
||||
python: None,
|
||||
@@ -10417,6 +10470,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -10449,7 +10503,7 @@ fn upgrade_project_cli_config_interaction() -> anyhow::Result<()> {
|
||||
}
|
||||
LockSettings {
|
||||
lock_check: Disabled,
|
||||
frozen: false,
|
||||
frozen: None,
|
||||
dry_run: Disabled,
|
||||
script: None,
|
||||
python: None,
|
||||
@@ -10593,6 +10647,7 @@ fn build_isolation_override() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
@@ -10768,6 +10823,7 @@ fn build_isolation_override() -> anyhow::Result<()> {
|
||||
color: Auto,
|
||||
network_settings: NetworkSettings {
|
||||
connectivity: Online,
|
||||
offline: Disabled,
|
||||
native_tls: false,
|
||||
http_proxy: None,
|
||||
https_proxy: None,
|
||||
|
||||
Reference in New Issue
Block a user