From 48e8a718ecceb42c6648a2c7ce7efa8d2c37161b Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 10:58:44 -0600 Subject: [PATCH 001/181] test(git): Collect tests that use the same body --- tests/testsuite/git_shallow.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/testsuite/git_shallow.rs b/tests/testsuite/git_shallow.rs index 6a45621e63b..df4be11498d 100644 --- a/tests/testsuite/git_shallow.rs +++ b/tests/testsuite/git_shallow.rs @@ -14,6 +14,11 @@ fn gitoxide_clones_shallow_two_revs_same_deps() { perform_two_revs_same_deps(true) } +#[cargo_test] +fn two_revs_same_deps() { + perform_two_revs_same_deps(false) +} + fn perform_two_revs_same_deps(shallow: bool) { let bar = git::new("meta-dep", |project| { project @@ -106,11 +111,6 @@ fn perform_two_revs_same_deps(shallow: bool) { foo.process(&foo.bin("foo")).run(); } -#[cargo_test] -fn two_revs_same_deps() { - perform_two_revs_same_deps(false) -} - #[cargo_test] fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_with_git2_fetch( ) -> anyhow::Result<()> { From 89b89bde65eb0c687e19dba575ade0c9cc9f0f3a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 11:04:47 -0600 Subject: [PATCH 002/181] test(git): Clarify test parameter --- tests/testsuite/git_shallow.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/testsuite/git_shallow.rs b/tests/testsuite/git_shallow.rs index df4be11498d..e58ce784ce3 100644 --- a/tests/testsuite/git_shallow.rs +++ b/tests/testsuite/git_shallow.rs @@ -11,15 +11,15 @@ enum RepoMode { #[cargo_test] fn gitoxide_clones_shallow_two_revs_same_deps() { - perform_two_revs_same_deps(true) + perform_two_revs_same_deps(RepoMode::Shallow) } #[cargo_test] fn two_revs_same_deps() { - perform_two_revs_same_deps(false) + perform_two_revs_same_deps(RepoMode::Complete) } -fn perform_two_revs_same_deps(shallow: bool) { +fn perform_two_revs_same_deps(mode: RepoMode) { let bar = git::new("meta-dep", |project| { project .file("Cargo.toml", &basic_manifest("bar", "0.0.0")) @@ -97,10 +97,9 @@ fn perform_two_revs_same_deps(shallow: bool) { ) .build(); - let args = if shallow { - "build -v -Zgitoxide=fetch -Zgit=shallow-deps" - } else { - "build -v" + let args = match mode { + RepoMode::Complete => "build -v", + RepoMode::Shallow => "build -v -Zgitoxide=fetch -Zgit=shallow-deps", }; foo.cargo(args) .masquerade_as_nightly_cargo(&[ From 4cc7ff5ab594ff8c3834b8dc277d190f0a938066 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 11:22:59 -0600 Subject: [PATCH 003/181] test(git): Fix masquerade feature list for shallow fetch --- tests/testsuite/git_shallow.rs | 62 ++++++++++------------------------ 1 file changed, 17 insertions(+), 45 deletions(-) diff --git a/tests/testsuite/git_shallow.rs b/tests/testsuite/git_shallow.rs index e58ce784ce3..f456584192d 100644 --- a/tests/testsuite/git_shallow.rs +++ b/tests/testsuite/git_shallow.rs @@ -102,9 +102,7 @@ fn perform_two_revs_same_deps(mode: RepoMode) { RepoMode::Shallow => "build -v -Zgitoxide=fetch -Zgit=shallow-deps", }; foo.cargo(args) - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) .run(); assert!(foo.bin("foo").is_file()); foo.process(&foo.bin("foo")).run(); @@ -131,9 +129,7 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_with_git2_fetch( p.cargo("fetch") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-index") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-index"]) .run(); let shallow_repo = gix::open_opts(find_index(), gix::open::Options::isolated())?; @@ -214,9 +210,7 @@ fn gitoxide_clones_git_dependency_with_shallow_protocol_and_git2_is_used_for_fol p.cargo("update") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-deps") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) .run(); let db_clone = gix::open_opts( @@ -352,9 +346,7 @@ fn gitoxide_shallow_clone_followed_by_non_shallow_update() -> anyhow::Result<()> p.cargo("update") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-deps") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) .run(); let shallow_db_clone = gix::open_opts( @@ -398,7 +390,7 @@ fn gitoxide_shallow_clone_followed_by_non_shallow_update() -> anyhow::Result<()> p.cargo("update") .arg("-Zgitoxide=fetch") // shallow-deps is omitted intentionally - .masquerade_as_nightly_cargo(&["unstable features must be available for -Z gitoxide"]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch"]) .run(); let db_clone = gix::open_opts( @@ -471,9 +463,7 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_fetch_maintains_ p.cargo("fetch") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-index") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-index"]) .run(); let repo = gix::open_opts(find_index(), gix::open::Options::isolated())?; @@ -491,9 +481,7 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_fetch_maintains_ p.cargo("update") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-index") // NOTE: the flag needs to be consistent or else a different index is created - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-index"]) .run(); assert_eq!( @@ -511,9 +499,7 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_fetch_maintains_ p.cargo("update") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-index") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-index"]) .run(); assert_eq!( @@ -550,7 +536,7 @@ fn gitoxide_clones_registry_without_shallow_protocol_and_follow_up_fetch_uses_sh .build(); p.cargo("fetch") .arg("-Zgitoxide=fetch") - .masquerade_as_nightly_cargo(&["unstable features must be available for -Z gitoxide"]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch"]) .run(); let repo = gix::open_opts(find_index(), gix::open::Options::isolated())?; @@ -568,9 +554,7 @@ fn gitoxide_clones_registry_without_shallow_protocol_and_follow_up_fetch_uses_sh p.cargo("update") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-index") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-index"]) .run(); let shallow_repo = gix::open_opts( @@ -592,9 +576,7 @@ fn gitoxide_clones_registry_without_shallow_protocol_and_follow_up_fetch_uses_sh p.cargo("update") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-index") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-index"]) .run(); assert_eq!( @@ -610,7 +592,7 @@ fn gitoxide_clones_registry_without_shallow_protocol_and_follow_up_fetch_uses_sh p.cargo("update") .arg("-Zgitoxide=fetch") - .masquerade_as_nightly_cargo(&["unstable features must be available for -Z gitoxide"]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch"]) .run(); assert_eq!( @@ -662,9 +644,7 @@ fn gitoxide_git_dependencies_switch_from_branch_to_rev() -> anyhow::Result<()> { p.cargo("check") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-deps") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) .run(); let db_clone = gix::open_opts( @@ -695,9 +675,7 @@ fn gitoxide_git_dependencies_switch_from_branch_to_rev() -> anyhow::Result<()> { p.cargo("check") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-deps") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) .run(); assert!( @@ -746,9 +724,7 @@ fn shallow_deps_work_with_revisions_and_branches_mixed_on_same_dependency() -> a p.cargo("check") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-deps") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) .run(); let db_paths = glob::glob(paths::home().join(".cargo/git/db/bar-*").to_str().unwrap())? @@ -789,9 +765,7 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_aborts_and_updates_again( p.cargo("fetch") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-index") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-index"]) .run(); let repo = gix::open_opts(find_index(), gix::open::Options::isolated())?; @@ -814,9 +788,7 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_aborts_and_updates_again( p.cargo("update") .arg("-Zgitoxide=fetch") .arg("-Zgit=shallow-index") - .masquerade_as_nightly_cargo(&[ - "unstable features must be available for -Z gitoxide and -Z git", - ]) + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-index"]) .run(); assert!(!shallow_lock.is_file(), "the repository was re-initialized"); From 1c82fe420e0989024138c47c9d8ebf58fd741980 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 11:49:51 -0600 Subject: [PATCH 004/181] test(git): Prefer check over build for faster tests If check passes, it should be sufficient. --- tests/testsuite/git_shallow.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/testsuite/git_shallow.rs b/tests/testsuite/git_shallow.rs index f456584192d..c84e758d8b0 100644 --- a/tests/testsuite/git_shallow.rs +++ b/tests/testsuite/git_shallow.rs @@ -98,14 +98,12 @@ fn perform_two_revs_same_deps(mode: RepoMode) { .build(); let args = match mode { - RepoMode::Complete => "build -v", - RepoMode::Shallow => "build -v -Zgitoxide=fetch -Zgit=shallow-deps", + RepoMode::Complete => "check -v", + RepoMode::Shallow => "check -v -Zgitoxide=fetch -Zgit=shallow-deps", }; foo.cargo(args) .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) .run(); - assert!(foo.bin("foo").is_file()); - foo.process(&foo.bin("foo")).run(); } #[cargo_test] From 34d0bcb3e9c44df9eb80b27887aec30d00236092 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 11:56:37 -0600 Subject: [PATCH 005/181] feat(test); Add arg_line support to Execs --- crates/cargo-test-support/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/cargo-test-support/src/lib.rs b/crates/cargo-test-support/src/lib.rs index f282b3d9bdd..9eeb4eb00f8 100644 --- a/crates/cargo-test-support/src/lib.rs +++ b/crates/cargo-test-support/src/lib.rs @@ -1524,6 +1524,12 @@ impl ArgLineCommandExt for &mut ProcessBuilder { } } +impl ArgLineCommandExt for &mut Execs { + fn arg>(self, s: S) -> Self { + self.arg(s) + } +} + impl ArgLineCommandExt for snapbox::cmd::Command { fn arg>(self, s: S) -> Self { self.arg(s) From 4e3e353978e1d54fbf754106ae14cea568f432d2 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 11:57:16 -0600 Subject: [PATCH 006/181] test(git): Reduce duplication in shallow test --- tests/testsuite/git_shallow.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/testsuite/git_shallow.rs b/tests/testsuite/git_shallow.rs index c84e758d8b0..fce4c7c1d85 100644 --- a/tests/testsuite/git_shallow.rs +++ b/tests/testsuite/git_shallow.rs @@ -97,11 +97,12 @@ fn perform_two_revs_same_deps(mode: RepoMode) { ) .build(); - let args = match mode { - RepoMode::Complete => "check -v", - RepoMode::Shallow => "check -v -Zgitoxide=fetch -Zgit=shallow-deps", + let mode_args = match mode { + RepoMode::Complete => "", + RepoMode::Shallow => "-Zgitoxide=fetch -Zgit=shallow-deps", }; - foo.cargo(args) + foo.cargo("check -v") + .arg_line(mode_args) .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) .run(); } From cade73a7a09a8ed0384ea47f372c910cff42cc8c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 14:56:12 -0600 Subject: [PATCH 007/181] test(git): Make test backend clearer --- tests/testsuite/git_shallow.rs | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/tests/testsuite/git_shallow.rs b/tests/testsuite/git_shallow.rs index fce4c7c1d85..f330c7f9727 100644 --- a/tests/testsuite/git_shallow.rs +++ b/tests/testsuite/git_shallow.rs @@ -4,22 +4,27 @@ use cargo_test_support::{basic_manifest, git, paths, project}; use crate::git_gc::find_index; +enum Backend { + Git2, + Gitoxide, +} + enum RepoMode { Shallow, Complete, } #[cargo_test] -fn gitoxide_clones_shallow_two_revs_same_deps() { - perform_two_revs_same_deps(RepoMode::Shallow) +fn gitoxide_fetch_shallow_two_revs_same_deps() { + fetch_two_revs_same_deps(Backend::Gitoxide, RepoMode::Shallow) } #[cargo_test] -fn two_revs_same_deps() { - perform_two_revs_same_deps(RepoMode::Complete) +fn git2_fetch_complete_two_revs_same_deps() { + fetch_two_revs_same_deps(Backend::Git2, RepoMode::Complete) } -fn perform_two_revs_same_deps(mode: RepoMode) { +fn fetch_two_revs_same_deps(backend: Backend, mode: RepoMode) { let bar = git::new("meta-dep", |project| { project .file("Cargo.toml", &basic_manifest("bar", "0.0.0")) @@ -97,12 +102,18 @@ fn perform_two_revs_same_deps(mode: RepoMode) { ) .build(); + let backend_args = match backend { + Backend::Git2 => "", + Backend::Gitoxide => "-Zgitoxide=fetch", + }; let mode_args = match mode { RepoMode::Complete => "", - RepoMode::Shallow => "-Zgitoxide=fetch -Zgit=shallow-deps", + RepoMode::Shallow => "-Zgit=shallow-deps", }; foo.cargo("check -v") + .arg_line(backend_args) .arg_line(mode_args) + .env("__CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2", "0") // respect `backend` .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) .run(); } From adf25782e08315e2b91c79f747aa57d8b5179358 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 14:58:36 -0600 Subject: [PATCH 008/181] test(git): Extract CLI arg creation --- tests/testsuite/git_shallow.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/tests/testsuite/git_shallow.rs b/tests/testsuite/git_shallow.rs index f330c7f9727..4cd13e4dd2a 100644 --- a/tests/testsuite/git_shallow.rs +++ b/tests/testsuite/git_shallow.rs @@ -9,11 +9,29 @@ enum Backend { Gitoxide, } +impl Backend { + fn to_arg(&self) -> &'static str { + match self { + Backend::Git2 => "", + Backend::Gitoxide => "-Zgitoxide=fetch", + } + } +} + enum RepoMode { Shallow, Complete, } +impl RepoMode { + fn to_deps_arg(&self) -> &'static str { + match self { + RepoMode::Complete => "", + RepoMode::Shallow => "-Zgit=shallow-deps", + } + } +} + #[cargo_test] fn gitoxide_fetch_shallow_two_revs_same_deps() { fetch_two_revs_same_deps(Backend::Gitoxide, RepoMode::Shallow) @@ -102,17 +120,9 @@ fn fetch_two_revs_same_deps(backend: Backend, mode: RepoMode) { ) .build(); - let backend_args = match backend { - Backend::Git2 => "", - Backend::Gitoxide => "-Zgitoxide=fetch", - }; - let mode_args = match mode { - RepoMode::Complete => "", - RepoMode::Shallow => "-Zgit=shallow-deps", - }; foo.cargo("check -v") - .arg_line(backend_args) - .arg_line(mode_args) + .arg_line(backend.to_arg()) + .arg_line(mode.to_deps_arg()) .env("__CARGO_USE_GITOXIDE_INSTEAD_OF_GIT2", "0") // respect `backend` .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) .run(); From a739b00f300d4ba317735607d504acee0bc8f14c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 15:03:18 -0600 Subject: [PATCH 009/181] test(git): Clarify we are doing shallow fetches --- tests/testsuite/git_shallow.rs | 44 +++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/testsuite/git_shallow.rs b/tests/testsuite/git_shallow.rs index 4cd13e4dd2a..76425c19704 100644 --- a/tests/testsuite/git_shallow.rs +++ b/tests/testsuite/git_shallow.rs @@ -129,7 +129,7 @@ fn fetch_two_revs_same_deps(backend: Backend, mode: RepoMode) { } #[cargo_test] -fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_with_git2_fetch( +fn gitoxide_fetch_registry_with_shallow_protocol_and_follow_up_with_git2_fetch( ) -> anyhow::Result<()> { Package::new("bar", "1.0.0").publish(); let p = project() @@ -160,7 +160,7 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_with_git2_fetch( .all()? .count(), 1, - "shallow clones always start at depth of 1 to minimize download size" + "shallow fetch always start at depth of 1 to minimize download size" ); assert!(shallow_repo.is_shallow()); @@ -179,14 +179,14 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_with_git2_fetch( .all()? .count(), 3, - "an entirely new repo was cloned which is never shallow" + "an entirely new repo was fetched which is never shallow" ); assert!(!repo.is_shallow()); Ok(()) } #[cargo_test] -fn gitoxide_clones_git_dependency_with_shallow_protocol_and_git2_is_used_for_followup_fetches( +fn gitoxide_fetch_git_dependency_with_shallow_protocol_and_git2_is_used_for_followup_fetches( ) -> anyhow::Result<()> { // Example where an old lockfile with an explicit branch="master" in Cargo.toml. Package::new("bar", "1.0.0").publish(); @@ -245,7 +245,7 @@ fn gitoxide_clones_git_dependency_with_shallow_protocol_and_git2_is_used_for_fol .all()? .count(), 1, - "db clones are shallow and have a shortened history" + "db fetch are shallow and have a shortened history" ); let dep_checkout = gix::open_opts( @@ -256,7 +256,7 @@ fn gitoxide_clones_git_dependency_with_shallow_protocol_and_git2_is_used_for_fol assert_eq!( dep_checkout.head_id()?.ancestors().all()?.count(), 1, - "db checkouts are hard-linked clones with the shallow file copied separately." + "db checkouts are hard-linked fetches with the shallow file copied separately." ); bar.change_file("src/lib.rs", "// another change"); @@ -324,7 +324,7 @@ fn gitoxide_clones_git_dependency_with_shallow_protocol_and_git2_is_used_for_fol } #[cargo_test] -fn gitoxide_shallow_clone_followed_by_non_shallow_update() -> anyhow::Result<()> { +fn gitoxide_shallow_fetch_followed_by_non_shallow_update() -> anyhow::Result<()> { Package::new("bar", "1.0.0").publish(); let (bar, bar_repo) = git::new_repo("bar", |p| { p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) @@ -381,7 +381,7 @@ fn gitoxide_shallow_clone_followed_by_non_shallow_update() -> anyhow::Result<()> .all()? .count(), 1, - "db clones are shallow and have a shortened history" + "db fetches are shallow and have a shortened history" ); let dep_checkout = gix::open_opts( @@ -392,7 +392,7 @@ fn gitoxide_shallow_clone_followed_by_non_shallow_update() -> anyhow::Result<()> assert_eq!( dep_checkout.head_id()?.ancestors().all()?.count(), 1, - "db checkouts are hard-linked clones with the shallow file copied separately." + "db checkouts are hard-linked fetches with the shallow file copied separately." ); bar.change_file("src/lib.rs", "// another change"); @@ -463,7 +463,7 @@ fn gitoxide_shallow_clone_followed_by_non_shallow_update() -> anyhow::Result<()> } #[cargo_test] -fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_fetch_maintains_shallowness( +fn gitoxide_fetch_registry_with_shallow_protocol_and_follow_up_fetch_maintains_shallowness( ) -> anyhow::Result<()> { Package::new("bar", "1.0.0").publish(); let p = project() @@ -493,7 +493,7 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_fetch_maintains_ .all()? .count(), 1, - "shallow clones always start at depth of 1 to minimize download size" + "shallow fetches always start at depth of 1 to minimize download size" ); assert!(repo.is_shallow()); @@ -535,9 +535,9 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_follow_up_fetch_maintains_ Ok(()) } -/// If there is shallow *and* non-shallow clones, non-shallow will naturally be returned due to sort order. +/// If there is shallow *and* non-shallow fetches, non-shallow will naturally be returned due to sort order. #[cargo_test] -fn gitoxide_clones_registry_without_shallow_protocol_and_follow_up_fetch_uses_shallowness( +fn gitoxide_fetch_registry_without_shallow_protocol_and_follow_up_fetch_uses_shallowness( ) -> anyhow::Result<()> { Package::new("bar", "1.0.0").publish(); let p = project() @@ -587,7 +587,7 @@ fn gitoxide_clones_registry_without_shallow_protocol_and_follow_up_fetch_uses_sh .all()? .count(), 1, - "the follow up clones an entirely new index which is now shallow and which is in its own location" + "the follow up fetch an entirely new index which is now shallow and which is in its own location" ); assert!(shallow_repo.is_shallow()); @@ -630,14 +630,14 @@ fn gitoxide_clones_registry_without_shallow_protocol_and_follow_up_fetch_uses_sh #[cargo_test] fn gitoxide_git_dependencies_switch_from_branch_to_rev() -> anyhow::Result<()> { // db exists from previous build, then dependency changes to refer to revision that isn't - // available in the shallow clone. + // available in the shallow fetch. let (bar, bar_repo) = git::new_repo("bar", |p| { p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) .file("src/lib.rs", "") }); - // this commit would not be available in a shallow clone. + // this commit would not be available in a shallow fetch. let first_commit_pre_change = bar_repo.head().unwrap().target().unwrap(); bar.change_file("src/lib.rs", "// change"); @@ -713,7 +713,7 @@ fn shallow_deps_work_with_revisions_and_branches_mixed_on_same_dependency() -> a .file("src/lib.rs", "") }); - // this commit would not be available in a shallow clone. + // this commit would not be available in a shallow fetch. let first_commit_pre_change = bar_repo.head().unwrap().target().unwrap(); bar.change_file("src/lib.rs", "// change"); @@ -765,8 +765,8 @@ fn shallow_deps_work_with_revisions_and_branches_mixed_on_same_dependency() -> a } #[cargo_test] -fn gitoxide_clones_registry_with_shallow_protocol_and_aborts_and_updates_again( -) -> anyhow::Result<()> { +fn gitoxide_fetch_registry_with_shallow_protocol_and_aborts_and_updates_again() -> anyhow::Result<()> +{ Package::new("bar", "1.0.0").publish(); let p = project() .file( @@ -795,11 +795,11 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_aborts_and_updates_again( .all()? .count(), 1, - "shallow clones always start at depth of 1 to minimize download size" + "shallow fetches always start at depth of 1 to minimize download size" ); assert!(repo.is_shallow()); let shallow_lock = repo.shallow_file().with_extension("lock"); - // adding a lock file and deleting the original simulates a left-over clone that was aborted, leaving a lock file + // adding a lock file and deleting the original simulates a left-over fetch that was aborted, leaving a lock file // in place without ever having moved it to the right location. std::fs::write(&shallow_lock, &[])?; std::fs::remove_file(repo.shallow_file())?; @@ -819,7 +819,7 @@ fn gitoxide_clones_registry_with_shallow_protocol_and_aborts_and_updates_again( .all()? .count(), 1, - "it's a fresh shallow clone - otherwise it would have 2 commits if the previous shallow clone would still be present" + "it's a fresh shallow fetch - otherwise it would have 2 commits if the previous shallow fetch would still be present" ); Ok(()) From e0f8cc06da88353f79fa74898f0e8671bd8e0bb9 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 15:09:03 -0600 Subject: [PATCH 010/181] test(git): Group related shallow tests --- tests/testsuite/git_shallow.rs | 274 ++++++++++++++++----------------- 1 file changed, 137 insertions(+), 137 deletions(-) diff --git a/tests/testsuite/git_shallow.rs b/tests/testsuite/git_shallow.rs index 76425c19704..8a64e17cc80 100644 --- a/tests/testsuite/git_shallow.rs +++ b/tests/testsuite/git_shallow.rs @@ -128,6 +128,143 @@ fn fetch_two_revs_same_deps(backend: Backend, mode: RepoMode) { .run(); } +#[cargo_test] +fn shallow_deps_work_with_revisions_and_branches_mixed_on_same_dependency() -> anyhow::Result<()> { + let (bar, bar_repo) = git::new_repo("bar", |p| { + p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) + .file("src/lib.rs", "") + }); + + // this commit would not be available in a shallow fetch. + let first_commit_pre_change = bar_repo.head().unwrap().target().unwrap(); + + bar.change_file("src/lib.rs", "// change"); + git::add(&bar_repo); + git::commit(&bar_repo); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar-renamed = {{ package = "bar", git = "{}", rev = "{}" }} + bar = {{ git = "{}", branch = "master" }} + "#, + bar.url(), + first_commit_pre_change, + bar.url(), + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check") + .arg("-Zgitoxide=fetch") + .arg("-Zgit=shallow-deps") + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) + .run(); + + let db_paths = glob::glob(paths::home().join(".cargo/git/db/bar-*").to_str().unwrap())? + .map(Result::unwrap) + .collect::>(); + assert_eq!( + db_paths.len(), + 1, + "only one db checkout source is used per dependency" + ); + let db_clone = gix::open_opts(&db_paths[0], gix::open::Options::isolated())?; + assert!( + db_clone.is_shallow(), + "the repo is shallow while having all data it needs" + ); + + Ok(()) +} + +#[cargo_test] +fn gitoxide_git_dependencies_switch_from_branch_to_rev() -> anyhow::Result<()> { + // db exists from previous build, then dependency changes to refer to revision that isn't + // available in the shallow fetch. + + let (bar, bar_repo) = git::new_repo("bar", |p| { + p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) + .file("src/lib.rs", "") + }); + + // this commit would not be available in a shallow fetch. + let first_commit_pre_change = bar_repo.head().unwrap().target().unwrap(); + + bar.change_file("src/lib.rs", "// change"); + git::add(&bar_repo); + git::commit(&bar_repo); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = {{ git = "{}", branch = "master" }} + "#, + bar.url(), + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check") + .arg("-Zgitoxide=fetch") + .arg("-Zgit=shallow-deps") + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) + .run(); + + let db_clone = gix::open_opts( + find_bar_db(RepoMode::Shallow), + gix::open::Options::isolated(), + )?; + assert!(db_clone.is_shallow()); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = {{ git = "{}", rev = "{}" }} + "#, + bar.url(), + first_commit_pre_change + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check") + .arg("-Zgitoxide=fetch") + .arg("-Zgit=shallow-deps") + .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) + .run(); + + assert!( + db_clone.is_shallow(), + "we maintain shallowness and never unshallow" + ); + + Ok(()) +} + #[cargo_test] fn gitoxide_fetch_registry_with_shallow_protocol_and_follow_up_with_git2_fetch( ) -> anyhow::Result<()> { @@ -627,143 +764,6 @@ fn gitoxide_fetch_registry_without_shallow_protocol_and_follow_up_fetch_uses_sha Ok(()) } -#[cargo_test] -fn gitoxide_git_dependencies_switch_from_branch_to_rev() -> anyhow::Result<()> { - // db exists from previous build, then dependency changes to refer to revision that isn't - // available in the shallow fetch. - - let (bar, bar_repo) = git::new_repo("bar", |p| { - p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) - .file("src/lib.rs", "") - }); - - // this commit would not be available in a shallow fetch. - let first_commit_pre_change = bar_repo.head().unwrap().target().unwrap(); - - bar.change_file("src/lib.rs", "// change"); - git::add(&bar_repo); - git::commit(&bar_repo); - let p = project() - .file( - "Cargo.toml", - &format!( - r#" - [package] - name = "foo" - version = "0.1.0" - - [dependencies] - bar = {{ git = "{}", branch = "master" }} - "#, - bar.url(), - ), - ) - .file("src/lib.rs", "") - .build(); - - p.cargo("check") - .arg("-Zgitoxide=fetch") - .arg("-Zgit=shallow-deps") - .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) - .run(); - - let db_clone = gix::open_opts( - find_bar_db(RepoMode::Shallow), - gix::open::Options::isolated(), - )?; - assert!(db_clone.is_shallow()); - - let p = project() - .file( - "Cargo.toml", - &format!( - r#" - [package] - name = "foo" - version = "0.1.0" - - [dependencies] - bar = {{ git = "{}", rev = "{}" }} - "#, - bar.url(), - first_commit_pre_change - ), - ) - .file("src/lib.rs", "") - .build(); - - p.cargo("check") - .arg("-Zgitoxide=fetch") - .arg("-Zgit=shallow-deps") - .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) - .run(); - - assert!( - db_clone.is_shallow(), - "we maintain shallowness and never unshallow" - ); - - Ok(()) -} - -#[cargo_test] -fn shallow_deps_work_with_revisions_and_branches_mixed_on_same_dependency() -> anyhow::Result<()> { - let (bar, bar_repo) = git::new_repo("bar", |p| { - p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) - .file("src/lib.rs", "") - }); - - // this commit would not be available in a shallow fetch. - let first_commit_pre_change = bar_repo.head().unwrap().target().unwrap(); - - bar.change_file("src/lib.rs", "// change"); - git::add(&bar_repo); - git::commit(&bar_repo); - - let p = project() - .file( - "Cargo.toml", - &format!( - r#" - [package] - name = "foo" - version = "0.1.0" - - [dependencies] - bar-renamed = {{ package = "bar", git = "{}", rev = "{}" }} - bar = {{ git = "{}", branch = "master" }} - "#, - bar.url(), - first_commit_pre_change, - bar.url(), - ), - ) - .file("src/lib.rs", "") - .build(); - - p.cargo("check") - .arg("-Zgitoxide=fetch") - .arg("-Zgit=shallow-deps") - .masquerade_as_nightly_cargo(&["gitoxide=fetch", "git=shallow-deps"]) - .run(); - - let db_paths = glob::glob(paths::home().join(".cargo/git/db/bar-*").to_str().unwrap())? - .map(Result::unwrap) - .collect::>(); - assert_eq!( - db_paths.len(), - 1, - "only one db checkout source is used per dependency" - ); - let db_clone = gix::open_opts(&db_paths[0], gix::open::Options::isolated())?; - assert!( - db_clone.is_shallow(), - "the repo is shallow while having all data it needs" - ); - - Ok(()) -} - #[cargo_test] fn gitoxide_fetch_registry_with_shallow_protocol_and_aborts_and_updates_again() -> anyhow::Result<()> { From 24388070488952b39e8d3c7d9a707b0d25e8ac7f Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 18 Dec 2024 15:20:03 -0600 Subject: [PATCH 011/181] test(git): Be consistent on shallow test names --- tests/testsuite/git_shallow.rs | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/tests/testsuite/git_shallow.rs b/tests/testsuite/git_shallow.rs index 8a64e17cc80..86291714cd9 100644 --- a/tests/testsuite/git_shallow.rs +++ b/tests/testsuite/git_shallow.rs @@ -33,16 +33,16 @@ impl RepoMode { } #[cargo_test] -fn gitoxide_fetch_shallow_two_revs_same_deps() { - fetch_two_revs_same_deps(Backend::Gitoxide, RepoMode::Shallow) +fn gitoxide_fetch_shallow_dep_two_revs() { + fetch_dep_two_revs(Backend::Gitoxide, RepoMode::Shallow) } #[cargo_test] -fn git2_fetch_complete_two_revs_same_deps() { - fetch_two_revs_same_deps(Backend::Git2, RepoMode::Complete) +fn git2_fetch_complete_dep_two_revs() { + fetch_dep_two_revs(Backend::Git2, RepoMode::Complete) } -fn fetch_two_revs_same_deps(backend: Backend, mode: RepoMode) { +fn fetch_dep_two_revs(backend: Backend, mode: RepoMode) { let bar = git::new("meta-dep", |project| { project .file("Cargo.toml", &basic_manifest("bar", "0.0.0")) @@ -129,7 +129,7 @@ fn fetch_two_revs_same_deps(backend: Backend, mode: RepoMode) { } #[cargo_test] -fn shallow_deps_work_with_revisions_and_branches_mixed_on_same_dependency() -> anyhow::Result<()> { +fn gitoxide_fetch_shallow_dep_branch_and_rev() -> anyhow::Result<()> { let (bar, bar_repo) = git::new_repo("bar", |p| { p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) .file("src/lib.rs", "") @@ -187,7 +187,7 @@ fn shallow_deps_work_with_revisions_and_branches_mixed_on_same_dependency() -> a } #[cargo_test] -fn gitoxide_git_dependencies_switch_from_branch_to_rev() -> anyhow::Result<()> { +fn gitoxide_fetch_shallow_dep_branch_to_rev() -> anyhow::Result<()> { // db exists from previous build, then dependency changes to refer to revision that isn't // available in the shallow fetch. @@ -266,8 +266,7 @@ fn gitoxide_git_dependencies_switch_from_branch_to_rev() -> anyhow::Result<()> { } #[cargo_test] -fn gitoxide_fetch_registry_with_shallow_protocol_and_follow_up_with_git2_fetch( -) -> anyhow::Result<()> { +fn gitoxide_fetch_shallow_index_then_git2_fetch_complete() -> anyhow::Result<()> { Package::new("bar", "1.0.0").publish(); let p = project() .file( @@ -323,8 +322,7 @@ fn gitoxide_fetch_registry_with_shallow_protocol_and_follow_up_with_git2_fetch( } #[cargo_test] -fn gitoxide_fetch_git_dependency_with_shallow_protocol_and_git2_is_used_for_followup_fetches( -) -> anyhow::Result<()> { +fn gitoxide_fetch_shallow_dep_then_git2_fetch_complete() -> anyhow::Result<()> { // Example where an old lockfile with an explicit branch="master" in Cargo.toml. Package::new("bar", "1.0.0").publish(); let (bar, bar_repo) = git::new_repo("bar", |p| { @@ -461,7 +459,7 @@ fn gitoxide_fetch_git_dependency_with_shallow_protocol_and_git2_is_used_for_foll } #[cargo_test] -fn gitoxide_shallow_fetch_followed_by_non_shallow_update() -> anyhow::Result<()> { +fn gitoxide_fetch_shallow_dep_then_gitoxide_fetch_complete() -> anyhow::Result<()> { Package::new("bar", "1.0.0").publish(); let (bar, bar_repo) = git::new_repo("bar", |p| { p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) @@ -600,8 +598,7 @@ fn gitoxide_shallow_fetch_followed_by_non_shallow_update() -> anyhow::Result<()> } #[cargo_test] -fn gitoxide_fetch_registry_with_shallow_protocol_and_follow_up_fetch_maintains_shallowness( -) -> anyhow::Result<()> { +fn gitoxide_fetch_shallow_index_then_preserve_shallow() -> anyhow::Result<()> { Package::new("bar", "1.0.0").publish(); let p = project() .file( @@ -674,8 +671,7 @@ fn gitoxide_fetch_registry_with_shallow_protocol_and_follow_up_fetch_maintains_s /// If there is shallow *and* non-shallow fetches, non-shallow will naturally be returned due to sort order. #[cargo_test] -fn gitoxide_fetch_registry_without_shallow_protocol_and_follow_up_fetch_uses_shallowness( -) -> anyhow::Result<()> { +fn gitoxide_fetch_complete_index_then_shallow() -> anyhow::Result<()> { Package::new("bar", "1.0.0").publish(); let p = project() .file( @@ -765,8 +761,7 @@ fn gitoxide_fetch_registry_without_shallow_protocol_and_follow_up_fetch_uses_sha } #[cargo_test] -fn gitoxide_fetch_registry_with_shallow_protocol_and_aborts_and_updates_again() -> anyhow::Result<()> -{ +fn gitoxide_fetch_shallow_index_then_abort_and_update() -> anyhow::Result<()> { Package::new("bar", "1.0.0").publish(); let p = project() .file( From 2a9527be4926c75f99030d76cc6715641acf48b9 Mon Sep 17 00:00:00 2001 From: Jacob Finkelman Date: Tue, 24 Dec 2024 19:04:38 +0000 Subject: [PATCH 012/181] assert that this comparison is unneeded --- src/cargo/core/source_id.rs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/cargo/core/source_id.rs b/src/cargo/core/source_id.rs index 876d34281e9..4104cf31a6f 100644 --- a/src/cargo/core/source_id.rs +++ b/src/cargo/core/source_id.rs @@ -598,14 +598,38 @@ impl Ord for SourceId { other => return other, } - // If the `kind` and the `url` are equal, then for git sources we also - // ensure that the canonical urls are equal. + let ord = self.inner.canonical_url.cmp(&other.inner.canonical_url); + match (&self.inner.kind, &other.inner.kind) { (SourceKind::Git(_), SourceKind::Git(_)) => { - self.inner.canonical_url.cmp(&other.inner.canonical_url) + // In the pre-PR code we returned Ord here, + // so there is no chance that this commit has broken anything about this match arm. + } + _ => { + // In the pre-PR code we returned cmp of url here, so let's make sure that's the same. + assert_eq!(self.inner.url.cmp(&other.inner.url), ord); + // I am quite sure that this assert will never fire. + // In order for it to fire either `url`s are equal but `canonical_url`s are not, + // or the other way around. The algorithm for constructing a canonical URL is deterministic, + // so if it's given the same URL it will return the same canonical URL. + + // But what if we have two different URLs that canonical eyes the same? + // I assert that the second one would get thrown out when the second `SourceId` was interned. + // `SourceId::new` is the only way to make a `SourceId`. It allways construct them with + // `precise: None`. Furthermore, it uses `SourceId::wrap` to see if it has ever constructed + // a previous instance with a `SourceIdInner` that is `SourceIdInner::eq` with the one beeing added. + // `SourceIdInner::eq` only looks at `kind`, `precise`, and `canonical_url`. + // Proof by contradiction: If we had constructed two `SourceId` that: + // 1. have the same `kind` (check that a few lines ago) + // 2. have the same `precise` (as at construction time it is allways None) + // 3. have the same `canonical_url` (by the assumption of this paragraph) + // then the `ptr::eq` would return equal. Even if they were constructed with different `url`s, + // `SourceId::wrap` would have noticed that they `SourceIdInner::eq` + // and thus returned a pointer to the first one. } - _ => self.inner.url.cmp(&other.inner.url), } + + ord } } From a84336e792a9ee6e2ac81544ead50f83ff419c31 Mon Sep 17 00:00:00 2001 From: Jacob Finkelman Date: Tue, 24 Dec 2024 19:50:02 +0000 Subject: [PATCH 013/181] remove the assert for cleaner code --- src/cargo/core/source_id.rs | 41 +++---------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-) diff --git a/src/cargo/core/source_id.rs b/src/cargo/core/source_id.rs index 4104cf31a6f..d3578d98b9a 100644 --- a/src/cargo/core/source_id.rs +++ b/src/cargo/core/source_id.rs @@ -591,45 +591,10 @@ impl Ord for SourceId { return Ordering::Equal; } - // Sort first based on `kind`, deferring to the URL comparison below if + // Sort first based on `kind`, deferring to the URL comparison if // the kinds are equal. - match self.inner.kind.cmp(&other.inner.kind) { - Ordering::Equal => {} - other => return other, - } - - let ord = self.inner.canonical_url.cmp(&other.inner.canonical_url); - - match (&self.inner.kind, &other.inner.kind) { - (SourceKind::Git(_), SourceKind::Git(_)) => { - // In the pre-PR code we returned Ord here, - // so there is no chance that this commit has broken anything about this match arm. - } - _ => { - // In the pre-PR code we returned cmp of url here, so let's make sure that's the same. - assert_eq!(self.inner.url.cmp(&other.inner.url), ord); - // I am quite sure that this assert will never fire. - // In order for it to fire either `url`s are equal but `canonical_url`s are not, - // or the other way around. The algorithm for constructing a canonical URL is deterministic, - // so if it's given the same URL it will return the same canonical URL. - - // But what if we have two different URLs that canonical eyes the same? - // I assert that the second one would get thrown out when the second `SourceId` was interned. - // `SourceId::new` is the only way to make a `SourceId`. It allways construct them with - // `precise: None`. Furthermore, it uses `SourceId::wrap` to see if it has ever constructed - // a previous instance with a `SourceIdInner` that is `SourceIdInner::eq` with the one beeing added. - // `SourceIdInner::eq` only looks at `kind`, `precise`, and `canonical_url`. - // Proof by contradiction: If we had constructed two `SourceId` that: - // 1. have the same `kind` (check that a few lines ago) - // 2. have the same `precise` (as at construction time it is allways None) - // 3. have the same `canonical_url` (by the assumption of this paragraph) - // then the `ptr::eq` would return equal. Even if they were constructed with different `url`s, - // `SourceId::wrap` would have noticed that they `SourceIdInner::eq` - // and thus returned a pointer to the first one. - } - } - - ord + let ord_kind = self.inner.kind.cmp(&other.inner.kind); + ord_kind.then_with(|| self.inner.canonical_url.cmp(&other.inner.canonical_url)) } } From a014fd0814c3f513c52eb84f70949d89e681084b Mon Sep 17 00:00:00 2001 From: Lin Yihai Date: Wed, 30 Oct 2024 11:15:47 +0800 Subject: [PATCH 014/181] test: add test for `rerun-if-env-changed` custom build script. --- tests/testsuite/build_script_env.rs | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/testsuite/build_script_env.rs b/tests/testsuite/build_script_env.rs index 2c6b984b070..426c815e28c 100644 --- a/tests/testsuite/build_script_env.rs +++ b/tests/testsuite/build_script_env.rs @@ -383,3 +383,70 @@ fn rustc_cfg_with_and_without_value() { ); check.run(); } + +#[cargo_test] +fn rerun_if_env_is_exsited_config() { + let p = project() + .file("src/main.rs", "fn main() {}") + .file( + "build.rs", + r#" + fn main() { + println!("cargo::rerun-if-env-changed=FOO"); + } + "#, + ) + .file( + ".cargo/config.toml", + r#" + [env] + FOO = "foo" + "#, + ) + .build(); + + p.cargo("check") + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); + + p.cargo(r#"check --config 'env.FOO="bar"'"#) + .with_stderr_data(str![[r#" +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn rerun_if_env_newly_added_in_config() { + let p = project() + .file("src/main.rs", "fn main() {}") + .file( + "build.rs", + r#" + fn main() { + println!("cargo::rerun-if-env-changed=FOO"); + } + "#, + ) + .build(); + + p.cargo("check") + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); + + p.cargo(r#"check --config 'env.FOO="foo"'"#) + .with_stderr_data(str![[r#" +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} From 4c06c57d0dc303b2bc93a5a52f5b962cae48bbce Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 31 Dec 2024 13:24:38 -0500 Subject: [PATCH 015/181] refactor(cargo-util): one generic for each argument So `path` and `base` are able to accept different types --- crates/cargo-util/src/paths.rs | 6 +++--- src/cargo/ops/cargo_package/vcs.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/cargo-util/src/paths.rs b/crates/cargo-util/src/paths.rs index 5d7e3c5a681..cc73fbad892 100644 --- a/crates/cargo-util/src/paths.rs +++ b/crates/cargo-util/src/paths.rs @@ -710,9 +710,9 @@ pub fn set_file_time_no_err>(path: P, time: FileTime) { /// This canonicalizes both paths before stripping. This is useful if the /// paths are obtained in different ways, and one or the other may or may not /// have been normalized in some way. -pub fn strip_prefix_canonical>( - path: P, - base: P, +pub fn strip_prefix_canonical( + path: impl AsRef, + base: impl AsRef, ) -> Result { // Not all filesystems support canonicalize. Just ignore if it doesn't work. let safe_canonicalize = |path: &Path| match path.canonicalize() { diff --git a/src/cargo/ops/cargo_package/vcs.rs b/src/cargo/ops/cargo_package/vcs.rs index 3c447f32b72..990c944a6c1 100644 --- a/src/cargo/ops/cargo_package/vcs.rs +++ b/src/cargo/ops/cargo_package/vcs.rs @@ -235,11 +235,11 @@ fn dirty_metadata_paths(pkg: &Package, repo: &git2::Repository) -> CargoResult Date: Tue, 31 Dec 2024 12:40:23 -0500 Subject: [PATCH 016/181] refactor(package): simplify metadata path field report path join `abs_path` and `workdir.join(rel_path)` are the same at that point. --- src/cargo/ops/cargo_package/vcs.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/cargo/ops/cargo_package/vcs.rs b/src/cargo/ops/cargo_package/vcs.rs index 990c944a6c1..522133b94aa 100644 --- a/src/cargo/ops/cargo_package/vcs.rs +++ b/src/cargo/ops/cargo_package/vcs.rs @@ -242,12 +242,7 @@ fn dirty_metadata_paths(pkg: &Package, repo: &git2::Repository) -> CargoResult Date: Sat, 28 Dec 2024 22:42:11 -0500 Subject: [PATCH 017/181] refactor(source): preserve whether a path is under a symlink dir This is helpful for VCS status check. Paths emitted by PathSource are always under package root, We lose the track of file type info of paths under symlink dirs, so we need this extra bit of information. --- src/cargo/sources/path.rs | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index 8bafcf18099..c1e81528fbd 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -448,6 +448,8 @@ impl From for FileType { pub struct PathEntry { path: PathBuf, ty: FileType, + /// Whether this path was visited when traversing a symlink directory. + under_symlink_dir: bool, } impl PathEntry { @@ -469,10 +471,21 @@ impl PathEntry { /// Similar to [`std::path::Path::is_symlink`] /// but doesn't follow the symbolic link nor make any system call + /// + /// If the path is not a symlink but under a symlink parent directory, + /// this will return false. + /// See [`PathEntry::is_symlink_or_under_symlink`] for an alternative. pub fn is_symlink(&self) -> bool { matches!(self.ty, FileType::Symlink) } + /// Whether a path is a symlink or a path under a symlink directory. + /// + /// Use [`PathEntry::is_symlink`] to get the exact file type of the path only. + pub fn is_symlink_or_under_symlink(&self) -> bool { + self.is_symlink() || self.under_symlink_dir + } + /// Whether this path might be a plain text symlink. /// /// Git may check out symlinks as plain text files that contain the link texts, @@ -826,6 +839,9 @@ fn list_files_gix( files.push(PathEntry { path: file_path, ty, + // Git index doesn't include files from symlink diretory, + // symlink dirs are handled in `list_files_walk`. + under_symlink_dir: false, }); } } @@ -847,6 +863,10 @@ fn list_files_walk( ) -> CargoResult<()> { let walkdir = WalkDir::new(path) .follow_links(true) + // While this is the default, set it explicitly. + // We need walkdir to visit the directory tree in depth-first order, + // so we can ensure a path visited later be under a certain directory. + .contents_first(false) .into_iter() .filter_entry(|entry| { let path = entry.path(); @@ -876,10 +896,27 @@ fn list_files_walk( true }); + + let mut current_symlink_dir = None; for entry in walkdir { match entry { Ok(entry) => { let file_type = entry.file_type(); + + match current_symlink_dir.as_ref() { + Some(dir) if entry.path().starts_with(dir) => { + // Still walk under the same parent symlink dir, so keep it + } + Some(_) | None => { + // Not under any parent symlink dir, update the current one. + current_symlink_dir = if file_type.is_dir() && entry.path_is_symlink() { + Some(entry.path().to_path_buf()) + } else { + None + }; + } + } + if file_type.is_file() || file_type.is_symlink() { // We follow_links(true) here so check if entry was created from a symlink let ty = if entry.path_is_symlink() { @@ -890,6 +927,8 @@ fn list_files_walk( ret.push(PathEntry { path: entry.into_path(), ty, + // This rely on contents_first(false), which walks in depth-first order + under_symlink_dir: current_symlink_dir.is_some(), }); } } @@ -907,6 +946,7 @@ fn list_files_walk( Some(path) => ret.push(PathEntry { path: path.to_path_buf(), ty: FileType::Other, + under_symlink_dir: false, }), None => return Err(err.into()), }, From 014e516e743cc9edd567ce956304f98841c45f17 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Sun, 29 Dec 2024 01:43:43 -0500 Subject: [PATCH 018/181] test(package): symlink dirty also under dirtiness check This show that a regular file under a symlink directory is also not tarcked by the current vcs dirtiness check. --- tests/testsuite/package.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index 9c6d0493f83..7ee9433a2e3 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -1339,10 +1339,12 @@ fn dirty_file_outside_pkg_root_considered_dirty() { license-file = "../LICENSE" "#, ) + .file("original-dir/file", "before") .symlink("lib.rs", "isengard/src/lib.rs") .symlink("README.md", "isengard/README.md") .file(&main_outside_pkg_root, "fn main() {}") .symlink(&main_outside_pkg_root, "isengard/src/main.rs") + .symlink_dir("original-dir", "isengard/symlink-dir") }); git::commit(&repo); @@ -1352,6 +1354,7 @@ fn dirty_file_outside_pkg_root_considered_dirty() { // * Changes in files outside package root that source files symlink to p.change_file("README.md", "after"); p.change_file("lib.rs", "pub fn after() {}"); + p.change_file("original-dir/file", "after"); // * Changes in files outside pkg root that `license-file`/`readme` point to p.change_file("LICENSE", "after"); // * When workspace inheritance is involved and changed @@ -1388,7 +1391,7 @@ to proceed despite this and include the uncommitted changes, pass the `--allow-d p.cargo("package --workspace --no-verify --allow-dirty") .with_stderr_data(str![[r#" [PACKAGING] isengard v0.0.0 ([ROOT]/foo/isengard) -[PACKAGED] 8 files, [FILE_SIZE]B ([FILE_SIZE]B compressed) +[PACKAGED] 9 files, [FILE_SIZE]B ([FILE_SIZE]B compressed) "#]]) .run(); @@ -1411,6 +1414,7 @@ edition = "2021" "Cargo.toml.orig", "src/lib.rs", "src/main.rs", + "symlink-dir/file", "Cargo.lock", "LICENSE", "README.md", @@ -1418,6 +1422,7 @@ edition = "2021" [ ("src/lib.rs", str!["pub fn after() {}"]), ("src/main.rs", str![r#"fn main() { eprintln!("after"); }"#]), + ("symlink-dir/file", str!["after"]), ("README.md", str!["after"]), ("LICENSE", str!["after"]), ("Cargo.toml", cargo_toml), From de39f59e260eaeb7a6186da3311c8658ddf6c453 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 24 Dec 2024 00:09:17 -0500 Subject: [PATCH 019/181] fix(package): check dirtiness of symlink source files This adds a special case for checking source files are symlinks and have been modified when under a VCS control This is required because those paths may link to a file outside the current package root, but still under the git workdir, affecting the final packaged `.crate` file. This may have potential performance issue. If a package contains thousands of symlinks, Cargo will fire `git status` for each of them. --- src/cargo/ops/cargo_package/vcs.rs | 30 ++++++++++++++++++++++++++++++ tests/testsuite/package.rs | 5 ++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/cargo/ops/cargo_package/vcs.rs b/src/cargo/ops/cargo_package/vcs.rs index 522133b94aa..e007841e9e8 100644 --- a/src/cargo/ops/cargo_package/vcs.rs +++ b/src/cargo/ops/cargo_package/vcs.rs @@ -1,5 +1,6 @@ //! Helpers to gather the VCS information for `cargo package`. +use std::collections::HashSet; use std::path::Path; use std::path::PathBuf; @@ -187,6 +188,7 @@ fn git( .filter(|src_file| dirty_files.iter().any(|path| src_file.starts_with(path))) .map(|p| p.as_ref()) .chain(dirty_metadata_paths(pkg, repo)?.iter()) + .chain(dirty_symlinks(pkg, repo, src_files)?.iter()) .map(|path| { pathdiff::diff_paths(path, cwd) .as_ref() @@ -249,6 +251,34 @@ fn dirty_metadata_paths(pkg: &Package, repo: &git2::Repository) -> CargoResult CargoResult> { + let workdir = repo.workdir().unwrap(); + let mut dirty_symlinks = HashSet::new(); + for rel_path in src_files + .iter() + .filter(|p| p.is_symlink_or_under_symlink()) + .map(|p| p.as_ref().as_path()) + // If inside package root. Don't bother checking git status. + .filter(|p| paths::strip_prefix_canonical(p, pkg.root()).is_err()) + // Handle files outside package root but under git workdir, + .filter_map(|p| paths::strip_prefix_canonical(p, workdir).ok()) + { + if repo.status_file(&rel_path)? != git2::Status::CURRENT { + dirty_symlinks.insert(workdir.join(rel_path)); + } + } + Ok(dirty_symlinks) +} + /// Helper to collect dirty statuses for a single repo. fn collect_statuses(repo: &git2::Repository, dirty_files: &mut Vec) -> CargoResult<()> { let mut status_opts = git2::StatusOptions::new(); diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index 7ee9433a2e3..bb20f53e947 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -1378,10 +1378,13 @@ fn dirty_file_outside_pkg_root_considered_dirty() { p.cargo("package --workspace --no-verify") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] 2 files in the working directory contain changes that were not yet committed into git: +[ERROR] 5 files in the working directory contain changes that were not yet committed into git: LICENSE README.md +README.md +lib.rs +original-dir/file to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag From 24dd205d5a395ef9c462d1bc4599df3fb2c87f9a Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 31 Dec 2024 13:32:11 -0500 Subject: [PATCH 020/181] fix(package): deduplicate dirty symlink detection metdata path fields may point to a dirty symlilnk and cause duplicate report. This commit combines `dirty_metadata_paths` and `dirty_symlinks` into one so is able to de-duplicate them. --- src/cargo/ops/cargo_package/vcs.rs | 55 +++++++++++------------------- tests/testsuite/package.rs | 3 +- 2 files changed, 20 insertions(+), 38 deletions(-) diff --git a/src/cargo/ops/cargo_package/vcs.rs b/src/cargo/ops/cargo_package/vcs.rs index e007841e9e8..9f2f57284c4 100644 --- a/src/cargo/ops/cargo_package/vcs.rs +++ b/src/cargo/ops/cargo_package/vcs.rs @@ -1,7 +1,6 @@ //! Helpers to gather the VCS information for `cargo package`. use std::collections::HashSet; -use std::path::Path; use std::path::PathBuf; use anyhow::Context as _; @@ -187,8 +186,7 @@ fn git( .iter() .filter(|src_file| dirty_files.iter().any(|path| src_file.starts_with(path))) .map(|p| p.as_ref()) - .chain(dirty_metadata_paths(pkg, repo)?.iter()) - .chain(dirty_symlinks(pkg, repo, src_files)?.iter()) + .chain(dirty_files_outside_pkg_root(pkg, repo, src_files)?.iter()) .map(|path| { pathdiff::diff_paths(path, cwd) .as_ref() @@ -221,54 +219,39 @@ fn git( } } -/// Checks whether files at paths specified in `package.readme` and -/// `package.license-file` have been modified. +/// Checks whether "included" source files outside package root have been modified. /// -/// This is required because those paths may link to a file outside the -/// current package root, but still under the git workdir, affecting the -/// final packaged `.crate` file. -fn dirty_metadata_paths(pkg: &Package, repo: &git2::Repository) -> CargoResult> { - let mut dirty_files = Vec::new(); - let workdir = repo.workdir().unwrap(); - let root = pkg.root(); - let meta = pkg.manifest().metadata(); - for path in [&meta.license_file, &meta.readme] { - let Some(path) = path.as_deref().map(Path::new) else { - continue; - }; - let abs_path = paths::normalize_path(&root.join(path)); - if paths::strip_prefix_canonical(&abs_path, root).is_ok() { - // Inside package root. Don't bother checking git status. - continue; - } - if let Ok(rel_path) = paths::strip_prefix_canonical(&abs_path, workdir) { - // Outside package root but under git workdir, - if repo.status_file(&rel_path)? != git2::Status::CURRENT { - dirty_files.push(workdir.join(rel_path)) - } - } - } - Ok(dirty_files) -} - -/// Checks whether source files are symlinks and have been modified. +/// This currently looks at +/// +/// * `package.readme` and `package.license-file` pointing to paths outside package root +/// * symlinks targets reside outside package root /// /// This is required because those paths may link to a file outside the /// current package root, but still under the git workdir, affecting the /// final packaged `.crate` file. -fn dirty_symlinks( +fn dirty_files_outside_pkg_root( pkg: &Package, repo: &git2::Repository, src_files: &[PathEntry], ) -> CargoResult> { + let pkg_root = pkg.root(); let workdir = repo.workdir().unwrap(); + + let meta = pkg.manifest().metadata(); + let metadata_paths: Vec<_> = [&meta.license_file, &meta.readme] + .into_iter() + .filter_map(|p| p.as_deref()) + .map(|path| paths::normalize_path(&pkg_root.join(path))) + .collect(); + let mut dirty_symlinks = HashSet::new(); for rel_path in src_files .iter() .filter(|p| p.is_symlink_or_under_symlink()) - .map(|p| p.as_ref().as_path()) + .map(|p| p.as_ref()) + .chain(metadata_paths.iter()) // If inside package root. Don't bother checking git status. - .filter(|p| paths::strip_prefix_canonical(p, pkg.root()).is_err()) + .filter(|p| paths::strip_prefix_canonical(p, pkg_root).is_err()) // Handle files outside package root but under git workdir, .filter_map(|p| paths::strip_prefix_canonical(p, workdir).ok()) { diff --git a/tests/testsuite/package.rs b/tests/testsuite/package.rs index bb20f53e947..ae1c5d71024 100644 --- a/tests/testsuite/package.rs +++ b/tests/testsuite/package.rs @@ -1378,11 +1378,10 @@ fn dirty_file_outside_pkg_root_considered_dirty() { p.cargo("package --workspace --no-verify") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] 5 files in the working directory contain changes that were not yet committed into git: +[ERROR] 4 files in the working directory contain changes that were not yet committed into git: LICENSE README.md -README.md lib.rs original-dir/file From 5f42cf2873f4f8dca3b5f6bcccfc7d58726ed380 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Jan 2025 02:26:01 +0000 Subject: [PATCH 021/181] chore(deps): update alpine docker tag to v3.21 --- crates/cargo-test-support/containers/sshd/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cargo-test-support/containers/sshd/Dockerfile b/crates/cargo-test-support/containers/sshd/Dockerfile index de491fea85e..4e178d09e46 100644 --- a/crates/cargo-test-support/containers/sshd/Dockerfile +++ b/crates/cargo-test-support/containers/sshd/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.20 +FROM alpine:3.21 RUN apk add --no-cache openssh git RUN ssh-keygen -A From fb55f9b3113c981477fb59885903949b9b40d124 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Jan 2025 02:26:09 +0000 Subject: [PATCH 022/181] chore(deps): update rust crate itertools to 0.14.0 --- Cargo.lock | 10 +++++----- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ddb1eaee5b1..90e02006924 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -342,7 +342,7 @@ dependencies = [ "ignore", "im-rc", "indexmap 2.3.0", - "itertools 0.13.0", + "itertools 0.14.0", "jobserver", "lazycell", "libc", @@ -468,7 +468,7 @@ dependencies = [ "flate2", "git2", "glob", - "itertools 0.13.0", + "itertools 0.14.0", "pasetors", "regex", "serde", @@ -2183,9 +2183,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ "either", ] @@ -4285,7 +4285,7 @@ dependencies = [ "anyhow", "cargo", "clap", - "itertools 0.13.0", + "itertools 0.14.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0a73f86fdb8..7d2c5008b6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ humantime = "2.1.0" ignore = "0.4.22" im-rc = "15.1.0" indexmap = "2.2.6" -itertools = "0.13.0" +itertools = "0.14.0" jobserver = "0.1.32" lazycell = "1.3.0" libc = "0.2.155" From 3dabdcdd20d6382e7efa2c01833efa20944f3a79 Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 31 Dec 2024 21:55:45 -0500 Subject: [PATCH 023/181] perf(cargo-package): match certain path prefix with pathspec `check_repo_state` checks the entire git repo status. This is usually fine if you have only a few packages in a workspace. For huge monorepos, it may hit performance issues. For example, on awslabs/aws-sdk-rust@2cbd34d the workspace has roughly 434 members to publish. `git ls-files` reported us 204379 files in this Git repository. That means git may need to check status of all files 434 times. That would be `204379 * 434 = 88,700,486` checks! Moreover, the current algorithm is finding the intersection of `PathSource::list_files` and `git status`. It is an `O(n^2)` check. Let's assume files are evenly distributed into each package, so roughly 470 files per package. If we're unlucky to have some dirty files, say 100 files. We will have to do `470 * 100 = 47,000` times of path comparisons. Even worse, because we `git status` everything in the repo, we'll have to it for all members, even when those dirty files are not part of the current package in question. So it becomes `470 * 100 * 434 = 20,398,000`! Instead of comparing with the status of the entire repository, this patch use the magic pathspec[1] to tell git only reports paths that match a certain path prefix. This wouldn't help the `O(n^2)` algorithm, but at least it won't check dirty files outside the current package. Also, we don't `git status` against entire git worktree/index anymore. [1]: https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec --- src/cargo/ops/cargo_package/vcs.rs | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/cargo/ops/cargo_package/vcs.rs b/src/cargo/ops/cargo_package/vcs.rs index 9f2f57284c4..04d7a9d5afd 100644 --- a/src/cargo/ops/cargo_package/vcs.rs +++ b/src/cargo/ops/cargo_package/vcs.rs @@ -1,6 +1,7 @@ //! Helpers to gather the VCS information for `cargo package`. use std::collections::HashSet; +use std::path::Path; use std::path::PathBuf; use anyhow::Context as _; @@ -173,7 +174,9 @@ fn git( // - ignored (in case the user has an `include` directive that // conflicts with .gitignore). let mut dirty_files = Vec::new(); - collect_statuses(repo, &mut dirty_files)?; + let pathspec = relative_pathspec(repo, pkg.root()); + collect_statuses(repo, &[pathspec.as_str()], &mut dirty_files)?; + // Include each submodule so that the error message can provide // specifically *which* files in a submodule are modified. status_submodules(repo, &mut dirty_files)?; @@ -263,12 +266,18 @@ fn dirty_files_outside_pkg_root( } /// Helper to collect dirty statuses for a single repo. -fn collect_statuses(repo: &git2::Repository, dirty_files: &mut Vec) -> CargoResult<()> { +fn collect_statuses( + repo: &git2::Repository, + pathspecs: &[&str], + dirty_files: &mut Vec, +) -> CargoResult<()> { let mut status_opts = git2::StatusOptions::new(); // Exclude submodules, as they are being handled manually by recursing // into each one so that details about specific files can be // retrieved. - status_opts + pathspecs + .iter() + .fold(&mut status_opts, git2::StatusOptions::pathspec) .exclude_submodules(true) .include_ignored(true) .include_untracked(true); @@ -300,8 +309,16 @@ fn status_submodules(repo: &git2::Repository, dirty_files: &mut Vec) -> // If its files are required, then the verification step should fail. if let Ok(sub_repo) = submodule.open() { status_submodules(&sub_repo, dirty_files)?; - collect_statuses(&sub_repo, dirty_files)?; + collect_statuses(&sub_repo, &[], dirty_files)?; } } Ok(()) } + +/// Use pathspec so git only matches a certain path prefix +fn relative_pathspec(repo: &git2::Repository, pkg_root: &Path) -> String { + let workdir = repo.workdir().unwrap(); + let relpath = pkg_root.strip_prefix(workdir).unwrap_or(Path::new("")); + // to unix separators + relpath.to_str().unwrap().replace('\\', "/") +} From 76ffbe0571f866b3723240c720cbb11cc2f6c273 Mon Sep 17 00:00:00 2001 From: Lin Yihai Date: Wed, 30 Oct 2024 21:10:53 +0800 Subject: [PATCH 024/181] fix: envs in config can trigger rebuild by custom build script with `rerun-if-env-changed`. --- src/cargo/core/compiler/fingerprint/mod.rs | 45 +++++++++++++++------- tests/testsuite/build_script_env.rs | 2 + 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/cargo/core/compiler/fingerprint/mod.rs b/src/cargo/core/compiler/fingerprint/mod.rs index 623e4c59b60..b35a592ab11 100644 --- a/src/cargo/core/compiler/fingerprint/mod.rs +++ b/src/cargo/core/compiler/fingerprint/mod.rs @@ -374,6 +374,7 @@ mod dirty_reason; use std::collections::hash_map::{Entry, HashMap}; use std::env; +use std::ffi::OsString; use std::fs; use std::fs::File; use std::hash::{self, Hash, Hasher}; @@ -509,7 +510,7 @@ pub fn prepare_target( // thunk we can invoke on a foreign thread to calculate this. let build_script_outputs = Arc::clone(&build_runner.build_script_outputs); let metadata = build_runner.get_run_build_script_metadata(unit); - let (gen_local, _overridden) = build_script_local_fingerprints(build_runner, unit); + let (gen_local, _overridden) = build_script_local_fingerprints(build_runner, unit)?; let output_path = build_runner.build_explicit_deps[unit] .build_script_output .clone(); @@ -801,15 +802,24 @@ pub enum StaleItem { impl LocalFingerprint { /// Read the environment variable of the given env `key`, and creates a new - /// [`LocalFingerprint::RerunIfEnvChanged`] for it. + /// [`LocalFingerprint::RerunIfEnvChanged`] for it. The `env_config` is used firstly + /// to check if the env var is set in the config system as some envs need to be overridden. + /// If not, it will fallback to `std::env::var`. /// - // TODO: This is allowed at this moment. Should figure out if it makes - // sense if permitting to read env from the config system. + // TODO: `std::env::var` is allowed at this moment. Should figure out + // if it makes sense if permitting to read env from the env snapshot. #[allow(clippy::disallowed_methods)] - fn from_env>(key: K) -> LocalFingerprint { + fn from_env>( + key: K, + env_config: &Arc>, + ) -> LocalFingerprint { let key = key.as_ref(); let var = key.to_owned(); - let val = env::var(key).ok(); + let val = if let Some(val) = env_config.get(key) { + val.to_str().map(ToOwned::to_owned) + } else { + env::var(key).ok() + }; LocalFingerprint::RerunIfEnvChanged { var, val } } @@ -1577,7 +1587,7 @@ fn calculate_run_custom_build( // the build script this means we'll be watching files and env vars. // Otherwise if we haven't previously executed it we'll just start watching // the whole crate. - let (gen_local, overridden) = build_script_local_fingerprints(build_runner, unit); + let (gen_local, overridden) = build_script_local_fingerprints(build_runner, unit)?; let deps = &build_runner.build_explicit_deps[unit]; let local = (gen_local)( deps, @@ -1671,7 +1681,7 @@ See https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-change fn build_script_local_fingerprints( build_runner: &mut BuildRunner<'_, '_>, unit: &Unit, -) -> ( +) -> CargoResult<( Box< dyn FnOnce( &BuildDeps, @@ -1680,20 +1690,20 @@ fn build_script_local_fingerprints( + Send, >, bool, -) { +)> { assert!(unit.mode.is_run_custom_build()); // First up, if this build script is entirely overridden, then we just // return the hash of what we overrode it with. This is the easy case! if let Some(fingerprint) = build_script_override_fingerprint(build_runner, unit) { debug!("override local fingerprints deps {}", unit.pkg); - return ( + return Ok(( Box::new( move |_: &BuildDeps, _: Option<&dyn Fn() -> CargoResult>| { Ok(Some(vec![fingerprint])) }, ), true, // this is an overridden build script - ); + )); } // ... Otherwise this is a "real" build script and we need to return a real @@ -1705,6 +1715,7 @@ fn build_script_local_fingerprints( // obvious. let pkg_root = unit.pkg.root().to_path_buf(); let target_dir = target_root(build_runner); + let env_config = Arc::clone(build_runner.bcx.gctx.env_config()?); let calculate = move |deps: &BuildDeps, pkg_fingerprint: Option<&dyn Fn() -> CargoResult>| { if deps.rerun_if_changed.is_empty() && deps.rerun_if_env_changed.is_empty() { @@ -1734,11 +1745,16 @@ fn build_script_local_fingerprints( // Ok so now we're in "new mode" where we can have files listed as // dependencies as well as env vars listed as dependencies. Process // them all here. - Ok(Some(local_fingerprints_deps(deps, &target_dir, &pkg_root))) + Ok(Some(local_fingerprints_deps( + deps, + &target_dir, + &pkg_root, + &env_config, + ))) }; // Note that `false` == "not overridden" - (Box::new(calculate), false) + Ok((Box::new(calculate), false)) } /// Create a [`LocalFingerprint`] for an overridden build script. @@ -1769,6 +1785,7 @@ fn local_fingerprints_deps( deps: &BuildDeps, target_root: &Path, pkg_root: &Path, + env_config: &Arc>, ) -> Vec { debug!("new local fingerprints deps {:?}", pkg_root); let mut local = Vec::new(); @@ -1793,7 +1810,7 @@ fn local_fingerprints_deps( local.extend( deps.rerun_if_env_changed .iter() - .map(LocalFingerprint::from_env), + .map(|s| LocalFingerprint::from_env(s, env_config)), ); local diff --git a/tests/testsuite/build_script_env.rs b/tests/testsuite/build_script_env.rs index 426c815e28c..db48bcd8391 100644 --- a/tests/testsuite/build_script_env.rs +++ b/tests/testsuite/build_script_env.rs @@ -415,6 +415,7 @@ fn rerun_if_env_is_exsited_config() { p.cargo(r#"check --config 'env.FOO="bar"'"#) .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s "#]]) @@ -445,6 +446,7 @@ fn rerun_if_env_newly_added_in_config() { p.cargo(r#"check --config 'env.FOO="foo"'"#) .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s "#]]) From 729776b5890e3822374ef9a93152a4eccf381752 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 1 Jan 2025 10:14:31 -0600 Subject: [PATCH 025/181] fix(schema): Correct and update the JSON Schema Fixes #14999 --- .../cargo-util-schemas/manifest.schema.json | 696 +++++++++--------- crates/cargo-util-schemas/src/manifest/mod.rs | 2 +- 2 files changed, 349 insertions(+), 349 deletions(-) diff --git a/crates/cargo-util-schemas/manifest.schema.json b/crates/cargo-util-schemas/manifest.schema.json index 000f15f2300..37f84f4f792 100644 --- a/crates/cargo-util-schemas/manifest.schema.json +++ b/crates/cargo-util-schemas/manifest.schema.json @@ -33,15 +33,29 @@ } ] }, - "profile": { - "anyOf": [ - { - "$ref": "#/definitions/TomlProfiles" - }, - { - "type": "null" + "badges": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "object", + "additionalProperties": { + "type": "string" } - ] + } + }, + "features": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } }, "lib": { "anyOf": [ @@ -134,18 +148,6 @@ "$ref": "#/definitions/InheritableDependency" } }, - "features": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } - }, "target": { "type": [ "object", @@ -155,26 +157,15 @@ "$ref": "#/definitions/TomlPlatform" } }, - "replace": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "$ref": "#/definitions/TomlDependency_for_String" - } - }, - "patch": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/TomlDependency_for_String" + "lints": { + "anyOf": [ + { + "$ref": "#/definitions/InheritableLints" + }, + { + "type": "null" } - } + ] }, "workspace": { "anyOf": [ @@ -186,7 +177,17 @@ } ] }, - "badges": { + "profile": { + "anyOf": [ + { + "$ref": "#/definitions/TomlProfiles" + }, + { + "type": "null" + } + ] + }, + "patch": { "type": [ "object", "null" @@ -194,24 +195,23 @@ "additionalProperties": { "type": "object", "additionalProperties": { - "type": "string" + "$ref": "#/definitions/TomlDependency_for_String" } } }, - "lints": { - "anyOf": [ - { - "$ref": "#/definitions/InheritableLints" - }, - { - "type": "null" - } - ] + "replace": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "$ref": "#/definitions/TomlDependency_for_String" + } } }, "definitions": { "TomlPackage": { - "description": "Represents the `package`/`project` sections of a `Cargo.toml`./n/nNote that the order of the fields matters, since this is the order they are serialized to a TOML file. For example, you cannot have values after the field `metadata`, since it is a table and values cannot appear after tables.", + "description": "Represents the `package`/`project` sections of a `Cargo.toml`.\n\nNote that the order of the fields matters, since this is the order they are serialized to a TOML file. For example, you cannot have values after the field `metadata`, since it is a table and values cannot appear after tables.", "type": "object", "required": [ "name" @@ -517,7 +517,7 @@ { "description": "The type that is used when not inheriting from a workspace.", "type": "string", - "pattern": "^(0|[1-9]//d*)//.(0|[1-9]//d*)//.(0|[1-9]//d*)(?:-((?:0|[1-9]//d*|//d*[a-zA-Z-][0-9a-zA-Z-]*)(?://.(?:0|[1-9]//d*|//d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?://+([0-9a-zA-Z-]+(?://.[0-9a-zA-Z-]+)*))?$" + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" }, { "description": "The type when inheriting from a workspace.", @@ -560,7 +560,7 @@ ] }, "StringOrVec": { - "description": "A StringOrVec can be parsed from either a TOML string or array, but is always stored as a vector.", + "description": "This can be parsed from either a TOML string or array, but is always stored as a vector.", "type": "array", "items": { "type": "string" @@ -655,133 +655,94 @@ } } }, - "TomlProfiles": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/TomlProfile" - } - }, - "TomlProfile": { + "TomlTarget": { "type": "object", "properties": { - "opt-level": { - "default": null, - "anyOf": [ - { - "$ref": "#/definitions/TomlOptLevel" - }, - { - "type": "null" - } - ] - }, - "lto": { - "default": null, - "anyOf": [ - { - "$ref": "#/definitions/StringOrBool" - }, - { - "type": "null" - } - ] - }, - "codegen-backend": { - "default": null, + "name": { "type": [ "string", "null" ] }, - "codegen-units": { - "default": null, + "crate-type": { "type": [ - "integer", + "array", "null" ], - "format": "uint32", - "minimum": 0.0 + "items": { + "type": "string" + } }, - "debug": { - "default": null, - "anyOf": [ - { - "$ref": "#/definitions/TomlDebugInfo" - }, - { - "type": "null" - } + "crate_type": { + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "path": { + "type": [ + "string", + "null" ] }, - "split-debuginfo": { - "default": null, + "filename": { "type": [ "string", "null" ] }, - "debug-assertions": { - "default": null, + "test": { "type": [ "boolean", "null" ] }, - "rpath": { - "default": null, + "doctest": { "type": [ "boolean", "null" ] }, - "panic": { - "default": null, + "bench": { "type": [ - "string", + "boolean", "null" ] }, - "overflow-checks": { - "default": null, + "doc": { "type": [ "boolean", "null" ] }, - "incremental": { - "default": null, + "doc-scrape-examples": { "type": [ "boolean", "null" ] }, - "dir-name": { - "default": null, + "proc-macro": { "type": [ - "string", + "boolean", "null" ] }, - "inherits": { - "default": null, + "proc_macro": { "type": [ - "string", + "boolean", "null" ] }, - "strip": { - "default": null, - "anyOf": [ - { - "$ref": "#/definitions/StringOrBool" - }, - { - "type": "null" - } + "harness": { + "type": [ + "boolean", + "null" ] }, - "rustflags": { - "default": null, + "required-features": { "type": [ "array", "null" @@ -790,207 +751,42 @@ "type": "string" } }, - "package": { - "default": null, + "edition": { "type": [ - "object", + "string", "null" - ], - "additionalProperties": { - "$ref": "#/definitions/TomlProfile" - } - }, - "build-override": { - "default": null, - "anyOf": [ - { - "$ref": "#/definitions/TomlProfile" - }, + ] + } + } + }, + "InheritableDependency": { + "anyOf": [ + { + "description": "The type that is used when not inheriting from a workspace.", + "allOf": [ { - "type": "null" + "$ref": "#/definitions/TomlDependency_for_String" } ] }, - "trim-paths": { - "description": "Unstable feature `-Ztrim-paths`.", - "default": null, - "anyOf": [ - { - "$ref": "#/definitions/TomlTrimPaths" - }, + { + "description": "The type when inheriting from a workspace.", + "allOf": [ { - "type": "null" + "$ref": "#/definitions/TomlInheritedDependency" } ] } - } - }, - "TomlOptLevel": { - "type": "string" - }, - "TomlDebugInfo": { - "type": "string", - "enum": [ - "None", - "LineDirectivesOnly", - "LineTablesOnly", - "Limited", - "Full" - ] - }, - "TomlTrimPaths": { - "anyOf": [ - { - "type": "array", - "items": { - "$ref": "#/definitions/TomlTrimPathsValue" - } - }, - { - "type": "null" - } - ] - }, - "TomlTrimPathsValue": { - "type": "string", - "enum": [ - "diagnostics", - "macro", - "object" - ] - }, - "TomlTarget": { - "type": "object", - "properties": { - "name": { - "type": [ - "string", - "null" - ] - }, - "crate-type": { - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "crate_type": { - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "path": { - "type": [ - "string", - "null" - ] - }, - "filename": { - "type": [ - "string", - "null" - ] - }, - "test": { - "type": [ - "boolean", - "null" - ] - }, - "doctest": { - "type": [ - "boolean", - "null" - ] - }, - "bench": { - "type": [ - "boolean", - "null" - ] - }, - "doc": { - "type": [ - "boolean", - "null" - ] - }, - "doc-scrape-examples": { - "type": [ - "boolean", - "null" - ] - }, - "proc-macro": { - "type": [ - "boolean", - "null" - ] - }, - "proc_macro": { - "type": [ - "boolean", - "null" - ] - }, - "harness": { - "type": [ - "boolean", - "null" - ] - }, - "required-features": { - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - } - }, - "edition": { - "type": [ - "string", - "null" - ] - } - } - }, - "InheritableDependency": { - "anyOf": [ - { - "description": "The type that is used when not inheriting from a workspace.", - "allOf": [ - { - "$ref": "#/definitions/TomlDependency_for_String" - } - ] - }, - { - "description": "The type when inheriting from a workspace.", - "allOf": [ - { - "$ref": "#/definitions/TomlInheritedDependency" - } - ] - } - ] + ] }, "TomlDependency_for_String": { "anyOf": [ { - "description": "In the simple format, only a version is specified, eg. `package = /"/"`", + "description": "In the simple format, only a version is specified, eg. `package = \"\"`", "type": "string" }, { - "description": "The simple format is equivalent to a detailed dependency specifying only a version, eg. `package = { version = /"/" }`", + "description": "The simple format is equivalent to a detailed dependency specifying only a version, eg. `package = { version = \"\" }`", "allOf": [ { "$ref": "#/definitions/TomlDetailedDependency_for_String" @@ -1218,6 +1014,52 @@ } } }, + "InheritableLints": { + "type": "object", + "required": [ + "workspace" + ], + "properties": { + "workspace": { + "type": "boolean" + } + } + }, + "TomlLint": { + "anyOf": [ + { + "$ref": "#/definitions/TomlLintLevel" + }, + { + "$ref": "#/definitions/TomlLintConfig" + } + ] + }, + "TomlLintLevel": { + "type": "string", + "enum": [ + "forbid", + "deny", + "warn", + "allow" + ] + }, + "TomlLintConfig": { + "type": "object", + "required": [ + "level" + ], + "properties": { + "level": { + "$ref": "#/definitions/TomlLintLevel" + }, + "priority": { + "default": 0, + "type": "integer", + "format": "int8" + } + } + }, "TomlWorkspace": { "type": "object", "properties": { @@ -1306,7 +1148,7 @@ "string", "null" ], - "pattern": "^(0|[1-9]//d*)//.(0|[1-9]//d*)//.(0|[1-9]//d*)(?:-((?:0|[1-9]//d*|//d*[a-zA-Z-][0-9a-zA-Z-]*)(?://.(?:0|[1-9]//d*|//d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?://+([0-9a-zA-Z-]+(?://.[0-9a-zA-Z-]+)*))?$" + "pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$" }, "authors": { "type": [ @@ -1435,51 +1277,209 @@ } } }, - "TomlLint": { - "anyOf": [ - { - "$ref": "#/definitions/TomlLintLevel" + "TomlProfiles": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/TomlProfile" + } + }, + "TomlProfile": { + "type": "object", + "properties": { + "opt-level": { + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/TomlOptLevel" + }, + { + "type": "null" + } + ] }, - { - "$ref": "#/definitions/TomlLintConfig" + "lto": { + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/StringOrBool" + }, + { + "type": "null" + } + ] + }, + "codegen-backend": { + "default": null, + "type": [ + "string", + "null" + ] + }, + "codegen-units": { + "default": null, + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "debug": { + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/TomlDebugInfo" + }, + { + "type": "null" + } + ] + }, + "split-debuginfo": { + "default": null, + "type": [ + "string", + "null" + ] + }, + "debug-assertions": { + "default": null, + "type": [ + "boolean", + "null" + ] + }, + "rpath": { + "default": null, + "type": [ + "boolean", + "null" + ] + }, + "panic": { + "default": null, + "type": [ + "string", + "null" + ] + }, + "overflow-checks": { + "default": null, + "type": [ + "boolean", + "null" + ] + }, + "incremental": { + "default": null, + "type": [ + "boolean", + "null" + ] + }, + "dir-name": { + "default": null, + "type": [ + "string", + "null" + ] + }, + "inherits": { + "default": null, + "type": [ + "string", + "null" + ] + }, + "strip": { + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/StringOrBool" + }, + { + "type": "null" + } + ] + }, + "rustflags": { + "default": null, + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "package": { + "default": null, + "type": [ + "object", + "null" + ], + "additionalProperties": { + "$ref": "#/definitions/TomlProfile" + } + }, + "build-override": { + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/TomlProfile" + }, + { + "type": "null" + } + ] + }, + "trim-paths": { + "description": "Unstable feature `-Ztrim-paths`.", + "default": null, + "anyOf": [ + { + "$ref": "#/definitions/TomlTrimPaths" + }, + { + "type": "null" + } + ] } - ] + } }, - "TomlLintLevel": { + "TomlOptLevel": { + "type": "string" + }, + "TomlDebugInfo": { "type": "string", "enum": [ - "forbid", - "deny", - "warn", - "allow" + "None", + "LineDirectivesOnly", + "LineTablesOnly", + "Limited", + "Full" ] }, - "TomlLintConfig": { - "type": "object", - "required": [ - "level" - ], - "properties": { - "level": { - "$ref": "#/definitions/TomlLintLevel" + "TomlTrimPaths": { + "anyOf": [ + { + "type": "array", + "items": { + "$ref": "#/definitions/TomlTrimPathsValue" + } }, - "priority": { - "default": 0, - "type": "integer", - "format": "int8" + { + "type": "null" } - } + ] }, - "InheritableLints": { - "type": "object", - "required": [ - "workspace" - ], - "properties": { - "workspace": { - "type": "boolean" - } - } + "TomlTrimPathsValue": { + "type": "string", + "enum": [ + "diagnostics", + "macro", + "object" + ] } } } \ No newline at end of file diff --git a/crates/cargo-util-schemas/src/manifest/mod.rs b/crates/cargo-util-schemas/src/manifest/mod.rs index bfb23495c3e..efa125ce533 100644 --- a/crates/cargo-util-schemas/src/manifest/mod.rs +++ b/crates/cargo-util-schemas/src/manifest/mod.rs @@ -1787,5 +1787,5 @@ pub struct UnresolvedError; fn dump_manifest_schema() { let schema = schemars::schema_for!(crate::manifest::TomlManifest); let dump = serde_json::to_string_pretty(&schema).unwrap(); - snapbox::assert_data_eq!(dump, snapbox::file!("../../manifest.schema.json")); + snapbox::assert_data_eq!(dump, snapbox::file!("../../manifest.schema.json").raw()); } From 876f17d46b12b36b5ecbc40abfdad16161542095 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Wed, 1 Jan 2025 10:16:18 -0600 Subject: [PATCH 026/181] chore(ci): Ensure JSON schema gets updated --- .github/workflows/main.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9b7fa428136..5caebcee6da 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -205,6 +205,13 @@ jobs: - name: Fetch smoke test run: ci/fetch-smoke-test.sh + schema: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: rustup update stable && rustup default stable + - run: cargo test -p cargo-util-schemas -F unstable-schema + resolver: runs-on: ubuntu-latest steps: From 5465e6a451938dcf4d1e032909cfef7da1b7814c Mon Sep 17 00:00:00 2001 From: Rustin170506 Date: Tue, 17 Dec 2024 21:39:18 +0800 Subject: [PATCH 027/181] fix: remove unsupported embedded workspace check from `cargo pkgid` command Signed-off-by: Rustin170506 --- src/bin/cargo/commands/pkgid.rs | 7 ------- tests/testsuite/script.rs | 13 ++++++++++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/bin/cargo/commands/pkgid.rs b/src/bin/cargo/commands/pkgid.rs index 5fcf85b8fd9..aa98dc5c335 100644 --- a/src/bin/cargo/commands/pkgid.rs +++ b/src/bin/cargo/commands/pkgid.rs @@ -18,13 +18,6 @@ pub fn cli() -> Command { pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { let ws = args.workspace(gctx)?; - if ws.root_maybe().is_embedded() { - return Err(anyhow::format_err!( - "{} is unsupported by `cargo pkgid`", - ws.root_manifest().display() - ) - .into()); - } if args.is_present_with_zero_values("package") { print_available_packages(&ws)? } diff --git a/tests/testsuite/script.rs b/tests/testsuite/script.rs index 3c31c77f360..8db5fcc1279 100644 --- a/tests/testsuite/script.rs +++ b/tests/testsuite/script.rs @@ -1297,18 +1297,25 @@ fn cmd_verify_project_with_embedded() { .run(); } -#[cargo_test] +#[cargo_test(nightly, reason = "edition2024 hasn't hit stable yet")] fn cmd_pkgid_with_embedded() { let p = cargo_test_support::project() .file("script.rs", ECHO_SCRIPT) .build(); + p.cargo("-Zscript script.rs") + .masquerade_as_nightly_cargo(&["script"]) + .run(); + + // FIXME: It should be `path+[ROOTURL]/foo/script.rs#script@0.0.0`. p.cargo("-Zscript pkgid --manifest-path script.rs") .masquerade_as_nightly_cargo(&["script"]) - .with_status(101) + .with_stdout_data(str![[r#" +path+[ROOTURL]/foo#script@0.0.0 + +"#]]) .with_stderr_data(str![[r#" [WARNING] `package.edition` is unspecified, defaulting to `2024` -[ERROR] [ROOT]/foo/script.rs is unsupported by `cargo pkgid` "#]]) .run(); From feda97d9f27f3b70e7de266ffec05fc48cd60b23 Mon Sep 17 00:00:00 2001 From: Rustin170506 Date: Thu, 19 Dec 2024 22:33:42 +0800 Subject: [PATCH 028/181] test: add the no lock file case Signed-off-by: Rustin170506 --- tests/testsuite/script.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/testsuite/script.rs b/tests/testsuite/script.rs index 8db5fcc1279..bae2c2837ec 100644 --- a/tests/testsuite/script.rs +++ b/tests/testsuite/script.rs @@ -1321,6 +1321,23 @@ path+[ROOTURL]/foo#script@0.0.0 .run(); } +#[cargo_test] +fn cmd_pkgid_with_embedded_no_lock_file() { + let p = cargo_test_support::project() + .file("script.rs", ECHO_SCRIPT) + .build(); + + p.cargo("-Zscript pkgid --manifest-path script.rs") + .masquerade_as_nightly_cargo(&["script"]) + .with_status(101) + .with_stderr_data(str![[r#" +[WARNING] `package.edition` is unspecified, defaulting to `2024` +[ERROR] a Cargo.lock must exist for this command + +"#]]) + .run(); +} + #[cargo_test] fn cmd_package_with_embedded() { let p = cargo_test_support::project() From 0c2bb4e5a8afbeba257dbe10123823d1e0f5541c Mon Sep 17 00:00:00 2001 From: Rustin170506 Date: Thu, 19 Dec 2024 22:43:48 +0800 Subject: [PATCH 029/181] test: add the dep case Signed-off-by: Rustin170506 --- tests/testsuite/script.rs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/tests/testsuite/script.rs b/tests/testsuite/script.rs index bae2c2837ec..520ebbe556d 100644 --- a/tests/testsuite/script.rs +++ b/tests/testsuite/script.rs @@ -1338,6 +1338,39 @@ fn cmd_pkgid_with_embedded_no_lock_file() { .run(); } +#[cargo_test(nightly, reason = "edition2024 hasn't hit stable yet")] +fn cmd_pkgid_with_embedded_dep() { + Package::new("dep", "1.0.0").publish(); + let script = r#"#!/usr/bin/env cargo +--- +[dependencies] +dep = "1.0.0" +--- + +fn main() { + println!("Hello world!"); +}"#; + let p = cargo_test_support::project() + .file("script.rs", script) + .build(); + + p.cargo("-Zscript script.rs") + .masquerade_as_nightly_cargo(&["script"]) + .run(); + + p.cargo("-Zscript pkgid --manifest-path script.rs -p dep") + .masquerade_as_nightly_cargo(&["script"]) + .with_stdout_data(str![[r#" +registry+https://github.com/rust-lang/crates.io-index#dep@1.0.0 + +"#]]) + .with_stderr_data(str![[r#" +[WARNING] `package.edition` is unspecified, defaulting to `2024` + +"#]]) + .run(); +} + #[cargo_test] fn cmd_package_with_embedded() { let p = cargo_test_support::project() From 13af53a5189c5ad663b03075a37468e253589b56 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Jan 2025 03:37:26 +0000 Subject: [PATCH 030/181] chore(deps): update rust crate thiserror to v2 --- Cargo.lock | 10 +++++----- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 90e02006924..4b185db5105 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -372,7 +372,7 @@ dependencies = [ "supports-unicode", "tar", "tempfile", - "thiserror 1.0.63", + "thiserror 2.0.3", "time", "toml", "toml_edit", @@ -395,7 +395,7 @@ dependencies = [ "serde", "serde_json", "snapbox", - "thiserror 1.0.63", + "thiserror 2.0.3", "time", "windows-sys 0.59.0", ] @@ -514,7 +514,7 @@ dependencies = [ "serde-value", "serde_json", "snapbox", - "thiserror 1.0.63", + "thiserror 2.0.3", "toml", "unicode-xid", "url", @@ -711,7 +711,7 @@ dependencies = [ "percent-encoding", "serde", "serde_json", - "thiserror 1.0.63", + "thiserror 2.0.3", "url", ] @@ -3109,7 +3109,7 @@ dependencies = [ "serde_json", "similar", "tempfile", - "thiserror 1.0.63", + "thiserror 2.0.3", "tracing", "tracing-subscriber", ] diff --git a/Cargo.toml b/Cargo.toml index 7d2c5008b6c..17ecfcff0fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,7 +102,7 @@ supports-unicode = "3.0.0" snapbox = { version = "0.6.20", features = ["diff", "dir", "term-svg", "regex", "json"] } tar = { version = "0.4.42", default-features = false } tempfile = "3.10.1" -thiserror = "1.0.63" +thiserror = "2.0.0" time = { version = "0.3.36", features = ["parsing", "formatting", "serde"] } toml = "0.8.19" toml_edit = { version = "0.22.20", features = ["serde"] } From b16514de3b794a05c0c95887e90d18b330ce3882 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 2 Jan 2025 14:52:57 -0600 Subject: [PATCH 031/181] refactor(manifest): Fully qualify manifest env vars This simplifies the macro and makes the content searchable --- src/cargo/core/manifest.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 88845ff26e0..726091d55b6 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -172,23 +172,21 @@ macro_rules! metadata_envs { pub fn should_track(key: &str) -> bool { let keys = [$($key),*]; - key.strip_prefix("CARGO_PKG_") - .map(|key| keys.iter().any(|k| *k == key)) - .unwrap_or_default() + keys.iter().any(|k| *k == key) } pub fn var<'a>(meta: &'a ManifestMetadata, key: &str) -> Option> { - key.strip_prefix("CARGO_PKG_").and_then(|key| match key { + match key { $($key => Some(Self::$field(meta)),)* _ => None, - }) + } } pub fn vars(meta: &ManifestMetadata) -> impl Iterator)> { [ $( ( - concat!("CARGO_PKG_", $key), + $key, Self::$field(meta), ), )* @@ -202,14 +200,14 @@ macro_rules! metadata_envs { // If these change we need to trigger a rebuild. // NOTE: The env var name will be prefixed with `CARGO_PKG_` metadata_envs! { - (description, "DESCRIPTION"), - (homepage, "HOMEPAGE"), - (repository, "REPOSITORY"), - (license, "LICENSE"), - (license_file, "LICENSE_FILE"), - (authors, "AUTHORS", |m: &ManifestMetadata| m.authors.join(":")), - (rust_version, "RUST_VERSION", |m: &ManifestMetadata| m.rust_version.as_ref().map(ToString::to_string).unwrap_or_default()), - (readme, "README"), + (description, "CARGO_PKG_DESCRIPTION"), + (homepage, "CARGO_PKG_HOMEPAGE"), + (repository, "CARGO_PKG_REPOSITORY"), + (license, "CARGO_PKG_LICENSE"), + (license_file, "CARGO_PKG_LICENSE_FILE"), + (authors, "CARGO_PKG_AUTHORS", |m: &ManifestMetadata| m.authors.join(":")), + (rust_version, "CARGO_PKG_RUST_VERSION", |m: &ManifestMetadata| m.rust_version.as_ref().map(ToString::to_string).unwrap_or_default()), + (readme, "CARGO_PKG_README"), } impl ManifestMetadata { From 711d6bef36ceec9ac7e7f7f953ee4bc16821b266 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 2 Jan 2025 15:03:11 -0600 Subject: [PATCH 032/181] refactor(manifest): Make env macro as minimal as possible Macros add a lot of code complexity. This tries to reduce it by making the macro do the bare minimum possible. This does cause some extra branching (unless its compiled out) but that shouldn't be prohibitive. --- src/cargo/core/manifest.rs | 36 +++++++++++------------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index 726091d55b6..b1a54a8e43f 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -156,42 +156,25 @@ macro_rules! get_metadata_env { }; } +struct MetadataEnvs; + macro_rules! metadata_envs { ( $( ($field:ident, $key:literal$(, $to_var:expr)?), )* ) => { - struct MetadataEnvs; impl MetadataEnvs { - $( - fn $field(meta: &ManifestMetadata) -> Cow<'_, str> { - get_metadata_env!(meta, $field$(, $to_var)?) - } - )* - - pub fn should_track(key: &str) -> bool { - let keys = [$($key),*]; - keys.iter().any(|k| *k == key) + fn keys() -> &'static [&'static str] { + &[$($key),*] } - pub fn var<'a>(meta: &'a ManifestMetadata, key: &str) -> Option> { + fn var<'a>(meta: &'a ManifestMetadata, key: &str) -> Option> { match key { - $($key => Some(Self::$field(meta)),)* + $($key => Some(get_metadata_env!(meta, $field$(, $to_var)?)),)* _ => None, } } - - pub fn vars(meta: &ManifestMetadata) -> impl Iterator)> { - [ - $( - ( - $key, - Self::$field(meta), - ), - )* - ].into_iter() - } } } } @@ -213,7 +196,8 @@ metadata_envs! { impl ManifestMetadata { /// Whether the given env var should be tracked by Cargo's dep-info. pub fn should_track(env_key: &str) -> bool { - MetadataEnvs::should_track(env_key) + let keys = MetadataEnvs::keys(); + keys.iter().any(|k| *k == env_key) } pub fn env_var<'a>(&'a self, env_key: &str) -> Option> { @@ -221,7 +205,9 @@ impl ManifestMetadata { } pub fn env_vars(&self) -> impl Iterator)> { - MetadataEnvs::vars(self) + MetadataEnvs::keys() + .iter() + .map(|k| (*k, MetadataEnvs::var(self, k).unwrap())) } } From 0414bb5ac1bc5bf55e79c58370da984b91184ba6 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 2 Jan 2025 15:06:17 -0600 Subject: [PATCH 033/181] refactor(manifest): Keep struct/impl close for easier viewing --- src/cargo/core/manifest.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/cargo/core/manifest.rs b/src/cargo/core/manifest.rs index b1a54a8e43f..0273d8fa4d3 100644 --- a/src/cargo/core/manifest.rs +++ b/src/cargo/core/manifest.rs @@ -147,6 +147,24 @@ pub struct ManifestMetadata { pub rust_version: Option, } +impl ManifestMetadata { + /// Whether the given env var should be tracked by Cargo's dep-info. + pub fn should_track(env_key: &str) -> bool { + let keys = MetadataEnvs::keys(); + keys.iter().any(|k| *k == env_key) + } + + pub fn env_var<'a>(&'a self, env_key: &str) -> Option> { + MetadataEnvs::var(self, env_key) + } + + pub fn env_vars(&self) -> impl Iterator)> { + MetadataEnvs::keys() + .iter() + .map(|k| (*k, MetadataEnvs::var(self, k).unwrap())) + } +} + macro_rules! get_metadata_env { ($meta:ident, $field:ident) => { $meta.$field.as_deref().unwrap_or_default().into() @@ -193,24 +211,6 @@ metadata_envs! { (readme, "CARGO_PKG_README"), } -impl ManifestMetadata { - /// Whether the given env var should be tracked by Cargo's dep-info. - pub fn should_track(env_key: &str) -> bool { - let keys = MetadataEnvs::keys(); - keys.iter().any(|k| *k == env_key) - } - - pub fn env_var<'a>(&'a self, env_key: &str) -> Option> { - MetadataEnvs::var(self, env_key) - } - - pub fn env_vars(&self) -> impl Iterator)> { - MetadataEnvs::keys() - .iter() - .map(|k| (*k, MetadataEnvs::var(self, k).unwrap())) - } -} - #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] pub enum TargetKind { Lib(Vec), From 3e9b28a0d6423789f7d7eed9a5b01b634a55326e Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 3 Jan 2025 14:27:19 -0500 Subject: [PATCH 034/181] chore: bump gix-lock to remove thiserror@1 from `cargo` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Other dev tools for cargo development are fine keeping v1. They are not shipped to end users. Before ``` cargo tree --workspace -i thiserror@1.0.63 thiserror v1.0.63 ├── cargo_metadata v0.19.0 │ └── capture v0.1.0 (/projects/cargo/benches/capture) ├── gix-lock v15.0.0 │ ├── gix v0.69.1 │ │ └── cargo v0.86.0 (/projects/cargo) │ │ ├── benchsuite v0.0.0 (/projects/cargo/benches/benchsuite) │ │ ├── resolver-tests v0.0.0 (/projects/cargo/crates/resolver-tests) │ │ ├── xtask-bump-check v0.0.0 (/projects/cargo/crates/xtask-bump-check) │ │ └── xtask-lint-docs v0.1.0 (/projects/cargo/crates/xtask-lint-docs) │ │ [dev-dependencies] │ │ └── cargo v0.86.0 (/projects/cargo) (*) │ ├── gix-index v0.37.0 │ │ ├── gix v0.69.1 (*) │ │ ├── gix-dir v0.11.0 │ │ │ └── gix v0.69.1 (*) │ │ └── gix-worktree v0.38.0 │ │ ├── gix v0.69.1 (*) │ │ └── gix-dir v0.11.0 (*) │ ├── gix-protocol v0.47.0 │ │ └── gix v0.69.1 (*) │ ├── gix-ref v0.49.1 │ │ ├── gix v0.69.1 (*) │ │ ├── gix-config v0.42.0 │ │ │ ├── gix v0.69.1 (*) │ │ │ └── gix-submodule v0.16.0 │ │ │ └── gix v0.69.1 (*) │ │ ├── gix-discover v0.37.0 │ │ │ ├── gix v0.69.1 (*) │ │ │ └── gix-dir v0.11.0 (*) │ │ └── gix-protocol v0.47.0 (*) │ └── gix-shallow v0.1.0 │ ├── gix v0.69.1 (*) │ └── gix-protocol v0.47.0 (*) ├── handlebars v6.2.0 │ └── mdman v0.0.0 (/projects/cargo/crates/mdman) ├── pest v2.7.9 │ ├── handlebars v6.2.0 (*) │ ├── pest_derive v2.7.9 (proc-macro) │ │ └── handlebars v6.2.0 (*) │ ├── pest_generator v2.7.9 │ │ └── pest_derive v2.7.9 (proc-macro) (*) │ └── pest_meta v2.7.9 │ └── pest_generator v2.7.9 (*) ├── varisat v0.2.2 │ └── resolver-tests v0.0.0 (/projects/cargo/crates/resolver-tests) ├── varisat-checker v0.2.2 │ └── varisat v0.2.2 (*) └── varisat-dimacs v0.2.2 ├── varisat v0.2.2 (*) └── varisat-checker v0.2.2 (*) ``` After ``` cargo tree --workspace -i thiserror@1.0.63 thiserror v1.0.63 ├── cargo_metadata v0.19.0 │ └── capture v0.1.0 (/projects/cargo/benches/capture) ├── handlebars v6.2.0 │ └── mdman v0.0.0 (/projects/cargo/crates/mdman) ├── pest v2.7.9 │ ├── handlebars v6.2.0 (*) │ ├── pest_derive v2.7.9 (proc-macro) │ │ └── handlebars v6.2.0 (*) │ ├── pest_generator v2.7.9 │ │ └── pest_derive v2.7.9 (proc-macro) (*) │ └── pest_meta v2.7.9 │ └── pest_generator v2.7.9 (*) ├── varisat v0.2.2 │ └── resolver-tests v0.0.0 (/projects/cargo/crates/resolver-tests) ├── varisat-checker v0.2.2 │ └── varisat v0.2.2 (*) └── varisat-dimacs v0.2.2 ├── varisat v0.2.2 (*) └── varisat-checker v0.2.2 (*) ``` --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4b185db5105..68c1d24b178 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1529,13 +1529,13 @@ dependencies = [ [[package]] name = "gix-lock" -version = "15.0.0" +version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5102acdf4acae2644e38dbbd18cdfba9597a218f7d85f810fe5430207e03c2de" +checksum = "1cd3ab68a452db63d9f3ebdacb10f30dba1fa0d31ac64f4203d395ed1102d940" dependencies = [ "gix-tempfile", "gix-utils", - "thiserror 1.0.63", + "thiserror 2.0.3", ] [[package]] From 22690a32367b27910c805583025ea6fd59dc3293 Mon Sep 17 00:00:00 2001 From: Kornel Date: Sat, 4 Jan 2025 00:22:53 +0000 Subject: [PATCH 035/181] Make --allow-dirty imply --allow-staged --- src/bin/cargo/commands/fix.rs | 8 +++++--- src/cargo/ops/fix.rs | 2 +- src/doc/man/cargo-fix.md | 2 +- tests/testsuite/fix.rs | 6 +++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/bin/cargo/commands/fix.rs b/src/bin/cargo/commands/fix.rs index a4471d7b148..38bd75497a4 100644 --- a/src/bin/cargo/commands/fix.rs +++ b/src/bin/cargo/commands/fix.rs @@ -21,7 +21,7 @@ pub fn cli() -> Command { )) .arg(flag( "allow-dirty", - "Fix code even if the working directory is dirty", + "Fix code even if the working directory is dirty or has staged changes", )) .arg(flag( "allow-staged", @@ -86,6 +86,8 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { opts.filter = ops::CompileFilter::new_all_targets(); } + let allow_dirty = args.flag("allow-dirty"); + ops::fix( gctx, &ws, @@ -94,9 +96,9 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { edition: args.flag("edition"), idioms: args.flag("edition-idioms"), compile_opts: opts, - allow_dirty: args.flag("allow-dirty"), + allow_dirty, + allow_staged: allow_dirty || args.flag("allow-staged"), allow_no_vcs: args.flag("allow-no-vcs"), - allow_staged: args.flag("allow-staged"), broken_code: args.flag("broken-code"), requested_lockfile_path: lockfile_path, }, diff --git a/src/cargo/ops/fix.rs b/src/cargo/ops/fix.rs index 1530e77f48e..fdd2b33f1df 100644 --- a/src/cargo/ops/fix.rs +++ b/src/cargo/ops/fix.rs @@ -242,7 +242,7 @@ fn check_version_control(gctx: &GlobalContext, opts: &FixOptions) -> CargoResult bail!( "the working directory of this package has uncommitted changes, and \ `cargo fix` can potentially perform destructive changes; if you'd \ - like to suppress this error pass `--allow-dirty`, `--allow-staged`, \ + like to suppress this error pass `--allow-dirty`, \ or commit the changes to these files:\n\ \n\ {}\n\ diff --git a/src/doc/man/cargo-fix.md b/src/doc/man/cargo-fix.md index 2c25720db48..efb116d69a8 100644 --- a/src/doc/man/cargo-fix.md +++ b/src/doc/man/cargo-fix.md @@ -93,7 +93,7 @@ Fix code even if a VCS was not detected. {{/option}} {{#option "`--allow-dirty`" }} -Fix code even if the working directory has changes. +Fix code even if the working directory has changes (including staged changes). {{/option}} {{#option "`--allow-staged`" }} diff --git a/tests/testsuite/fix.rs b/tests/testsuite/fix.rs index f475fe5ba21..cd2de1d75d4 100644 --- a/tests/testsuite/fix.rs +++ b/tests/testsuite/fix.rs @@ -635,7 +635,7 @@ fn warns_about_dirty_working_directory() { p.cargo("fix") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] the working directory of this package has uncommitted changes, and `cargo fix` can potentially perform destructive changes; if you'd like to suppress this error pass `--allow-dirty`, `--allow-staged`, or commit the changes to these files: +[ERROR] the working directory of this package has uncommitted changes, and `cargo fix` can potentially perform destructive changes; if you'd like to suppress this error pass `--allow-dirty`, or commit the changes to these files: * src/lib.rs (dirty) @@ -656,7 +656,7 @@ fn warns_about_staged_working_directory() { p.cargo("fix") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] the working directory of this package has uncommitted changes, and `cargo fix` can potentially perform destructive changes; if you'd like to suppress this error pass `--allow-dirty`, `--allow-staged`, or commit the changes to these files: +[ERROR] the working directory of this package has uncommitted changes, and `cargo fix` can potentially perform destructive changes; if you'd like to suppress this error pass `--allow-dirty`, or commit the changes to these files: * src/lib.rs (staged) @@ -677,7 +677,7 @@ fn errors_about_untracked_files() { p.cargo("fix") .with_status(101) .with_stderr_data(str![[r#" -[ERROR] the working directory of this package has uncommitted changes, and `cargo fix` can potentially perform destructive changes; if you'd like to suppress this error pass `--allow-dirty`, `--allow-staged`, or commit the changes to these files: +[ERROR] the working directory of this package has uncommitted changes, and `cargo fix` can potentially perform destructive changes; if you'd like to suppress this error pass `--allow-dirty`, or commit the changes to these files: * Cargo.toml (dirty) * src/ (dirty) From 208f817c83f6bc93d888953564e2807074598554 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 2 Jan 2025 17:13:00 +0100 Subject: [PATCH 036/181] Add preparatory tests for `lib.test = false` check-cfg changes --- tests/testsuite/check_cfg.rs | 121 +++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/tests/testsuite/check_cfg.rs b/tests/testsuite/check_cfg.rs index 2e03254337a..0b3a8d45a91 100644 --- a/tests/testsuite/check_cfg.rs +++ b/tests/testsuite/check_cfg.rs @@ -317,6 +317,127 @@ fn well_known_names_values_doctest() { .run(); } +#[cargo_test] +fn test_false_lib() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + + [lib] + test = false + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .run(); + + p.cargo("clean").run(); + p.cargo("test -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .run(); + + p.cargo("clean").run(); + p.cargo("test --lib -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .run(); +} + +#[cargo_test] +fn test_false_bins() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + + [[bin]] + name = "daemon" + test = false + path = "src/deamon.rs" + "#, + ) + .file("src/main.rs", "fn main() {}") + .file("src/deamon.rs", "fn main() {}") + .build(); + + p.cargo("check -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) // for foo & deamon + .run(); +} + +#[cargo_test] +fn test_false_examples() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + edition = "2018" + + [lib] + test = false + + [[example]] + name = "daemon" + test = false + path = "src/deamon.rs" + "#, + ) + .file("src/lib.rs", "") + .file("src/deamon.rs", "fn main() {}") + .build(); + + p.cargo("check --examples -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .run(); +} + +#[cargo_test(nightly, reason = "bench is nightly")] +fn test_false_benches() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.0" + edition = "2018" + + [[bench]] + name = "ben1" + test = false + path = "benches/ben1.rs" + "#, + ) + .file("src/lib.rs", "") + .file( + "benches/ben1.rs", + r#" + #![feature(test)] + extern crate test; + #[bench] fn run1(_ben: &mut test::Bencher) { } + "#, + ) + .build(); + + p.cargo("bench --bench ben1 -v") + .with_stderr_contains(x!("rustc" => "cfg" of "docsrs,test")) + .run(); +} + #[cargo_test] fn features_doc() { let p = project() From 973cd5338e31ecb266c5f97df3ce8149c2f205b1 Mon Sep 17 00:00:00 2001 From: Kornel Date: Sat, 4 Jan 2025 14:37:39 +0000 Subject: [PATCH 037/181] Update autogenerated files --- src/doc/man/generated_txt/cargo-fix.txt | 3 +- src/doc/src/commands/cargo-fix.md | 2 +- src/etc/man/cargo-fix.1 | 2 +- .../testsuite/cargo_fix/help/stdout.term.svg | 110 +++++++++--------- 4 files changed, 60 insertions(+), 57 deletions(-) diff --git a/src/doc/man/generated_txt/cargo-fix.txt b/src/doc/man/generated_txt/cargo-fix.txt index 9b056183afa..f15544bfa29 100644 --- a/src/doc/man/generated_txt/cargo-fix.txt +++ b/src/doc/man/generated_txt/cargo-fix.txt @@ -84,7 +84,8 @@ OPTIONS Fix code even if a VCS was not detected. --allow-dirty - Fix code even if the working directory has changes. + Fix code even if the working directory has changes (including staged + changes). --allow-staged Fix code even if the working directory has staged changes. diff --git a/src/doc/src/commands/cargo-fix.md b/src/doc/src/commands/cargo-fix.md index eefcd8a51b9..1a05599b488 100644 --- a/src/doc/src/commands/cargo-fix.md +++ b/src/doc/src/commands/cargo-fix.md @@ -89,7 +89,7 @@ edition.
--allow-dirty
-
Fix code even if the working directory has changes.
+
Fix code even if the working directory has changes (including staged changes).
--allow-staged
diff --git a/src/etc/man/cargo-fix.1 b/src/etc/man/cargo-fix.1 index b96c1e46ad1..f9896b8025a 100644 --- a/src/etc/man/cargo-fix.1 +++ b/src/etc/man/cargo-fix.1 @@ -103,7 +103,7 @@ Fix code even if a VCS was not detected. .sp \fB\-\-allow\-dirty\fR .RS 4 -Fix code even if the working directory has changes. +Fix code even if the working directory has changes (including staged changes). .RE .sp \fB\-\-allow\-staged\fR diff --git a/tests/testsuite/cargo_fix/help/stdout.term.svg b/tests/testsuite/cargo_fix/help/stdout.term.svg index 3268041f100..1c860989650 100644 --- a/tests/testsuite/cargo_fix/help/stdout.term.svg +++ b/tests/testsuite/cargo_fix/help/stdout.term.svg @@ -1,4 +1,4 @@ - +