Skip to content

Commit

Permalink
Add new SourceKind::SparseRegistry to differentiate sparse registries
Browse files Browse the repository at this point in the history
  • Loading branch information
arlosi committed Oct 10, 2022
1 parent e691e18 commit f4fcb53
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 24 deletions.
70 changes: 48 additions & 22 deletions src/cargo/core/source/source_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ enum SourceKind {
Path,
/// A remote registry.
Registry,
/// A sparse registry.
SparseRegistry,
/// A local filesystem-based registry.
LocalRegistry,
/// A directory-based registry.
Expand Down Expand Up @@ -100,6 +102,14 @@ impl SourceId {
SourceId { inner }
}

fn remote_source_kind(url: &Url) -> SourceKind {
if url.as_str().starts_with("sparse+") {
SourceKind::SparseRegistry
} else {
SourceKind::Registry
}
}

/// Parses a source URL and returns the corresponding ID.
///
/// ## Example
Expand Down Expand Up @@ -143,7 +153,7 @@ impl SourceId {
}
"sparse" => {
let url = string.into_url()?;
Ok(SourceId::new(SourceKind::Registry, url, None)?
Ok(SourceId::new(SourceKind::SparseRegistry, url, None)?
.with_precise(Some("locked".to_string())))
}
"path" => {
Expand Down Expand Up @@ -180,12 +190,14 @@ impl SourceId {
/// Use [`SourceId::for_alt_registry`] if a name can provided, which
/// generates better messages for cargo.
pub fn for_registry(url: &Url) -> CargoResult<SourceId> {
SourceId::new(SourceKind::Registry, url.clone(), None)
let kind = Self::remote_source_kind(url);
SourceId::new(kind, url.clone(), None)
}

/// Creates a `SourceId` from a remote registry URL with given name.
pub fn for_alt_registry(url: &Url, name: &str) -> CargoResult<SourceId> {
SourceId::new(SourceKind::Registry, url.clone(), Some(name))
let kind = Self::remote_source_kind(url);
SourceId::new(kind, url.clone(), Some(name))
}

/// Creates a SourceId from a local registry path.
Expand Down Expand Up @@ -218,7 +230,7 @@ impl SourceId {
if config.cli_unstable().sparse_registry {
config.check_registry_index_not_set()?;
let url = CRATES_IO_HTTP_INDEX.into_url().unwrap();
SourceId::new(SourceKind::Registry, url, Some(CRATES_IO_REGISTRY))
SourceId::new(SourceKind::SparseRegistry, url, Some(CRATES_IO_REGISTRY))
} else {
Self::crates_io(config)
}
Expand All @@ -230,8 +242,9 @@ impl SourceId {
return Self::crates_io(config);
}
let url = config.get_registry_index(key)?;
let kind = Self::remote_source_kind(&url);
Ok(SourceId::wrap(SourceIdInner {
kind: SourceKind::Registry,
kind,
canonical_url: CanonicalUrl::new(&url)?,
url,
precise: None,
Expand Down Expand Up @@ -298,16 +311,24 @@ impl SourceId {
pub fn is_registry(self) -> bool {
matches!(
self.inner.kind,
SourceKind::Registry | SourceKind::LocalRegistry
SourceKind::Registry | SourceKind::SparseRegistry | SourceKind::LocalRegistry
)
}

/// Returns `true` if this source is from a sparse registry.
pub fn is_sparse(self) -> bool {
matches!(self.inner.kind, SourceKind::SparseRegistry)
}

/// Returns `true` if this source is a "remote" registry.
///
/// "remote" may also mean a file URL to a git index, so it is not
/// necessarily "remote". This just means it is not `local-registry`.
pub fn is_remote_registry(self) -> bool {
matches!(self.inner.kind, SourceKind::Registry)
matches!(
self.inner.kind,
SourceKind::Registry | SourceKind::SparseRegistry
)
}

/// Returns `true` if this source from a Git repository.
Expand All @@ -331,11 +352,9 @@ impl SourceId {
};
Ok(Box::new(PathSource::new(&path, self, config)))
}
SourceKind::Registry => Ok(Box::new(RegistrySource::remote(
self,
yanked_whitelist,
config,
)?)),
SourceKind::Registry | SourceKind::SparseRegistry => Ok(Box::new(
RegistrySource::remote(self, yanked_whitelist, config)?,
)),
SourceKind::LocalRegistry => {
let path = match self.inner.url.to_file_path() {
Ok(p) => p,
Expand Down Expand Up @@ -382,7 +401,7 @@ impl SourceId {
/// Returns `true` if the remote registry is the standard <https://crates.io>.
pub fn is_crates_io(self) -> bool {
match self.inner.kind {
SourceKind::Registry => {}
SourceKind::Registry | SourceKind::SparseRegistry => {}
_ => return false,
}
let url = self.inner.url.as_str();
Expand Down Expand Up @@ -514,7 +533,9 @@ impl fmt::Display for SourceId {
Ok(())
}
SourceKind::Path => write!(f, "{}", url_display(&self.inner.url)),
SourceKind::Registry => write!(f, "registry `{}`", self.display_registry_name()),
SourceKind::Registry | SourceKind::SparseRegistry => {
write!(f, "registry `{}`", self.display_registry_name())
}
SourceKind::LocalRegistry => write!(f, "registry `{}`", url_display(&self.inner.url)),
SourceKind::Directory => write!(f, "dir {}", url_display(&self.inner.url)),
}
Expand Down Expand Up @@ -628,6 +649,10 @@ impl Ord for SourceKind {
(SourceKind::Registry, _) => Ordering::Less,
(_, SourceKind::Registry) => Ordering::Greater,

(SourceKind::SparseRegistry, SourceKind::SparseRegistry) => Ordering::Equal,
(SourceKind::SparseRegistry, _) => Ordering::Less,
(_, SourceKind::SparseRegistry) => Ordering::Greater,

(SourceKind::LocalRegistry, SourceKind::LocalRegistry) => Ordering::Equal,
(SourceKind::LocalRegistry, _) => Ordering::Less,
(_, SourceKind::LocalRegistry) => Ordering::Greater,
Expand Down Expand Up @@ -699,14 +724,15 @@ impl<'a> fmt::Display for SourceIdAsUrl<'a> {
ref url,
..
} => {
// For sparse http registry the URL already contains the prefix.
if url.scheme().starts_with("sparse+") {
// e.g. sparse+http://example.com
write!(f, "{url}")
} else {
// e.g. registry+http://example.com
write!(f, "registry+{url}")
}
write!(f, "registry+{url}")
}
SourceIdInner {
kind: SourceKind::SparseRegistry,
ref url,
..
} => {
// For sparse registries, the URL already contains the `sparse+` prefix
write!(f, "{url}")
}
SourceIdInner {
kind: SourceKind::LocalRegistry,
Expand Down
3 changes: 2 additions & 1 deletion src/cargo/sources/registry/http_remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ impl<'cfg> HttpRegistry<'cfg> {
anyhow::bail!("registry url must end in a slash `/`: {url}")
}
let url = url
.trim_start_matches("sparse+")
.strip_prefix("sparse+")
.expect("sparse registry URLs must start with sparse+")
.into_url()
.expect("a url with the protocol stripped should still be valid");

Expand Down
2 changes: 1 addition & 1 deletion src/cargo/sources/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ impl<'cfg> RegistrySource<'cfg> {
config: &'cfg Config,
) -> CargoResult<RegistrySource<'cfg>> {
let name = short_name(source_id);
let ops = if source_id.url().scheme().starts_with("sparse+") {
let ops = if source_id.is_sparse() {
Box::new(http_remote::HttpRegistry::new(source_id, config, &name)?) as Box<_>
} else {
Box::new(remote::RemoteRegistry::new(source_id, config, &name)) as Box<_>
Expand Down

0 comments on commit f4fcb53

Please sign in to comment.