mirror of https://github.com/astral-sh/uv
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.
This commit is contained in:
parent
a034a8b83b
commit
2153c6ac0d
|
|
@ -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<String>,
|
||||
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<Project>), Box<Error>> {
|
||||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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<T> Maybe<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parse a string into an [`IndexUrl`], mapping the empty string to `None`.
|
||||
fn parse_index_url(input: &str) -> Result<Maybe<IndexUrl>, String> {
|
||||
/// Parse an `--index-url` argument into an [`PipIndex`], mapping the empty string to `None`.
|
||||
fn parse_index_url(input: &str) -> Result<Maybe<PipIndex>, 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 a string into an [`Index`], mapping the empty string to `None`.
|
||||
fn parse_index_source(input: &str) -> Result<Maybe<Index>, String> {
|
||||
/// Parse an `--extra-index-url` argument into an [`PipExtraIndex`], mapping the empty string to `None`.
|
||||
fn parse_extra_index_url(input: &str) -> Result<Maybe<PipExtraIndex>, 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<Maybe<PipFindLinks>, 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 an `--index` argument into an [`Index`], mapping the empty string to `None`.
|
||||
fn parse_index(input: &str) -> Result<Maybe<Index>, 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<Maybe<Index>, String> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parse a string into an [`Index`], mapping the empty string to `None`.
|
||||
fn parse_default_index_source(input: &str) -> Result<Maybe<Index>, String> {
|
||||
/// Parse a `--default-index` argument into an [`Index`], mapping the empty string to `None`.
|
||||
fn parse_default_index(input: &str) -> Result<Maybe<Index>, 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<Vec<Maybe<Index>>>,
|
||||
|
||||
/// The URL of the default package index (by default: <https://pypi.org/simple>).
|
||||
|
|
@ -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<Maybe<Index>>,
|
||||
|
||||
/// (Deprecated: use `--default-index` instead) The URL of the Python package index (by default: <https://pypi.org/simple>).
|
||||
|
|
@ -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<Maybe<IndexUrl>>,
|
||||
pub index_url: Option<Maybe<PipIndex>>,
|
||||
|
||||
/// (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<Vec<Maybe<IndexUrl>>>,
|
||||
#[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<Vec<Maybe<PipExtraIndex>>>,
|
||||
|
||||
/// 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<Vec<Maybe<IndexUrl>>>,
|
||||
pub find_links: Option<Vec<Maybe<PipFindLinks>>>,
|
||||
|
||||
/// Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those
|
||||
/// provided via `--find-links`.
|
||||
|
|
|
|||
|
|
@ -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<IndexArgs> 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<IndexArgs> for PipOptions {
|
|||
find_links
|
||||
.into_iter()
|
||||
.filter_map(Maybe::into_option)
|
||||
.map(PipFindLinks::from)
|
||||
.collect()
|
||||
}),
|
||||
..PipOptions::default()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<Origin>,
|
||||
// /// 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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
@ -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<Index> for $name {
|
||||
fn from(value: Index) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for $name {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.0.url().serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for $name {
|
||||
fn deserialize<D>(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);
|
||||
|
|
@ -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<PackageName, Sources>,
|
||||
project_indexes: &'data [Index],
|
||||
locations: &'data IndexLocations,
|
||||
workspace: &'data Workspace,
|
||||
lower_bound: LowerBound,
|
||||
) -> impl Iterator<Item = Result<LoweredRequirement, LoweringError>> + 'data {
|
||||
) -> impl Iterator<Item = Result<Self, LoweringError>> + '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<PackageName, Sources>,
|
||||
indexes: &'data [Index],
|
||||
) -> impl Iterator<Item = Result<LoweredRequirement, LoweringError>> + 'data {
|
||||
locations: &'data IndexLocations,
|
||||
) -> impl Iterator<Item = Result<Self, LoweringError>> + '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<Path>,
|
||||
origin: Origin,
|
||||
origin: RequirementOrigin,
|
||||
project_dir: &Path,
|
||||
workspace_root: &Path,
|
||||
editable: bool,
|
||||
) -> Result<RequirementSource, LoweringError> {
|
||||
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(|()| {
|
||||
|
|
|
|||
|
|
@ -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<Self, MetadataError> {
|
||||
// Lower the requirements.
|
||||
|
|
@ -76,6 +78,7 @@ impl Metadata {
|
|||
provides_extras: metadata.provides_extras,
|
||||
},
|
||||
install_path,
|
||||
locations,
|
||||
sources,
|
||||
LowerBound::Warn,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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<Self, MetadataError> {
|
||||
|
|
@ -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<Self, MetadataError> {
|
||||
// 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,
|
||||
)?)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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?,
|
||||
))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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<T> Combine for Option<Vec<T>> {
|
||||
|
|
|
|||
|
|
@ -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<Vec<Index>>,
|
||||
pub index_url: Option<IndexUrl>,
|
||||
pub extra_index_url: Option<Vec<IndexUrl>>,
|
||||
pub index_url: Option<PipIndex>,
|
||||
pub extra_index_url: Option<Vec<PipExtraIndex>>,
|
||||
pub no_index: Option<bool>,
|
||||
pub find_links: Option<Vec<IndexUrl>>,
|
||||
pub find_links: Option<Vec<PipFindLinks>>,
|
||||
pub index_strategy: Option<IndexStrategy>,
|
||||
pub keyring_provider: Option<KeyringProviderType>,
|
||||
pub allow_insecure_host: Option<Vec<TrustedHost>>,
|
||||
|
|
@ -256,10 +255,10 @@ pub struct InstallerOptions {
|
|||
#[derive(Debug, Clone, Default, CombineOptions)]
|
||||
pub struct ResolverOptions {
|
||||
pub index: Option<Vec<Index>>,
|
||||
pub index_url: Option<IndexUrl>,
|
||||
pub extra_index_url: Option<Vec<IndexUrl>>,
|
||||
pub index_url: Option<PipIndex>,
|
||||
pub extra_index_url: Option<Vec<PipExtraIndex>>,
|
||||
pub no_index: Option<bool>,
|
||||
pub find_links: Option<Vec<IndexUrl>>,
|
||||
pub find_links: Option<Vec<PipFindLinks>>,
|
||||
pub index_strategy: Option<IndexStrategy>,
|
||||
pub keyring_provider: Option<KeyringProviderType>,
|
||||
pub allow_insecure_host: Option<Vec<TrustedHost>>,
|
||||
|
|
@ -339,7 +338,7 @@ pub struct ResolverInstallerOptions {
|
|||
index-url = "https://test.pypi.org/simple"
|
||||
"#
|
||||
)]
|
||||
pub index_url: Option<IndexUrl>,
|
||||
pub index_url: Option<PipIndex>,
|
||||
/// 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<Vec<IndexUrl>>,
|
||||
pub extra_index_url: Option<Vec<PipExtraIndex>>,
|
||||
/// 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<Vec<IndexUrl>>,
|
||||
pub find_links: Option<Vec<PipFindLinks>>,
|
||||
/// 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<IndexUrl>,
|
||||
pub index_url: Option<PipIndex>,
|
||||
/// 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<Vec<IndexUrl>>,
|
||||
pub extra_index_url: Option<Vec<PipExtraIndex>>,
|
||||
/// 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<Vec<IndexUrl>>,
|
||||
pub find_links: Option<Vec<PipFindLinks>>,
|
||||
/// 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<ResolverInstallerOptions> for InstallerOptions {
|
|||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct ToolOptions {
|
||||
pub index: Option<Vec<Index>>,
|
||||
pub index_url: Option<IndexUrl>,
|
||||
pub extra_index_url: Option<Vec<IndexUrl>>,
|
||||
pub index_url: Option<PipIndex>,
|
||||
pub extra_index_url: Option<Vec<PipExtraIndex>>,
|
||||
pub no_index: Option<bool>,
|
||||
pub find_links: Option<Vec<IndexUrl>>,
|
||||
pub find_links: Option<Vec<PipFindLinks>>,
|
||||
pub index_strategy: Option<IndexStrategy>,
|
||||
pub keyring_provider: Option<KeyringProviderType>,
|
||||
pub allow_insecure_host: Option<Vec<TrustedHost>>,
|
||||
|
|
@ -1502,7 +1501,7 @@ impl From<ToolOptions> for ResolverInstallerOptions {
|
|||
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
|
||||
pub struct OptionsWire {
|
||||
// #[serde(flatten)]
|
||||
// globals: GlobalOptions,
|
||||
// globals: GlobalOptions
|
||||
native_tls: Option<bool>,
|
||||
offline: Option<bool>,
|
||||
no_cache: Option<bool>,
|
||||
|
|
@ -1515,12 +1514,12 @@ pub struct OptionsWire {
|
|||
concurrent_installs: Option<NonZeroUsize>,
|
||||
|
||||
// #[serde(flatten)]
|
||||
// top_level: ResolverInstallerOptions,
|
||||
// top_level: ResolverInstallerOptions
|
||||
index: Option<Vec<Index>>,
|
||||
index_url: Option<IndexUrl>,
|
||||
extra_index_url: Option<Vec<IndexUrl>>,
|
||||
index_url: Option<PipIndex>,
|
||||
extra_index_url: Option<Vec<PipExtraIndex>>,
|
||||
no_index: Option<bool>,
|
||||
find_links: Option<Vec<IndexUrl>>,
|
||||
find_links: Option<Vec<PipFindLinks>>,
|
||||
index_strategy: Option<IndexStrategy>,
|
||||
keyring_provider: Option<KeyringProviderType>,
|
||||
allow_insecure_host: Option<Vec<TrustedHost>>,
|
||||
|
|
@ -1542,6 +1541,9 @@ pub struct OptionsWire {
|
|||
no_build_package: Option<Vec<PackageName>>,
|
||||
no_binary: Option<bool>,
|
||||
no_binary_package: Option<Vec<PackageName>>,
|
||||
|
||||
// #[serde(flatten)]
|
||||
// publish: PublishOptions
|
||||
publish_url: Option<Url>,
|
||||
trusted_publishing: Option<TrustedPublishing>,
|
||||
|
||||
|
|
|
|||
|
|
@ -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>(
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1972,20 +1972,14 @@ impl From<ResolverOptions> 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<ResolverInstallerOptions> 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(),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
|
|
|
|||
|
|
@ -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: [],
|
||||
|
|
|
|||
Loading…
Reference in New Issue