diff --git a/crates/uv-workspace/src/combine.rs b/crates/uv-workspace/src/combine.rs index f53b1ad20..f5df46151 100644 --- a/crates/uv-workspace/src/combine.rs +++ b/crates/uv-workspace/src/combine.rs @@ -42,6 +42,7 @@ impl Combine for Options { fn combine(self, other: Options) -> Options { Options { native_tls: self.native_tls.combine(other.native_tls), + offline: self.offline.combine(other.offline), no_cache: self.no_cache.combine(other.no_cache), preview: self.preview.combine(other.preview), cache_dir: self.cache_dir.combine(other.cache_dir), @@ -68,7 +69,6 @@ impl Combine for PipOptions { .break_system_packages .combine(other.break_system_packages), target: self.target.combine(other.target), - offline: self.offline.combine(other.offline), index_url: self.index_url.combine(other.index_url), extra_index_url: self.extra_index_url.combine(other.extra_index_url), no_index: self.no_index.combine(other.no_index), diff --git a/crates/uv-workspace/src/settings.rs b/crates/uv-workspace/src/settings.rs index f05e51106..7c7856618 100644 --- a/crates/uv-workspace/src/settings.rs +++ b/crates/uv-workspace/src/settings.rs @@ -32,6 +32,7 @@ pub(crate) struct Tools { #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Options { pub native_tls: Option, + pub offline: Option, pub no_cache: Option, pub preview: Option, pub cache_dir: Option, @@ -48,7 +49,6 @@ pub struct PipOptions { pub system: Option, pub break_system_packages: Option, pub target: Option, - pub offline: Option, pub index_url: Option, pub extra_index_url: Option>, pub no_index: Option, diff --git a/crates/uv/src/cli.rs b/crates/uv/src/cli.rs index 8f1d3fa0b..438fad5b2 100644 --- a/crates/uv/src/cli.rs +++ b/crates/uv/src/cli.rs @@ -81,6 +81,13 @@ pub(crate) struct GlobalArgs { #[arg(global = true, long, overrides_with("native_tls"), hide = true)] pub(crate) no_native_tls: bool, + /// Disable network access, relying only on locally cached data and locally available files. + #[arg(global = true, long, overrides_with("no_offline"))] + pub(crate) offline: bool, + + #[arg(global = true, long, overrides_with("offline"), hide = true)] + pub(crate) no_offline: bool, + /// Whether to enable experimental, preview features. #[arg(global = true, long, hide = true, env = "UV_PREVIEW", value_parser = clap::builder::BoolishValueParser::new(), overrides_with("no_preview"))] pub(crate) preview: bool, @@ -366,23 +373,17 @@ pub(crate) struct PipCompileArgs { pub(crate) custom_compile_command: Option, /// Run offline, i.e., without accessing the network. - #[arg( - global = true, - long, - conflicts_with = "refresh", - conflicts_with = "refresh_package", - overrides_with("no_offline") - )] - pub(crate) offline: bool, - - #[arg(long, overrides_with("offline"), hide = true)] - pub(crate) no_offline: bool, /// Refresh all cached data. - #[arg(long, overrides_with("no_refresh"))] + #[arg(long, conflicts_with("offline"), overrides_with("no_refresh"))] pub(crate) refresh: bool, - #[arg(long, overrides_with("refresh"), hide = true)] + #[arg( + long, + conflicts_with("offline"), + overrides_with("refresh"), + hide = true + )] pub(crate) no_refresh: bool, /// Refresh cached data for a specific package. @@ -649,23 +650,16 @@ pub(crate) struct PipSyncArgs { #[arg(long)] pub(crate) reinstall_package: Vec, - #[arg( - global = true, - long, - conflicts_with = "refresh", - conflicts_with = "refresh_package", - overrides_with("no_offline") - )] - pub(crate) offline: bool, - - #[arg(long, overrides_with("offline"), hide = true)] - pub(crate) no_offline: bool, - /// Refresh all cached data. - #[arg(long, overrides_with("no_refresh"))] + #[arg(long, conflicts_with("offline"), overrides_with("no_refresh"))] pub(crate) refresh: bool, - #[arg(long, overrides_with("refresh"), hide = true)] + #[arg( + long, + conflicts_with("offline"), + overrides_with("refresh"), + hide = true + )] pub(crate) no_refresh: bool, /// Refresh cached data for a specific package. @@ -1013,23 +1007,16 @@ pub(crate) struct PipInstallArgs { #[arg(long)] pub(crate) reinstall_package: Vec, - #[arg( - global = true, - long, - conflicts_with = "refresh", - conflicts_with = "refresh_package", - overrides_with("no_offline") - )] - pub(crate) offline: bool, - - #[arg(long, overrides_with("offline"), hide = true)] - pub(crate) no_offline: bool, - /// Refresh all cached data. - #[arg(long, overrides_with("no_refresh"))] + #[arg(long, conflicts_with("offline"), overrides_with("no_refresh"))] pub(crate) refresh: bool, - #[arg(long, overrides_with("refresh"), hide = true)] + #[arg( + long, + conflicts_with("offline"), + overrides_with("refresh"), + hide = true + )] pub(crate) no_refresh: bool, /// Refresh cached data for a specific package. @@ -1430,13 +1417,6 @@ pub(crate) struct PipUninstallArgs { /// or system Python interpreter. #[arg(long)] pub(crate) target: Option, - - /// Run offline, i.e., without accessing the network. - #[arg(long, overrides_with("no_offline"))] - pub(crate) offline: bool, - - #[arg(long, overrides_with("offline"), hide = true)] - pub(crate) no_offline: bool, } #[derive(Args)] @@ -1808,13 +1788,6 @@ pub(crate) struct VenvArgs { #[arg(long, value_enum, env = "UV_KEYRING_PROVIDER")] pub(crate) keyring_provider: Option, - /// Run offline, i.e., without accessing the network. - #[arg(long, overrides_with("no_offline"))] - pub(crate) offline: bool, - - #[arg(long, overrides_with("offline"), hide = true)] - pub(crate) no_offline: bool, - /// Limit candidate packages to those that were uploaded prior to the given date. /// /// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same @@ -1840,13 +1813,6 @@ pub(crate) struct RunArgs { #[arg(long)] pub(crate) with: Vec, - /// Run offline, i.e., without accessing the network. - #[arg(global = true, long, overrides_with("no_offline"))] - pub(crate) offline: bool, - - #[arg(long, overrides_with("offline"), hide = true)] - pub(crate) no_offline: bool, - /// The Python interpreter to use to build the run environment. /// /// By default, `uv` uses the virtual environment in the current working directory or any parent @@ -1961,11 +1927,4 @@ pub(crate) struct ToolRunArgs { group = "discovery" )] pub(crate) python: Option, - - /// Run offline, i.e., without accessing the network. - #[arg(global = true, long, overrides_with("no_offline"))] - pub(crate) offline: bool, - - #[arg(long, overrides_with("offline"), hide = true)] - pub(crate) no_offline: bool, } diff --git a/crates/uv/src/main.rs b/crates/uv/src/main.rs index 149bf7820..e8ed30778 100644 --- a/crates/uv/src/main.rs +++ b/crates/uv/src/main.rs @@ -7,12 +7,11 @@ use anstream::eprintln; use anyhow::Result; use clap::error::{ContextKind, ContextValue}; use clap::{CommandFactory, Parser}; -use cli::{ToolCommand, ToolNamespace}; use owo_colors::OwoColorize; use tracing::instrument; +use cli::{ToolCommand, ToolNamespace}; use uv_cache::Cache; -use uv_client::Connectivity; use uv_requirements::RequirementsSource; use uv_workspace::Combine; @@ -227,7 +226,7 @@ async fn run() -> Result { args.shared.keyring_provider, args.shared.setup_py, args.shared.config_setting, - args.shared.connectivity, + globals.connectivity, args.shared.no_build_isolation, args.shared.no_build, args.shared.python_version, @@ -277,7 +276,7 @@ async fn run() -> Result { args.shared.index_strategy, args.shared.keyring_provider, args.shared.setup_py, - args.shared.connectivity, + globals.connectivity, &args.shared.config_setting, args.shared.no_build_isolation, args.shared.no_build, @@ -350,7 +349,7 @@ async fn run() -> Result { args.shared.compile_bytecode, args.shared.require_hashes, args.shared.setup_py, - args.shared.connectivity, + globals.connectivity, &args.shared.config_setting, args.shared.no_build_isolation, args.shared.no_build, @@ -399,7 +398,7 @@ async fn run() -> Result { args.shared.break_system_packages, args.shared.target, cache, - args.shared.connectivity, + globals.connectivity, globals.native_tls, globals.preview, args.shared.keyring_provider, @@ -522,7 +521,7 @@ async fn run() -> Result { args.shared.keyring_provider, uv_virtualenv::Prompt::from_args(prompt), args.system_site_packages, - args.shared.connectivity, + globals.connectivity, args.seed, args.allow_existing, args.shared.exclude_newer, @@ -566,7 +565,7 @@ async fn run() -> Result { args.python, globals.isolated, globals.preview, - args.connectivity, + globals.connectivity, &cache, printer, ) @@ -605,18 +604,13 @@ async fn run() -> Result { Commands::Tool(ToolNamespace { command: ToolCommand::Run(args), }) => { - let connectivity = if args.offline { - Connectivity::Offline - } else { - Connectivity::Online - }; commands::run_tool( args.target, args.args, args.python, globals.isolated, globals.preview, - connectivity, + globals.connectivity, &cache, printer, ) diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index ea377ff3d..c1b035e5c 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -34,6 +34,7 @@ pub(crate) struct GlobalSettings { pub(crate) verbose: u8, pub(crate) color: ColorChoice, pub(crate) native_tls: bool, + pub(crate) connectivity: Connectivity, pub(crate) isolated: bool, pub(crate) preview: PreviewMode, } @@ -52,6 +53,14 @@ impl GlobalSettings { native_tls: flag(args.native_tls, args.no_native_tls) .combine(workspace.and_then(|workspace| workspace.options.native_tls)) .unwrap_or(false), + connectivity: if flag(args.offline, args.no_offline) + .combine(workspace.and_then(|workspace| workspace.options.offline)) + .unwrap_or(false) + { + Connectivity::Offline + } else { + Connectivity::Online + }, isolated: args.isolated, preview: PreviewMode::from( flag(args.preview, args.no_preview) @@ -94,10 +103,6 @@ pub(crate) struct RunSettings { pub(crate) args: Vec, pub(crate) with: Vec, pub(crate) python: Option, - - // Shared settings. - // TODO(zanieb): should be moved to a global setting - pub(crate) connectivity: Connectivity, } impl RunSettings { @@ -109,8 +114,6 @@ impl RunSettings { args, with, python, - offline, - no_offline, } = args; Self { @@ -119,16 +122,6 @@ impl RunSettings { args, with, python, - // Shared settings - connectivity: flag(offline, no_offline) - .map(|offline| { - if offline { - Connectivity::Offline - } else { - Connectivity::Online - } - }) - .unwrap_or_default(), } } } @@ -215,8 +208,7 @@ impl PipCompileSettings { header, annotation_style, custom_compile_command, - offline, - no_offline, + refresh, no_refresh, refresh_package, @@ -277,7 +269,7 @@ impl PipCompileSettings { PipOptions { python, system: flag(system, no_system), - offline: flag(offline, no_offline), + index_url: index_url.and_then(Maybe::into_option), extra_index_url: extra_index_url.map(|extra_index_urls| { extra_index_urls @@ -353,9 +345,7 @@ impl PipSyncSettings { reinstall, no_reinstall, reinstall_package, - offline, refresh, - no_offline, no_refresh, refresh_package, link_mode, @@ -404,7 +394,7 @@ impl PipSyncSettings { system: flag(system, no_system), break_system_packages: flag(break_system_packages, no_break_system_packages), target, - offline: flag(offline, no_offline), + index_url: index_url.and_then(Maybe::into_option), extra_index_url: extra_index_url.map(|extra_index_urls| { extra_index_urls @@ -478,9 +468,7 @@ impl PipInstallSettings { reinstall, no_reinstall, reinstall_package, - offline, refresh, - no_offline, no_refresh, refresh_package, no_deps, @@ -547,7 +535,7 @@ impl PipInstallSettings { system: flag(system, no_system), break_system_packages: flag(break_system_packages, no_break_system_packages), target, - offline: flag(offline, no_offline), + index_url: index_url.and_then(Maybe::into_option), extra_index_url: extra_index_url.map(|extra_index_urls| { extra_index_urls @@ -618,8 +606,6 @@ impl PipUninstallSettings { break_system_packages, no_break_system_packages, target, - offline, - no_offline, } = args; Self { @@ -634,7 +620,7 @@ impl PipUninstallSettings { system: flag(system, no_system), break_system_packages: flag(break_system_packages, no_break_system_packages), target, - offline: flag(offline, no_offline), + keyring_provider, ..PipOptions::default() }, @@ -842,8 +828,7 @@ impl VenvSettings { no_index, index_strategy, keyring_provider, - offline, - no_offline, + exclude_newer, compat_args: _, } = args; @@ -861,7 +846,7 @@ impl VenvSettings { PipOptions { python, system: flag(system, no_system), - offline: flag(offline, no_offline), + index_url: index_url.and_then(Maybe::into_option), extra_index_url: extra_index_url.map(|extra_index_urls| { extra_index_urls @@ -894,7 +879,6 @@ pub(crate) struct PipSharedSettings { pub(crate) extras: ExtrasSpecification, pub(crate) break_system_packages: bool, pub(crate) target: Option, - pub(crate) connectivity: Connectivity, pub(crate) index_strategy: IndexStrategy, pub(crate) keyring_provider: KeyringProviderType, pub(crate) no_binary: NoBinary, @@ -935,7 +919,6 @@ impl PipSharedSettings { system, break_system_packages, target, - offline, index_url, extra_index_url, no_index, @@ -1011,11 +994,6 @@ impl PipSharedSettings { .annotation_style .combine(annotation_style) .unwrap_or_default(), - connectivity: if args.offline.combine(offline).unwrap_or_default() { - Connectivity::Offline - } else { - Connectivity::Online - }, index_strategy: args .index_strategy .combine(index_strategy) diff --git a/uv.schema.json b/uv.schema.json index 3ba5ccbb0..b91680620 100644 --- a/uv.schema.json +++ b/uv.schema.json @@ -22,6 +22,12 @@ "null" ] }, + "offline": { + "type": [ + "boolean", + "null" + ] + }, "pip": { "anyOf": [ { @@ -460,12 +466,6 @@ "null" ] }, - "offline": { - "type": [ - "boolean", - "null" - ] - }, "only-binary": { "type": [ "array",