Skip to content

Commit

Permalink
Respect declared sources
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Sep 18, 2024
1 parent 35df820 commit d213730
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 14 deletions.
34 changes: 31 additions & 3 deletions crates/distribution-types/src/index_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use url::{ParseError, Url};

use pep508_rs::{VerbatimUrl, VerbatimUrlError};

use crate::Verbatim;
use crate::{IndexSource, Verbatim};

static PYPI_URL: LazyLock<Url> = LazyLock::new(|| Url::parse("https://pypi.org/simple").unwrap());

Expand Down Expand Up @@ -55,6 +55,14 @@ impl IndexUrl {
}
}

pub fn into_url(self) -> Url {
match self {
Self::Pypi(url) => url.into_url(),
Self::Url(url) => url.into_url(),
Self::Path(url) => url.into_url(),
}
}

/// Return the redacted URL for the index, omitting any sensitive credentials.
pub fn redacted(&self) -> Cow<'_, Url> {
let url = self.url();
Expand Down Expand Up @@ -292,6 +300,7 @@ impl From<VerbatimUrl> for FlatIndexLocation {
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
pub struct IndexLocations {
sources: Vec<IndexSource>,
index: Option<IndexUrl>,
extra_index: Vec<IndexUrl>,
flat_index: Vec<FlatIndexLocation>,
Expand All @@ -302,6 +311,7 @@ impl Default for IndexLocations {
/// By default, use the `PyPI` index.
fn default() -> Self {
Self {
sources: Vec::new(),
index: Some(DEFAULT_INDEX_URL.clone()),
extra_index: Vec::new(),
flat_index: Vec::new(),
Expand All @@ -313,12 +323,14 @@ impl Default for IndexLocations {
impl IndexLocations {
/// Determine the index URLs to use for fetching packages.
pub fn new(
sources: Vec<IndexSource>,
index: Option<IndexUrl>,
extra_index: Vec<IndexUrl>,
flat_index: Vec<FlatIndexLocation>,
no_index: bool,
) -> Self {
Self {
sources,
index,
extra_index,
flat_index,
Expand All @@ -335,12 +347,14 @@ impl IndexLocations {
#[must_use]
pub fn combine(
self,
sources: Vec<IndexSource>,
index: Option<IndexUrl>,
extra_index: Vec<IndexUrl>,
flat_index: Vec<FlatIndexLocation>,
no_index: bool,
) -> Self {
Self {
sources: self.sources.into_iter().chain(sources).collect(),
index: self.index.or(index),
extra_index: self.extra_index.into_iter().chain(extra_index).collect(),
flat_index: self.flat_index.into_iter().chain(flat_index).collect(),
Expand All @@ -351,7 +365,8 @@ impl IndexLocations {
/// Returns `true` if no index configuration is set, i.e., the [`IndexLocations`] matches the
/// default configuration.
pub fn is_none(&self) -> bool {
self.index.is_none()
self.sources.is_empty()
&& self.index.is_none()
&& self.extra_index.is_empty()
&& self.flat_index.is_empty()
&& !self.no_index
Expand Down Expand Up @@ -402,6 +417,7 @@ impl<'a> IndexLocations {
/// Clone the index locations into a [`IndexUrls`] instance.
pub fn index_urls(&'a self) -> IndexUrls {
IndexUrls {
sources: self.sources.clone(),
index: self.index.clone(),
extra_index: self.extra_index.clone(),
no_index: self.no_index,
Expand All @@ -424,6 +440,7 @@ impl<'a> IndexLocations {
/// From a pip perspective, this type merges `--index-url` and `--extra-index-url`.
#[derive(Debug, Clone)]
pub struct IndexUrls {
sources: Vec<IndexSource>,
index: Option<IndexUrl>,
extra_index: Vec<IndexUrl>,
no_index: bool,
Expand All @@ -433,6 +450,7 @@ impl Default for IndexUrls {
/// By default, use the `PyPI` index.
fn default() -> Self {
Self {
sources: Vec::new(),
index: Some(DEFAULT_INDEX_URL.clone()),
extra_index: Vec::new(),
no_index: false,
Expand All @@ -441,6 +459,15 @@ impl Default for IndexUrls {
}

impl<'a> IndexUrls {
/// Return an iterator over the `tool.uv.index` sources.
fn sources(&'a self) -> impl Iterator<Item = &'a IndexUrl> + 'a {
if self.no_index {
Either::Left(std::iter::empty())
} else {
Either::Right(self.sources.iter().map(|source| &source.index))
}
}

/// Return the fallback [`IndexUrl`] entry.
///
/// If `--no-index` is set, return `None`.
Expand Down Expand Up @@ -473,13 +500,14 @@ impl<'a> IndexUrls {
/// If `no_index` was enabled, then this always returns an empty
/// iterator.
pub fn indexes(&'a self) -> impl Iterator<Item = &'a IndexUrl> + 'a {
self.extra_index().chain(self.index())
self.sources().chain(self.extra_index()).chain(self.index())
}
}

impl From<IndexLocations> for IndexUrls {
fn from(locations: IndexLocations) -> Self {
Self {
sources: locations.sources,
index: locations.index,
extra_index: locations.extra_index,
no_index: locations.no_index,
Expand Down
4 changes: 2 additions & 2 deletions crates/distribution-types/src/named_index.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use url::Url;
use crate::IndexUrl;

#[derive(Debug, Clone, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct IndexSource {
pub name: String,
pub index: Url,
pub index: IndexUrl,
#[serde(default)]
pub kind: IndexKind,
}
Expand Down
5 changes: 5 additions & 0 deletions crates/pep508-rs/src/verbatim_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ impl VerbatimUrl {
self.url.clone()
}

/// Convert a [`VerbatimUrl`] into a [`Url`].
pub fn into_url(self) -> Url {
self.url
}

/// Return the underlying [`Path`], if the URL is a file URL.
pub fn as_path(&self) -> Result<PathBuf, VerbatimUrlError> {
self.url
Expand Down
2 changes: 2 additions & 0 deletions crates/uv-cli/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ pub fn resolver_options(
} = build_args;

ResolverOptions {
index: None,
index_url: index_args.index_url.and_then(Maybe::into_option),
extra_index_url: index_args.extra_index_url.map(|extra_index_urls| {
extra_index_urls
Expand Down Expand Up @@ -325,6 +326,7 @@ pub fn resolver_installer_options(
} = build_args;

ResolverInstallerOptions {
index: None,
index_url: index_args.index_url.and_then(Maybe::into_option),
extra_index_url: index_args.extra_index_url.map(|extra_index_urls| {
extra_index_urls
Expand Down
4 changes: 2 additions & 2 deletions crates/uv-distribution/src/metadata/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl LoweredRequirement {
else {
return Err(LoweringError::MissingIndex(requirement.name, index));
};
registry_source(&requirement, index)?
registry_source(&requirement, index.into_url())?
}
Source::Workspace {
workspace: is_workspace,
Expand Down Expand Up @@ -245,7 +245,7 @@ impl LoweredRequirement {
else {
return Err(LoweringError::MissingIndex(requirement.name, index));
};
registry_source(&requirement, index)?
registry_source(&requirement, index.into_url())?
}
Source::Workspace { .. } => {
return Err(LoweringError::WorkspaceMember);
Expand Down
24 changes: 23 additions & 1 deletion crates/uv-settings/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{fmt::Debug, num::NonZeroUsize, path::PathBuf};

use serde::{Deserialize, Serialize};

use distribution_types::{FlatIndexLocation, IndexUrl};
use distribution_types::{FlatIndexLocation, IndexSource, IndexUrl};
use install_wheel_rs::linker::LinkMode;
use pep508_rs::Requirement;
use pypi_types::{SupportedEnvironments, VerbatimParsedUrl};
Expand Down Expand Up @@ -252,6 +252,7 @@ pub struct GlobalOptions {
#[serde(rename_all = "kebab-case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct InstallerOptions {
pub index: Option<Vec<IndexSource>>,
pub index_url: Option<IndexUrl>,
pub extra_index_url: Option<Vec<IndexUrl>>,
pub no_index: Option<bool>,
Expand Down Expand Up @@ -279,6 +280,7 @@ pub struct InstallerOptions {
#[serde(rename_all = "kebab-case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct ResolverOptions {
pub index: Option<Vec<IndexSource>>,
pub index_url: Option<IndexUrl>,
pub extra_index_url: Option<Vec<IndexUrl>>,
pub no_index: Option<bool>,
Expand Down Expand Up @@ -311,6 +313,21 @@ pub struct ResolverOptions {
#[serde(rename_all = "kebab-case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct ResolverInstallerOptions {
/// The URL of the Python package index (by default: <https://pypi.org/simple>).
///
/// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
/// (the simple repository API), or a local directory laid out in the same format.
///
/// The index provided by this setting is given lower priority than any indexes specified via
/// [`extra_index_url`](#extra-index-url).
#[option(
default = "\"https://pypi.org/simple\"",
value_type = "str",
example = r#"
index-url = "https://test.pypi.org/simple"
"#
)]
pub index: Option<Vec<IndexSource>>,
/// The URL of the Python package index (by default: <https://pypi.org/simple>).
///
/// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
Expand Down Expand Up @@ -1281,6 +1298,7 @@ pub struct PipOptions {
impl From<ResolverInstallerOptions> for ResolverOptions {
fn from(value: ResolverInstallerOptions) -> Self {
Self {
index: value.index,
index_url: value.index_url,
extra_index_url: value.extra_index_url,
no_index: value.no_index,
Expand Down Expand Up @@ -1309,6 +1327,7 @@ impl From<ResolverInstallerOptions> for ResolverOptions {
impl From<ResolverInstallerOptions> for InstallerOptions {
fn from(value: ResolverInstallerOptions) -> Self {
Self {
index: value.index,
index_url: value.index_url,
extra_index_url: value.extra_index_url,
no_index: value.no_index,
Expand Down Expand Up @@ -1342,6 +1361,7 @@ impl From<ResolverInstallerOptions> for InstallerOptions {
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct ToolOptions {
pub index: Option<Vec<IndexSource>>,
pub index_url: Option<IndexUrl>,
pub extra_index_url: Option<Vec<IndexUrl>>,
pub no_index: Option<bool>,
Expand All @@ -1367,6 +1387,7 @@ pub struct ToolOptions {
impl From<ResolverInstallerOptions> for ToolOptions {
fn from(value: ResolverInstallerOptions) -> Self {
Self {
index: value.index,
index_url: value.index_url,
extra_index_url: value.extra_index_url,
no_index: value.no_index,
Expand Down Expand Up @@ -1394,6 +1415,7 @@ impl From<ResolverInstallerOptions> for ToolOptions {
impl From<ToolOptions> for ResolverInstallerOptions {
fn from(value: ToolOptions) -> Self {
Self {
index: value.index,
index_url: value.index_url,
extra_index_url: value.extra_index_url,
no_index: value.no_index,
Expand Down
9 changes: 7 additions & 2 deletions crates/uv/src/commands/pip/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,13 @@ pub(crate) async fn pip_compile(
let dev = Vec::default();

// Incorporate any index locations from the provided sources.
let index_locations =
index_locations.combine(index_url, extra_index_urls, find_links, no_index);
let index_locations = index_locations.combine(
Vec::default(),
index_url,
extra_index_urls,
find_links,
no_index,
);

// Add all authenticated sources to the cache.
for url in index_locations.urls() {
Expand Down
9 changes: 7 additions & 2 deletions crates/uv/src/commands/pip/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,13 @@ pub(crate) async fn pip_install(
let dev = Vec::default();

// Incorporate any index locations from the provided sources.
let index_locations =
index_locations.combine(index_url, extra_index_urls, find_links, no_index);
let index_locations = index_locations.combine(
Vec::default(),
index_url,
extra_index_urls,
find_links,
no_index,
);

// Add all authenticated sources to the cache.
for url in index_locations.urls() {
Expand Down
9 changes: 7 additions & 2 deletions crates/uv/src/commands/pip/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,13 @@ pub(crate) async fn pip_sync(
};

// Incorporate any index locations from the provided sources.
let index_locations =
index_locations.combine(index_url, extra_index_urls, find_links, no_index);
let index_locations = index_locations.combine(
Vec::default(),
index_url,
extra_index_urls,
find_links,
no_index,
);

// Add all authenticated sources to the cache.
for url in index_locations.urls() {
Expand Down
4 changes: 4 additions & 0 deletions crates/uv/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1873,6 +1873,7 @@ impl From<ResolverOptions> for ResolverSettings {
fn from(value: ResolverOptions) -> Self {
Self {
index_locations: IndexLocations::new(
value.index.unwrap_or_default(),
value.index_url,
value.extra_index_url.unwrap_or_default(),
value.find_links.unwrap_or_default(),
Expand Down Expand Up @@ -1995,6 +1996,7 @@ impl From<ResolverInstallerOptions> for ResolverInstallerSettings {
fn from(value: ResolverInstallerOptions) -> Self {
Self {
index_locations: IndexLocations::new(
value.index.unwrap_or_default(),
value.index_url,
value.extra_index_url.unwrap_or_default(),
value.find_links.unwrap_or_default(),
Expand Down Expand Up @@ -2148,6 +2150,7 @@ impl PipSettings {
} = pip.unwrap_or_default();

let ResolverInstallerOptions {
index: top_level_index,
index_url: top_level_index_url,
extra_index_url: top_level_extra_index_url,
no_index: top_level_no_index,
Expand Down Expand Up @@ -2202,6 +2205,7 @@ impl PipSettings {

Self {
index_locations: IndexLocations::new(
top_level_index.unwrap_or_default(),
args.index_url.combine(index_url),
args.extra_index_url
.combine(extra_index_url)
Expand Down

0 comments on commit d213730

Please sign in to comment.