From d77aef5ba44396c03d250e84d97a2bf130d211e0 Mon Sep 17 00:00:00 2001 From: Arlo Siemsen Date: Tue, 11 Oct 2022 13:03:30 -0500 Subject: [PATCH] Add configuration option for controlling crates.io protocol `registries.crates-io.protocol` can be set to either `sparse` or `git`. The default is `git` unless `-Z sparse-registry` is passed. --- src/cargo/core/source/source_id.rs | 19 +++++++++++++++++-- src/cargo/sources/config.rs | 2 +- tests/testsuite/registry.rs | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/cargo/core/source/source_id.rs b/src/cargo/core/source/source_id.rs index 0621b1637a4..f604c818a3f 100644 --- a/src/cargo/core/source/source_id.rs +++ b/src/cargo/core/source/source_id.rs @@ -2,7 +2,7 @@ use crate::core::PackageId; use crate::sources::registry::CRATES_IO_HTTP_INDEX; use crate::sources::{DirectorySource, CRATES_IO_DOMAIN, CRATES_IO_INDEX, CRATES_IO_REGISTRY}; use crate::sources::{GitSource, PathSource, RegistrySource}; -use crate::util::{CanonicalUrl, CargoResult, Config, IntoUrl}; +use crate::util::{config, CanonicalUrl, CargoResult, Config, IntoUrl}; use log::trace; use serde::de; use serde::ser; @@ -215,7 +215,7 @@ impl SourceId { /// Returns the `SourceId` corresponding to the main repository, using the /// sparse HTTP index if allowed. pub fn crates_io_maybe_sparse_http(config: &Config) -> CargoResult { - if config.cli_unstable().sparse_registry { + if Self::crates_io_is_sparse(config)? { config.check_registry_index_not_set()?; let url = CRATES_IO_HTTP_INDEX.into_url().unwrap(); SourceId::new(SourceKind::Registry, url, Some(CRATES_IO_REGISTRY)) @@ -224,6 +224,21 @@ impl SourceId { } } + /// Returns whether to access crates.io over the sparse protocol. + pub fn crates_io_is_sparse(config: &Config) -> CargoResult { + let proto: Option> = config.get("registries.crates-io.protocol")?; + let is_sparse = match proto.as_ref().map(|v| v.val.as_str()) { + Some("sparse") => true, + Some("git") => false, + Some(unknown) => anyhow::bail!( + "unsupported registry protocol `{unknown}` (defined in {})", + proto.as_ref().unwrap().definition + ), + None => config.cli_unstable().sparse_registry, + }; + Ok(is_sparse) + } + /// Gets the `SourceId` associated with given name of the remote registry. pub fn alt_registry(config: &Config, key: &str) -> CargoResult { if key == CRATES_IO_REGISTRY { diff --git a/src/cargo/sources/config.rs b/src/cargo/sources/config.rs index c10c0563fa0..880831bf808 100644 --- a/src/cargo/sources/config.rs +++ b/src/cargo/sources/config.rs @@ -91,7 +91,7 @@ impl<'cfg> SourceConfigMap<'cfg> { replace_with: None, }, )?; - if config.cli_unstable().sparse_registry { + if SourceId::crates_io_is_sparse(config)? { base.add( CRATES_IO_REGISTRY, SourceConfig { diff --git a/tests/testsuite/registry.rs b/tests/testsuite/registry.rs index 12bd7560c3a..8eb82795136 100644 --- a/tests/testsuite/registry.rs +++ b/tests/testsuite/registry.rs @@ -2703,6 +2703,24 @@ fn http_requires_z_flag() { .run(); } +#[cargo_test] +fn protocol_sparse_requires_z_flag() { + cargo_process("install bar") + .with_status(101) + .env("CARGO_REGISTRIES_CRATES_IO_PROTOCOL", "sparse") + .with_stderr("[ERROR] usage of sparse registries requires `-Z sparse-registry`") + .run() +} + +#[cargo_test] +fn protocol() { + cargo_process("install bar") + .with_status(101) + .env("CARGO_REGISTRIES_CRATES_IO_PROTOCOL", "invalid") + .with_stderr("[ERROR] unsupported registry protocol `invalid` (defined in environment variable `CARGO_REGISTRIES_CRATES_IO_PROTOCOL`)") + .run() +} + #[cargo_test] fn http_requires_trailing_slash() { cargo_process("-Z sparse-registry install bar --index sparse+https://index.crates.io")