Skip to content

Commit a004f94

Browse files
committed
Auto merge of #11387 - arlosi:sparse-url, r=weihanglo
Store the sparse+ prefix in the SourceId for sparse registries #11209 added a new `SourceKind::SparseRegistry` and removed the `sparse+` prefix from the URLs stored in the `SourceId`. The removal of the `sparse+` prefix from the URLs in the `SourceId` has led to several bugs, since registry URLs no longer round-trip through a `SourceId`. The most recent one I found was that the example configuration generated by `cargo vendor` did not include the `sparse+` prefix. Any place that calls the `.url()` method on a `SourceId` potentially has this bug. This change puts the `sparse+` prefix back in the URL stored in the `SourceId`, but keeps the new `SourceKind::SparseRegistry`. A test is added for doing `cargo vendor` on an alternative registry using the sparse protocol.
2 parents 1382b44 + 37d9b5c commit a004f94

File tree

4 files changed

+55
-23
lines changed

4 files changed

+55
-23
lines changed

src/cargo/core/source/source_id.rs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,11 @@ impl SourceId {
102102
SourceId { inner }
103103
}
104104

105-
fn remote_source_kind(url: &Url) -> (SourceKind, Url) {
105+
fn remote_source_kind(url: &Url) -> SourceKind {
106106
if url.as_str().starts_with("sparse+") {
107-
let url = url
108-
.to_string()
109-
.strip_prefix("sparse+")
110-
.expect("we just found that prefix")
111-
.into_url()
112-
.expect("a valid url without a protocol specifier should still be valid");
113-
(SourceKind::SparseRegistry, url)
107+
SourceKind::SparseRegistry
114108
} else {
115-
(SourceKind::Registry, url.to_owned())
109+
SourceKind::Registry
116110
}
117111
}
118112

@@ -196,14 +190,14 @@ impl SourceId {
196190
/// Use [`SourceId::for_alt_registry`] if a name can provided, which
197191
/// generates better messages for cargo.
198192
pub fn for_registry(url: &Url) -> CargoResult<SourceId> {
199-
let (kind, url) = Self::remote_source_kind(url);
200-
SourceId::new(kind, url, None)
193+
let kind = Self::remote_source_kind(url);
194+
SourceId::new(kind, url.to_owned(), None)
201195
}
202196

203197
/// Creates a `SourceId` from a remote registry URL with given name.
204198
pub fn for_alt_registry(url: &Url, name: &str) -> CargoResult<SourceId> {
205-
let (kind, url) = Self::remote_source_kind(url);
206-
SourceId::new(kind, url, Some(name))
199+
let kind = Self::remote_source_kind(url);
200+
SourceId::new(kind, url.to_owned(), Some(name))
207201
}
208202

209203
/// Creates a SourceId from a local registry path.
@@ -263,7 +257,7 @@ impl SourceId {
263257
return Self::crates_io(config);
264258
}
265259
let url = config.get_registry_index(key)?;
266-
let (kind, url) = Self::remote_source_kind(&url);
260+
let kind = Self::remote_source_kind(&url);
267261
Ok(SourceId::wrap(SourceIdInner {
268262
kind,
269263
canonical_url: CanonicalUrl::new(&url)?,
@@ -428,10 +422,7 @@ impl SourceId {
428422
let url = self.inner.url.as_str();
429423
url == CRATES_IO_INDEX
430424
|| url == CRATES_IO_HTTP_INDEX
431-
|| std::env::var("__CARGO_TEST_CRATES_IO_URL_DO_NOT_USE_THIS")
432-
.as_deref()
433-
.map(|u| u.trim_start_matches("sparse+"))
434-
== Ok(url)
425+
|| std::env::var("__CARGO_TEST_CRATES_IO_URL_DO_NOT_USE_THIS").as_deref() == Ok(url)
435426
}
436427

437428
/// Hashes `self`.
@@ -755,7 +746,7 @@ impl<'a> fmt::Display for SourceIdAsUrl<'a> {
755746
ref url,
756747
..
757748
} => {
758-
write!(f, "sparse+{url}")
749+
write!(f, "{url}")
759750
}
760751
SourceIdInner {
761752
kind: SourceKind::LocalRegistry,

src/cargo/sources/registry/http_remote.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,21 @@ impl<'cfg> HttpRegistry<'cfg> {
163163
let url = source_id.url().as_str();
164164
// Ensure the url ends with a slash so we can concatenate paths.
165165
if !url.ends_with('/') {
166-
anyhow::bail!("sparse registry url must end in a slash `/`: sparse+{url}")
166+
anyhow::bail!("sparse registry url must end in a slash `/`: {url}")
167167
}
168+
assert!(source_id.is_sparse());
169+
let url = url
170+
.strip_prefix("sparse+")
171+
.expect("sparse registry needs sparse+ prefix")
172+
.into_url()
173+
.expect("a url with the sparse+ stripped should still be valid");
168174

169175
Ok(HttpRegistry {
170176
index_path: config.registry_index_path().join(name),
171177
cache_path: config.registry_cache_path().join(name),
172178
source_id,
173179
config,
174-
url: source_id.url().to_owned(),
180+
url,
175181
multi: Multi::new(),
176182
multiplexing: false,
177183
downloads: Downloads {

src/cargo/sources/registry/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ use crate::util::{
188188

189189
const PACKAGE_SOURCE_LOCK: &str = ".cargo-ok";
190190
pub const CRATES_IO_INDEX: &str = "https://github.com/rust-lang/crates.io-index";
191-
pub const CRATES_IO_HTTP_INDEX: &str = "https://index.crates.io/";
191+
pub const CRATES_IO_HTTP_INDEX: &str = "sparse+https://index.crates.io/";
192192
pub const CRATES_IO_REGISTRY: &str = "crates-io";
193193
pub const CRATES_IO_DOMAIN: &str = "crates.io";
194194
const CRATE_TEMPLATE: &str = "{crate}";

tests/testsuite/vendor.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use std::fs;
88

99
use cargo_test_support::git;
10-
use cargo_test_support::registry::{self, Package};
10+
use cargo_test_support::registry::{self, Package, RegistryBuilder};
1111
use cargo_test_support::{basic_lib_manifest, paths, project, Project};
1212

1313
#[cargo_test]
@@ -68,6 +68,41 @@ directory = "vendor"
6868
.run();
6969
}
7070

71+
#[cargo_test]
72+
fn vendor_sample_config_alt_registry() {
73+
let registry = RegistryBuilder::new().alternative().http_index().build();
74+
let p = project()
75+
.file(
76+
"Cargo.toml",
77+
r#"
78+
[package]
79+
name = "foo"
80+
version = "0.1.0"
81+
82+
[dependencies]
83+
log = { version = "0.3.5", registry = "alternative" }
84+
"#,
85+
)
86+
.file("src/lib.rs", "")
87+
.build();
88+
89+
Package::new("log", "0.3.5").alternative(true).publish();
90+
91+
p.cargo("vendor --respect-source-config -Z sparse-registry")
92+
.masquerade_as_nightly_cargo(&["sparse-registry"])
93+
.with_stdout(format!(
94+
r#"[source."{0}"]
95+
registry = "{0}"
96+
replace-with = "vendored-sources"
97+
98+
[source.vendored-sources]
99+
directory = "vendor"
100+
"#,
101+
registry.index_url()
102+
))
103+
.run();
104+
}
105+
71106
#[cargo_test]
72107
fn vendor_path_specified() {
73108
let p = project()

0 commit comments

Comments
 (0)