From 2153c6ac0d692b9eccedbd7567087907667645fb Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 15 Oct 2024 16:56:24 -0700 Subject: [PATCH] Respect named `--index` and `--default-index` values in `tool.uv.sources` (#7910) ## Summary If you pass a named index via the CLI, you can now reference it as a named source. This required some surprisingly large refactors, since we now need to be able to track whether a given index was provided on the CLI vs. elsewhere (since, e.g., we don't want users to be able to reference named indexes defined in global configuration). Closes https://github.com/astral-sh/uv/issues/7899. --- crates/uv-build-frontend/src/lib.rs | 9 ++- crates/uv-cli/src/lib.rs | 77 ++++++++++++++----- crates/uv-cli/src/options.rs | 9 ++- crates/uv-dispatch/src/lib.rs | 3 +- crates/uv-distribution-types/src/index.rs | 24 +++++- crates/uv-distribution-types/src/lib.rs | 4 + crates/uv-distribution-types/src/origin.rs | 12 +++ crates/uv-distribution-types/src/pip_index.rs | 59 ++++++++++++++ .../uv-distribution/src/metadata/lowering.rs | 42 +++++----- crates/uv-distribution/src/metadata/mod.rs | 3 + .../src/metadata/requires_dist.rs | 31 +++++--- crates/uv-distribution/src/source/mod.rs | 37 ++++++++- crates/uv-resolver/src/resolver/mod.rs | 2 +- crates/uv-settings/src/combine.rs | 8 +- crates/uv-settings/src/settings.rs | 48 ++++++------ crates/uv-types/src/traits.rs | 2 +- crates/uv/src/commands/pip/compile.rs | 9 ++- crates/uv/src/commands/pip/install.rs | 9 ++- crates/uv/src/commands/pip/sync.rs | 9 ++- crates/uv/src/commands/project/run.rs | 1 + crates/uv/src/settings.rs | 46 +++-------- crates/uv/tests/it/lock.rs | 16 ++-- crates/uv/tests/it/show_settings.rs | 43 +++++++++++ 23 files changed, 370 insertions(+), 133 deletions(-) create mode 100644 crates/uv-distribution-types/src/origin.rs create mode 100644 crates/uv-distribution-types/src/pip_index.rs diff --git a/crates/uv-build-frontend/src/lib.rs b/crates/uv-build-frontend/src/lib.rs index 903d45f85842..641fedc3c7c3 100644 --- a/crates/uv-build-frontend/src/lib.rs +++ b/crates/uv-build-frontend/src/lib.rs @@ -30,7 +30,7 @@ use tracing::{debug, info_span, instrument, Instrument}; pub use crate::error::{Error, MissingHeaderCause}; use uv_configuration::{BuildKind, BuildOutput, ConfigSettings, SourceStrategy}; use uv_distribution::{LowerBound, RequiresDist}; -use uv_distribution_types::Resolution; +use uv_distribution_types::{IndexLocations, Resolution}; use uv_fs::{rename_with_retry, PythonExt, Simplified}; use uv_pep440::Version; use uv_pep508::PackageName; @@ -250,6 +250,7 @@ impl SourceBuild { build_context: &impl BuildContext, source_build_context: SourceBuildContext, version_id: Option, + locations: &IndexLocations, source_strategy: SourceStrategy, config_settings: ConfigSettings, build_isolation: BuildIsolation<'_>, @@ -272,6 +273,7 @@ impl SourceBuild { let (pep517_backend, project) = Self::extract_pep517_backend( &source_tree, fallback_package_name, + locations, source_strategy, &default_backend, ) @@ -371,6 +373,7 @@ impl SourceBuild { package_name.as_ref(), package_version.as_ref(), version_id.as_deref(), + locations, source_strategy, build_kind, level, @@ -433,6 +436,7 @@ impl SourceBuild { async fn extract_pep517_backend( source_tree: &Path, package_name: Option<&PackageName>, + locations: &IndexLocations, source_strategy: SourceStrategy, default_backend: &Pep517Backend, ) -> Result<(Pep517Backend, Option), Box> { @@ -465,6 +469,7 @@ impl SourceBuild { let requires_dist = RequiresDist::from_project_maybe_workspace( requires_dist, source_tree, + locations, source_strategy, LowerBound::Allow, ) @@ -803,6 +808,7 @@ async fn create_pep517_build_environment( package_name: Option<&PackageName>, package_version: Option<&Version>, version_id: Option<&str>, + locations: &IndexLocations, source_strategy: SourceStrategy, build_kind: BuildKind, level: BuildOutput, @@ -915,6 +921,7 @@ async fn create_pep517_build_environment( let requires_dist = RequiresDist::from_project_maybe_workspace( requires_dist, source_tree, + locations, source_strategy, LowerBound::Allow, ) diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index e66e07291c84..8343e0270629 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -14,7 +14,7 @@ use uv_configuration::{ ConfigSettingEntry, ExportFormat, IndexStrategy, KeyringProviderType, PackageNameSpecifier, TargetTriple, TrustedHost, TrustedPublishing, VersionControlSystem, }; -use uv_distribution_types::{Index, IndexUrl}; +use uv_distribution_types::{Index, IndexUrl, Origin, PipExtraIndex, PipFindLinks, PipIndex}; use uv_normalize::{ExtraName, PackageName}; use uv_pep508::Requirement; use uv_pypi_types::VerbatimParsedUrl; @@ -774,26 +774,66 @@ impl Maybe { } } -/// Parse a string into an [`IndexUrl`], mapping the empty string to `None`. -fn parse_index_url(input: &str) -> Result, String> { +/// Parse an `--index-url` argument into an [`PipIndex`], mapping the empty string to `None`. +fn parse_index_url(input: &str) -> Result, String> { if input.is_empty() { Ok(Maybe::None) } else { - match IndexUrl::from_str(input) { - Ok(url) => Ok(Maybe::Some(url)), - Err(err) => Err(err.to_string()), - } + IndexUrl::from_str(input) + .map(Index::from_index_url) + .map(|index| Index { + origin: Some(Origin::Cli), + ..index + }) + .map(PipIndex::from) + .map(Maybe::Some) + .map_err(|err| err.to_string()) + } +} + +/// Parse an `--extra-index-url` argument into an [`PipExtraIndex`], mapping the empty string to `None`. +fn parse_extra_index_url(input: &str) -> Result, String> { + if input.is_empty() { + Ok(Maybe::None) + } else { + IndexUrl::from_str(input) + .map(Index::from_extra_index_url) + .map(|index| Index { + origin: Some(Origin::Cli), + ..index + }) + .map(PipExtraIndex::from) + .map(Maybe::Some) + .map_err(|err| err.to_string()) + } +} + +/// Parse a `--find-links` argument into an [`PipFindLinks`], mapping the empty string to `None`. +fn parse_find_links(input: &str) -> Result, String> { + if input.is_empty() { + Ok(Maybe::None) + } else { + IndexUrl::from_str(input) + .map(Index::from_find_links) + .map(|index| Index { + origin: Some(Origin::Cli), + ..index + }) + .map(PipFindLinks::from) + .map(Maybe::Some) + .map_err(|err| err.to_string()) } } -/// Parse a string into an [`Index`], mapping the empty string to `None`. -fn parse_index_source(input: &str) -> Result, String> { +/// Parse an `--index` argument into an [`Index`], mapping the empty string to `None`. +fn parse_index(input: &str) -> Result, String> { if input.is_empty() { Ok(Maybe::None) } else { match Index::from_str(input) { Ok(index) => Ok(Maybe::Some(Index { default: false, + origin: Some(Origin::Cli), ..index })), Err(err) => Err(err.to_string()), @@ -801,14 +841,15 @@ fn parse_index_source(input: &str) -> Result, String> { } } -/// Parse a string into an [`Index`], mapping the empty string to `None`. -fn parse_default_index_source(input: &str) -> Result, String> { +/// Parse a `--default-index` argument into an [`Index`], mapping the empty string to `None`. +fn parse_default_index(input: &str) -> Result, String> { if input.is_empty() { Ok(Maybe::None) } else { match Index::from_str(input) { Ok(index) => Ok(Maybe::Some(Index { default: true, + origin: Some(Origin::Cli), ..index })), Err(err) => Err(err.to_string()), @@ -3839,7 +3880,7 @@ pub struct IndexArgs { /// All indexes provided via this flag take priority over the index specified by /// `--default-index` (which defaults to PyPI). When multiple `--index` flags are /// provided, earlier values take priority. - #[arg(long, env = "UV_INDEX", value_delimiter = ' ', value_parser = parse_index_source, help_heading = "Index options")] + #[arg(long, env = "UV_INDEX", value_delimiter = ' ', value_parser = parse_index, help_heading = "Index options")] pub index: Option>>, /// The URL of the default package index (by default: ). @@ -3849,7 +3890,7 @@ pub struct IndexArgs { /// /// The index given by this flag is given lower priority than all other indexes specified via /// the `--index` flag. - #[arg(long, env = "UV_DEFAULT_INDEX", value_parser = parse_default_index_source, help_heading = "Index options")] + #[arg(long, env = "UV_DEFAULT_INDEX", value_parser = parse_default_index, help_heading = "Index options")] pub default_index: Option>, /// (Deprecated: use `--default-index` instead) The URL of the Python package index (by default: ). @@ -3860,7 +3901,7 @@ pub struct IndexArgs { /// The index given by this flag is given lower priority than all other /// indexes specified via the `--extra-index-url` flag. #[arg(long, short, env = EnvVars::UV_INDEX_URL, value_parser = parse_index_url, help_heading = "Index options")] - pub index_url: Option>, + pub index_url: Option>, /// (Deprecated: use `--index` instead) Extra URLs of package indexes to use, in addition to `--index-url`. /// @@ -3870,8 +3911,8 @@ pub struct IndexArgs { /// All indexes provided via this flag take priority over the index specified by /// `--index-url` (which defaults to PyPI). When multiple `--extra-index-url` flags are /// provided, earlier values take priority. - #[arg(long, env = EnvVars::UV_EXTRA_INDEX_URL, value_delimiter = ' ', value_parser = parse_index_url, help_heading = "Index options")] - pub extra_index_url: Option>>, + #[arg(long, env = EnvVars::UV_EXTRA_INDEX_URL, value_delimiter = ' ', value_parser = parse_extra_index_url, help_heading = "Index options")] + pub extra_index_url: Option>>, /// Locations to search for candidate distributions, in addition to those found in the registry /// indexes. @@ -3885,10 +3926,10 @@ pub struct IndexArgs { long, short, env = EnvVars::UV_FIND_LINKS, - value_parser = parse_index_url, + value_parser = parse_find_links, help_heading = "Index options" )] - pub find_links: Option>>, + pub find_links: Option>>, /// Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those /// provided via `--find-links`. diff --git a/crates/uv-cli/src/options.rs b/crates/uv-cli/src/options.rs index 499a2109a80d..404129793856 100644 --- a/crates/uv-cli/src/options.rs +++ b/crates/uv-cli/src/options.rs @@ -1,5 +1,6 @@ use uv_cache::Refresh; use uv_configuration::ConfigSettings; +use uv_distribution_types::{PipExtraIndex, PipFindLinks, PipIndex}; use uv_resolver::PrereleaseMode; use uv_settings::{Combine, PipOptions, ResolverInstallerOptions, ResolverOptions}; @@ -201,11 +202,12 @@ impl From for PipOptions { .combine( index.map(|index| index.into_iter().filter_map(Maybe::into_option).collect()), ), - index_url: index_url.and_then(Maybe::into_option), - extra_index_url: extra_index_url.map(|extra_index_url| { - extra_index_url + index_url: index_url.and_then(Maybe::into_option).map(PipIndex::from), + extra_index_url: extra_index_url.map(|extra_index_urls| { + extra_index_urls .into_iter() .filter_map(Maybe::into_option) + .map(PipExtraIndex::from) .collect() }), no_index: if no_index { Some(true) } else { None }, @@ -213,6 +215,7 @@ impl From for PipOptions { find_links .into_iter() .filter_map(Maybe::into_option) + .map(PipFindLinks::from) .collect() }), ..PipOptions::default() diff --git a/crates/uv-dispatch/src/lib.rs b/crates/uv-dispatch/src/lib.rs index 907de1872f6b..c56b4c0d3710 100644 --- a/crates/uv-dispatch/src/lib.rs +++ b/crates/uv-dispatch/src/lib.rs @@ -156,7 +156,7 @@ impl<'a> BuildContext for BuildDispatch<'a> { self.sources } - fn index_locations(&self) -> &IndexLocations { + fn locations(&self) -> &IndexLocations { self.index_locations } @@ -350,6 +350,7 @@ impl<'a> BuildContext for BuildDispatch<'a> { self, self.source_build_context.clone(), version_id, + self.index_locations, sources, self.config_settings.clone(), self.build_isolation, diff --git a/crates/uv-distribution-types/src/index.rs b/crates/uv-distribution-types/src/index.rs index 737b8cac9b18..3e90bacf4ef6 100644 --- a/crates/uv-distribution-types/src/index.rs +++ b/crates/uv-distribution-types/src/index.rs @@ -1,9 +1,11 @@ -use crate::{IndexUrl, IndexUrlError}; use std::str::FromStr; use thiserror::Error; use url::Url; use uv_auth::Credentials; +use crate::origin::Origin; +use crate::{IndexUrl, IndexUrlError}; + #[derive(Debug, Clone, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct Index { @@ -52,6 +54,9 @@ pub struct Index { /// is given the highest priority when resolving packages. #[serde(default)] pub default: bool, + /// The origin of the index (e.g., a CLI flag, a user-level configuration file, etc.). + #[serde(skip)] + pub origin: Option, // /// The type of the index. // /// // /// Indexes can either be PEP 503-compliant (i.e., a registry implementing the Simple API) or @@ -81,6 +86,7 @@ impl Index { name: None, explicit: false, default: true, + origin: None, } } @@ -91,6 +97,7 @@ impl Index { name: None, explicit: false, default: false, + origin: None, } } @@ -101,14 +108,27 @@ impl Index { name: None, explicit: false, default: false, + origin: None, } } + /// Set the [`Origin`] of the index. + #[must_use] + pub fn with_origin(mut self, origin: Origin) -> Self { + self.origin = Some(origin); + self + } + /// Return the [`IndexUrl`] of the index. pub fn url(&self) -> &IndexUrl { &self.url } + /// Consume the [`Index`] and return the [`IndexUrl`]. + pub fn into_url(self) -> IndexUrl { + self.url + } + /// Return the raw [`URL`] of the index. pub fn raw_url(&self) -> &Url { self.url.url() @@ -145,6 +165,7 @@ impl FromStr for Index { url, explicit: false, default: false, + origin: None, }); } } @@ -156,6 +177,7 @@ impl FromStr for Index { url, explicit: false, default: false, + origin: None, }) } } diff --git a/crates/uv-distribution-types/src/lib.rs b/crates/uv-distribution-types/src/lib.rs index 3758284a19e6..b8c050baf780 100644 --- a/crates/uv-distribution-types/src/lib.rs +++ b/crates/uv-distribution-types/src/lib.rs @@ -60,6 +60,8 @@ pub use crate::id::*; pub use crate::index::*; pub use crate::index_url::*; pub use crate::installed::*; +pub use crate::origin::*; +pub use crate::pip_index::*; pub use crate::prioritized_distribution::*; pub use crate::resolution::*; pub use crate::resolved::*; @@ -79,6 +81,8 @@ mod id; mod index; mod index_url; mod installed; +mod origin; +mod pip_index; mod prioritized_distribution; mod resolution; mod resolved; diff --git a/crates/uv-distribution-types/src/origin.rs b/crates/uv-distribution-types/src/origin.rs new file mode 100644 index 000000000000..286735545d08 --- /dev/null +++ b/crates/uv-distribution-types/src/origin.rs @@ -0,0 +1,12 @@ +/// The origin of a piece of configuration. +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +pub enum Origin { + /// The setting was provided via the CLI. + Cli, + /// The setting was provided via a user-level configuration file. + User, + /// The setting was provided via a project-level configuration file. + Project, + /// The setting was provided via a `requirements.txt` file. + RequirementsTxt, +} diff --git a/crates/uv-distribution-types/src/pip_index.rs b/crates/uv-distribution-types/src/pip_index.rs new file mode 100644 index 000000000000..9d5de50ea34e --- /dev/null +++ b/crates/uv-distribution-types/src/pip_index.rs @@ -0,0 +1,59 @@ +//! Compatibility structs for converting between [`IndexUrl`] and [`Index`]. These structs are +//! parsed and deserialized as [`IndexUrl`], but are stored as [`Index`] with the appropriate +//! flags set. + +use serde::{Deserialize, Deserializer, Serialize}; + +use crate::{Index, IndexUrl}; + +macro_rules! impl_index { + ($name:ident, $from:expr) => { + #[derive(Debug, Clone, Eq, PartialEq)] + pub struct $name(Index); + + impl From<$name> for Index { + fn from(value: $name) -> Self { + value.0 + } + } + + impl From for $name { + fn from(value: Index) -> Self { + Self(value) + } + } + + impl Serialize for $name { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.0.url().serialize(serializer) + } + } + + impl<'de> Deserialize<'de> for $name { + fn deserialize(deserializer: D) -> Result<$name, D::Error> + where + D: Deserializer<'de>, + { + IndexUrl::deserialize(deserializer).map($from).map(Self) + } + } + + #[cfg(feature = "schemars")] + impl schemars::JsonSchema for $name { + fn schema_name() -> String { + IndexUrl::schema_name() + } + + fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema { + IndexUrl::json_schema(gen) + } + } + }; +} + +impl_index!(PipIndex, Index::from_index_url); +impl_index!(PipExtraIndex, Index::from_extra_index_url); +impl_index!(PipFindLinks, Index::from_find_links); diff --git a/crates/uv-distribution/src/metadata/lowering.rs b/crates/uv-distribution/src/metadata/lowering.rs index 5f3480eab6a6..9960972b0bfe 100644 --- a/crates/uv-distribution/src/metadata/lowering.rs +++ b/crates/uv-distribution/src/metadata/lowering.rs @@ -6,7 +6,7 @@ use thiserror::Error; use url::Url; use uv_distribution_filename::DistExtension; -use uv_distribution_types::Index; +use uv_distribution_types::{Index, IndexLocations, Origin}; use uv_git::GitReference; use uv_normalize::PackageName; use uv_pep440::VersionSpecifiers; @@ -20,7 +20,7 @@ use uv_workspace::Workspace; pub struct LoweredRequirement(Requirement); #[derive(Debug, Clone, Copy)] -enum Origin { +enum RequirementOrigin { /// The `tool.uv.sources` were read from the project. Project, /// The `tool.uv.sources` were read from the workspace root. @@ -35,15 +35,16 @@ impl LoweredRequirement { project_dir: &'data Path, project_sources: &'data BTreeMap, project_indexes: &'data [Index], + locations: &'data IndexLocations, workspace: &'data Workspace, lower_bound: LowerBound, - ) -> impl Iterator> + 'data { + ) -> impl Iterator> + 'data { let (source, origin) = if let Some(source) = project_sources.get(&requirement.name) { - (Some(source), Origin::Project) + (Some(source), RequirementOrigin::Project) } else if let Some(source) = workspace.sources().get(&requirement.name) { - (Some(source), Origin::Workspace) + (Some(source), RequirementOrigin::Workspace) } else { - (None, Origin::Project) + (None, RequirementOrigin::Project) }; let source = source.cloned(); @@ -155,16 +156,14 @@ impl LoweredRequirement { Source::Registry { index, marker } => { // Identify the named index from either the project indexes or the workspace indexes, // in that order. - let Some(index) = project_indexes - .iter() + let Some(index) = locations + .indexes() + .filter(|index| matches!(index.origin, Some(Origin::Cli))) + .chain(project_indexes.iter()) + .chain(workspace.indexes().iter()) .find(|Index { name, .. }| { name.as_ref().is_some_and(|name| *name == index) }) - .or_else(|| { - workspace.indexes().iter().find(|Index { name, .. }| { - name.as_ref().is_some_and(|name| *name == index) - }) - }) .map(|Index { url: index, .. }| index.clone()) else { return Err(LoweringError::MissingIndex( @@ -260,7 +259,8 @@ impl LoweredRequirement { dir: &'data Path, sources: &'data BTreeMap, indexes: &'data [Index], - ) -> impl Iterator> + 'data { + locations: &'data IndexLocations, + ) -> impl Iterator> + 'data { let source = sources.get(&requirement.name).cloned(); let Some(source) = source else { @@ -332,7 +332,7 @@ impl LoweredRequirement { } let source = path_source( PathBuf::from(path), - Origin::Project, + RequirementOrigin::Project, dir, dir, editable.unwrap_or(false), @@ -340,8 +340,10 @@ impl LoweredRequirement { (source, marker) } Source::Registry { index, marker } => { - let Some(index) = indexes - .iter() + let Some(index) = locations + .indexes() + .filter(|index| matches!(index.origin, Some(Origin::Cli))) + .chain(indexes.iter()) .find(|Index { name, .. }| { name.as_ref().is_some_and(|name| *name == index) }) @@ -508,15 +510,15 @@ fn registry_source( /// Convert a path string to a file or directory source. fn path_source( path: impl AsRef, - origin: Origin, + origin: RequirementOrigin, project_dir: &Path, workspace_root: &Path, editable: bool, ) -> Result { let path = path.as_ref(); let base = match origin { - Origin::Project => project_dir, - Origin::Workspace => workspace_root, + RequirementOrigin::Project => project_dir, + RequirementOrigin::Workspace => workspace_root, }; let url = VerbatimUrl::from_path(path, base)?.with_given(path.to_string_lossy()); let install_path = url.to_file_path().map_err(|()| { diff --git a/crates/uv-distribution/src/metadata/mod.rs b/crates/uv-distribution/src/metadata/mod.rs index fe1884a215eb..69b28fa8a980 100644 --- a/crates/uv-distribution/src/metadata/mod.rs +++ b/crates/uv-distribution/src/metadata/mod.rs @@ -4,6 +4,7 @@ use std::path::Path; use thiserror::Error; use uv_configuration::SourceStrategy; +use uv_distribution_types::IndexLocations; use uv_normalize::{ExtraName, GroupName, PackageName}; use uv_pep440::{Version, VersionSpecifiers}; use uv_pypi_types::{HashDigest, ResolutionMetadata}; @@ -61,6 +62,7 @@ impl Metadata { pub async fn from_workspace( metadata: ResolutionMetadata, install_path: &Path, + locations: &IndexLocations, sources: SourceStrategy, ) -> Result { // Lower the requirements. @@ -76,6 +78,7 @@ impl Metadata { provides_extras: metadata.provides_extras, }, install_path, + locations, sources, LowerBound::Warn, ) diff --git a/crates/uv-distribution/src/metadata/requires_dist.rs b/crates/uv-distribution/src/metadata/requires_dist.rs index 2df77967a237..885a0be760ca 100644 --- a/crates/uv-distribution/src/metadata/requires_dist.rs +++ b/crates/uv-distribution/src/metadata/requires_dist.rs @@ -1,10 +1,11 @@ +use crate::metadata::lowering::LowerBound; use crate::metadata::{LoweredRequirement, MetadataError}; use crate::Metadata; -use crate::metadata::lowering::LowerBound; use std::collections::BTreeMap; use std::path::Path; use uv_configuration::SourceStrategy; +use uv_distribution_types::IndexLocations; use uv_normalize::{ExtraName, GroupName, PackageName, DEV_DEPENDENCIES}; use uv_workspace::pyproject::ToolUvSources; use uv_workspace::{DiscoveryOptions, ProjectWorkspace}; @@ -38,6 +39,7 @@ impl RequiresDist { pub async fn from_project_maybe_workspace( metadata: uv_pypi_types::RequiresDist, install_path: &Path, + locations: &IndexLocations, sources: SourceStrategy, lower_bound: LowerBound, ) -> Result { @@ -50,18 +52,25 @@ impl RequiresDist { return Ok(Self::from_metadata23(metadata)); }; - Self::from_project_workspace(metadata, &project_workspace, sources, lower_bound) + Self::from_project_workspace( + metadata, + &project_workspace, + locations, + sources, + lower_bound, + ) } fn from_project_workspace( metadata: uv_pypi_types::RequiresDist, project_workspace: &ProjectWorkspace, + locations: &IndexLocations, source_strategy: SourceStrategy, lower_bound: LowerBound, ) -> Result { // Collect any `tool.uv.index` entries. let empty = vec![]; - let indexes = match source_strategy { + let project_indexes = match source_strategy { SourceStrategy::Enabled => project_workspace .current_project() .pyproject_toml() @@ -75,7 +84,7 @@ impl RequiresDist { // Collect any `tool.uv.sources` and `tool.uv.dev_dependencies` from `pyproject.toml`. let empty = BTreeMap::default(); - let sources = match source_strategy { + let project_sources = match source_strategy { SourceStrategy::Enabled => project_workspace .current_project() .pyproject_toml() @@ -107,8 +116,9 @@ impl RequiresDist { requirement, &metadata.name, project_workspace.project_root(), - sources, - indexes, + project_sources, + project_indexes, + locations, project_workspace.workspace(), lower_bound, ) @@ -141,8 +151,9 @@ impl RequiresDist { requirement, &metadata.name, project_workspace.project_root(), - sources, - indexes, + project_sources, + project_indexes, + locations, project_workspace.workspace(), lower_bound, ) @@ -188,6 +199,7 @@ mod test { use indoc::indoc; use insta::assert_snapshot; use uv_configuration::SourceStrategy; + use uv_distribution_types::IndexLocations; use uv_workspace::pyproject::PyProjectToml; use uv_workspace::{DiscoveryOptions, ProjectWorkspace}; @@ -214,7 +226,8 @@ mod test { Ok(RequiresDist::from_project_workspace( requires_dist, &project_workspace, - SourceStrategy::Enabled, + &IndexLocations::default(), + SourceStrategy::default(), LowerBound::Warn, )?) } diff --git a/crates/uv-distribution/src/source/mod.rs b/crates/uv-distribution/src/source/mod.rs index 9cb3a3d1d5a6..b616f7043f81 100644 --- a/crates/uv-distribution/src/source/mod.rs +++ b/crates/uv-distribution/src/source/mod.rs @@ -388,6 +388,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { let requires_dist = RequiresDist::from_project_maybe_workspace( requires_dist, project_root, + self.build_context.locations(), self.build_context.sources(), LowerBound::Warn, ) @@ -1086,6 +1087,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { Metadata::from_workspace( metadata, resource.install_path.as_ref(), + self.build_context.locations(), self.build_context.sources(), ) .await?, @@ -1120,6 +1122,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { Metadata::from_workspace( metadata, resource.install_path.as_ref(), + self.build_context.locations(), self.build_context.sources(), ) .await?, @@ -1149,6 +1152,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { Metadata::from_workspace( metadata, resource.install_path.as_ref(), + self.build_context.locations(), self.build_context.sources(), ) .await?, @@ -1194,6 +1198,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { Metadata::from_workspace( metadata, resource.install_path.as_ref(), + self.build_context.locations(), self.build_context.sources(), ) .await?, @@ -1374,7 +1379,13 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { Self::read_static_metadata(source, fetch.path(), resource.subdirectory).await? { return Ok(ArchiveMetadata::from( - Metadata::from_workspace(metadata, &path, self.build_context.sources()).await?, + Metadata::from_workspace( + metadata, + &path, + self.build_context.locations(), + self.build_context.sources(), + ) + .await?, )); } @@ -1395,7 +1406,13 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { debug!("Using cached metadata for: {source}"); return Ok(ArchiveMetadata::from( - Metadata::from_workspace(metadata, &path, self.build_context.sources()).await?, + Metadata::from_workspace( + metadata, + &path, + self.build_context.locations(), + self.build_context.sources(), + ) + .await?, )); } } @@ -1420,7 +1437,13 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { .map_err(Error::CacheWrite)?; return Ok(ArchiveMetadata::from( - Metadata::from_workspace(metadata, &path, self.build_context.sources()).await?, + Metadata::from_workspace( + metadata, + &path, + self.build_context.locations(), + self.build_context.sources(), + ) + .await?, )); } @@ -1460,7 +1483,13 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> { .map_err(Error::CacheWrite)?; Ok(ArchiveMetadata::from( - Metadata::from_workspace(metadata, fetch.path(), self.build_context.sources()).await?, + Metadata::from_workspace( + metadata, + fetch.path(), + self.build_context.locations(), + self.build_context.sources(), + ) + .await?, )) } diff --git a/crates/uv-resolver/src/resolver/mod.rs b/crates/uv-resolver/src/resolver/mod.rs index dea365b61251..8d87292b8cd5 100644 --- a/crates/uv-resolver/src/resolver/mod.rs +++ b/crates/uv-resolver/src/resolver/mod.rs @@ -177,7 +177,7 @@ impl<'a, Context: BuildContext, InstalledPackages: InstalledPackagesProvider> index, build_context.git(), build_context.capabilities(), - build_context.index_locations(), + build_context.locations(), provider, installed_packages, ) diff --git a/crates/uv-settings/src/combine.rs b/crates/uv-settings/src/combine.rs index f57675695db7..dfd39085e463 100644 --- a/crates/uv-settings/src/combine.rs +++ b/crates/uv-settings/src/combine.rs @@ -5,7 +5,7 @@ use url::Url; use uv_configuration::{ ConfigSettings, IndexStrategy, KeyringProviderType, TargetTriple, TrustedPublishing, }; -use uv_distribution_types::IndexUrl; +use uv_distribution_types::{Index, IndexUrl, PipExtraIndex, PipFindLinks, PipIndex}; use uv_install_wheel::linker::LinkMode; use uv_pypi_types::SupportedEnvironments; use uv_python::{PythonDownloads, PythonPreference, PythonVersion}; @@ -72,13 +72,16 @@ macro_rules! impl_combine_or { impl_combine_or!(AnnotationStyle); impl_combine_or!(ExcludeNewer); +impl_combine_or!(Index); impl_combine_or!(IndexStrategy); impl_combine_or!(IndexUrl); -impl_combine_or!(Url); impl_combine_or!(KeyringProviderType); impl_combine_or!(LinkMode); impl_combine_or!(NonZeroUsize); impl_combine_or!(PathBuf); +impl_combine_or!(PipExtraIndex); +impl_combine_or!(PipFindLinks); +impl_combine_or!(PipIndex); impl_combine_or!(PrereleaseMode); impl_combine_or!(PythonDownloads); impl_combine_or!(PythonPreference); @@ -88,6 +91,7 @@ impl_combine_or!(String); impl_combine_or!(SupportedEnvironments); impl_combine_or!(TargetTriple); impl_combine_or!(TrustedPublishing); +impl_combine_or!(Url); impl_combine_or!(bool); impl Combine for Option> { diff --git a/crates/uv-settings/src/settings.rs b/crates/uv-settings/src/settings.rs index 4ae01f992fdc..ee22dd560a96 100644 --- a/crates/uv-settings/src/settings.rs +++ b/crates/uv-settings/src/settings.rs @@ -1,13 +1,12 @@ -use std::{fmt::Debug, num::NonZeroUsize, path::PathBuf}; - use serde::{Deserialize, Serialize}; +use std::{fmt::Debug, num::NonZeroUsize, path::PathBuf}; use url::Url; use uv_cache_info::CacheKey; use uv_configuration::{ ConfigSettings, IndexStrategy, KeyringProviderType, PackageNameSpecifier, TargetTriple, TrustedHost, TrustedPublishing, }; -use uv_distribution_types::{Index, IndexUrl, StaticMetadata}; +use uv_distribution_types::{Index, PipExtraIndex, PipFindLinks, PipIndex, StaticMetadata}; use uv_install_wheel::linker::LinkMode; use uv_macros::{CombineOptions, OptionsMetadata}; use uv_normalize::{ExtraName, PackageName}; @@ -231,10 +230,10 @@ pub struct GlobalOptions { #[derive(Debug, Clone, Default, CombineOptions)] pub struct InstallerOptions { pub index: Option>, - pub index_url: Option, - pub extra_index_url: Option>, + pub index_url: Option, + pub extra_index_url: Option>, pub no_index: Option, - pub find_links: Option>, + pub find_links: Option>, pub index_strategy: Option, pub keyring_provider: Option, pub allow_insecure_host: Option>, @@ -256,10 +255,10 @@ pub struct InstallerOptions { #[derive(Debug, Clone, Default, CombineOptions)] pub struct ResolverOptions { pub index: Option>, - pub index_url: Option, - pub extra_index_url: Option>, + pub index_url: Option, + pub extra_index_url: Option>, pub no_index: Option, - pub find_links: Option>, + pub find_links: Option>, pub index_strategy: Option, pub keyring_provider: Option, pub allow_insecure_host: Option>, @@ -339,7 +338,7 @@ pub struct ResolverInstallerOptions { index-url = "https://test.pypi.org/simple" "# )] - pub index_url: Option, + pub index_url: Option, /// Extra URLs of package indexes to use, in addition to `--index-url`. /// /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/) @@ -360,7 +359,7 @@ pub struct ResolverInstallerOptions { extra-index-url = ["https://download.pytorch.org/whl/cpu"] "# )] - pub extra_index_url: Option>, + pub extra_index_url: Option>, /// Ignore all registry indexes (e.g., PyPI), instead relying on direct URL dependencies and /// those provided via `--find-links`. #[option( @@ -386,7 +385,7 @@ pub struct ResolverInstallerOptions { find-links = ["https://download.pytorch.org/whl/torch_stable.html"] "# )] - pub find_links: Option>, + pub find_links: Option>, /// The strategy to use when resolving against multiple index URLs. /// /// By default, uv will stop at the first index on which a given package is available, and @@ -754,7 +753,7 @@ pub struct PipOptions { index-url = "https://test.pypi.org/simple" "# )] - pub index_url: Option, + pub index_url: Option, /// Extra URLs of package indexes to use, in addition to `--index-url`. /// /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/) @@ -772,7 +771,7 @@ pub struct PipOptions { extra-index-url = ["https://download.pytorch.org/whl/cpu"] "# )] - pub extra_index_url: Option>, + pub extra_index_url: Option>, /// Ignore all registry indexes (e.g., PyPI), instead relying on direct URL dependencies and /// those provided via `--find-links`. #[option( @@ -798,7 +797,7 @@ pub struct PipOptions { find-links = ["https://download.pytorch.org/whl/torch_stable.html"] "# )] - pub find_links: Option>, + pub find_links: Option>, /// The strategy to use when resolving against multiple index URLs. /// /// By default, uv will stop at the first index on which a given package is available, and @@ -1411,10 +1410,10 @@ impl From for InstallerOptions { #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] pub struct ToolOptions { pub index: Option>, - pub index_url: Option, - pub extra_index_url: Option>, + pub index_url: Option, + pub extra_index_url: Option>, pub no_index: Option, - pub find_links: Option>, + pub find_links: Option>, pub index_strategy: Option, pub keyring_provider: Option, pub allow_insecure_host: Option>, @@ -1502,7 +1501,7 @@ impl From for ResolverInstallerOptions { #[serde(rename_all = "kebab-case", deny_unknown_fields)] pub struct OptionsWire { // #[serde(flatten)] - // globals: GlobalOptions, + // globals: GlobalOptions native_tls: Option, offline: Option, no_cache: Option, @@ -1515,12 +1514,12 @@ pub struct OptionsWire { concurrent_installs: Option, // #[serde(flatten)] - // top_level: ResolverInstallerOptions, + // top_level: ResolverInstallerOptions index: Option>, - index_url: Option, - extra_index_url: Option>, + index_url: Option, + extra_index_url: Option>, no_index: Option, - find_links: Option>, + find_links: Option>, index_strategy: Option, keyring_provider: Option, allow_insecure_host: Option>, @@ -1542,6 +1541,9 @@ pub struct OptionsWire { no_build_package: Option>, no_binary: Option, no_binary_package: Option>, + + // #[serde(flatten)] + // publish: PublishOptions publish_url: Option, trusted_publishing: Option, diff --git a/crates/uv-types/src/traits.rs b/crates/uv-types/src/traits.rs index 2738ad682188..5a06f6abb3b3 100644 --- a/crates/uv-types/src/traits.rs +++ b/crates/uv-types/src/traits.rs @@ -79,7 +79,7 @@ pub trait BuildContext { fn sources(&self) -> SourceStrategy; /// The index locations being searched. - fn index_locations(&self) -> &IndexLocations; + fn locations(&self) -> &IndexLocations; /// Resolve the given requirements into a ready-to-install set of package versions. fn resolve<'a>( diff --git a/crates/uv/src/commands/pip/compile.rs b/crates/uv/src/commands/pip/compile.rs index 36711aa33f49..b726e755c539 100644 --- a/crates/uv/src/commands/pip/compile.rs +++ b/crates/uv/src/commands/pip/compile.rs @@ -16,7 +16,7 @@ use uv_configuration::{KeyringProviderType, TargetTriple}; use uv_dispatch::BuildDispatch; use uv_distribution_types::{ DependencyMetadata, Index, IndexCapabilities, IndexLocations, NameRequirementSpecification, - UnresolvedRequirementSpecification, Verbatim, + Origin, UnresolvedRequirementSpecification, Verbatim, }; use uv_fs::Simplified; use uv_git::GitResolver; @@ -277,8 +277,13 @@ pub(crate) async fn pip_compile( .into_iter() .map(Index::from_extra_index_url) .chain(index_url.map(Index::from_index_url)) + .map(|index| index.with_origin(Origin::RequirementsTxt)) + .collect(), + find_links + .into_iter() + .map(Index::from_find_links) + .map(|index| index.with_origin(Origin::RequirementsTxt)) .collect(), - find_links.into_iter().map(Index::from_find_links).collect(), no_index, ); diff --git a/crates/uv/src/commands/pip/install.rs b/crates/uv/src/commands/pip/install.rs index e05dedbc4b55..5340e32a754d 100644 --- a/crates/uv/src/commands/pip/install.rs +++ b/crates/uv/src/commands/pip/install.rs @@ -13,7 +13,7 @@ use uv_configuration::{ use uv_configuration::{KeyringProviderType, TargetTriple}; use uv_dispatch::BuildDispatch; use uv_distribution_types::{ - DependencyMetadata, Index, IndexLocations, NameRequirementSpecification, Resolution, + DependencyMetadata, Index, IndexLocations, NameRequirementSpecification, Origin, Resolution, UnresolvedRequirementSpecification, }; use uv_fs::Simplified; @@ -279,8 +279,13 @@ pub(crate) async fn pip_install( .into_iter() .map(Index::from_extra_index_url) .chain(index_url.map(Index::from_index_url)) + .map(|index| index.with_origin(Origin::RequirementsTxt)) + .collect(), + find_links + .into_iter() + .map(Index::from_find_links) + .map(|index| index.with_origin(Origin::RequirementsTxt)) .collect(), - find_links.into_iter().map(Index::from_find_links).collect(), no_index, ); diff --git a/crates/uv/src/commands/pip/sync.rs b/crates/uv/src/commands/pip/sync.rs index 744679979709..bb6a0340651f 100644 --- a/crates/uv/src/commands/pip/sync.rs +++ b/crates/uv/src/commands/pip/sync.rs @@ -12,7 +12,7 @@ use uv_configuration::{ }; use uv_configuration::{KeyringProviderType, TargetTriple}; use uv_dispatch::BuildDispatch; -use uv_distribution_types::{DependencyMetadata, Index, IndexLocations, Resolution}; +use uv_distribution_types::{DependencyMetadata, Index, IndexLocations, Origin, Resolution}; use uv_fs::Simplified; use uv_install_wheel::linker::LinkMode; use uv_installer::SitePackages; @@ -215,8 +215,13 @@ pub(crate) async fn pip_sync( .into_iter() .map(Index::from_extra_index_url) .chain(index_url.map(Index::from_index_url)) + .map(|index| index.with_origin(Origin::RequirementsTxt)) + .collect(), + find_links + .into_iter() + .map(Index::from_find_links) + .map(|index| index.with_origin(Origin::RequirementsTxt)) .collect(), - find_links.into_iter().map(Index::from_find_links).collect(), no_index, ); diff --git a/crates/uv/src/commands/project/run.rs b/crates/uv/src/commands/project/run.rs index 1a55f11797c8..9d1fee24e803 100644 --- a/crates/uv/src/commands/project/run.rs +++ b/crates/uv/src/commands/project/run.rs @@ -247,6 +247,7 @@ pub(crate) async fn run( script_dir.as_ref(), script_sources, script_indexes, + &settings.index_locations, ) .map_ok(LoweredRequirement::into_inner) }) diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index 6938a006a61a..e3df2eeeefea 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -1972,20 +1972,14 @@ impl From for ResolverSettings { .index .into_iter() .flatten() - .chain( - value - .extra_index_url - .into_iter() - .flatten() - .map(Index::from_extra_index_url), - ) - .chain(value.index_url.into_iter().map(Index::from_index_url)) + .chain(value.extra_index_url.into_iter().flatten().map(Index::from)) + .chain(value.index_url.into_iter().map(Index::from)) .collect(), value .find_links .into_iter() .flatten() - .map(Index::from_find_links) + .map(Index::from) .collect(), value.no_index.unwrap_or_default(), ), @@ -2115,20 +2109,14 @@ impl From for ResolverInstallerSettings { .index .into_iter() .flatten() - .chain( - value - .extra_index_url - .into_iter() - .flatten() - .map(Index::from_extra_index_url), - ) - .chain(value.index_url.into_iter().map(Index::from_index_url)) + .chain(value.extra_index_url.into_iter().flatten().map(Index::from)) + .chain(value.index_url.into_iter().map(Index::from)) .collect(), value .find_links .into_iter() .flatten() - .map(Index::from_find_links) + .map(Index::from) .collect(), value.no_index.unwrap_or_default(), ), @@ -2319,9 +2307,9 @@ impl PipSettings { // // For example, prefer `tool.uv.pip.index-url` over `tool.uv.index-url`. let index = index.combine(top_level_index); + let no_index = no_index.combine(top_level_no_index); let index_url = index_url.combine(top_level_index_url); let extra_index_url = extra_index_url.combine(top_level_extra_index_url); - let no_index = no_index.combine(top_level_no_index); let find_links = find_links.combine(top_level_find_links); let index_strategy = index_strategy.combine(top_level_index_strategy); let keyring_provider = keyring_provider.combine(top_level_keyring_provider); @@ -2347,27 +2335,17 @@ impl PipSettings { args.index .into_iter() .flatten() - .chain( - args.extra_index_url - .into_iter() - .flatten() - .map(Index::from_extra_index_url), - ) - .chain(args.index_url.into_iter().map(Index::from_index_url)) + .chain(args.extra_index_url.into_iter().flatten().map(Index::from)) + .chain(args.index_url.into_iter().map(Index::from)) .chain(index.into_iter().flatten()) - .chain( - extra_index_url - .into_iter() - .flatten() - .map(Index::from_extra_index_url), - ) - .chain(index_url.into_iter().map(Index::from_index_url)) + .chain(extra_index_url.into_iter().flatten().map(Index::from)) + .chain(index_url.into_iter().map(Index::from)) .collect(), args.find_links .combine(find_links) .into_iter() .flatten() - .map(Index::from_find_links) + .map(Index::from) .collect(), args.no_index.combine(no_index).unwrap_or_default(), ), diff --git a/crates/uv/tests/it/lock.rs b/crates/uv/tests/it/lock.rs index 7f1a57fc223d..059e6278185f 100644 --- a/crates/uv/tests/it/lock.rs +++ b/crates/uv/tests/it/lock.rs @@ -12298,7 +12298,7 @@ fn lock_named_index_cli() -> Result<()> { name = "project" version = "0.1.0" requires-python = ">=3.12" - dependencies = ["anyio==3.7.0", "jinja2"] + dependencies = ["jinja2==3.1.2"] [tool.uv.sources] jinja2 = { index = "pytorch" } @@ -12306,7 +12306,7 @@ fn lock_named_index_cli() -> Result<()> { )?; // The package references a non-existent index. - uv_snapshot!(context.filters(), context.lock(), @r###" + uv_snapshot!(context.filters(), context.lock().env_remove("UV_EXCLUDE_NEWER"), @r###" success: false exit_code: 2 ----- stdout ----- @@ -12317,16 +12317,14 @@ fn lock_named_index_cli() -> Result<()> { Caused by: Package `jinja2` references an undeclared index: `pytorch` "###); - // This also isn't supported right now; you need to specify the index in the `pyproject.toml`. - uv_snapshot!(context.filters(), context.lock().arg("--index").arg("pytorch=https://download.pytorch.org/whl/cu121"), @r###" - success: false - exit_code: 2 + // But it's fine if it comes from the CLI. + uv_snapshot!(context.filters(), context.lock().arg("--index").arg("pytorch=https://download.pytorch.org/whl/cu121").env_remove("UV_EXCLUDE_NEWER"), @r###" + success: true + exit_code: 0 ----- stdout ----- ----- stderr ----- - error: Failed to build: `project @ file://[TEMP_DIR]/` - Caused by: Failed to parse entry for: `jinja2` - Caused by: Package `jinja2` references an undeclared index: `pytorch` + Resolved 3 packages in [TIME] "###); Ok(()) diff --git a/crates/uv/tests/it/show_settings.rs b/crates/uv/tests/it/show_settings.rs index b9565ffd930c..da2d38a32c34 100644 --- a/crates/uv/tests/it/show_settings.rs +++ b/crates/uv/tests/it/show_settings.rs @@ -115,6 +115,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -261,6 +262,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -408,6 +410,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -587,6 +590,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -864,6 +868,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -1035,6 +1040,7 @@ fn resolve_index_url() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: None, }, Index { name: None, @@ -1062,6 +1068,7 @@ fn resolve_index_url() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -1210,6 +1217,9 @@ fn resolve_index_url() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: Some( + Cli, + ), }, Index { name: None, @@ -1237,6 +1247,7 @@ fn resolve_index_url() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: None, }, Index { name: None, @@ -1264,6 +1275,7 @@ fn resolve_index_url() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -1436,6 +1448,7 @@ fn resolve_find_links() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: None, }, ], no_index: true, @@ -1740,6 +1753,7 @@ fn resolve_top_level() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: None, }, Index { name: None, @@ -1767,6 +1781,7 @@ fn resolve_top_level() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: None, }, ], flat_index: [], @@ -1913,6 +1928,7 @@ fn resolve_top_level() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: None, }, Index { name: None, @@ -1940,6 +1956,7 @@ fn resolve_top_level() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: None, }, ], flat_index: [], @@ -2943,6 +2960,7 @@ fn resolve_both() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -3116,6 +3134,7 @@ fn resolve_config_file() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -3778,6 +3797,9 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: Some( + Cli, + ), }, Index { name: None, @@ -3805,6 +3827,7 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: None, }, ], flat_index: [], @@ -3951,6 +3974,9 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: Some( + Cli, + ), }, Index { name: None, @@ -3978,6 +4004,7 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: None, }, ], flat_index: [], @@ -4130,6 +4157,9 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: Some( + Cli, + ), }, Index { name: None, @@ -4157,6 +4187,7 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -4304,6 +4335,9 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: Some( + Cli, + ), }, Index { name: None, @@ -4331,6 +4365,7 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -4485,6 +4520,9 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: Some( + Cli, + ), }, Index { name: None, @@ -4512,6 +4550,7 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [], @@ -4659,6 +4698,9 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: false, + origin: Some( + Cli, + ), }, Index { name: None, @@ -4686,6 +4728,7 @@ fn index_priority() -> anyhow::Result<()> { ), explicit: false, default: true, + origin: None, }, ], flat_index: [],