Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the flat index types #7759

Open
wants to merge 1 commit into
base: charlie/index-api-uv-pin
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions crates/distribution-types/src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ impl Index {
}
}

/// Initialize an [`Index`] from a pip-style `--find-links`.
pub fn from_find_links(url: IndexUrl) -> Self {
Self {
url,
name: None,
explicit: false,
default: false,
}
}

/// Return the [`IndexUrl`] of the index.
pub fn url(&self) -> &IndexUrl {
&self.url
Expand Down
142 changes: 8 additions & 134 deletions crates/distribution-types/src/index_url.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,6 @@ impl Verbatim for IndexUrl {
}
}

impl From<FlatIndexLocation> for IndexUrl {
fn from(location: FlatIndexLocation) -> Self {
match location {
FlatIndexLocation::Path(url) => Self::Path(url),
FlatIndexLocation::Url(url) => Self::Url(url),
}
}
}

/// An error that can occur when parsing an [`IndexUrl`].
#[derive(Error, Debug)]
pub enum IndexUrlError {
Expand Down Expand Up @@ -185,117 +176,6 @@ impl Deref for IndexUrl {
}
}

/// A directory with distributions or a URL to an HTML file with a flat listing of distributions.
///
/// Also known as `--find-links`.
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub enum FlatIndexLocation {
Path(VerbatimUrl),
Url(VerbatimUrl),
}

#[cfg(feature = "schemars")]
impl schemars::JsonSchema for FlatIndexLocation {
fn schema_name() -> String {
"FlatIndexLocation".to_string()
}

fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
schemars::schema::SchemaObject {
instance_type: Some(schemars::schema::InstanceType::String.into()),
metadata: Some(Box::new(schemars::schema::Metadata {
description: Some("The path to a directory of distributions, or a URL to an HTML file with a flat listing of distributions.".to_string()),
..schemars::schema::Metadata::default()
})),
..schemars::schema::SchemaObject::default()
}
.into()
}
}

impl FlatIndexLocation {
/// Return the raw URL for the `--find-links` index.
pub fn url(&self) -> &Url {
match self {
Self::Url(url) => url.raw(),
Self::Path(url) => url.raw(),
}
}

/// Return the redacted URL for the `--find-links` index, omitting any sensitive credentials.
pub fn redacted(&self) -> Cow<'_, Url> {
let url = self.url();
if url.username().is_empty() && url.password().is_none() {
Cow::Borrowed(url)
} else {
let mut url = url.clone();
let _ = url.set_username("");
let _ = url.set_password(None);
Cow::Owned(url)
}
}
}

impl Display for FlatIndexLocation {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Url(url) => Display::fmt(url, f),
Self::Path(url) => Display::fmt(url, f),
}
}
}

impl Verbatim for FlatIndexLocation {
fn verbatim(&self) -> Cow<'_, str> {
match self {
Self::Url(url) => url.verbatim(),
Self::Path(url) => url.verbatim(),
}
}
}

impl FromStr for FlatIndexLocation {
type Err = IndexUrlError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
let url = if Path::new(s).exists() {
VerbatimUrl::from_absolute_path(std::path::absolute(s)?)?
} else {
VerbatimUrl::parse_url(s)?
};
Ok(Self::from(url.with_given(s)))
}
}

impl serde::ser::Serialize for FlatIndexLocation {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::ser::Serializer,
{
self.to_string().serialize(serializer)
}
}

impl<'de> serde::de::Deserialize<'de> for FlatIndexLocation {
fn deserialize<D>(deserializer: D) -> Result<FlatIndexLocation, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
FlatIndexLocation::from_str(&s).map_err(serde::de::Error::custom)
}
}

impl From<VerbatimUrl> for FlatIndexLocation {
fn from(url: VerbatimUrl) -> Self {
if url.scheme() == "file" {
Self::Path(url)
} else {
Self::Url(url)
}
}
}

/// The index locations to use for fetching packages. By default, uses the PyPI index.
///
/// From a pip perspective, this type merges `--index-url`, `--extra-index-url`, and `--find-links`,
Expand All @@ -304,13 +184,13 @@ impl From<VerbatimUrl> for FlatIndexLocation {
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
pub struct IndexLocations {
indexes: Vec<Index>,
flat_index: Vec<FlatIndexLocation>,
flat_index: Vec<Index>,
no_index: bool,
}

impl IndexLocations {
/// Determine the index URLs to use for fetching packages.
pub fn new(indexes: Vec<Index>, flat_index: Vec<FlatIndexLocation>, no_index: bool) -> Self {
pub fn new(indexes: Vec<Index>, flat_index: Vec<Index>, no_index: bool) -> Self {
Self {
indexes,
flat_index,
Expand All @@ -325,12 +205,7 @@ impl IndexLocations {
///
/// If the current index location has an `index` set, it will be preserved.
#[must_use]
pub fn combine(
self,
indexes: Vec<Index>,
flat_index: Vec<FlatIndexLocation>,
no_index: bool,
) -> Self {
pub fn combine(self, indexes: Vec<Index>, flat_index: Vec<Index>, no_index: bool) -> Self {
Self {
indexes: self.indexes.into_iter().chain(indexes).collect(),
flat_index: self.flat_index.into_iter().chain(flat_index).collect(),
Expand Down Expand Up @@ -407,7 +282,7 @@ impl<'a> IndexLocations {
}

/// Return an iterator over the [`FlatIndexLocation`] entries.
pub fn flat_indexes(&'a self) -> impl Iterator<Item = &'a FlatIndexLocation> + 'a {
pub fn flat_indexes(&'a self) -> impl Iterator<Item = &'a Index> + 'a {
self.flat_index.iter()
}

Expand All @@ -426,13 +301,12 @@ impl<'a> IndexLocations {

/// Return an iterator over all allowed [`Index`] entries.
///
/// This includes both explicit and implicit indexes, as well as the default index (but _not_
/// the flat indexes).
/// This includes explicit indexes, implicit indexes flat indexes, and the default index.
///
/// If `no_index` was enabled, then this always returns an empty
/// iterator.
/// If `no_index` was enabled, then this always returns an empty iterator.
pub fn allowed_indexes(&'a self) -> impl Iterator<Item = &'a Index> + 'a {
self.explicit_indexes()
self.flat_indexes()
.chain(self.explicit_indexes())
.chain(self.implicit_indexes())
.chain(self.default_index())
}
Expand Down
4 changes: 2 additions & 2 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use anyhow::{anyhow, Result};
use clap::builder::styling::{AnsiColor, Effects, Style};
use clap::builder::Styles;
use clap::{Args, Parser, Subcommand};
use distribution_types::{FlatIndexLocation, Index, IndexUrl};
use distribution_types::{Index, IndexUrl};
use pep508_rs::Requirement;
use pypi_types::VerbatimParsedUrl;
use url::Url;
Expand Down Expand Up @@ -3783,7 +3783,7 @@ pub struct IndexArgs {
/// If a URL, the page must contain a flat list of links to package files adhering to the
/// formats described above.
#[arg(long, short, help_heading = "Index options")]
pub find_links: Option<Vec<FlatIndexLocation>>,
pub find_links: Option<Vec<IndexUrl>>,

/// Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those
/// provided via `--find-links`.
Expand Down
16 changes: 8 additions & 8 deletions crates/uv-client/src/flat_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use tracing::{debug, info_span, warn, Instrument};
use url::Url;

use distribution_filename::DistFilename;
use distribution_types::{File, FileLocation, FlatIndexLocation, IndexUrl, UrlString};
use distribution_types::{File, FileLocation, IndexUrl, UrlString};
use uv_cache::{Cache, CacheBucket};

use crate::cached_client::{CacheControl, CachedClientError};
Expand Down Expand Up @@ -94,19 +94,19 @@ impl<'a> FlatIndexClient<'a> {
#[allow(clippy::result_large_err)]
pub async fn fetch(
&self,
indexes: impl Iterator<Item = &FlatIndexLocation>,
indexes: impl Iterator<Item = &IndexUrl>,
) -> Result<FlatIndexEntries, FlatIndexError> {
let mut fetches = futures::stream::iter(indexes)
.map(|index| async move {
let entries = match index {
FlatIndexLocation::Path(url) => {
IndexUrl::Path(url) => {
let path = url
.to_file_path()
.map_err(|()| FlatIndexError::NonFileUrl(url.to_url()))?;
Self::read_from_directory(&path, index)
.map_err(|err| FlatIndexError::FindLinksDirectory(path.clone(), err))?
}
FlatIndexLocation::Url(url) => self
IndexUrl::Pypi(url) | IndexUrl::Url(url) => self
.read_from_url(url, index)
.await
.map_err(|err| FlatIndexError::FindLinksUrl(url.to_url(), err))?,
Expand Down Expand Up @@ -136,7 +136,7 @@ impl<'a> FlatIndexClient<'a> {
async fn read_from_url(
&self,
url: &Url,
flat_index: &FlatIndexLocation,
flat_index: &IndexUrl,
) -> Result<FlatIndexEntries, Error> {
let cache_entry = self.cache.entry(
CacheBucket::FlatIndex,
Expand Down Expand Up @@ -210,7 +210,7 @@ impl<'a> FlatIndexClient<'a> {
Some((
DistFilename::try_from_normalized_filename(&file.filename)?,
file,
IndexUrl::from(flat_index.clone()),
flat_index.clone(),
))
})
.collect();
Expand All @@ -226,7 +226,7 @@ impl<'a> FlatIndexClient<'a> {
/// Read a flat remote index from a `--find-links` directory.
fn read_from_directory(
path: &Path,
flat_index: &FlatIndexLocation,
flat_index: &IndexUrl,
) -> Result<FlatIndexEntries, FindLinksDirectoryError> {
let mut dists = Vec::new();
for entry in fs_err::read_dir(path)? {
Expand Down Expand Up @@ -279,7 +279,7 @@ impl<'a> FlatIndexClient<'a> {
);
continue;
};
dists.push((filename, file, IndexUrl::from(flat_index.clone())));
dists.push((filename, file, flat_index.clone()));
}
Ok(FlatIndexEntries::from_entries(dists))
}
Expand Down
11 changes: 1 addition & 10 deletions crates/uv-distribution/src/index/registry_wheel_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,7 @@ impl<'a> RegistryWheelIndex<'a> {
) -> IndexMap<Index, BTreeMap<Version, CachedRegistryDist>> {
let mut map = IndexMap::new();

// Collect into owned `IndexUrl`.
let flat_index_urls: Vec<Index> = index_locations
.flat_indexes()
.map(|flat_index| Index::from_extra_index_url(IndexUrl::from(flat_index.clone())))
.collect();

for index in index_locations
.allowed_indexes()
.chain(flat_index_urls.iter())
{
for index in index_locations.allowed_indexes() {
let mut versions = BTreeMap::new();

// Index all the wheels that were downloaded directly from the registry.
Expand Down
6 changes: 3 additions & 3 deletions crates/uv-requirements/src/specification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use tracing::instrument;

use cache_key::CanonicalUrl;
use distribution_types::{
FlatIndexLocation, IndexUrl, NameRequirementSpecification, UnresolvedRequirement,
IndexUrl, NameRequirementSpecification, UnresolvedRequirement,
UnresolvedRequirementSpecification,
};
use pep508_rs::{MarkerTree, UnnamedRequirement, UnnamedRequirementUrl};
Expand Down Expand Up @@ -71,7 +71,7 @@ pub struct RequirementsSpecification {
/// Whether to disallow index usage.
pub no_index: bool,
/// The `--find-links` locations to use for fetching packages.
pub find_links: Vec<FlatIndexLocation>,
pub find_links: Vec<IndexUrl>,
/// The `--no-binary` flags to enforce when selecting distributions.
pub no_binary: NoBinary,
/// The `--no-build` flags to enforce when selecting distributions.
Expand Down Expand Up @@ -142,7 +142,7 @@ impl RequirementsSpecification {
find_links: requirements_txt
.find_links
.into_iter()
.map(FlatIndexLocation::from)
.map(IndexUrl::from)
.collect(),
no_binary: requirements_txt.no_binary,
no_build: requirements_txt.only_binary,
Expand Down
31 changes: 3 additions & 28 deletions crates/uv-resolver/src/lock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ use cache_key::RepositoryUrl;
use distribution_filename::{DistExtension, ExtensionError, SourceDistExtension, WheelFilename};
use distribution_types::{
BuiltDist, DependencyMetadata, DirectUrlBuiltDist, DirectUrlSourceDist, DirectorySourceDist,
Dist, DistributionMetadata, FileLocation, FlatIndexLocation, GitSourceDist, HashPolicy,
IndexLocations, IndexUrl, Name, PathBuiltDist, PathSourceDist, RegistryBuiltDist,
RegistryBuiltWheel, RegistrySourceDist, RemoteSource, Resolution, ResolvedDist, StaticMetadata,
ToUrlError, UrlString,
Dist, DistributionMetadata, FileLocation, GitSourceDist, HashPolicy, IndexLocations, IndexUrl,
Name, PathBuiltDist, PathSourceDist, RegistryBuiltDist, RegistryBuiltWheel, RegistrySourceDist,
RemoteSource, Resolution, ResolvedDist, StaticMetadata, ToUrlError, UrlString,
};
use pep440_rs::Version;
use pep508_rs::{split_scheme, MarkerEnvironment, MarkerTree, VerbatimUrl, VerbatimUrlError};
Expand Down Expand Up @@ -1053,16 +1052,6 @@ impl Lock {
}
IndexUrl::Path(_) => None,
})
.chain(
locations
.flat_indexes()
.filter_map(|index_url| match index_url {
FlatIndexLocation::Url(_) => {
Some(UrlString::from(index_url.redacted()))
}
FlatIndexLocation::Path(_) => None,
}),
)
.collect::<BTreeSet<_>>()
});

Expand All @@ -1079,20 +1068,6 @@ impl Lock {
Some(path)
}
})
.chain(
locations
.flat_indexes()
.filter_map(|index_url| match index_url {
FlatIndexLocation::Url(_) => None,
FlatIndexLocation::Path(index_url) => {
let path = index_url.to_file_path().ok()?;
let path = relative_to(&path, workspace.install_path())
.or_else(|_| std::path::absolute(path))
.ok()?;
Some(path)
}
}),
)
.collect::<BTreeSet<_>>()
});

Expand Down
Loading
Loading