Skip to content

Commit

Permalink
Remove the flat index types
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Sep 28, 2024
1 parent 9f79821 commit 42af3e5
Show file tree
Hide file tree
Showing 19 changed files with 115 additions and 271 deletions.
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 @@ -3777,7 +3777,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

0 comments on commit 42af3e5

Please sign in to comment.