Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(vendor): trust crate version only when coming from registries #14530

Merged
merged 2 commits into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/cargo/ops/vendor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,10 @@ fn sync(
let dst = canonical_destination.join(&dst_name);
to_remove.remove(&dst);
let cksum = dst.join(".cargo-checksum.json");
if dir_has_version_suffix && cksum.exists() {
// Always re-copy directory without version suffix in case the version changed
// Registries are the only immutable sources,
// path and git dependencies' versions cannot be trusted to mean "no change"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Path dependencies don't get vendored yet, see #13347.

And I feel like we can assume that all registry sources are immutable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we keep this comment for when they will be or would you prefer I remove the mention to path dependencies ?
I wasn't sure whether to include all registries or not, but you are right, if a registry is not immutable, it will probably cause other problems before that. I'll change this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can leave the comment there. It just a note that Cargo doesn't vendor local path deps.

I wasn't sure whether to include all registries or not, but you are right, if a registry is not immutable, it will probably cause other problems before that. I'll change this.

Rebuild detection also holds that assumption, so yeah thanks for the update.

if dir_has_version_suffix && id.source_id().is_registry() && cksum.exists() {
// Don't re-copy directory with version suffix in case it comes from a registry
continue;
}

Expand Down
61 changes: 61 additions & 0 deletions tests/testsuite/vendor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,67 @@ path = [..]
);
}

#[cargo_test]
fn git_update_rev() {
let (git_project, git_repo) = git::new_repo("git", |p| {
p.file("Cargo.toml", &basic_manifest("a", "0.1.0"))
.file("src/lib.rs", "")
});
let url = git_project.url();
let ref_1 = "initial";
let ref_2 = "update";

git::tag(&git_repo, ref_1);

git_project.change_file("src/lib.rs", "pub fn f() {}");
git::add(&git_repo);
git::commit(&git_repo);
git::tag(&git_repo, ref_2);

let p = project()
.file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.1.0"

[dependencies]
a = {{ git = '{url}', rev = '{ref_1}' }}
"#
),
)
.file("src/lib.rs", "")
.build();

p.cargo("vendor --respect-source-config --versioned-dirs")
.run();

let lib = p.read_file("vendor/a-0.1.0/src/lib.rs");
assert_e2e().eq(lib, "");

p.change_file(
"Cargo.toml",
&format!(
r#"
[package]
name = "foo"
version = "0.1.0"

[dependencies]
a = {{ git = '{url}', rev = '{ref_2}' }}
"#
),
);

p.cargo("vendor --respect-source-config --versioned-dirs")
.run();

let lib = p.read_file("vendor/a-0.1.0/src/lib.rs");
assert_e2e().eq(lib, "pub fn f() {}");
}

#[cargo_test]
fn depend_on_vendor_dir_not_deleted() {
let p = project()
Expand Down