diff --git a/crates/uv/src/cli.rs b/crates/uv/src/cli.rs index 0fc9edc6d..1cacf9488 100644 --- a/crates/uv/src/cli.rs +++ b/crates/uv/src/cli.rs @@ -397,42 +397,8 @@ pub(crate) struct PipCompileArgs { #[arg(long, value_enum, env = "UV_LINK_MODE")] pub(crate) link_mode: Option, - /// The URL of the Python package index (by default: ). - /// - /// The index given by this flag is given lower priority than all other - /// indexes specified via the `--extra-index-url` flag. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, short, env = "UV_INDEX_URL", value_parser = parse_index_url)] - pub(crate) index_url: Option>, - - /// Extra URLs of package indexes to use, in addition to `--index-url`. - /// - /// All indexes given via this flag take priority over the index - /// in `--index-url` (which defaults to PyPI). And when multiple - /// `--extra-index-url` flags are given, earlier values take priority. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, env = "UV_EXTRA_INDEX_URL", value_delimiter = ' ', value_parser = parse_index_url)] - pub(crate) extra_index_url: Option>>, - - /// Locations to search for candidate distributions, beyond those found in the indexes. - /// - /// If a path, the target must be a directory that contains package as wheel files (`.whl`) or - /// source distributions (`.tar.gz` or `.zip`) at the top level. - /// - /// If a URL, the page must contain a flat list of links to package files. - #[arg(long, short)] - pub(crate) find_links: Option>, - - /// Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those - /// discovered via `--find-links`. - #[arg(long)] - pub(crate) no_index: bool, + #[command(flatten)] + pub(crate) index_args: IndexArgs, /// The strategy to use when resolving against multiple index URLs. /// @@ -680,42 +646,8 @@ pub(crate) struct PipSyncArgs { #[arg(long, value_enum, env = "UV_LINK_MODE")] pub(crate) link_mode: Option, - /// The URL of the Python package index (by default: ). - /// - /// The index given by this flag is given lower priority than all other - /// indexes specified via the `--extra-index-url` flag. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, short, env = "UV_INDEX_URL", value_parser = parse_index_url)] - pub(crate) index_url: Option>, - - /// Extra URLs of package indexes to use, in addition to `--index-url`. - /// - /// All indexes given via this flag take priority over the index - /// in `--index-url` (which defaults to PyPI). And when multiple - /// `--extra-index-url` flags are given, earlier values take priority. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, env = "UV_EXTRA_INDEX_URL", value_delimiter = ' ', value_parser = parse_index_url)] - pub(crate) extra_index_url: Option>>, - - /// Locations to search for candidate distributions, beyond those found in the indexes. - /// - /// If a path, the target must be a directory that contains package as wheel files (`.whl`) or - /// source distributions (`.tar.gz` or `.zip`) at the top level. - /// - /// If a URL, the page must contain a flat list of links to package files. - #[arg(long, short)] - pub(crate) find_links: Option>, - - /// Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those - /// discovered via `--find-links`. - #[arg(long)] - pub(crate) no_index: bool, + #[command(flatten)] + pub(crate) index_args: IndexArgs, /// The strategy to use when resolving against multiple index URLs. /// @@ -820,7 +752,6 @@ pub(crate) struct PipSyncArgs { /// Disable isolation when building source distributions. /// /// Assumes that build dependencies specified by PEP 518 are already installed. - #[arg( long, env = "UV_NO_BUILD_ISOLATION", @@ -1067,42 +998,8 @@ pub(crate) struct PipInstallArgs { #[arg(long, hide = true)] pub(crate) pre: bool, - /// The URL of the Python package index (by default: ). - /// - /// The index given by this flag is given lower priority than all other - /// indexes specified via the `--extra-index-url` flag. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, short, env = "UV_INDEX_URL", value_parser = parse_index_url)] - pub(crate) index_url: Option>, - - /// Extra URLs of package indexes to use, in addition to `--index-url`. - /// - /// All indexes given via this flag take priority over the index - /// in `--index-url` (which defaults to PyPI). And when multiple - /// `--extra-index-url` flags are given, earlier values take priority. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, env = "UV_EXTRA_INDEX_URL", value_delimiter = ' ', value_parser = parse_index_url)] - pub(crate) extra_index_url: Option>>, - - /// Locations to search for candidate distributions, beyond those found in the indexes. - /// - /// If a path, the target must be a directory that contains package as wheel files (`.whl`) or - /// source distributions (`.tar.gz` or `.zip`) at the top level. - /// - /// If a URL, the page must contain a flat list of links to package files. - #[arg(long, short)] - pub(crate) find_links: Option>, - - /// Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those - /// discovered via `--find-links`. - #[arg(long)] - pub(crate) no_index: bool, + #[command(flatten)] + pub(crate) index_args: IndexArgs, /// The strategy to use when resolving against multiple index URLs. /// @@ -1124,8 +1021,12 @@ pub(crate) struct PipInstallArgs { /// - Editable installs are not supported. /// - Local dependencies are not supported, unless they point to a specific wheel (`.whl`) or /// source archive (`.zip`, `.tar.gz`), as opposed to a directory. - #[arg(long, env = "UV_REQUIRE_HASHES", - value_parser = clap::builder::BoolishValueParser::new(), overrides_with("no_require_hashes"))] + #[arg( + long, + env = "UV_REQUIRE_HASHES", + value_parser = clap::builder::BoolishValueParser::new(), + overrides_with("no_require_hashes"), + )] pub(crate) require_hashes: bool, #[arg(long, overrides_with("require_hashes"), hide = true)] @@ -1811,42 +1712,8 @@ pub(crate) struct RunArgs { #[arg(long, short = 'P')] pub(crate) upgrade_package: Vec, - /// The URL of the Python package index (by default: ). - /// - /// The index given by this flag is given lower priority than all other - /// indexes specified via the `--extra-index-url` flag. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, short, env = "UV_INDEX_URL", value_parser = parse_index_url)] - pub(crate) index_url: Option>, - - /// Extra URLs of package indexes to use, in addition to `--index-url`. - /// - /// All indexes given via this flag take priority over the index - /// in `--index-url` (which defaults to PyPI). And when multiple - /// `--extra-index-url` flags are given, earlier values take priority. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, env = "UV_EXTRA_INDEX_URL", value_delimiter = ' ', value_parser = parse_index_url)] - pub(crate) extra_index_url: Option>>, - - /// Locations to search for candidate distributions, beyond those found in the indexes. - /// - /// If a path, the target must be a directory that contains package as wheel files (`.whl`) or - /// source distributions (`.tar.gz` or `.zip`) at the top level. - /// - /// If a URL, the page must contain a flat list of links to package files. - #[arg(long, short)] - pub(crate) find_links: Option>, - - /// Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those - /// discovered via `--find-links`. - #[arg(long)] - pub(crate) no_index: bool, + #[command(flatten)] + pub(crate) index_args: IndexArgs, /// The Python interpreter to use to build the run environment. /// @@ -1904,42 +1771,8 @@ pub(crate) struct SyncArgs { #[arg(long)] pub(crate) refresh_package: Vec, - /// The URL of the Python package index (by default: ). - /// - /// The index given by this flag is given lower priority than all other - /// indexes specified via the `--extra-index-url` flag. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, short, env = "UV_INDEX_URL", value_parser = parse_index_url)] - pub(crate) index_url: Option>, - - /// Extra URLs of package indexes to use, in addition to `--index-url`. - /// - /// All indexes given via this flag take priority over the index - /// in `--index-url` (which defaults to PyPI). And when multiple - /// `--extra-index-url` flags are given, earlier values take priority. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, env = "UV_EXTRA_INDEX_URL", value_delimiter = ' ', value_parser = parse_index_url)] - pub(crate) extra_index_url: Option>>, - - /// Locations to search for candidate distributions, beyond those found in the indexes. - /// - /// If a path, the target must be a directory that contains package as wheel files (`.whl`) or - /// source distributions (`.tar.gz` or `.zip`) at the top level. - /// - /// If a URL, the page must contain a flat list of links to package files. - #[arg(long, short)] - pub(crate) find_links: Option>, - - /// Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those - /// discovered via `--find-links`. - #[arg(long)] - pub(crate) no_index: bool, + #[command(flatten)] + pub(crate) index_args: IndexArgs, /// The Python interpreter to use to build the run environment. /// @@ -1986,42 +1819,8 @@ pub(crate) struct LockArgs { #[arg(long, short = 'P')] pub(crate) upgrade_package: Vec, - /// The URL of the Python package index (by default: ). - /// - /// The index given by this flag is given lower priority than all other - /// indexes specified via the `--extra-index-url` flag. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, short, env = "UV_INDEX_URL", value_parser = parse_index_url)] - pub(crate) index_url: Option>, - - /// Extra URLs of package indexes to use, in addition to `--index-url`. - /// - /// All indexes given via this flag take priority over the index - /// in `--index-url` (which defaults to PyPI). And when multiple - /// `--extra-index-url` flags are given, earlier values take priority. - /// - /// Unlike `pip`, `uv` will stop looking for versions of a package as soon - /// as it finds it in an index. That is, it isn't possible for `uv` to - /// consider versions of the same package across multiple indexes. - #[arg(long, env = "UV_EXTRA_INDEX_URL", value_delimiter = ' ', value_parser = parse_index_url)] - pub(crate) extra_index_url: Option>>, - - /// Locations to search for candidate distributions, beyond those found in the indexes. - /// - /// If a path, the target must be a directory that contains package as wheel files (`.whl`) or - /// source distributions (`.tar.gz` or `.zip`) at the top level. - /// - /// If a URL, the page must contain a flat list of links to package files. - #[arg(long, short)] - pub(crate) find_links: Option>, - - /// Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those - /// discovered via `--find-links`. - #[arg(long)] - pub(crate) no_index: bool, + #[command(flatten)] + pub(crate) index_args: IndexArgs, /// The Python interpreter to use to build the run environment. /// @@ -2091,6 +1890,26 @@ pub(crate) struct ToolRunArgs { #[arg(long)] pub(crate) with: Vec, + #[command(flatten)] + pub(crate) index_args: IndexArgs, + + /// 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 + /// directory, falling back to searching for a Python executable in `PATH`. The `--python` + /// option allows you to specify a different interpreter. + /// + /// Supported formats: + /// - `3.10` looks for an installed Python 3.10 using `py --list-paths` on Windows, or + /// `python3.10` on Linux and macOS. + /// - `python3.10` or `python.exe` looks for a binary with the given name in `PATH`. + /// - `/home/ferris/.local/bin/python3.10` uses the exact Python at the given path. + #[arg(long, short, env = "UV_PYTHON", verbatim_doc_comment)] + pub(crate) python: Option, +} + +#[derive(Args)] +pub(crate) struct IndexArgs { /// The URL of the Python package index (by default: ). /// /// The index given by this flag is given lower priority than all other @@ -2127,18 +1946,4 @@ pub(crate) struct ToolRunArgs { /// discovered via `--find-links`. #[arg(long)] pub(crate) no_index: 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 - /// directory, falling back to searching for a Python executable in `PATH`. The `--python` - /// option allows you to specify a different interpreter. - /// - /// Supported formats: - /// - `3.10` looks for an installed Python 3.10 using `py --list-paths` on Windows, or - /// `python3.10` on Linux and macOS. - /// - `python3.10` or `python.exe` looks for a binary with the given name in `PATH`. - /// - `/home/ferris/.local/bin/python3.10` uses the exact Python at the given path. - #[arg(long, short, env = "UV_PYTHON", verbatim_doc_comment)] - pub(crate) python: Option, } diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index d04ad824b..71f86cd88 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -128,10 +128,8 @@ impl RunSettings { upgrade, no_upgrade, upgrade_package, - index_url, - extra_index_url, - find_links, - no_index, + + index_args, python, exclude_newer, package, @@ -139,8 +137,9 @@ impl RunSettings { Self { index_locations: IndexLocations::new( - index_url.and_then(Maybe::into_option), - extra_index_url + index_args.index_url.and_then(Maybe::into_option), + index_args + .extra_index_url .map(|extra_index_urls| { extra_index_urls .into_iter() @@ -148,8 +147,8 @@ impl RunSettings { .collect() }) .unwrap_or_default(), - find_links.unwrap_or_default(), - no_index, + index_args.find_links.unwrap_or_default(), + index_args.no_index, ), refresh: Refresh::from_args(flag(refresh, no_refresh), refresh_package), upgrade: Upgrade::from_args(flag(upgrade, no_upgrade), upgrade_package), @@ -188,17 +187,15 @@ impl ToolRunSettings { args, from, with, - index_url, - extra_index_url, - find_links, - no_index, + index_args, python, } = args; Self { index_locations: IndexLocations::new( - index_url.and_then(Maybe::into_option), - extra_index_url + index_args.index_url.and_then(Maybe::into_option), + index_args + .extra_index_url .map(|extra_index_urls| { extra_index_urls .into_iter() @@ -206,8 +203,8 @@ impl ToolRunSettings { .collect() }) .unwrap_or_default(), - find_links.unwrap_or_default(), - no_index, + index_args.find_links.unwrap_or_default(), + index_args.no_index, ), target, args, @@ -239,17 +236,15 @@ impl SyncSettings { refresh, no_refresh, refresh_package, - index_url, - extra_index_url, - find_links, - no_index, + index_args, python, } = args; Self { index_locations: IndexLocations::new( - index_url.and_then(Maybe::into_option), - extra_index_url + index_args.index_url.and_then(Maybe::into_option), + index_args + .extra_index_url .map(|extra_index_urls| { extra_index_urls .into_iter() @@ -257,8 +252,8 @@ impl SyncSettings { .collect() }) .unwrap_or_default(), - find_links.unwrap_or_default(), - no_index, + index_args.find_links.unwrap_or_default(), + index_args.no_index, ), refresh: Refresh::from_args(flag(refresh, no_refresh), refresh_package), extras: ExtrasSpecification::from_args( @@ -292,18 +287,16 @@ impl LockSettings { upgrade, no_upgrade, upgrade_package, - index_url, - extra_index_url, - find_links, - no_index, + index_args, exclude_newer, python, } = args; Self { index_locations: IndexLocations::new( - index_url.and_then(Maybe::into_option), - extra_index_url + index_args.index_url.and_then(Maybe::into_option), + index_args + .extra_index_url .map(|extra_index_urls| { extra_index_urls .into_iter() @@ -311,8 +304,8 @@ impl LockSettings { .collect() }) .unwrap_or_default(), - find_links.unwrap_or_default(), - no_index, + index_args.find_links.unwrap_or_default(), + index_args.no_index, ), refresh: Refresh::from_args(flag(refresh, no_refresh), refresh_package), upgrade: Upgrade::from_args(flag(upgrade, no_upgrade), upgrade_package), @@ -368,12 +361,9 @@ impl PipCompileSettings { no_refresh, refresh_package, link_mode, - index_url, - extra_index_url, - no_index, + index_args, index_strategy, keyring_provider, - find_links, python, system, no_system, @@ -441,15 +431,15 @@ impl PipCompileSettings { python, system: flag(system, no_system), - index_url: index_url.and_then(Maybe::into_option), - extra_index_url: extra_index_url.map(|extra_index_urls| { + index_url: index_args.index_url.and_then(Maybe::into_option), + extra_index_url: index_args.extra_index_url.map(|extra_index_urls| { extra_index_urls .into_iter() .filter_map(Maybe::into_option) .collect() }), - no_index: Some(no_index), - find_links, + no_index: Some(index_args.no_index), + find_links: index_args.find_links, index_strategy, keyring_provider, no_build: flag(no_build, build), @@ -523,10 +513,7 @@ impl PipSyncSettings { no_refresh, refresh_package, link_mode, - index_url, - extra_index_url, - find_links, - no_index, + index_args, index_strategy, require_hashes, no_require_hashes, @@ -575,16 +562,15 @@ impl PipSyncSettings { system: flag(system, no_system), break_system_packages: flag(break_system_packages, no_break_system_packages), target, - - index_url: index_url.and_then(Maybe::into_option), - extra_index_url: extra_index_url.map(|extra_index_urls| { + index_url: index_args.index_url.and_then(Maybe::into_option), + extra_index_url: index_args.extra_index_url.map(|extra_index_urls| { extra_index_urls .into_iter() .filter_map(Maybe::into_option) .collect() }), - no_index: Some(no_index), - find_links, + no_index: Some(index_args.no_index), + find_links: index_args.find_links, index_strategy, keyring_provider, no_build: flag(no_build, build), @@ -661,10 +647,7 @@ impl PipInstallSettings { resolution, prerelease, pre, - index_url, - extra_index_url, - find_links, - no_index, + index_args, index_strategy, require_hashes, no_require_hashes, @@ -736,16 +719,15 @@ impl PipInstallSettings { system: flag(system, no_system), break_system_packages: flag(break_system_packages, no_break_system_packages), target, - - index_url: index_url.and_then(Maybe::into_option), - extra_index_url: extra_index_url.map(|extra_index_urls| { + index_url: index_args.index_url.and_then(Maybe::into_option), + extra_index_url: index_args.extra_index_url.map(|extra_index_urls| { extra_index_urls .into_iter() .filter_map(Maybe::into_option) .collect() }), - no_index: Some(no_index), - find_links, + no_index: Some(index_args.no_index), + find_links: index_args.find_links, index_strategy, keyring_provider, no_build: flag(no_build, build),