Skip to content

Commit 1d1d646

Browse files
authored
fix(package): Fix lookups to capitalized workspace member's index entry (#15216)
### What does this PR try to resolve? When investigating a report of a package-rename bug in `-Zpackage-workspace`, I found that we weren't correctly naming the file for index entries for generating `Cargo.lock` and verifying. We must first `to_lowercase` the name. In fixing this, I also tried to clarify the API to reduce the chance of this happening in the future. Still not great that the caller is expected to handle this and know about it. The problem is `make_dep_path` is shared between the index and `.crate` files which are handled differently (and sharing of the `to_lowercase` would be nice). Maybe if made a `make_index_path` that had an assert and called `make_dep_path`. I held off on that for now. ### How should we test and review this PR? ### Additional information
2 parents fcaf596 + 19d3071 commit 1d1d646

File tree

4 files changed

+76
-7
lines changed

4 files changed

+76
-7
lines changed

crates/cargo-util/src/registry.rs

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
/// - [index from of Cargo's index on filesystem][1], and
44
/// - [index from Crates.io][2].
55
///
6+
/// <div class="warning">
7+
///
8+
/// Note: For index files, `dep_name` must have had `to_lowercase` called on it.
9+
///
10+
/// </div>
11+
///
612
/// [1]: https://docs.rs/cargo/latest/cargo/sources/registry/index.html#the-format-of-the-index
713
/// [2]: https://github.com/rust-lang/crates.io-index
814
pub fn make_dep_path(dep_name: &str, prefix_only: bool) -> String {

src/cargo/ops/cargo_package/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,8 @@ impl<'a> TmpRegistry<'a> {
10681068
v: Some(2),
10691069
})?;
10701070

1071-
let file = cargo_util::registry::make_dep_path(package.name().as_str(), false);
1071+
let file =
1072+
cargo_util::registry::make_dep_path(&package.name().as_str().to_lowercase(), false);
10721073
let mut dst = self.index_path().open_rw_exclusive_create(
10731074
file,
10741075
self.gctx,

src/cargo/sources/registry/index/mod.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -584,19 +584,19 @@ impl Summaries {
584584
) -> Poll<CargoResult<Option<Summaries>>> {
585585
// This is the file we're loading from cache or the index data.
586586
// See module comment in `registry/mod.rs` for why this is structured the way it is.
587-
let name = &name.to_lowercase();
588-
let relative = make_dep_path(&name, false);
587+
let lowered_name = &name.to_lowercase();
588+
let relative = make_dep_path(&lowered_name, false);
589589

590590
let mut cached_summaries = None;
591591
let mut index_version = None;
592-
if let Some(contents) = cache_manager.get(name) {
592+
if let Some(contents) = cache_manager.get(lowered_name) {
593593
match Summaries::parse_cache(contents) {
594594
Ok((s, v)) => {
595595
cached_summaries = Some(s);
596596
index_version = Some(v);
597597
}
598598
Err(e) => {
599-
tracing::debug!("failed to parse {name:?} cache: {e}");
599+
tracing::debug!("failed to parse {lowered_name:?} cache: {e}");
600600
}
601601
}
602602
}
@@ -609,7 +609,7 @@ impl Summaries {
609609
return Poll::Ready(Ok(cached_summaries));
610610
}
611611
LoadResponse::NotFound => {
612-
cache_manager.invalidate(name);
612+
cache_manager.invalidate(lowered_name);
613613
return Poll::Ready(Ok(None));
614614
}
615615
LoadResponse::Data {
@@ -658,7 +658,7 @@ impl Summaries {
658658
// Once we have our `cache_bytes` which represents the `Summaries` we're
659659
// about to return, write that back out to disk so future Cargo
660660
// invocations can use it.
661-
cache_manager.put(name, &cache_bytes);
661+
cache_manager.put(lowered_name, &cache_bytes);
662662

663663
// If we've got debug assertions enabled read back in the cached values
664664
// and assert they match the expected result.

tests/testsuite/package.rs

+62
Original file line numberDiff line numberDiff line change
@@ -6430,6 +6430,68 @@ fn workspace_with_local_and_remote_deps() {
64306430
.run();
64316431
}
64326432

6433+
#[cargo_test]
6434+
fn workspace_with_capitalized_member() {
6435+
let reg = registry::init();
6436+
6437+
let p = project()
6438+
.file(
6439+
"Cargo.toml",
6440+
r#"
6441+
[workspace]
6442+
members = ["dep", "main"]
6443+
"#,
6444+
)
6445+
.file(
6446+
"main/Cargo.toml",
6447+
r#"
6448+
[package]
6449+
name = "main"
6450+
version = "0.0.1"
6451+
edition = "2015"
6452+
authors = []
6453+
license = "MIT"
6454+
description = "main"
6455+
repository = "bar"
6456+
6457+
[dependencies]
6458+
DEP = { path = "../dep", version = "0.1.0" }
6459+
"#,
6460+
)
6461+
.file("main/src/main.rs", "fn main() {}")
6462+
.file(
6463+
"dep/Cargo.toml",
6464+
r#"
6465+
[package]
6466+
name = "DEP"
6467+
version = "0.1.0"
6468+
edition = "2015"
6469+
authors = []
6470+
license = "MIT"
6471+
description = "dep"
6472+
repository = "bar"
6473+
"#,
6474+
)
6475+
.file("dep/src/lib.rs", "")
6476+
.build();
6477+
6478+
p.cargo("package -Zpackage-workspace --no-verify")
6479+
.masquerade_as_nightly_cargo(&["package-workspace"])
6480+
.replace_crates_io(reg.index_url())
6481+
.with_stderr_data(
6482+
str![[r#"
6483+
[PACKAGING] main v0.0.1 ([ROOT]/foo/main)
6484+
[UPDATING] crates.io index
6485+
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
6486+
[PACKAGING] DEP v0.1.0 ([ROOT]/foo/dep)
6487+
[PACKAGED] 4 files, [FILE_SIZE]B ([FILE_SIZE]B compressed)
6488+
6489+
"#]]
6490+
.unordered(),
6491+
)
6492+
.run();
6493+
}
6494+
64336495
#[cargo_test]
64346496
fn registry_not_in_publish_list() {
64356497
let p = project()

0 commit comments

Comments
 (0)