diff options
Diffstat (limited to 'src/tools/cargo/tests')
180 files changed, 4487 insertions, 397 deletions
diff --git a/src/tools/cargo/tests/build-std/main.rs b/src/tools/cargo/tests/build-std/main.rs index 47a4bb671..c905deb49 100644 --- a/src/tools/cargo/tests/build-std/main.rs +++ b/src/tools/cargo/tests/build-std/main.rs @@ -18,6 +18,8 @@ //! `CARGO_RUN_BUILD_STD_TESTS` env var to be set to actually run these tests. //! Otherwise the tests are skipped. +#![allow(clippy::disallowed_methods)] + use cargo_test_support::*; use std::env; use std::path::Path; @@ -227,3 +229,46 @@ fn custom_test_framework() { .build_std_arg("core") .run(); } + +// Fixing rust-lang/rust#117839. +// on macOS it never gets remapped. +// Might be a separate issue, so only run on Linux. +#[cargo_test(build_std_real)] +#[cfg(target_os = "linux")] +fn remap_path_scope() { + let p = project() + .file( + "src/main.rs", + " + fn main() { + panic!(\"remap to /rustc/<hash>\"); + } + ", + ) + .file( + ".cargo/config.toml", + " + [profile.release] + debug = \"line-tables-only\" + ", + ) + .build(); + + p.cargo("run --release -Ztrim-paths") + .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) + .env("RUST_BACKTRACE", "1") + .build_std() + .target_host() + .with_status(101) + .with_stderr_contains( + "\ +[FINISHED] release [optimized + debuginfo] [..] +[RUNNING] [..] +[..]thread '[..]' panicked at [..]src/main.rs:3:[..]", + ) + .with_stderr_contains("remap to /rustc/<hash>") + .with_stderr_contains("[..]at /rustc/[..]/library/std/src/[..]") + .with_stderr_contains("[..]at src/main.rs:3[..]") + .with_stderr_contains("[..]at /rustc/[..]/library/core/src/[..]") + .run(); +} diff --git a/src/tools/cargo/tests/testsuite/alt_registry.rs b/src/tools/cargo/tests/testsuite/alt_registry.rs index d6d7dd531..e347af1c7 100644 --- a/src/tools/cargo/tests/testsuite/alt_registry.rs +++ b/src/tools/cargo/tests/testsuite/alt_registry.rs @@ -715,7 +715,14 @@ fn bad_registry_name() { [ERROR] failed to parse manifest at `[CWD]/Cargo.toml` Caused by: - invalid character ` ` in registry name: `bad name`, [..]", + TOML parse error at line 7, column 17 + | + 7 | [dependencies.bar] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + invalid character ` ` in registry name: `bad name`, [..] + + +", ) .run(); @@ -1546,3 +1553,86 @@ or use environment variable CARGO_REGISTRY_TOKEN", ) .run(); } + +#[cargo_test] +fn config_empty_registry_name() { + let _ = RegistryBuilder::new() + .no_configure_token() + .alternative() + .build(); + let p = project() + .file("src/lib.rs", "") + .file( + ".cargo/config.toml", + "[registry.''] + ", + ) + .build(); + + p.cargo("publish") + .arg("--registry") + .arg("") + .with_status(101) + .with_stderr( + "\ +[ERROR] registry name cannot be empty", + ) + .run(); +} + +#[cargo_test] +fn empty_registry_flag() { + let p = project().file("src/lib.rs", "").build(); + + p.cargo("publish") + .arg("--registry") + .arg("") + .with_status(101) + .with_stderr( + "\ +[ERROR] registry name cannot be empty", + ) + .run(); +} + +#[cargo_test] +fn empty_dependency_registry() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + bar = { version = "0.1.0", registry = "" } + "#, + ) + .file( + "src/lib.rs", + " + extern crate bar; + pub fn f() { bar::bar(); } + ", + ) + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + TOML parse error at line 7, column 23 + | + 7 | bar = { version = \"0.1.0\", registry = \"\" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + registry name cannot be empty + + +", + ) + .run(); +} diff --git a/src/tools/cargo/tests/testsuite/artifact_dep.rs b/src/tools/cargo/tests/testsuite/artifact_dep.rs index c51298735..01b4ecf47 100644 --- a/src/tools/cargo/tests/testsuite/artifact_dep.rs +++ b/src/tools/cargo/tests/testsuite/artifact_dep.rs @@ -2167,8 +2167,11 @@ fn doc_lib_true() { p.cargo("doc -Z bindeps") .masquerade_as_nightly_cargo(&["bindeps"]) - .env("CARGO_LOG", "cargo::ops::cargo_rustc::fingerprint") - .with_stdout("") + .with_stderr( + "\ +[FINISHED] [..] +[GENERATED] [CWD]/target/doc/foo/index.html", + ) .run(); assert!(p.root().join("target/doc").is_dir()); diff --git a/src/tools/cargo/tests/testsuite/build.rs b/src/tools/cargo/tests/testsuite/build.rs index 23840ad9a..dd67161d6 100644 --- a/src/tools/cargo/tests/testsuite/build.rs +++ b/src/tools/cargo/tests/testsuite/build.rs @@ -460,7 +460,11 @@ fn cargo_compile_with_empty_package_name() { [ERROR] failed to parse manifest at `[..]` Caused by: - package name cannot be an empty string + TOML parse error at line 3, column 16 + | + 3 | name = \"\" + | ^^ + package name cannot be empty ", ) .run(); @@ -479,6 +483,10 @@ fn cargo_compile_with_invalid_package_name() { [ERROR] failed to parse manifest at `[..]` Caused by: + TOML parse error at line 3, column 16 + | + 3 | name = \"foo::bar\" + | ^^^^^^^^^^ invalid character `:` in package name: `foo::bar`, [..] ", ) @@ -760,7 +768,7 @@ fn cargo_compile_with_invalid_code() { p.cargo("build") .with_status(101) .with_stderr_contains( - "[ERROR] could not compile `foo` (bin \"foo\") due to previous error\n", + "[ERROR] could not compile `foo` (bin \"foo\") due to 1 previous error\n", ) .run(); assert!(p.root().join("Cargo.lock").is_file()); @@ -1182,7 +1190,11 @@ fn cargo_compile_with_invalid_dep_rename() { error: failed to parse manifest at `[..]` Caused by: - invalid character ` ` in dependency name: `haha this isn't a valid name 🐛`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters) + TOML parse error at line 7, column 17 + | + 7 | \"haha this isn't a valid name 🐛\" = { package = \"libc\", version = \"0.1\" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + invalid character ` ` in package name: `haha this isn't a valid name 🐛`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters) ", ) .run(); @@ -1545,6 +1557,11 @@ fn crate_env_vars() { // Verify CARGO_TARGET_TMPDIR isn't set for bins assert!(option_env!("CARGO_TARGET_TMPDIR").is_none()); + + // Verify CARGO_RUSTC_CURRENT_DIR is set for examples + let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR")); + let file_path = workspace_dir.join(file!()); + assert!(file_path.exists(), "{}", file_path.display()); } "#, ) @@ -1581,14 +1598,26 @@ fn crate_env_vars() { // Check that CARGO_TARGET_TMPDIR isn't set for lib code assert!(option_env!("CARGO_TARGET_TMPDIR").is_none()); env::var("CARGO_TARGET_TMPDIR").unwrap_err(); + + // Verify CARGO_RUSTC_CURRENT_DIR is set for examples + let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR")); + let file_path = workspace_dir.join(file!()); + assert!(file_path.exists(), "{}", file_path.display()); } #[test] - fn env() { + fn unit_env_cargo_target_tmpdir() { // Check that CARGO_TARGET_TMPDIR isn't set for unit tests assert!(option_env!("CARGO_TARGET_TMPDIR").is_none()); env::var("CARGO_TARGET_TMPDIR").unwrap_err(); } + + #[test] + fn unit_env_cargo_rustc_current_dir() { + let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR")); + let file_path = workspace_dir.join(file!()); + assert!(file_path.exists(), "{}", file_path.display()); + } "#, ) .file( @@ -1605,6 +1634,11 @@ fn crate_env_vars() { // Verify CARGO_TARGET_TMPDIR isn't set for examples assert!(option_env!("CARGO_TARGET_TMPDIR").is_none()); + + // Verify CARGO_RUSTC_CURRENT_DIR is set for examples + let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR")); + let file_path = workspace_dir.join(file!()); + assert!(file_path.exists(), "{}", file_path.display()); } "#, ) @@ -1612,9 +1646,16 @@ fn crate_env_vars() { "tests/env.rs", r#" #[test] - fn env() { + fn integration_env_cargo_target_tmpdir() { foo::check_tmpdir(option_env!("CARGO_TARGET_TMPDIR")); } + + #[test] + fn integration_env_cargo_rustc_current_dir() { + let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR")); + let file_path = workspace_dir.join(file!()); + assert!(file_path.exists(), "{}", file_path.display()); + } "#, ); @@ -1627,9 +1668,16 @@ fn crate_env_vars() { use test::Bencher; #[bench] - fn env(_: &mut Bencher) { + fn bench_env_cargo_target_tmpdir(_: &mut Bencher) { foo::check_tmpdir(option_env!("CARGO_TARGET_TMPDIR")); } + + #[test] + fn bench_env_cargo_rustc_current_dir() { + let workspace_dir = std::path::Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR")); + let file_path = workspace_dir.join(file!()); + assert!(file_path.exists(), "{}", file_path.display()); + } "#, ) .build() @@ -1638,7 +1686,9 @@ fn crate_env_vars() { }; println!("build"); - p.cargo("build -v").run(); + p.cargo("build -v") + .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"]) + .run(); println!("bin"); p.process(&p.bin("foo-bar")) @@ -1646,15 +1696,175 @@ fn crate_env_vars() { .run(); println!("example"); - p.cargo("run --example ex-env-vars -v").run(); + p.cargo("run --example ex-env-vars -v") + .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"]) + .run(); println!("test"); - p.cargo("test -v").run(); + p.cargo("test -v") + .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"]) + .run(); if is_nightly() { println!("bench"); - p.cargo("bench -v").run(); + p.cargo("bench -v") + .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"]) + .run(); + } +} + +#[cargo_test] +fn cargo_rustc_current_dir_foreign_workspace_dep() { + let foo = project() + .file( + "Cargo.toml", + r#" + [workspace] + + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + baz.path = "../baz" + baz_member.path = "../baz/baz_member" + "#, + ) + .file("src/lib.rs", "") + .build(); + let _baz = project() + .at("baz") + .file( + "Cargo.toml", + r#" + [workspace] + members = ["baz_member"] + + [package] + name = "baz" + version = "0.1.0" + "#, + ) + .file("src/lib.rs", "") + .file( + "tests/env.rs", + r#" + use std::path::Path; + + #[test] + fn baz_env() { + let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR")); + let manifest_dir = Path::new(option_env!("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR")); + let current_dir = std::env::current_dir().expect("current_dir"); + let file_path = workspace_dir.join(file!()); + assert!(file_path.exists(), "{}", file_path.display()); + let workspace_dir = std::fs::canonicalize(current_dir.join(workspace_dir)).expect("CARGO_RUSTC_CURRENT_DIR"); + let manifest_dir = std::fs::canonicalize(current_dir.join(manifest_dir)).expect("CARGO_MANIFEST_DIR"); + assert_eq!(workspace_dir, manifest_dir); + } + "#, + ) + .file( + "baz_member/Cargo.toml", + r#" + [package] + name = "baz_member" + version = "0.1.0" + authors = [] + "#, + ) + .file("baz_member/src/lib.rs", "") + .file( + "baz_member/tests/env.rs", + r#" + use std::path::Path; + + #[test] + fn baz_member_env() { + let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR")); + let file_path = workspace_dir.join(file!()); + assert!(file_path.exists(), "{}", file_path.display()); + } + "#, + ) + .build(); + + // Verify it works from a different workspace + foo.cargo("test -p baz") + .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"]) + .with_stdout_contains("running 1 test\ntest baz_env ... ok") + .run(); + foo.cargo("test -p baz_member") + .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"]) + .with_stdout_contains("running 1 test\ntest baz_member_env ... ok") + .run(); +} + +#[cargo_test] +fn cargo_rustc_current_dir_non_local_dep() { + Package::new("bar", "0.1.0") + .file( + "tests/bar_env.rs", + r#" + use std::path::Path; + + #[test] + fn bar_env() { + let workspace_dir = Path::new(option_env!("CARGO_RUSTC_CURRENT_DIR").expect("CARGO_RUSTC_CURRENT_DIR")); + let manifest_dir = Path::new(option_env!("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR")); + let current_dir = std::env::current_dir().expect("current_dir"); + let file_path = workspace_dir.join(file!()); + assert!(file_path.exists(), "{}", file_path.display()); + let workspace_dir = std::fs::canonicalize(current_dir.join(workspace_dir)).expect("CARGO_RUSTC_CURRENT_DIR"); + let manifest_dir = std::fs::canonicalize(current_dir.join(manifest_dir)).expect("CARGO_MANIFEST_DIR"); + assert_eq!(workspace_dir, manifest_dir); + } + "#, + ) + .publish(); + + let p = project() + .file("src/lib.rs", "") + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + bar = "0.1.0" + "#, + ) + .build(); + + p.cargo("test -p bar") + .masquerade_as_nightly_cargo(&["CARGO_RUSTC_CURRENT_DIR"]) + .with_stdout_contains("running 1 test\ntest bar_env ... ok") + .run(); +} + +#[cargo_test] +fn cargo_rustc_current_dir_is_not_stable() { + if is_nightly() { + return; } + let p = project() + .file( + "tests/env.rs", + r#" + use std::path::Path; + + #[test] + fn env() { + assert_eq!(option_env!("CARGO_RUSTC_CURRENT_DIR"), None); + } + "#, + ) + .build(); + + p.cargo("test").run(); } #[cargo_test] @@ -2959,12 +3169,12 @@ fn freshness_ignores_excluded() { // Smoke test to make sure it doesn't compile again println!("first pass"); - foo.cargo("build").with_stdout("").run(); + foo.cargo("build").with_stderr("[FINISHED] [..]").run(); // Modify an ignored file and make sure we don't rebuild println!("second pass"); foo.change_file("src/bar.rs", ""); - foo.cargo("build").with_stdout("").run(); + foo.cargo("build").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -3064,7 +3274,7 @@ fn recompile_space_in_name() { .build(); foo.cargo("build").run(); foo.root().move_into_the_past(); - foo.cargo("build").with_stdout("").run(); + foo.cargo("build").with_stderr("[FINISHED] [..]").run(); } #[cfg(unix)] diff --git a/src/tools/cargo/tests/testsuite/build_script.rs b/src/tools/cargo/tests/testsuite/build_script.rs index 408ce6457..f7361fcf3 100644 --- a/src/tools/cargo/tests/testsuite/build_script.rs +++ b/src/tools/cargo/tests/testsuite/build_script.rs @@ -1028,7 +1028,7 @@ versions that meet the requirements `*` are: 0.5.0 the package `a-sys` links to the native library `a`, but it conflicts with a previous package which links to `a` as well: package `foo v0.5.0 ([..])` -Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the links ='a-sys' value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links. +Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the `links = \"a\"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links. failed to select a version for `a-sys` which could resolve this conflict ").run(); @@ -1148,7 +1148,7 @@ versions that meet the requirements `*` are: 0.5.0 the package `a-sys` links to the native library `a`, but it conflicts with a previous package which links to `a` as well: package `foo v0.5.0 ([..])` -Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the links ='a-sys' value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links. +Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the `links = \"a\"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links. failed to select a version for `a-sys` which could resolve this conflict ").run(); @@ -1716,7 +1716,7 @@ fn build_deps_not_for_normal() { .with_stderr_contains("[..]can't find crate for `aaaaa`[..]") .with_stderr_contains( "\ -[ERROR] could not compile `foo` (lib) due to previous error +[ERROR] could not compile `foo` (lib) due to 1 previous error Caused by: process didn't exit successfully: [..] @@ -3245,7 +3245,6 @@ fn fresh_builds_possible_with_multiple_metadata_overrides() { .run(); p.cargo("build -v") - .env("CARGO_LOG", "cargo::ops::cargo_rustc::fingerprint=info") .with_stderr( "\ [FRESH] foo v0.5.0 ([..]) @@ -3472,7 +3471,7 @@ fn rebuild_only_on_explicit_paths() { // random other files do not affect freshness println!("run baz"); - p.change_file("baz", ""); + p.change_file("baz", "// modified"); p.cargo("build -v") .with_stderr( "\ @@ -3484,7 +3483,7 @@ fn rebuild_only_on_explicit_paths() { // but changing dependent files does println!("run foo change"); - p.change_file("foo", ""); + p.change_file("foo", "// modified"); p.cargo("build -v") .with_stderr( "\ @@ -4382,7 +4381,7 @@ versions that meet the requirements `*` are: 0.5.0 the package `a` links to the native library `a`, but it conflicts with a previous package which links to `a` as well: package `foo v0.5.0 ([..])` -Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the links ='a' value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links. +Only one package in the dependency graph may specify the same links value. This helps ensure that only one copy of a native library is linked in the final binary. Try to adjust your dependencies so that only one package uses the `links = \"a\"` value. For more information, see https://doc.rust-lang.org/cargo/reference/resolver.html#links. failed to select a version for `a` which could resolve this conflict ").run(); diff --git a/src/tools/cargo/tests/testsuite/build_script_env.rs b/src/tools/cargo/tests/testsuite/build_script_env.rs index afa2925f1..5220506a7 100644 --- a/src/tools/cargo/tests/testsuite/build_script_env.rs +++ b/src/tools/cargo/tests/testsuite/build_script_env.rs @@ -96,7 +96,7 @@ fn rerun_if_env_or_file_changes() { .with_stderr("[FINISHED] [..]") .run(); sleep_ms(1000); - p.change_file("foo", ""); + p.change_file("foo", "// modified"); p.cargo("check") .env("FOO", "bar") .with_stderr( diff --git a/src/tools/cargo/tests/testsuite/cargo_add/change_rename_target/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/change_rename_target/out/Cargo.toml index 70cd31826..bc29fac8e 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/change_rename_target/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/change_rename_target/out/Cargo.toml @@ -6,3 +6,6 @@ version = "0.0.0" [dependencies] some-package = { package = "my-package2", version = "99999.0.0", optional = true } + +[features] +some-package = ["dep:some-package"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_optional/out/primary/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_optional/out/primary/Cargo.toml index 6dd7fb6d6..38ff36eb3 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_optional/out/primary/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_optional/out/primary/Cargo.toml @@ -4,3 +4,6 @@ version = "0.0.0" [dependencies] foo = { workspace = true, optional = true } + +[features] +foo = ["dep:foo"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/Cargo.toml new file mode 100644 index 000000000..24c50556b --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] +members = ["primary", "dependency"] + +[workspace.dependencies] +foo = { version = "0.0.0", path = "./dependency"}
\ No newline at end of file diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/dependency/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/dependency/Cargo.toml new file mode 100644 index 000000000..2d247d4d2 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/dependency/Cargo.toml @@ -0,0 +1,3 @@ +[package] +name = "foo" +version = "0.0.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/dependency/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/dependency/src/lib.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/dependency/src/lib.rs diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/primary/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/primary/Cargo.toml new file mode 100644 index 000000000..b5923a106 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/primary/Cargo.toml @@ -0,0 +1,4 @@ +cargo-features = ["public-dependency"] +[package] +name = "bar" +version = "0.0.0"
\ No newline at end of file diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/primary/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/primary/src/lib.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/in/primary/src/lib.rs diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/mod.rs new file mode 100644 index 000000000..680d4c4e3 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/mod.rs @@ -0,0 +1,26 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + cargo_test_support::registry::init(); + + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("add") + .args(["foo", "-p", "bar", "--public"]) + .masquerade_as_nightly_cargo(&["public-dependency"]) + .current_dir(cwd) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/out/Cargo.toml new file mode 100644 index 000000000..24c50556b --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/out/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] +members = ["primary", "dependency"] + +[workspace.dependencies] +foo = { version = "0.0.0", path = "./dependency"}
\ No newline at end of file diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/out/dependency/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/out/dependency/Cargo.toml new file mode 100644 index 000000000..2d247d4d2 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/out/dependency/Cargo.toml @@ -0,0 +1,3 @@ +[package] +name = "foo" +version = "0.0.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/out/primary/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/out/primary/Cargo.toml new file mode 100644 index 000000000..665c6ae5e --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/out/primary/Cargo.toml @@ -0,0 +1,7 @@ +cargo-features = ["public-dependency"] +[package] +name = "bar" +version = "0.0.0" + +[dependencies] +foo = { workspace = true, public = true } diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/stderr.log new file mode 100644 index 000000000..efa1ae9fa --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/stderr.log @@ -0,0 +1 @@ + Adding foo (workspace) to public dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/stdout.log new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/detect_workspace_inherit_public/stdout.log diff --git a/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/in b/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/in new file mode 120000 index 000000000..6c6a27fcf --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/in @@ -0,0 +1 @@ +../add-basic.in
\ No newline at end of file diff --git a/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/mod.rs new file mode 100644 index 000000000..d7044ee11 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/mod.rs @@ -0,0 +1,24 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + cargo_test_support::registry::init(); + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("add") + .arg_line("@1.2.3") + .current_dir(cwd) + .assert() + .failure() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/out/Cargo.toml new file mode 100644 index 000000000..3ecdb6681 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/out/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/stderr.log new file mode 100644 index 000000000..d9547a42a --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/stderr.log @@ -0,0 +1 @@ +error: package name cannot be empty diff --git a/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/stdout.log new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/empty_dep_name/stdout.log diff --git a/src/tools/cargo/tests/testsuite/cargo_add/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/help/stdout.log index cf2a91313..d2931ae9c 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_add/help/stdout.log @@ -32,6 +32,17 @@ Options: The package will be removed from your features. + --public + Mark the dependency as public + + The dependency can be referenced in your library's public API. + + --no-public + Mark the dependency as private + + While you can use the crate in your implementation, it cannot be referenced in your public + API. + --rename <NAME> Rename the dependency @@ -45,12 +56,12 @@ Options: -n, --dry-run Don't actually write the manifest - -q, --quiet - Do not print cargo log messages - -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet + Do not print cargo log messages + --color <WHEN> Coloring: auto, always, never diff --git a/src/tools/cargo/tests/testsuite/cargo_add/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/mod.rs index e8633b0c4..653c2db94 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/mod.rs +++ b/src/tools/cargo/tests/testsuite/cargo_add/mod.rs @@ -12,10 +12,12 @@ mod deprecated_section; mod detect_workspace_inherit; mod detect_workspace_inherit_features; mod detect_workspace_inherit_optional; +mod detect_workspace_inherit_public; mod dev; mod dev_build_conflict; mod dev_prefer_existing_version; mod dry_run; +mod empty_dep_name; mod empty_dep_table; mod features; mod features_activated_over_limit; @@ -65,6 +67,7 @@ mod namever; mod no_args; mod no_default_features; mod no_optional; +mod no_public; mod offline_empty_cache; mod optional; mod overwrite_default_features; @@ -81,11 +84,16 @@ mod overwrite_no_default_features; mod overwrite_no_default_features_with_default_features; mod overwrite_no_optional; mod overwrite_no_optional_with_optional; +mod overwrite_no_public; +mod overwrite_no_public_with_public; mod overwrite_optional; mod overwrite_optional_with_no_optional; +mod overwrite_optional_with_optional; mod overwrite_path_noop; mod overwrite_path_with_version; mod overwrite_preserves_inline_table; +mod overwrite_public; +mod overwrite_public_with_no_public; mod overwrite_rename_with_no_rename; mod overwrite_rename_with_rename; mod overwrite_rename_with_rename_noop; @@ -103,6 +111,7 @@ mod preserve_dep_std_table; mod preserve_features_table; mod preserve_sorted; mod preserve_unsorted; +mod public; mod quiet; mod registry; mod rename; diff --git a/src/tools/cargo/tests/testsuite/cargo_add/no_optional/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/no_optional/mod.rs index 9145528bf..cc7e79b97 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/no_optional/mod.rs +++ b/src/tools/cargo/tests/testsuite/cargo_add/no_optional/mod.rs @@ -7,19 +7,7 @@ use cargo_test_support::curr_dir; #[cargo_test] fn case() { cargo_test_support::registry::init(); - for name in ["my-package1", "my-package2"] { - for ver in [ - "0.1.1+my-package", - "0.2.0+my-package", - "0.2.3+my-package", - "0.4.1+my-package", - "20.0.0+my-package", - "99999.0.0+my-package", - "99999.0.0-alpha.1+my-package", - ] { - cargo_test_support::registry::Package::new(name, ver).publish(); - } - } + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); let project = Project::from_template(curr_dir!().join("in")); let project_root = project.root(); @@ -27,7 +15,7 @@ fn case() { snapbox::cmd::Command::cargo_ui() .arg("add") - .arg_line("my-package1 my-package2@0.4.1 --no-optional") + .arg_line("my-package --no-optional") .current_dir(cwd) .assert() .success() diff --git a/src/tools/cargo/tests/testsuite/cargo_add/no_optional/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/no_optional/out/Cargo.toml index c5e017892..496ac8a62 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/no_optional/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/no_optional/out/Cargo.toml @@ -5,5 +5,4 @@ name = "cargo-list-test-fixture" version = "0.0.0" [dependencies] -my-package1 = "99999.0.0" -my-package2 = "0.4.1" +my-package = "0.1.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/no_optional/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/no_optional/stderr.log index fb8d4903d..8e025739f 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/no_optional/stderr.log +++ b/src/tools/cargo/tests/testsuite/cargo_add/no_optional/stderr.log @@ -1,3 +1,2 @@ Updating `dummy-registry` index - Adding my-package1 v99999.0.0 to dependencies. - Adding my-package2 v0.4.1 to dependencies. + Adding my-package v0.1.0 to dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/no_public/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/no_public/in/Cargo.toml new file mode 100644 index 000000000..e9087535b --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/no_public/in/Cargo.toml @@ -0,0 +1,6 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/no_public/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_add/no_public/in/src/lib.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/no_public/in/src/lib.rs diff --git a/src/tools/cargo/tests/testsuite/cargo_add/no_public/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/no_public/mod.rs new file mode 100644 index 000000000..912ac3fd3 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/no_public/mod.rs @@ -0,0 +1,26 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + cargo_test_support::registry::init(); + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("add") + .arg_line("my-package --no-public") + .current_dir(cwd) + .masquerade_as_nightly_cargo(&["public-dependency"]) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/src/tools/cargo/tests/testsuite/cargo_add/no_public/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/no_public/out/Cargo.toml new file mode 100644 index 000000000..b9f045116 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/no_public/out/Cargo.toml @@ -0,0 +1,9 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package = "0.1.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/no_public/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/no_public/stderr.log new file mode 100644 index 000000000..8e025739f --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/no_public/stderr.log @@ -0,0 +1,2 @@ + Updating `dummy-registry` index + Adding my-package v0.1.0 to dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/no_public/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/no_public/stdout.log new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/no_public/stdout.log diff --git a/src/tools/cargo/tests/testsuite/cargo_add/optional/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/optional/mod.rs index 408a46ed3..8daaa961d 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/optional/mod.rs +++ b/src/tools/cargo/tests/testsuite/cargo_add/optional/mod.rs @@ -7,19 +7,7 @@ use cargo_test_support::curr_dir; #[cargo_test] fn case() { cargo_test_support::registry::init(); - for name in ["my-package1", "my-package2"] { - for ver in [ - "0.1.1+my-package", - "0.2.0+my-package", - "0.2.3+my-package", - "0.4.1+my-package", - "20.0.0+my-package", - "99999.0.0+my-package", - "99999.0.0-alpha.1+my-package", - ] { - cargo_test_support::registry::Package::new(name, ver).publish(); - } - } + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); let project = Project::from_template(curr_dir!().join("in")); let project_root = project.root(); @@ -27,7 +15,7 @@ fn case() { snapbox::cmd::Command::cargo_ui() .arg("add") - .arg_line("my-package1 my-package2@0.4.1 --optional") + .arg_line("my-package --optional") .current_dir(cwd) .assert() .success() diff --git a/src/tools/cargo/tests/testsuite/cargo_add/optional/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/optional/out/Cargo.toml index eda5445c5..a8789b033 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/optional/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/optional/out/Cargo.toml @@ -5,5 +5,7 @@ name = "cargo-list-test-fixture" version = "0.0.0" [dependencies] -my-package1 = { version = "99999.0.0", optional = true } -my-package2 = { version = "0.4.1", optional = true } +my-package = { version = "0.1.0", optional = true } + +[features] +my-package = ["dep:my-package"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/optional/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/optional/stderr.log index 8cf4812cf..595ac276b 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/optional/stderr.log +++ b/src/tools/cargo/tests/testsuite/cargo_add/optional/stderr.log @@ -1,3 +1,2 @@ Updating `dummy-registry` index - Adding my-package1 v99999.0.0 to optional dependencies. - Adding my-package2 v0.4.1 to optional dependencies. + Adding my-package v0.1.0 to optional dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_git_with_path/out/primary/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_git_with_path/out/primary/Cargo.toml index ad1205481..27e6e175d 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_git_with_path/out/primary/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_git_with_path/out/primary/Cargo.toml @@ -6,3 +6,6 @@ version = "0.0.0" [dependencies] cargo-list-test-fixture-dependency = { optional = true, path = "../dependency", version = "0.0.0" } + +[features] +cargo-list-test-fixture-dependency = ["dep:cargo-list-test-fixture-dependency"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_inherit_optional_noop/out/primary/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_inherit_optional_noop/out/primary/Cargo.toml index 6dd7fb6d6..38ff36eb3 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_inherit_optional_noop/out/primary/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_inherit_optional_noop/out/primary/Cargo.toml @@ -4,3 +4,6 @@ version = "0.0.0" [dependencies] foo = { workspace = true, optional = true } + +[features] +foo = ["dep:foo"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_name_noop/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_name_noop/out/Cargo.toml index bbaf4f552..717252191 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_name_noop/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_name_noop/out/Cargo.toml @@ -7,3 +7,6 @@ version = "0.0.0" [dependencies] your-face = { version = "0.0.0", path = "dependency", optional = true, default-features = false, features = ["nose", "mouth"], registry = "alternative" } + +[features] +your-face = ["dep:your-face"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/in/Cargo.toml index c5e017892..496ac8a62 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/in/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/in/Cargo.toml @@ -5,5 +5,4 @@ name = "cargo-list-test-fixture" version = "0.0.0" [dependencies] -my-package1 = "99999.0.0" -my-package2 = "0.4.1" +my-package = "0.1.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/mod.rs index 9145528bf..cc7e79b97 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/mod.rs +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/mod.rs @@ -7,19 +7,7 @@ use cargo_test_support::curr_dir; #[cargo_test] fn case() { cargo_test_support::registry::init(); - for name in ["my-package1", "my-package2"] { - for ver in [ - "0.1.1+my-package", - "0.2.0+my-package", - "0.2.3+my-package", - "0.4.1+my-package", - "20.0.0+my-package", - "99999.0.0+my-package", - "99999.0.0-alpha.1+my-package", - ] { - cargo_test_support::registry::Package::new(name, ver).publish(); - } - } + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); let project = Project::from_template(curr_dir!().join("in")); let project_root = project.root(); @@ -27,7 +15,7 @@ fn case() { snapbox::cmd::Command::cargo_ui() .arg("add") - .arg_line("my-package1 my-package2@0.4.1 --no-optional") + .arg_line("my-package --no-optional") .current_dir(cwd) .assert() .success() diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/out/Cargo.toml index c5e017892..496ac8a62 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/out/Cargo.toml @@ -5,5 +5,4 @@ name = "cargo-list-test-fixture" version = "0.0.0" [dependencies] -my-package1 = "99999.0.0" -my-package2 = "0.4.1" +my-package = "0.1.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/stderr.log index fb8d4903d..8e025739f 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/stderr.log +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional/stderr.log @@ -1,3 +1,2 @@ Updating `dummy-registry` index - Adding my-package1 v99999.0.0 to dependencies. - Adding my-package2 v0.4.1 to dependencies. + Adding my-package v0.1.0 to dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/in/Cargo.toml index 8cd2616d4..98e2f7da1 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/in/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/in/Cargo.toml @@ -5,5 +5,4 @@ name = "cargo-list-test-fixture" version = "0.0.0" [dependencies] -my-package1 = { version = "99999.0.0", optional = false } -my-package2 = { version = "0.4.1", optional = false } +my-package = { version = "0.1.0", optional = false } diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/mod.rs index 408a46ed3..8daaa961d 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/mod.rs +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/mod.rs @@ -7,19 +7,7 @@ use cargo_test_support::curr_dir; #[cargo_test] fn case() { cargo_test_support::registry::init(); - for name in ["my-package1", "my-package2"] { - for ver in [ - "0.1.1+my-package", - "0.2.0+my-package", - "0.2.3+my-package", - "0.4.1+my-package", - "20.0.0+my-package", - "99999.0.0+my-package", - "99999.0.0-alpha.1+my-package", - ] { - cargo_test_support::registry::Package::new(name, ver).publish(); - } - } + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); let project = Project::from_template(curr_dir!().join("in")); let project_root = project.root(); @@ -27,7 +15,7 @@ fn case() { snapbox::cmd::Command::cargo_ui() .arg("add") - .arg_line("my-package1 my-package2@0.4.1 --optional") + .arg_line("my-package --optional") .current_dir(cwd) .assert() .success() diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/out/Cargo.toml index eda5445c5..a8789b033 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/out/Cargo.toml @@ -5,5 +5,7 @@ name = "cargo-list-test-fixture" version = "0.0.0" [dependencies] -my-package1 = { version = "99999.0.0", optional = true } -my-package2 = { version = "0.4.1", optional = true } +my-package = { version = "0.1.0", optional = true } + +[features] +my-package = ["dep:my-package"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/stderr.log index 8cf4812cf..595ac276b 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/stderr.log +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_optional_with_optional/stderr.log @@ -1,3 +1,2 @@ Updating `dummy-registry` index - Adding my-package1 v99999.0.0 to optional dependencies. - Adding my-package2 v0.4.1 to optional dependencies. + Adding my-package v0.1.0 to optional dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/in/Cargo.toml new file mode 100644 index 000000000..43d0d8238 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/in/Cargo.toml @@ -0,0 +1,9 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package = "0.1.0"
\ No newline at end of file diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/in/src/lib.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/in/src/lib.rs diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/mod.rs new file mode 100644 index 000000000..912ac3fd3 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/mod.rs @@ -0,0 +1,26 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + cargo_test_support::registry::init(); + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("add") + .arg_line("my-package --no-public") + .current_dir(cwd) + .masquerade_as_nightly_cargo(&["public-dependency"]) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/out/Cargo.toml new file mode 100644 index 000000000..b9f045116 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/out/Cargo.toml @@ -0,0 +1,9 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package = "0.1.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/stderr.log new file mode 100644 index 000000000..8e025739f --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/stderr.log @@ -0,0 +1,2 @@ + Updating `dummy-registry` index + Adding my-package v0.1.0 to dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/stdout.log new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public/stdout.log diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/in/Cargo.toml new file mode 100644 index 000000000..c6e61bdca --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/in/Cargo.toml @@ -0,0 +1,9 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package = { version = "0.1.0", public = false } diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/in/src/lib.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/in/src/lib.rs diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/mod.rs new file mode 100644 index 000000000..bbf8d65a6 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/mod.rs @@ -0,0 +1,26 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + cargo_test_support::registry::init(); + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("add") + .arg_line("my-package --public") + .current_dir(cwd) + .masquerade_as_nightly_cargo(&["public-dependency"]) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/out/Cargo.toml new file mode 100644 index 000000000..77fccaa6a --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/out/Cargo.toml @@ -0,0 +1,9 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package = { version = "0.1.0", public = true } diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/stderr.log new file mode 100644 index 000000000..5259bbde8 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/stderr.log @@ -0,0 +1,2 @@ + Updating `dummy-registry` index + Adding my-package v0.1.0 to public dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/stdout.log new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_no_public_with_public/stdout.log diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/in/Cargo.toml index c5e017892..496ac8a62 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/in/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/in/Cargo.toml @@ -5,5 +5,4 @@ name = "cargo-list-test-fixture" version = "0.0.0" [dependencies] -my-package1 = "99999.0.0" -my-package2 = "0.4.1" +my-package = "0.1.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/mod.rs index 408a46ed3..8daaa961d 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/mod.rs +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/mod.rs @@ -7,19 +7,7 @@ use cargo_test_support::curr_dir; #[cargo_test] fn case() { cargo_test_support::registry::init(); - for name in ["my-package1", "my-package2"] { - for ver in [ - "0.1.1+my-package", - "0.2.0+my-package", - "0.2.3+my-package", - "0.4.1+my-package", - "20.0.0+my-package", - "99999.0.0+my-package", - "99999.0.0-alpha.1+my-package", - ] { - cargo_test_support::registry::Package::new(name, ver).publish(); - } - } + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); let project = Project::from_template(curr_dir!().join("in")); let project_root = project.root(); @@ -27,7 +15,7 @@ fn case() { snapbox::cmd::Command::cargo_ui() .arg("add") - .arg_line("my-package1 my-package2@0.4.1 --optional") + .arg_line("my-package --optional") .current_dir(cwd) .assert() .success() diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/out/Cargo.toml index eda5445c5..a8789b033 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/out/Cargo.toml @@ -5,5 +5,7 @@ name = "cargo-list-test-fixture" version = "0.0.0" [dependencies] -my-package1 = { version = "99999.0.0", optional = true } -my-package2 = { version = "0.4.1", optional = true } +my-package = { version = "0.1.0", optional = true } + +[features] +my-package = ["dep:my-package"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/stderr.log index 8cf4812cf..595ac276b 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/stderr.log +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional/stderr.log @@ -1,3 +1,2 @@ Updating `dummy-registry` index - Adding my-package1 v99999.0.0 to optional dependencies. - Adding my-package2 v0.4.1 to optional dependencies. + Adding my-package v0.1.0 to optional dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/in/Cargo.toml index 5ef953209..a7722da07 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/in/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/in/Cargo.toml @@ -10,4 +10,3 @@ other = ["your-face/nose"] [dependencies] your-face = { version = "99999.0.0", optional = true } -my-package2 = { version = "0.4.1", optional = true } diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/mod.rs index 3090a7527..511b31e29 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/mod.rs +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/mod.rs @@ -7,17 +7,7 @@ use cargo_test_support::curr_dir; #[cargo_test] fn case() { cargo_test_support::registry::init(); - for ver in [ - "0.1.1+my-package", - "0.2.0+my-package", - "0.2.3+my-package", - "0.4.1+my-package", - "20.0.0+my-package", - "99999.0.0+my-package", - "99999.0.0-alpha.1+my-package", - ] { - cargo_test_support::registry::Package::new("my-package2", ver).publish(); - } + cargo_test_support::registry::Package::new("your-face", "99999.0.0+my-package") .feature("nose", &[]) .feature("mouth", &[]) @@ -31,7 +21,7 @@ fn case() { snapbox::cmd::Command::cargo_ui() .arg("add") - .arg_line("your-face my-package2@0.4.1 --no-optional") + .arg_line("your-face --no-optional") .current_dir(cwd) .assert() .success() diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/out/Cargo.toml index bf6c52963..b57286ed5 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/out/Cargo.toml @@ -10,4 +10,3 @@ other = ["your-face/nose"] [dependencies] your-face = { version = "99999.0.0" } -my-package2 = { version = "0.4.1" } diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/stderr.log index 5fe113e86..796b9601b 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/stderr.log +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_no_optional/stderr.log @@ -5,4 +5,3 @@ - eyes - mouth - nose - Adding my-package2 v0.4.1 to dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/in/Cargo.toml new file mode 100644 index 000000000..e446eca38 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/in/Cargo.toml @@ -0,0 +1,11 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package1 = { version = "99999.0.0", optional = true } + +[features] +default = ["dep:my-package1"]
\ No newline at end of file diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/in/src/lib.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/in/src/lib.rs diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/mod.rs new file mode 100644 index 000000000..434124e93 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/mod.rs @@ -0,0 +1,26 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + cargo_test_support::registry::init(); + cargo_test_support::registry::Package::new("my-package1", "99999.0.0").publish(); + + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("add") + .arg_line("my-package1 --optional") + .current_dir(cwd) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/out/Cargo.toml new file mode 100644 index 000000000..e68fcdb3c --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/out/Cargo.toml @@ -0,0 +1,11 @@ +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package1 = { version = "99999.0.0", optional = true } + +[features] +default = ["dep:my-package1"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/stderr.log new file mode 100644 index 000000000..ba9cb313d --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/stderr.log @@ -0,0 +1,2 @@ + Updating `dummy-registry` index + Adding my-package1 v99999.0.0 to optional dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/stdout.log new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_optional_with_optional/stdout.log diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_path_noop/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_path_noop/out/Cargo.toml index bbaf4f552..717252191 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_path_noop/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_path_noop/out/Cargo.toml @@ -7,3 +7,6 @@ version = "0.0.0" [dependencies] your-face = { version = "0.0.0", path = "dependency", optional = true, default-features = false, features = ["nose", "mouth"], registry = "alternative" } + +[features] +your-face = ["dep:your-face"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_path_with_version/out/primary/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_path_with_version/out/primary/Cargo.toml index a20f2095d..c45f79491 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_path_with_version/out/primary/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_path_with_version/out/primary/Cargo.toml @@ -6,3 +6,6 @@ version = "0.0.0" [dependencies] cargo-list-test-fixture-dependency = { optional = true, version = "20.0" } + +[features] +cargo-list-test-fixture-dependency = ["dep:cargo-list-test-fixture-dependency"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/in/Cargo.toml new file mode 100644 index 000000000..43d0d8238 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/in/Cargo.toml @@ -0,0 +1,9 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package = "0.1.0"
\ No newline at end of file diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/in/src/lib.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/in/src/lib.rs diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/mod.rs new file mode 100644 index 000000000..bbf8d65a6 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/mod.rs @@ -0,0 +1,26 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + cargo_test_support::registry::init(); + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("add") + .arg_line("my-package --public") + .current_dir(cwd) + .masquerade_as_nightly_cargo(&["public-dependency"]) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/out/Cargo.toml new file mode 100644 index 000000000..77fccaa6a --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/out/Cargo.toml @@ -0,0 +1,9 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package = { version = "0.1.0", public = true } diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/stderr.log new file mode 100644 index 000000000..5259bbde8 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/stderr.log @@ -0,0 +1,2 @@ + Updating `dummy-registry` index + Adding my-package v0.1.0 to public dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/stdout.log new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public/stdout.log diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/in/Cargo.toml new file mode 100644 index 000000000..cc7ec1a9b --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/in/Cargo.toml @@ -0,0 +1,9 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package = { version = "0.1.0", public = true }
\ No newline at end of file diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/in/src/lib.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/in/src/lib.rs diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/mod.rs new file mode 100644 index 000000000..912ac3fd3 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/mod.rs @@ -0,0 +1,26 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + cargo_test_support::registry::init(); + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("add") + .arg_line("my-package --no-public") + .current_dir(cwd) + .masquerade_as_nightly_cargo(&["public-dependency"]) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/out/Cargo.toml new file mode 100644 index 000000000..cfa80cc13 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/out/Cargo.toml @@ -0,0 +1,9 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package = { version = "0.1.0" } diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/stderr.log new file mode 100644 index 000000000..8e025739f --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/stderr.log @@ -0,0 +1,2 @@ + Updating `dummy-registry` index + Adding my-package v0.1.0 to dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/stdout.log new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_public_with_no_public/stdout.log diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_rename_with_rename_noop/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_rename_with_rename_noop/out/Cargo.toml index 450229245..0217d4176 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_rename_with_rename_noop/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_rename_with_rename_noop/out/Cargo.toml @@ -6,3 +6,6 @@ version = "0.0.0" [dependencies] a1 = { package = "versioned-package", version = "0.1.1", optional = true } + +[features] +a1 = ["dep:a1"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_version_with_git/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_version_with_git/out/Cargo.toml index 260014024..a3eabd065 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_version_with_git/out/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_version_with_git/out/Cargo.toml @@ -6,3 +6,6 @@ version = "0.0.0" [dependencies] versioned-package = { version = "0.3.0", optional = true, git = "[ROOTURL]/versioned-package" } + +[features] +versioned-package = ["dep:versioned-package"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_version_with_path/out/primary/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_version_with_path/out/primary/Cargo.toml index 07253670a..bd460a11b 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/overwrite_version_with_path/out/primary/Cargo.toml +++ b/src/tools/cargo/tests/testsuite/cargo_add/overwrite_version_with_path/out/primary/Cargo.toml @@ -6,3 +6,6 @@ version = "0.0.0" [dependencies] cargo-list-test-fixture-dependency = { version = "0.0.0", optional = true, path = "../dependency" } + +[features] +cargo-list-test-fixture-dependency = ["dep:cargo-list-test-fixture-dependency"] diff --git a/src/tools/cargo/tests/testsuite/cargo_add/public/in/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/public/in/Cargo.toml new file mode 100644 index 000000000..e9087535b --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/public/in/Cargo.toml @@ -0,0 +1,6 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" diff --git a/src/tools/cargo/tests/testsuite/cargo_add/public/in/src/lib.rs b/src/tools/cargo/tests/testsuite/cargo_add/public/in/src/lib.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/public/in/src/lib.rs diff --git a/src/tools/cargo/tests/testsuite/cargo_add/public/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/public/mod.rs new file mode 100644 index 000000000..bbf8d65a6 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/public/mod.rs @@ -0,0 +1,26 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::prelude::*; +use cargo_test_support::Project; + +use cargo_test_support::curr_dir; + +#[cargo_test] +fn case() { + cargo_test_support::registry::init(); + cargo_test_support::registry::Package::new("my-package", "0.1.0").publish(); + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("add") + .arg_line("my-package --public") + .current_dir(cwd) + .masquerade_as_nightly_cargo(&["public-dependency"]) + .assert() + .success() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/src/tools/cargo/tests/testsuite/cargo_add/public/out/Cargo.toml b/src/tools/cargo/tests/testsuite/cargo_add/public/out/Cargo.toml new file mode 100644 index 000000000..77fccaa6a --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/public/out/Cargo.toml @@ -0,0 +1,9 @@ +cargo-features = ["public-dependency"] +[workspace] + +[package] +name = "cargo-list-test-fixture" +version = "0.0.0" + +[dependencies] +my-package = { version = "0.1.0", public = true } diff --git a/src/tools/cargo/tests/testsuite/cargo_add/public/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/public/stderr.log new file mode 100644 index 000000000..5259bbde8 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/public/stderr.log @@ -0,0 +1,2 @@ + Updating `dummy-registry` index + Adding my-package v0.1.0 to public dependencies. diff --git a/src/tools/cargo/tests/testsuite/cargo_add/public/stdout.log b/src/tools/cargo/tests/testsuite/cargo_add/public/stdout.log new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_add/public/stdout.log diff --git a/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/mod.rs b/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/mod.rs index f8aac0ad8..0404d12b4 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/mod.rs +++ b/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/mod.rs @@ -26,7 +26,7 @@ fn case() { .current_dir(cwd) .masquerade_as_nightly_cargo(&["msrv-policy"]) .assert() - .code(101) + .code(0) .stdout_matches_path(curr_dir!().join("stdout.log")) .stderr_matches_path(curr_dir!().join("stderr.log")); diff --git a/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/stderr.log b/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/stderr.log index 96bcbddc2..430abe31b 100644 --- a/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/stderr.log +++ b/src/tools/cargo/tests/testsuite/cargo_add/rust_version_ignore/stderr.log @@ -1,7 +1,2 @@ Updating `dummy-registry` index Adding rust-version-user v0.2.1 to dependencies. -error: failed to select a version for the requirement `rust-version-user = "^0.2.1"` -candidate versions found which didn't match: 0.2.1, 0.1.0 -location searched: `dummy-registry` index (which is replacing registry `crates-io`) -required by package `cargo-list-test-fixture v0.0.0 ([ROOT]/case)` -perhaps a crate was updated and forgotten to be re-vendored? diff --git a/src/tools/cargo/tests/testsuite/cargo_bench/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_bench/help/stdout.log index 95546b4a3..cfea6e01e 100644 --- a/src/tools/cargo/tests/testsuite/cargo_bench/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_bench/help/stdout.log @@ -11,8 +11,8 @@ Options: --no-fail-fast Run all benchmarks regardless of failure --ignore-rust-version Ignore `rust-version` specification in packages --message-format <FMT> Error format - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_build/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_build/help/stdout.log index 58b12cdcd..3918fd44a 100644 --- a/src/tools/cargo/tests/testsuite/cargo_build/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_build/help/stdout.log @@ -6,8 +6,8 @@ Options: --ignore-rust-version Ignore `rust-version` specification in packages --future-incompat-report Outputs a future incompatibility report at the end of the build --message-format <FMT> Error format - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_check/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_check/help/stdout.log index bbf090d1d..7b6289798 100644 --- a/src/tools/cargo/tests/testsuite/cargo_check/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_check/help/stdout.log @@ -6,8 +6,8 @@ Options: --ignore-rust-version Ignore `rust-version` specification in packages --future-incompat-report Outputs a future incompatibility report at the end of the build --message-format <FMT> Error format - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_clean/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_clean/help/stdout.log index 6e9e82772..80571e5dc 100644 --- a/src/tools/cargo/tests/testsuite/cargo_clean/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_clean/help/stdout.log @@ -4,9 +4,9 @@ Usage: cargo[EXE] clean [OPTIONS] Options: --doc Whether or not to clean just the documentation directory - -q, --quiet Do not print cargo log messages -n, --dry-run Display what would be deleted without deleting anything -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_config/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_config/help/stdout.log index 50caca72a..5c14335fc 100644 --- a/src/tools/cargo/tests/testsuite/cargo_config/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_config/help/stdout.log @@ -7,6 +7,7 @@ Commands: Options: -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_doc/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_doc/help/stdout.log index 8ff5f9b72..e1a19bedd 100644 --- a/src/tools/cargo/tests/testsuite/cargo_doc/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_doc/help/stdout.log @@ -8,8 +8,8 @@ Options: --document-private-items Document private items --ignore-rust-version Ignore `rust-version` specification in packages --message-format <FMT> Error format - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_features.rs b/src/tools/cargo/tests/testsuite/cargo_features.rs index d319ed686..8b7daa214 100644 --- a/src/tools/cargo/tests/testsuite/cargo_features.rs +++ b/src/tools/cargo/tests/testsuite/cargo_features.rs @@ -296,7 +296,7 @@ fn allow_features_to_rustc() { "src/lib.rs", r#" #![allow(internal_features)] - #![feature(test_2018_feature)] + #![feature(rustc_attrs)] "#, ) .build(); @@ -307,7 +307,7 @@ fn allow_features_to_rustc() { .with_stderr_contains("[..]E0725[..]") .run(); - p.cargo("-Zallow-features=test_2018_feature check") + p.cargo("-Zallow-features=rustc_attrs check") .masquerade_as_nightly_cargo(&["allow-features"]) .with_stderr( "\ diff --git a/src/tools/cargo/tests/testsuite/cargo_fetch/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_fetch/help/stdout.log index 32f29f1b3..5645a6c03 100644 --- a/src/tools/cargo/tests/testsuite/cargo_fetch/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_fetch/help/stdout.log @@ -3,8 +3,8 @@ Fetch dependencies of a package from the network Usage: cargo[EXE] fetch [OPTIONS] Options: - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_fix/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_fix/help/stdout.log index 3e8b1427f..a93215c50 100644 --- a/src/tools/cargo/tests/testsuite/cargo_fix/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_fix/help/stdout.log @@ -11,8 +11,8 @@ Options: --allow-staged Fix code even if the working directory has staged changes --ignore-rust-version Ignore `rust-version` specification in packages --message-format <FMT> Error format - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_generate_lockfile/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_generate_lockfile/help/stdout.log index 07eff888a..5d0bf1359 100644 --- a/src/tools/cargo/tests/testsuite/cargo_generate_lockfile/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_generate_lockfile/help/stdout.log @@ -3,8 +3,8 @@ Generate the lockfile for a package Usage: cargo[EXE] generate-lockfile [OPTIONS] Options: - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_help/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_help/help/stdout.log index a03946b45..1f7a710d6 100644 --- a/src/tools/cargo/tests/testsuite/cargo_help/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_help/help/stdout.log @@ -7,6 +7,7 @@ Arguments: Options: -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_init/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_init/help/stdout.log index 588b45ccf..197a5f8d1 100644 --- a/src/tools/cargo/tests/testsuite/cargo_init/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_init/help/stdout.log @@ -15,8 +15,8 @@ Options: 2021, 2024] --name <NAME> Set the resulting package name, defaults to the directory name --registry <REGISTRY> Registry to use - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_install/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_install/help/stdout.log index 5e3458d37..baaba7a72 100644 --- a/src/tools/cargo/tests/testsuite/cargo_install/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_install/help/stdout.log @@ -20,9 +20,9 @@ Options: --list list all installed packages and their versions --ignore-rust-version Ignore `rust-version` specification in packages --message-format <FMT> Error format - -q, --quiet Do not print cargo log messages --debug Build in debug mode (with the 'dev' profile) instead of release mode -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_locate_project/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_locate_project/help/stdout.log index 1c6ea7b25..f39d61b7a 100644 --- a/src/tools/cargo/tests/testsuite/cargo_locate_project/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_locate_project/help/stdout.log @@ -5,8 +5,8 @@ Usage: cargo[EXE] locate-project [OPTIONS] Options: --workspace Locate Cargo.toml of the workspace root --message-format <FMT> Output representation [possible values: json, plain] - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_login/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_login/help/stdout.log index e0d5e7e69..0a699f72f 100644 --- a/src/tools/cargo/tests/testsuite/cargo_login/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_login/help/stdout.log @@ -8,8 +8,8 @@ Arguments: Options: --registry <REGISTRY> Registry to use - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_logout/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_logout/help/stdout.log index fe328d765..3f9679f9b 100644 --- a/src/tools/cargo/tests/testsuite/cargo_logout/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_logout/help/stdout.log @@ -4,8 +4,8 @@ Usage: cargo[EXE] logout [OPTIONS] Options: --registry <REGISTRY> Registry to use - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_metadata/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_metadata/help/stdout.log index 939fc40c9..f44f66c88 100644 --- a/src/tools/cargo/tests/testsuite/cargo_metadata/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_metadata/help/stdout.log @@ -8,8 +8,8 @@ Options: --no-deps Output information only about the workspace members and don't fetch dependencies --format-version <VERSION> Format version [possible values: 1] - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_new/empty_name/in/.keep b/src/tools/cargo/tests/testsuite/cargo_new/empty_name/in/.keep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_new/empty_name/in/.keep diff --git a/src/tools/cargo/tests/testsuite/cargo_new/empty_name/mod.rs b/src/tools/cargo/tests/testsuite/cargo_new/empty_name/mod.rs new file mode 100644 index 000000000..a7d56630f --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_new/empty_name/mod.rs @@ -0,0 +1,22 @@ +use cargo_test_support::compare::assert_ui; +use cargo_test_support::curr_dir; +use cargo_test_support::CargoCommand; +use cargo_test_support::Project; + +#[cargo_test] +fn case() { + let project = Project::from_template(curr_dir!().join("in")); + let project_root = project.root(); + let cwd = &project_root; + + snapbox::cmd::Command::cargo_ui() + .arg("new") + .args(["foo", "--name", ""]) + .current_dir(cwd) + .assert() + .failure() + .stdout_matches_path(curr_dir!().join("stdout.log")) + .stderr_matches_path(curr_dir!().join("stderr.log")); + + assert_ui().subset_matches(curr_dir!().join("out"), &project_root); +} diff --git a/src/tools/cargo/tests/testsuite/cargo_new/empty_name/out/.keep b/src/tools/cargo/tests/testsuite/cargo_new/empty_name/out/.keep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_new/empty_name/out/.keep diff --git a/src/tools/cargo/tests/testsuite/cargo_new/empty_name/stderr.log b/src/tools/cargo/tests/testsuite/cargo_new/empty_name/stderr.log new file mode 100644 index 000000000..d9547a42a --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_new/empty_name/stderr.log @@ -0,0 +1 @@ +error: package name cannot be empty diff --git a/src/tools/cargo/tests/testsuite/cargo_new/empty_name/stdout.log b/src/tools/cargo/tests/testsuite/cargo_new/empty_name/stdout.log new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/tools/cargo/tests/testsuite/cargo_new/empty_name/stdout.log diff --git a/src/tools/cargo/tests/testsuite/cargo_new/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_new/help/stdout.log index 3df5eceb8..52a6f83a1 100644 --- a/src/tools/cargo/tests/testsuite/cargo_new/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_new/help/stdout.log @@ -15,8 +15,8 @@ Options: 2021, 2024] --name <NAME> Set the resulting package name, defaults to the directory name --registry <REGISTRY> Registry to use - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_new/mod.rs b/src/tools/cargo/tests/testsuite/cargo_new/mod.rs index da0304409..806bd2ec3 100644 --- a/src/tools/cargo/tests/testsuite/cargo_new/mod.rs +++ b/src/tools/cargo/tests/testsuite/cargo_new/mod.rs @@ -4,6 +4,7 @@ mod add_members_to_workspace_with_absolute_package_path; mod add_members_to_workspace_with_empty_members; mod add_members_to_workspace_with_exclude_list; mod add_members_to_workspace_with_members_glob; +mod empty_name; mod help; mod inherit_workspace_lints; mod inherit_workspace_package_table; diff --git a/src/tools/cargo/tests/testsuite/cargo_owner/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_owner/help/stdout.log index 110df8e9a..b6f436d04 100644 --- a/src/tools/cargo/tests/testsuite/cargo_owner/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_owner/help/stdout.log @@ -12,8 +12,8 @@ Options: --index <INDEX> Registry index URL to modify owners for --registry <REGISTRY> Registry to modify owners for --token <TOKEN> API token to use when authenticating - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_package/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_package/help/stdout.log index 5079c2a6f..ec2464a8d 100644 --- a/src/tools/cargo/tests/testsuite/cargo_package/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_package/help/stdout.log @@ -7,8 +7,8 @@ Options: --no-verify Don't verify the contents by building them --no-metadata Ignore warnings about a lack of human-usable metadata --allow-dirty Allow dirty working directories to be packaged - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_pkgid/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_pkgid/help/stdout.log index 5971e88dc..657bb9e5d 100644 --- a/src/tools/cargo/tests/testsuite/cargo_pkgid/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_pkgid/help/stdout.log @@ -6,8 +6,8 @@ Arguments: [SPEC] Options: - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_publish/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_publish/help/stdout.log index df2594fb4..d598c93d6 100644 --- a/src/tools/cargo/tests/testsuite/cargo_publish/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_publish/help/stdout.log @@ -9,8 +9,8 @@ Options: --token <TOKEN> Token to use when uploading --no-verify Don't verify the contents by building them --allow-dirty Allow dirty working directories to be packaged - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_read_manifest/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_read_manifest/help/stdout.log index 83db5413d..a645ea3c2 100644 --- a/src/tools/cargo/tests/testsuite/cargo_read_manifest/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_read_manifest/help/stdout.log @@ -5,8 +5,8 @@ Deprecated, use `cargo metadata --no-deps` instead. Usage: cargo[EXE] read-manifest [OPTIONS] Options: - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_remove/help/stdout.log index 47d2c87ad..c3dc74b2d 100644 --- a/src/tools/cargo/tests/testsuite/cargo_remove/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_remove/help/stdout.log @@ -7,8 +7,8 @@ Arguments: Options: -n, --dry-run Don't actually write the manifest - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/update_lock_file/in/Cargo.lock b/src/tools/cargo/tests/testsuite/cargo_remove/update_lock_file/in/Cargo.lock index 06c2052d5..2302220f2 100644 --- a/src/tools/cargo/tests/testsuite/cargo_remove/update_lock_file/in/Cargo.lock +++ b/src/tools/cargo/tests/testsuite/cargo_remove/update_lock_file/in/Cargo.lock @@ -43,13 +43,13 @@ checksum = "31162e7d23a085553c42dee375787b451a481275473f7779c4a63bcc267a24fd" name = "semver" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3031434e07edc922bf1b8262f075fac1522694f17b1ee7ad314c4cabd5d2723f" +checksum = "106bee742e3199d9e59f4269e458dfc825c1b4648c483b1c2b7a45cd2610a308" [[package]] name = "serde" version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75d9264696ebbf5315a6b068e9910c4df9274365afac2d88abf66525df660218" +checksum = "be7d269f612a60e3c2c4a4a120e2d878a3f3298a5285eda6e95453905a107d9a" [[package]] name = "toml" diff --git a/src/tools/cargo/tests/testsuite/cargo_remove/update_lock_file/out/Cargo.lock b/src/tools/cargo/tests/testsuite/cargo_remove/update_lock_file/out/Cargo.lock index bd8c90f46..0946cee47 100644 --- a/src/tools/cargo/tests/testsuite/cargo_remove/update_lock_file/out/Cargo.lock +++ b/src/tools/cargo/tests/testsuite/cargo_remove/update_lock_file/out/Cargo.lock @@ -36,13 +36,13 @@ checksum = "84949cb53285a6c481d0133065a7b669871acfd9e20f273f4ce1283c309775d5" name = "semver" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3031434e07edc922bf1b8262f075fac1522694f17b1ee7ad314c4cabd5d2723f" +checksum = "106bee742e3199d9e59f4269e458dfc825c1b4648c483b1c2b7a45cd2610a308" [[package]] name = "serde" version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75d9264696ebbf5315a6b068e9910c4df9274365afac2d88abf66525df660218" +checksum = "be7d269f612a60e3c2c4a4a120e2d878a3f3298a5285eda6e95453905a107d9a" [[package]] name = "toml" diff --git a/src/tools/cargo/tests/testsuite/cargo_report/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_report/help/stdout.log index 67819de55..95872662e 100644 --- a/src/tools/cargo/tests/testsuite/cargo_report/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_report/help/stdout.log @@ -7,6 +7,7 @@ Commands: Options: -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_run/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_run/help/stdout.log index 97c13382a..2e39d4f9e 100644 --- a/src/tools/cargo/tests/testsuite/cargo_run/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_run/help/stdout.log @@ -8,8 +8,8 @@ Arguments: Options: --ignore-rust-version Ignore `rust-version` specification in packages --message-format <FMT> Error format - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_rustc/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_rustc/help/stdout.log index 60069f526..8952330b0 100644 --- a/src/tools/cargo/tests/testsuite/cargo_rustc/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_rustc/help/stdout.log @@ -11,8 +11,8 @@ Options: --future-incompat-report Outputs a future incompatibility report at the end of the build --ignore-rust-version Ignore `rust-version` specification in packages --message-format <FMT> Error format - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_rustdoc/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_rustdoc/help/stdout.log index 67ee27e6b..a0a3cde5d 100644 --- a/src/tools/cargo/tests/testsuite/cargo_rustdoc/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_rustdoc/help/stdout.log @@ -9,8 +9,8 @@ Options: --open Opens the docs in a browser after the operation --ignore-rust-version Ignore `rust-version` specification in packages --message-format <FMT> Error format - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_search/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_search/help/stdout.log index 9cc508bba..e2024a990 100644 --- a/src/tools/cargo/tests/testsuite/cargo_search/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_search/help/stdout.log @@ -1,4 +1,4 @@ -Search packages in crates.io +Search packages in the registry. Default registry is crates.io Usage: cargo[EXE] search [OPTIONS] [QUERY]... @@ -9,8 +9,8 @@ Options: --limit <LIMIT> Limit the number of results (default: 10, max: 100) --index <INDEX> Registry index URL to search packages in --registry <REGISTRY> Registry to search packages in - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_tree/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_tree/help/stdout.log index 4170583a8..9865fd59e 100644 --- a/src/tools/cargo/tests/testsuite/cargo_tree/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_tree/help/stdout.log @@ -3,7 +3,6 @@ Display a tree visualization of a dependency graph Usage: cargo[EXE] tree [OPTIONS] Options: - -q, --quiet Do not print cargo log messages -e, --edges <KINDS> The kinds of dependencies to display (features, normal, build, dev, all, no-normal, no-build, no-dev, no-proc-macro) -i, --invert [<SPEC>] Invert the tree direction and focus on the given package @@ -17,6 +16,7 @@ Options: ascii] -f, --format <FORMAT> Format string used for printing dependencies [default: {p}] -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_uninstall/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_uninstall/help/stdout.log index efdf11c03..1988e7a0e 100644 --- a/src/tools/cargo/tests/testsuite/cargo_uninstall/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_uninstall/help/stdout.log @@ -7,8 +7,8 @@ Arguments: Options: --root <DIR> Directory to uninstall packages from - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_update/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_update/help/stdout.log index 92caeb656..8e0bf2ccb 100644 --- a/src/tools/cargo/tests/testsuite/cargo_update/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_update/help/stdout.log @@ -6,8 +6,8 @@ Options: -n, --dry-run Don't actually write the lockfile --recursive Force updating all dependencies of [SPEC]... as well --precise <PRECISE> Update [SPEC] to exactly PRECISE - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_vendor/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_vendor/help/stdout.log index 7f37ab56e..4e05e75c8 100644 --- a/src/tools/cargo/tests/testsuite/cargo_vendor/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_vendor/help/stdout.log @@ -10,8 +10,8 @@ Options: -s, --sync <TOML> Additional `Cargo.toml` to sync and vendor --respect-source-config Respect `[source]` config in `.cargo/config` --versioned-dirs Always include version in subdir name - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for diff --git a/src/tools/cargo/tests/testsuite/cargo_verify_project/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_verify_project/help/stdout.log index a61534500..7adc34e6c 100644 --- a/src/tools/cargo/tests/testsuite/cargo_verify_project/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_verify_project/help/stdout.log @@ -3,8 +3,8 @@ Check correctness of crate manifest Usage: cargo[EXE] verify-project [OPTIONS] Options: - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_version/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_version/help/stdout.log index 3f79051ad..2ad1c551c 100644 --- a/src/tools/cargo/tests/testsuite/cargo_version/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_version/help/stdout.log @@ -3,8 +3,8 @@ Show version information Usage: cargo[EXE] version [OPTIONS] Options: - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/cargo_yank/help/stdout.log b/src/tools/cargo/tests/testsuite/cargo_yank/help/stdout.log index 61dc800c7..072ceaac7 100644 --- a/src/tools/cargo/tests/testsuite/cargo_yank/help/stdout.log +++ b/src/tools/cargo/tests/testsuite/cargo_yank/help/stdout.log @@ -11,8 +11,8 @@ Options: --index <INDEX> Registry index URL to yank from --registry <REGISTRY> Registry to yank from --token <TOKEN> API token to use when authenticating - -q, --quiet Do not print cargo log messages -v, --verbose... Use verbose output (-vv very verbose/build.rs output) + -q, --quiet Do not print cargo log messages --color <WHEN> Coloring: auto, always, never --config <KEY=VALUE> Override a configuration value -Z <FLAG> Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for details diff --git a/src/tools/cargo/tests/testsuite/check.rs b/src/tools/cargo/tests/testsuite/check.rs index 03611ae67..b7ad3eb1d 100644 --- a/src/tools/cargo/tests/testsuite/check.rs +++ b/src/tools/cargo/tests/testsuite/check.rs @@ -3,11 +3,12 @@ use std::fmt::{self, Write}; use crate::messages::raw_rustc_output; +use cargo_test_support::compare; use cargo_test_support::install::exe; use cargo_test_support::paths::CargoPathExt; use cargo_test_support::registry::Package; +use cargo_test_support::tools; use cargo_test_support::{basic_bin_manifest, basic_manifest, git, project}; -use cargo_test_support::{tools, wrapped_clippy_driver}; #[cargo_test] fn check_success() { @@ -804,7 +805,7 @@ fn short_message_format() { .with_stderr_contains( "\ src/lib.rs:1:27: error[E0308]: mismatched types -error: could not compile `foo` (lib) due to previous error +error: could not compile `foo` (lib) due to 1 previous error ", ) .run(); @@ -1250,7 +1251,7 @@ fn check_fixable_error_no_fix() { [CHECKING] foo v0.0.1 ([..]) {}\ [WARNING] `foo` (lib) generated 1 warning -[ERROR] could not compile `foo` (lib) due to previous error; 1 warning emitted +[ERROR] could not compile `foo` (lib) due to 1 previous error; 1 warning emitted ", rustc_message ); @@ -1432,7 +1433,7 @@ fn check_fixable_warning_for_clippy() { foo.cargo("check") // We can't use `clippy` so we use a `rustc` workspace wrapper instead - .env("RUSTC_WORKSPACE_WRAPPER", wrapped_clippy_driver()) + .env("RUSTC_WORKSPACE_WRAPPER", tools::wrapped_clippy_driver()) .with_stderr_contains("[..] (run `cargo clippy --fix --lib -p foo` to apply 1 suggestion)") .run(); } @@ -1519,3 +1520,43 @@ fn versionless_package() { ) .run(); } + +#[cargo_test] +fn pkgid_querystring_works() { + let git_project = git::new("gitdep", |p| { + p.file("Cargo.toml", &basic_manifest("gitdep", "1.0.0")) + .file("src/lib.rs", "") + }); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + + [dependencies] + gitdep = {{ git = "{}", branch = "master" }} + "#, + git_project.url() + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("generate-lockfile").run(); + + let output = p.cargo("pkgid").arg("gitdep").exec_with_output().unwrap(); + let gitdep_pkgid = String::from_utf8(output.stdout).unwrap(); + let gitdep_pkgid = gitdep_pkgid.trim(); + compare::assert_match_exact("git+file://[..]/gitdep?branch=master#1.0.0", &gitdep_pkgid); + + p.cargo("build -p") + .arg(gitdep_pkgid) + .with_stderr( + "\ +[COMPILING] gitdep v1.0.0 (file:///[..]/gitdep?branch=master#[..]) +[FINISHED] dev [..]", + ) + .run(); +} diff --git a/src/tools/cargo/tests/testsuite/check_cfg.rs b/src/tools/cargo/tests/testsuite/check_cfg.rs index 57d5f8053..42cfe6065 100644 --- a/src/tools/cargo/tests/testsuite/check_cfg.rs +++ b/src/tools/cargo/tests/testsuite/check_cfg.rs @@ -15,16 +15,16 @@ macro_rules! x { $what, '(', $($who,)* ')', "'", "[..]") } }}; - ($tool:tt => $what:tt of $who:tt with $($first_value:tt $($other_values:tt)*)?) => {{ + ($tool:tt => $what:tt of $who:tt with $first_value:tt $($other_values:tt)*) => {{ #[cfg(windows)] { concat!("[RUNNING] [..]", $tool, "[..] --check-cfg \"", - $what, '(', $who, ", values(", $("/\"", $first_value, "/\"", $(", ", "/\"", $other_values, "/\"",)*)* "))", '"', "[..]") + $what, '(', $who, ", values(", "/\"", $first_value, "/\"", $(", ", "/\"", $other_values, "/\"",)* "))", '"', "[..]") } #[cfg(not(windows))] { concat!("[RUNNING] [..]", $tool, "[..] --check-cfg '", - $what, '(', $who, ", values(", $("\"", $first_value, "\"", $(", ", "\"", $other_values, "\"",)*)* "))", "'", "[..]") + $what, '(', $who, ", values(", "\"", $first_value, "\"", $(", ", "\"", $other_values, "\"",)* "))", "'", "[..]") } }}; } @@ -142,6 +142,77 @@ fn features_with_namespaced_features() { } #[cargo_test(nightly, reason = "--check-cfg is unstable")] +fn features_fingerprint() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [features] + f_a = [] + f_b = [] + "#, + ) + .file("src/lib.rs", "#[cfg(feature = \"f_b\")] fn entry() {}") + .build(); + + p.cargo("check -v -Zcheck-cfg") + .masquerade_as_nightly_cargo(&["check-cfg"]) + .with_stderr_contains(x!("rustc" => "cfg" of "feature" with "f_a" "f_b")) + .with_stderr_does_not_contain("[..]unexpected_cfgs[..]") + .run(); + + p.cargo("check -v -Zcheck-cfg") + .masquerade_as_nightly_cargo(&["check-cfg"]) + .with_stderr_does_not_contain("[..]rustc[..]") + .run(); + + // checking that re-ordering the features does not invalid the fingerprint + p.change_file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [features] + f_b = [] + f_a = [] + "#, + ); + + p.cargo("check -v -Zcheck-cfg") + .masquerade_as_nightly_cargo(&["check-cfg"]) + .with_stderr_does_not_contain("[..]rustc[..]") + .run(); + + p.change_file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [features] + f_a = [] + "#, + ); + + p.cargo("check -v -Zcheck-cfg") + .masquerade_as_nightly_cargo(&["check-cfg"]) + // we check that the fingerprint is indeed dirty + .with_stderr_contains("[..]Dirty[..]the list of declared features changed") + // that is cause rustc to be called again with the new check-cfg args + .with_stderr_contains(x!("rustc" => "cfg" of "feature" with "f_a")) + // and that we indeed found a new warning from the unexpected_cfgs lint + .with_stderr_contains("[..]unexpected_cfgs[..]") + .run(); +} + +#[cargo_test(nightly, reason = "--check-cfg is unstable")] fn well_known_names_values() { let p = project() .file("Cargo.toml", &basic_manifest("foo", "0.1.0")) @@ -150,7 +221,7 @@ fn well_known_names_values() { p.cargo("check -v -Zcheck-cfg") .masquerade_as_nightly_cargo(&["check-cfg"]) - .with_stderr_contains(x!("rustc" => "cfg" of "feature" with)) + .with_stderr_contains(x!("rustc" => "cfg")) .run(); } @@ -213,7 +284,7 @@ fn well_known_names_values_test() { p.cargo("test -v -Zcheck-cfg") .masquerade_as_nightly_cargo(&["check-cfg"]) - .with_stderr_contains(x!("rustc" => "cfg" of "feature" with)) + .with_stderr_contains(x!("rustc" => "cfg")) .run(); } @@ -226,8 +297,8 @@ fn well_known_names_values_doctest() { p.cargo("test -v --doc -Zcheck-cfg") .masquerade_as_nightly_cargo(&["check-cfg"]) - .with_stderr_contains(x!("rustc" => "cfg" of "feature" with)) - .with_stderr_contains(x!("rustdoc" => "cfg" of "feature" with)) + .with_stderr_contains(x!("rustc" => "cfg")) + .with_stderr_contains(x!("rustdoc" => "cfg")) .run(); } diff --git a/src/tools/cargo/tests/testsuite/clean.rs b/src/tools/cargo/tests/testsuite/clean.rs index fbb4d3e5b..913bf19cb 100644 --- a/src/tools/cargo/tests/testsuite/clean.rs +++ b/src/tools/cargo/tests/testsuite/clean.rs @@ -1,5 +1,6 @@ //! Tests for the `cargo clean` command. +use cargo_test_support::paths::CargoPathExt; use cargo_test_support::registry::Package; use cargo_test_support::{ basic_bin_manifest, basic_manifest, git, main_file, project, project_in, rustc_host, @@ -33,7 +34,10 @@ fn different_dir() { p.cargo("build").run(); assert!(p.build_dir().is_dir()); - p.cargo("clean").cwd("src").with_stdout("").run(); + p.cargo("clean") + .cwd("src") + .with_stderr("[REMOVED] [..]") + .run(); assert!(!p.build_dir().is_dir()); } @@ -81,7 +85,7 @@ fn clean_multiple_packages() { p.cargo("clean -p d1 -p d2") .cwd("src") - .with_stdout("") + .with_stderr("[REMOVED] [..]") .run(); assert!(p.bin("foo").is_file()); assert!(!d1_path.is_file()); @@ -226,7 +230,9 @@ fn clean_release() { p.cargo("build --release").run(); p.cargo("clean -p foo").run(); - p.cargo("build --release").with_stdout("").run(); + p.cargo("build --release") + .with_stderr("[FINISHED] [..]") + .run(); p.cargo("clean -p foo --release").run(); p.cargo("build --release") @@ -354,7 +360,7 @@ fn clean_git() { .build(); p.cargo("build").run(); - p.cargo("clean -p dep").with_stdout("").run(); + p.cargo("clean -p dep").with_stderr("[REMOVED] [..]").run(); p.cargo("build").run(); } @@ -379,7 +385,7 @@ fn registry() { Package::new("bar", "0.1.0").publish(); p.cargo("build").run(); - p.cargo("clean -p bar").with_stdout("").run(); + p.cargo("clean -p bar").with_stderr("[REMOVED] [..]").run(); p.cargo("build").run(); } @@ -805,15 +811,6 @@ fn clean_dry_run() { .file("src/lib.rs", "") .build(); - let ls_r = || -> Vec<_> { - let mut file_list: Vec<_> = walkdir::WalkDir::new(p.build_dir()) - .into_iter() - .filter_map(|e| e.map(|e| e.path().to_owned()).ok()) - .collect(); - file_list.sort(); - file_list - }; - // Start with no files. p.cargo("clean --dry-run") .with_stdout("") @@ -823,7 +820,7 @@ fn clean_dry_run() { ) .run(); p.cargo("check").run(); - let before = ls_r(); + let before = p.build_dir().ls_r(); p.cargo("clean --dry-run") .with_stderr( "[SUMMARY] [..] files, [..] total\n\ @@ -831,7 +828,7 @@ fn clean_dry_run() { ) .run(); // Verify it didn't delete anything. - let after = ls_r(); + let after = p.build_dir().ls_r(); assert_eq!(before, after); let expected = cargo::util::iter_join(before.iter().map(|p| p.to_str().unwrap()), "\n"); eprintln!("{expected}"); @@ -854,3 +851,29 @@ fn doc_with_package_selection() { .with_stderr("error: --doc cannot be used with -p") .run(); } + +#[cargo_test] +fn quiet_does_not_show_summary() { + // Checks that --quiet works with `cargo clean`, since there was a + // subtle issue with how the flag is defined as a global flag. + let p = project() + .file("Cargo.toml", &basic_manifest("foo", "0.1.0")) + .file("src/lib.rs", "") + .build(); + + p.cargo("check").run(); + p.cargo("clean --quiet --dry-run") + .with_stdout("") + .with_stderr("") + .run(); + // Verify exact same command without -q would actually display something. + p.cargo("clean --dry-run") + .with_stdout("") + .with_stderr( + "\ +[SUMMARY] [..] files, [..] total +[WARNING] no files deleted due to --dry-run +", + ) + .run(); +} diff --git a/src/tools/cargo/tests/testsuite/config.rs b/src/tools/cargo/tests/testsuite/config.rs index e5078bd8e..bcd126020 100644 --- a/src/tools/cargo/tests/testsuite/config.rs +++ b/src/tools/cargo/tests/testsuite/config.rs @@ -2,9 +2,9 @@ use cargo::core::{PackageIdSpec, Shell}; use cargo::util::config::{self, Config, Definition, JobsConfig, SslVersionConfig, StringList}; -use cargo::util::toml::schema::TomlTrimPaths; -use cargo::util::toml::schema::TomlTrimPathsValue; -use cargo::util::toml::schema::{self as cargo_toml, TomlDebugInfo, VecStringOrBool as VSOB}; +use cargo::util_schemas::manifest::TomlTrimPaths; +use cargo::util_schemas::manifest::TomlTrimPathsValue; +use cargo::util_schemas::manifest::{self as cargo_toml, TomlDebugInfo, VecStringOrBool as VSOB}; use cargo::CargoResult; use cargo_test_support::compare; use cargo_test_support::{panic_error, paths, project, symlink_supported, t}; diff --git a/src/tools/cargo/tests/testsuite/custom_target.rs b/src/tools/cargo/tests/testsuite/custom_target.rs index a04029075..45cb3ac9f 100644 --- a/src/tools/cargo/tests/testsuite/custom_target.rs +++ b/src/tools/cargo/tests/testsuite/custom_target.rs @@ -178,6 +178,8 @@ fn changing_spec_rebuilds() { } #[cargo_test(nightly, reason = "requires features no_core, lang_items")] +// This is randomly crashing in lld. See https://github.com/rust-lang/rust/issues/115985 +#[cfg_attr(all(windows, target_env = "gnu"), ignore = "windows-gnu lld crashing")] fn changing_spec_relearns_crate_types() { // Changing the .json file will invalidate the cache of crate types. let p = project() diff --git a/src/tools/cargo/tests/testsuite/doc.rs b/src/tools/cargo/tests/testsuite/doc.rs index 65169d214..37dd47d76 100644 --- a/src/tools/cargo/tests/testsuite/doc.rs +++ b/src/tools/cargo/tests/testsuite/doc.rs @@ -75,7 +75,14 @@ fn doc_twice() { ) .run(); - p.cargo("doc").with_stdout("").run(); + p.cargo("doc") + .with_stderr( + "\ +[FINISHED] [..] +[GENERATED] [CWD]/target/doc/foo/index.html +", + ) + .run(); } #[cargo_test] @@ -118,9 +125,14 @@ fn doc_deps() { assert_eq!(p.glob("target/debug/**/*.rlib").count(), 0); assert_eq!(p.glob("target/debug/deps/libbar-*.rmeta").count(), 1); + // Make sure it doesn't recompile. p.cargo("doc") - .env("CARGO_LOG", "cargo::ops::cargo_rustc::fingerprint") - .with_stdout("") + .with_stderr( + "\ +[FINISHED] [..] +[GENERATED] [CWD]/target/doc/foo/index.html +", + ) .run(); assert!(p.root().join("target/doc").is_dir()); @@ -1686,6 +1698,7 @@ fn doc_message_format() { r#" { "message": { + "$message_type": "diagnostic", "children": "{...}", "code": "{...}", "level": "error", diff --git a/src/tools/cargo/tests/testsuite/docscrape.rs b/src/tools/cargo/tests/testsuite/docscrape.rs index d4d011ff3..91871be04 100644 --- a/src/tools/cargo/tests/testsuite/docscrape.rs +++ b/src/tools/cargo/tests/testsuite/docscrape.rs @@ -48,6 +48,84 @@ fn basic() { assert!(p.build_dir().join("doc/src/ex/ex.rs.html").exists()); } +// This test ensures that even if there is no `[workspace]` in the top-level `Cargo.toml` file, the +// dependencies will get their examples scraped and that they appear in the generated documentation. +#[cargo_test(nightly, reason = "-Zrustdoc-scrape-examples is unstable")] +fn scrape_examples_for_non_workspace_reexports() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + edition = "2021" + authors = [] + + [dependencies] + a = { path = "crates/a" } + "#, + ) + .file("src/lib.rs", "pub use a::*;") + // Example + .file( + "examples/one.rs", + r#"use foo::*; +fn main() { + let foo = Foo::new("yes".into()); + foo.maybe(); +}"#, + ) + // `a` crate + .file( + "crates/a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.0.1" + authors = [] + "#, + ) + .file( + "crates/a/src/lib.rs", + r#" +#[derive(Debug)] +pub struct Foo { + foo: String, + yes: bool, +} + +impl Foo { + pub fn new(foo: String) -> Self { + Self { foo, yes: true } + } + + pub fn maybe(&self) { + if self.yes { + println!("{}", self.foo) + } + } +}"#, + ) + .build(); + + p.cargo("doc -Zunstable-options -Zrustdoc-scrape-examples --no-deps") + .masquerade_as_nightly_cargo(&["rustdoc-scrape-examples"]) + .with_stderr_unordered( + "\ +[CHECKING] a v0.0.1 ([CWD]/crates/a) +[CHECKING] foo v0.0.1 ([CWD]) +[SCRAPING] foo v0.0.1 ([CWD]) +[DOCUMENTING] foo v0.0.1 ([CWD]) +[FINISHED] [..] +[GENERATED] [CWD]/target/doc/foo/index.html", + ) + .run(); + + let doc_html = p.read_file("target/doc/foo/struct.Foo.html"); + assert!(doc_html.contains("Examples found in repository")); +} + #[cargo_test(nightly, reason = "rustdoc scrape examples flags are unstable")] fn avoid_build_script_cycle() { let p = project() diff --git a/src/tools/cargo/tests/testsuite/features.rs b/src/tools/cargo/tests/testsuite/features.rs index 4b7455c37..febdf52fe 100644 --- a/src/tools/cargo/tests/testsuite/features.rs +++ b/src/tools/cargo/tests/testsuite/features.rs @@ -60,6 +60,10 @@ fn empty_feature_name() { [ERROR] failed to parse manifest at `[..]` Caused by: + TOML parse error at line 8, column 17 + | + 8 | \"\" = [] + | ^^ feature name cannot be empty ", ) @@ -627,7 +631,14 @@ fn cyclic_feature2() { .file("src/main.rs", "fn main() {}") .build(); - p.cargo("check").with_stdout("").run(); + p.cargo("check") + .with_stderr( + "\ +[CHECKING] foo [..] +[FINISHED] [..] +", + ) + .run(); } #[cargo_test] @@ -1047,8 +1058,8 @@ fn no_rebuild_when_frobbing_default_feature() { .build(); p.cargo("check").run(); - p.cargo("check").with_stdout("").run(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -1098,8 +1109,8 @@ fn unions_work_with_no_default_features() { .build(); p.cargo("check").run(); - p.cargo("check").with_stdout("").run(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -2048,7 +2059,11 @@ fn invalid_feature_names_error() { error: failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: - invalid character `+` in feature `+foo` in package foo v0.1.0 ([ROOT]/foo), \ + TOML parse error at line 8, column 17 + | + 8 | \"+foo\" = [] + | ^^^^^^ + invalid character `+` in feature `+foo`, \ the first character must be a Unicode XID start character or digit \ (most letters or `_` or `0` to `9`) ", @@ -2075,7 +2090,11 @@ Caused by: error: failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: - invalid character `&` in feature `a&b` in package foo v0.1.0 ([ROOT]/foo), \ + TOML parse error at line 8, column 13 + | + 8 | \"a&b\" = [] + | ^^^^^ + invalid character `&` in feature `a&b`, \ characters must be Unicode XID characters, '-', `+`, or `.` \ (numbers, `+`, `-`, `_`, `.`, or most letters) ", @@ -2108,6 +2127,10 @@ fn invalid_feature_name_slash_error() { error: failed to parse manifest at `[CWD]/Cargo.toml` Caused by: + TOML parse error at line 7, column 17 + | + 7 | \"foo/bar\" = [] + | ^^^^^^^^^ feature named `foo/bar` is not allowed to contain slashes ", ) diff --git a/src/tools/cargo/tests/testsuite/features_namespaced.rs b/src/tools/cargo/tests/testsuite/features_namespaced.rs index f24186c15..b79be55e8 100644 --- a/src/tools/cargo/tests/testsuite/features_namespaced.rs +++ b/src/tools/cargo/tests/testsuite/features_namespaced.rs @@ -439,6 +439,10 @@ fn crate_syntax_bad_name() { [ERROR] failed to parse manifest at [..]/foo/Cargo.toml` Caused by: + TOML parse error at line 10, column 17 + | + 10 | \"dep:bar\" = [] + | ^^^^^^^^^ feature named `dep:bar` is not allowed to start with `dep:` ", ) diff --git a/src/tools/cargo/tests/testsuite/fetch.rs b/src/tools/cargo/tests/testsuite/fetch.rs index f90131a59..9be5f79d0 100644 --- a/src/tools/cargo/tests/testsuite/fetch.rs +++ b/src/tools/cargo/tests/testsuite/fetch.rs @@ -11,7 +11,7 @@ fn no_deps() { .file("src/a.rs", "") .build(); - p.cargo("fetch").with_stdout("").run(); + p.cargo("fetch").with_stderr("").run(); } #[cargo_test] diff --git a/src/tools/cargo/tests/testsuite/fix.rs b/src/tools/cargo/tests/testsuite/fix.rs index 33de721cd..7cb5bd65e 100644 --- a/src/tools/cargo/tests/testsuite/fix.rs +++ b/src/tools/cargo/tests/testsuite/fix.rs @@ -5,8 +5,8 @@ use cargo_test_support::compare::assert_match_exact; use cargo_test_support::git::{self, init}; use cargo_test_support::paths::{self, CargoPathExt}; use cargo_test_support::registry::{Dependency, Package}; +use cargo_test_support::tools; use cargo_test_support::{basic_manifest, is_nightly, project, Project}; -use cargo_test_support::{tools, wrapped_clippy_driver}; #[cargo_test] fn do_not_fix_broken_builds() { @@ -29,7 +29,7 @@ fn do_not_fix_broken_builds() { p.cargo("fix --allow-no-vcs") .env("__CARGO_FIX_YOLO", "1") .with_status(101) - .with_stderr_contains("[ERROR] could not compile `foo` (lib) due to previous error") + .with_stderr_contains("[ERROR] could not compile `foo` (lib) due to 1 previous error") .run(); assert!(p.read_file("src/lib.rs").contains("let mut x = 3;")); } @@ -110,6 +110,7 @@ fn rustc_shim_for_cargo_fix() -> Project { } let status = Command::new("rustc") .args(env::args().skip(1)) + .env_remove("CARGO_MAKEFLAGS") .status() .expect("failed to run rustc"); process::exit(status.code().unwrap_or(2)); @@ -193,7 +194,7 @@ fn broken_clippy_fixes_backed_out() { .env("__CARGO_FIX_YOLO", "1") .env("RUSTC", p.root().join("foo/target/debug/foo")) // We can't use `clippy` so we use a `rustc` workspace wrapper instead - .env("RUSTC_WORKSPACE_WRAPPER", wrapped_clippy_driver()) + .env("RUSTC_WORKSPACE_WRAPPER", tools::wrapped_clippy_driver()) .with_stderr_contains( "warning: failed to automatically apply fixes suggested by rustc \ to crate `bar`\n\ @@ -1857,9 +1858,22 @@ fn non_edition_lint_migration() { assert!(contents.contains("from_utf8(crate::foo::FOO)")); } -// For rust-lang/cargo#9857 #[cargo_test] fn fix_in_dependency() { + // Tests what happens if rustc emits a suggestion to modify a file from a + // dependency in cargo's home directory. This should never happen, and + // indicates a bug in rustc. However, there are several known bugs in + // rustc where it does this (often involving macros), so `cargo fix` has a + // guard that says if the suggestion points to some location in CARGO_HOME + // to not apply it. + // + // See https://github.com/rust-lang/cargo/issues/9857 for some other + // examples. + // + // This test uses a simulated rustc which replays a suggestion via a JSON + // message that points into CARGO_HOME. This does not use the real rustc + // because as the bugs are fixed in the real rustc, that would cause this + // test to stop working. Package::new("bar", "1.0.0") .file( "src/lib.rs", @@ -1895,8 +1909,146 @@ fn fix_in_dependency() { "#, ) .build(); + p.cargo("fetch").run(); + + // The path in CARGO_HOME. + let bar_path = std::fs::read_dir(paths::home().join(".cargo/registry/src")) + .unwrap() + .next() + .unwrap() + .unwrap() + .path(); + // Since this is a substitution into a Rust string (representing a JSON + // string), deal with backslashes like on Windows. + let bar_path_str = bar_path.to_str().unwrap().replace("\\", "/"); + + // This is a fake rustc that will emit a JSON message when the `foo` crate + // builds that tells cargo to modify a file it shouldn't. + let rustc = project() + .at("rustc-replay") + .file("Cargo.toml", &basic_manifest("rustc-replay", "1.0.0")) + .file("src/main.rs", + &r##" + fn main() { + let pkg_name = match std::env::var("CARGO_PKG_NAME") { + Ok(pkg_name) => pkg_name, + Err(_) => { + let r = std::process::Command::new("rustc") + .args(std::env::args_os().skip(1)) + .status(); + std::process::exit(r.unwrap().code().unwrap_or(2)); + } + }; + if pkg_name == "foo" { + eprintln!("{}", r#"{ + "$message_type": "diagnostic", + "message": "unused variable: `abc`", + "code": + { + "code": "unused_variables", + "explanation": null + }, + "level": "warning", + "spans": + [ + { + "file_name": "__BAR_PATH__/bar-1.0.0/src/lib.rs", + "byte_start": 127, + "byte_end": 129, + "line_start": 5, + "line_end": 5, + "column_start": 29, + "column_end": 31, + "is_primary": true, + "text": + [ + { + "text": " let $i = 1;", + "highlight_start": 29, + "highlight_end": 31 + } + ], + "label": null, + "suggested_replacement": null, + "suggestion_applicability": null, + "expansion": null + } + ], + "children": + [ + { + "message": "`#[warn(unused_variables)]` on by default", + "code": null, + "level": "note", + "spans": + [], + "children": + [], + "rendered": null + }, + { + "message": "if this is intentional, prefix it with an underscore", + "code": null, + "level": "help", + "spans": + [ + { + "file_name": "__BAR_PATH__/bar-1.0.0/src/lib.rs", + "byte_start": 127, + "byte_end": 129, + "line_start": 5, + "line_end": 5, + "column_start": 29, + "column_end": 31, + "is_primary": true, + "text": + [ + { + "text": " let $i = 1;", + "highlight_start": 29, + "highlight_end": 31 + } + ], + "label": null, + "suggested_replacement": "_abc", + "suggestion_applicability": "MachineApplicable", + "expansion": null + } + ], + "children": + [], + "rendered": null + } + ], + "rendered": "warning: unused variable: `abc`\n --> __BAR_PATH__/bar-1.0.0/src/lib.rs:5:29\n |\n5 | let $i = 1;\n | ^^ help: if this is intentional, prefix it with an underscore: `_abc`\n |\n = note: `#[warn(unused_variables)]` on by default\n\n" + }"#.replace("\n", "")); + } + } + "##.replace("__BAR_PATH__", &bar_path_str)) + .build(); + rustc.cargo("build").run(); + let rustc_bin = rustc.bin("rustc-replay"); - p.cargo("fix --allow-no-vcs") - .with_stderr_does_not_contain("[FIXED] [..]") + // The output here should not say `Fixed`. + // + // It is OK to compare the full diagnostic output here because the text is + // hard-coded in rustc-replay. Normally tests should not be checking the + // compiler output. + p.cargo("fix --lib --allow-no-vcs") + .env("RUSTC", &rustc_bin) + .with_stderr("\ +[CHECKING] bar v1.0.0 +[CHECKING] foo v0.1.0 [..] +warning: unused variable: `abc` + --> [ROOT]/home/.cargo/registry/src/[..]/bar-1.0.0/src/lib.rs:5:29 + | +5 | let $i = 1; + | ^^ help: if this is intentional, prefix it with an underscore: `_abc` + | + = note: `#[warn(unused_variables)]` on by default + +warning: `foo` (lib) generated 1 warning (run `cargo fix --lib -p foo` to apply 1 suggestion) +[FINISHED] [..] +") .run(); } diff --git a/src/tools/cargo/tests/testsuite/freshness.rs b/src/tools/cargo/tests/testsuite/freshness.rs index d450cbbd9..2d9b3df68 100644 --- a/src/tools/cargo/tests/testsuite/freshness.rs +++ b/src/tools/cargo/tests/testsuite/freshness.rs @@ -34,7 +34,7 @@ fn modifying_and_moving() { ) .run(); - p.cargo("build").with_stdout("").run(); + p.cargo("build").with_stderr("[FINISHED] [..]").run(); p.root().move_into_the_past(); p.root().join("target").move_into_the_past(); @@ -223,7 +223,7 @@ fn changing_lib_features_caches_targets() { .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") .run(); - p.cargo("build").with_stdout("").run(); + p.cargo("build").with_stderr("[FINISHED] [..]").run(); p.cargo("build --features foo") .with_stderr("[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]") @@ -666,7 +666,7 @@ fn rerun_if_changed_in_dep() { .build(); p.cargo("build").run(); - p.cargo("build").with_stdout("").run(); + p.cargo("build").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -1522,7 +1522,7 @@ fn bust_patched_dep() { sleep_ms(1000); } - p.change_file("reg1new/src/lib.rs", ""); + p.change_file("reg1new/src/lib.rs", "// modified"); if is_coarse_mtime() { sleep_ms(1000); } diff --git a/src/tools/cargo/tests/testsuite/generate_lockfile.rs b/src/tools/cargo/tests/testsuite/generate_lockfile.rs index d2b633605..ed282fc19 100644 --- a/src/tools/cargo/tests/testsuite/generate_lockfile.rs +++ b/src/tools/cargo/tests/testsuite/generate_lockfile.rs @@ -161,13 +161,13 @@ fn cargo_update_generate_lockfile() { let lockfile = p.root().join("Cargo.lock"); assert!(!lockfile.is_file()); - p.cargo("update").with_stdout("").run(); + p.cargo("update").with_stderr("").run(); assert!(lockfile.is_file()); fs::remove_file(p.root().join("Cargo.lock")).unwrap(); assert!(!lockfile.is_file()); - p.cargo("update").with_stdout("").run(); + p.cargo("update").with_stderr("").run(); assert!(lockfile.is_file()); } diff --git a/src/tools/cargo/tests/testsuite/git.rs b/src/tools/cargo/tests/testsuite/git.rs index e27315346..d9289acc6 100644 --- a/src/tools/cargo/tests/testsuite/git.rs +++ b/src/tools/cargo/tests/testsuite/git.rs @@ -591,12 +591,12 @@ fn recompilation() { .run(); // Don't recompile the second time - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); // Modify a file manually, shouldn't trigger a recompile git_project.change_file("src/bar.rs", r#"pub fn bar() { println!("hello!"); }"#); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); p.cargo("update") .with_stderr(&format!( @@ -605,7 +605,7 @@ fn recompilation() { )) .run(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); // Commit the changes and make sure we don't trigger a recompile because the // lock file says not to change @@ -614,7 +614,7 @@ fn recompilation() { git::commit(&repo); println!("compile after commit"); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); p.root().move_into_the_past(); // Update the dependency and carry on! @@ -638,7 +638,7 @@ fn recompilation() { .run(); // Make sure clean only cleans one dep - p.cargo("clean -p foo").with_stdout("").run(); + p.cargo("clean -p foo").with_stderr("[REMOVED] [..]").run(); p.cargo("check") .with_stderr( "[CHECKING] foo v0.5.0 ([CWD])\n\ @@ -742,7 +742,14 @@ fn update_with_shared_deps() { // By default, not transitive updates println!("dep1 update"); - p.cargo("update dep1").with_stdout("").run(); + p.cargo("update dep1") + .with_stderr( + "\ +[UPDATING] git repository [..] +[UPDATING] bar v0.5.0 [..] +", + ) + .run(); // Don't do anything bad on a weird --precise argument println!("bar bad precise update"); @@ -766,7 +773,7 @@ Caused by: println!("bar precise update"); p.cargo("update bar --precise") .arg(&old_head.to_string()) - .with_stdout("") + .with_stderr("[UPDATING] bar v0.5.0 [..]") .run(); // Updating recursively should, however, update the repo. @@ -1496,12 +1503,12 @@ fn git_build_cmd_freshness() { // Smoke test to make sure it doesn't compile again println!("first pass"); - foo.cargo("check").with_stdout("").run(); + foo.cargo("check").with_stderr("[FINISHED] [..]").run(); // Modify an ignored file and make sure we don't rebuild println!("second pass"); foo.change_file("src/bar.rs", ""); - foo.cargo("check").with_stdout("").run(); + foo.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -1636,7 +1643,7 @@ fn git_repo_changing_no_rebuild() { // And now for the real test! Make sure that p1 doesn't get rebuilt // even though the git repo has changed. - p1.cargo("check").with_stdout("").run(); + p1.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -1741,7 +1748,7 @@ fn fetch_downloads() { )) .run(); - p.cargo("fetch").with_stdout("").run(); + p.cargo("fetch").with_stderr("").run(); } #[cargo_test] @@ -1786,7 +1793,7 @@ fn fetch_downloads_with_git2_first_then_with_gitoxide_and_vice_versa() { .run(); Package::new("bar", "1.0.0").publish(); // trigger a crates-index change. - p.cargo("fetch").with_stdout("").run(); + p.cargo("fetch").with_stderr("").run(); } #[cargo_test] diff --git a/src/tools/cargo/tests/testsuite/git_auth.rs b/src/tools/cargo/tests/testsuite/git_auth.rs index b6e68fa3d..c79ae7ce0 100644 --- a/src/tools/cargo/tests/testsuite/git_auth.rs +++ b/src/tools/cargo/tests/testsuite/git_auth.rs @@ -105,11 +105,6 @@ fn setup_failed_auth_test() -> (SocketAddr, JoinHandle<()>, Arc<AtomicUsize>) { // Tests that HTTP auth is offered from `credential.helper`. #[cargo_test] fn http_auth_offered() { - // TODO(Seb): remove this once possible. - if cargo_uses_gitoxide() { - // Without the fixes in https://github.com/Byron/gitoxide/releases/tag/gix-v0.41.0 this test is flaky. - return; - } let (addr, t, connections) = setup_failed_auth_test(); let p = project() .file( @@ -372,11 +367,6 @@ Caused by: #[cargo_test] fn instead_of_url_printed() { - // TODO(Seb): remove this once possible. - if cargo_uses_gitoxide() { - // Without the fixes in https://github.com/Byron/gitoxide/releases/tag/gix-v0.41.0 this test is flaky. - return; - } let (addr, t, _connections) = setup_failed_auth_test(); let config = paths::home().join(".gitconfig"); let mut config = git2::Config::open(&config).unwrap(); diff --git a/src/tools/cargo/tests/testsuite/global_cache_tracker.rs b/src/tools/cargo/tests/testsuite/global_cache_tracker.rs new file mode 100644 index 000000000..68a606902 --- /dev/null +++ b/src/tools/cargo/tests/testsuite/global_cache_tracker.rs @@ -0,0 +1,1862 @@ +//! Tests for last-use tracking and auto-gc. +//! +//! Cargo supports an environment variable called `__CARGO_TEST_LAST_USE_NOW` +//! to have cargo pretend that the current time is the given time (in seconds +//! since the unix epoch). This is used throughout these tests to simulate +//! what happens when time passes. The [`days_ago_unix`] and +//! [`months_ago_unix`] functions help with setting this value. + +use super::config::ConfigBuilder; +use cargo::core::global_cache_tracker::{self, DeferredGlobalLastUse, GlobalCacheTracker}; +use cargo::util::cache_lock::CacheLockMode; +use cargo::util::interning::InternedString; +use cargo::Config; +use cargo_test_support::paths::{self, CargoPathExt}; +use cargo_test_support::registry::{Package, RegistryBuilder}; +use cargo_test_support::{ + basic_manifest, cargo_process, execs, git, project, retry, sleep_ms, thread_wait_timeout, + Project, +}; +use itertools::Itertools; +use std::fmt::Write; +use std::path::PathBuf; +use std::process::Stdio; +use std::time::{Duration, SystemTime}; + +/// Helper to create a simple `foo` project which depends on a registry +/// dependency called `bar`. +fn basic_foo_bar_project() -> Project { + Package::new("bar", "1.0.0").publish(); + project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build() +} + +/// Helper to get the names of files in a directory as strings. +fn get_names(glob: &str) -> Vec<String> { + let mut names: Vec<_> = glob::glob(paths::home().join(glob).to_str().unwrap()) + .unwrap() + .map(|p| p.unwrap().file_name().unwrap().to_str().unwrap().to_owned()) + .collect(); + names.sort(); + names +} + +fn get_registry_names(which: &str) -> Vec<String> { + get_names(&format!(".cargo/registry/{which}/*/*")) +} + +fn get_index_names() -> Vec<String> { + get_names(&format!(".cargo/registry/index/*")) +} + +fn get_git_db_names() -> Vec<String> { + get_names(&format!(".cargo/git/db/*")) +} + +fn get_git_checkout_names(db_name: &str) -> Vec<String> { + get_names(&format!(".cargo/git/checkouts/{db_name}/*")) +} + +fn days_ago(n: u64) -> SystemTime { + SystemTime::now() - Duration::from_secs(60 * 60 * 24 * n) +} + +/// Helper for simulating running cargo in the past. Use with the +/// __CARGO_TEST_LAST_USE_NOW environment variable. +fn days_ago_unix(n: u64) -> String { + days_ago(n) + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs() + .to_string() +} + +/// Helper for simulating running cargo in the past. Use with the +/// __CARGO_TEST_LAST_USE_NOW environment variable. +fn months_ago_unix(n: u64) -> String { + days_ago_unix(n * 30) +} + +/// Populates last-use database and the cache files. +/// +/// This makes it easier to more accurately specify exact sizes. Creating +/// specific sizes with `Package` is too difficult. +fn populate_cache(config: &Config, test_crates: &[(&str, u64, u64, u64)]) -> (PathBuf, PathBuf) { + let cache_dir = paths::home().join(".cargo/registry/cache/example.com-a6c4a5adcb232b9a"); + let src_dir = paths::home().join(".cargo/registry/src/example.com-a6c4a5adcb232b9a"); + + GlobalCacheTracker::db_path(&config) + .into_path_unlocked() + .rm_rf(); + + let _lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let mut tracker = GlobalCacheTracker::new(&config).unwrap(); + let mut deferred = DeferredGlobalLastUse::new(); + + cache_dir.rm_rf(); + cache_dir.mkdir_p(); + src_dir.rm_rf(); + src_dir.mkdir_p(); + paths::home() + .join(".cargo/registry/index/example.com-a6c4a5adcb232b9a") + .mkdir_p(); + let mut create = |name: &str, age, crate_size: u64, src_size: u64| { + let crate_filename = InternedString::new(&format!("{name}.crate")); + deferred.mark_registry_crate_used_stamp( + global_cache_tracker::RegistryCrate { + encoded_registry_name: "example.com-a6c4a5adcb232b9a".into(), + crate_filename, + size: crate_size, + }, + Some(&days_ago(age)), + ); + deferred.mark_registry_src_used_stamp( + global_cache_tracker::RegistrySrc { + encoded_registry_name: "example.com-a6c4a5adcb232b9a".into(), + package_dir: name.into(), + size: Some(src_size), + }, + Some(&days_ago(age)), + ); + std::fs::write( + cache_dir.join(crate_filename), + "x".repeat(crate_size as usize), + ) + .unwrap(); + let path = src_dir.join(name); + path.mkdir_p(); + std::fs::write(path.join("data"), "x".repeat(src_size as usize)).unwrap() + }; + + for (name, age, crate_size, src_size) in test_crates { + create(name, *age, *crate_size, *src_size); + } + deferred.save(&mut tracker).unwrap(); + + (cache_dir, src_dir) +} + +#[cargo_test] +fn auto_gc_gated() { + // Requires -Zgc to both track last-use data and to run auto-gc. + let p = basic_foo_bar_project(); + p.cargo("check") + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + // Check that it did not create a database or delete anything. + let config = ConfigBuilder::new().build(); + assert!(!GlobalCacheTracker::db_path(&config) + .into_path_unlocked() + .exists()); + assert_eq!(get_index_names().len(), 1); + + // Again in the future, shouldn't auto-gc. + p.cargo("check").run(); + assert!(!GlobalCacheTracker::db_path(&config) + .into_path_unlocked() + .exists()); + assert_eq!(get_index_names().len(), 1); +} + +#[cargo_test] +fn clean_gc_gated() { + cargo_process("clean gc") + .with_status(101) + .with_stderr( + "\ +error: the `cargo clean gc` command is unstable, and only available on the \ +nightly channel of Cargo, but this is the `stable` channel +See [..] +See [..] +", + ) + .run(); +} + +#[cargo_test] +fn implies_source() { + // Checks that when a src, crate, or checkout is marked as used, the + // corresponding index or git db also gets marked as used. + let config = ConfigBuilder::new().unstable_flag("gc").build(); + let _lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let mut deferred = DeferredGlobalLastUse::new(); + let mut tracker = GlobalCacheTracker::new(&config).unwrap(); + + deferred.mark_registry_crate_used(global_cache_tracker::RegistryCrate { + encoded_registry_name: "example.com-a6c4a5adcb232b9a".into(), + crate_filename: "regex-1.8.4.crate".into(), + size: 123, + }); + deferred.mark_registry_src_used(global_cache_tracker::RegistrySrc { + encoded_registry_name: "index.crates.io-6f17d22bba15001f".into(), + package_dir: "rand-0.8.5".into(), + size: None, + }); + deferred.mark_git_checkout_used(global_cache_tracker::GitCheckout { + encoded_git_name: "cargo-e7ff1db891893a9e".into(), + short_name: "f0a4ee0".into(), + size: None, + }); + deferred.save(&mut tracker).unwrap(); + + let mut indexes = tracker.registry_index_all().unwrap(); + assert_eq!(indexes.len(), 2); + indexes.sort_by(|a, b| a.0.encoded_registry_name.cmp(&b.0.encoded_registry_name)); + assert_eq!( + indexes[0].0.encoded_registry_name, + "example.com-a6c4a5adcb232b9a" + ); + assert_eq!( + indexes[1].0.encoded_registry_name, + "index.crates.io-6f17d22bba15001f" + ); + + let dbs = tracker.git_db_all().unwrap(); + assert_eq!(dbs.len(), 1); + assert_eq!(dbs[0].0.encoded_git_name, "cargo-e7ff1db891893a9e"); +} + +#[cargo_test] +fn auto_gc_defaults() { + // Checks that the auto-gc deletes old entries, and leaves new ones intact. + Package::new("old", "1.0.0").publish(); + Package::new("new", "1.0.0").publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + old = "1.0" + new = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + // Populate the last-use data. + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + assert_eq!(get_registry_names("src"), ["new-1.0.0", "old-1.0.0"]); + assert_eq!( + get_registry_names("cache"), + ["new-1.0.0.crate", "old-1.0.0.crate"] + ); + + // Run again with just one package. Make sure the old src gets deleted, + // but .crate does not. + p.change_file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + new = "1.0" + "#, + ); + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(2)) + .run(); + assert_eq!(get_registry_names("src"), ["new-1.0.0"]); + assert_eq!( + get_registry_names("cache"), + ["new-1.0.0.crate", "old-1.0.0.crate"] + ); + + // Run again after the .crate should have aged out. + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + assert_eq!(get_registry_names("src"), ["new-1.0.0"]); + assert_eq!(get_registry_names("cache"), ["new-1.0.0.crate"]); +} + +#[cargo_test] +fn auto_gc_config() { + // Can configure auto gc settings. + Package::new("old", "1.0.0").publish(); + Package::new("new", "1.0.0").publish(); + let p = project() + .file( + ".cargo/config.toml", + r#" + [gc.auto] + frequency = "always" + max-src-age = "1 day" + max-crate-age = "3 days" + max-index-age = "3 days" + max-git-co-age = "1 day" + max-git-db-age = "3 days" + "#, + ) + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + old = "1.0" + new = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + // Populate the last-use data. + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(4)) + .run(); + assert_eq!(get_registry_names("src"), ["new-1.0.0", "old-1.0.0"]); + assert_eq!( + get_registry_names("cache"), + ["new-1.0.0.crate", "old-1.0.0.crate"] + ); + + // Run again with just one package. Make sure the old src gets deleted, + // but .crate does not. + p.change_file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + new = "1.0" + "#, + ); + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(2)) + .run(); + assert_eq!(get_registry_names("src"), ["new-1.0.0"]); + assert_eq!( + get_registry_names("cache"), + ["new-1.0.0.crate", "old-1.0.0.crate"] + ); + + // Run again after the .crate should have aged out. + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + assert_eq!(get_registry_names("src"), ["new-1.0.0"]); + assert_eq!(get_registry_names("cache"), ["new-1.0.0.crate"]); +} + +#[cargo_test] +fn frequency() { + // gc.auto.frequency settings + let p = basic_foo_bar_project(); + p.change_file( + ".cargo/config.toml", + r#" + [gc.auto] + frequency = "never" + "#, + ); + // Populate data in the past. + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + assert_eq!(get_index_names().len(), 1); + assert_eq!(get_registry_names("src"), ["bar-1.0.0"]); + assert_eq!(get_registry_names("cache"), ["bar-1.0.0.crate"]); + + p.change_file("Cargo.toml", &basic_manifest("foo", "0.2.0")); + + // Try after the default expiration time, with "never" it shouldn't gc. + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + assert_eq!(get_index_names().len(), 1); + assert_eq!(get_registry_names("src"), ["bar-1.0.0"]); + assert_eq!(get_registry_names("cache"), ["bar-1.0.0.crate"]); + + // Try again with a setting that allows it to run. + p.cargo("check -Zgc") + .env("CARGO_GC_AUTO_FREQUENCY", "1 day") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + assert_eq!(get_index_names().len(), 0); + assert_eq!(get_registry_names("src").len(), 0); + assert_eq!(get_registry_names("cache").len(), 0); +} + +#[cargo_test] +fn auto_gc_index() { + // Deletes the index if it hasn't been used in a while. + let p = basic_foo_bar_project(); + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + assert_eq!(get_index_names().len(), 1); + + // Make sure it stays within the time frame. + p.change_file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + "#, + ); + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(2)) + .run(); + assert_eq!(get_index_names().len(), 1); + + // After it expires, it should be deleted. + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + assert_eq!(get_index_names().len(), 0); +} + +#[cargo_test] +fn auto_gc_git() { + // auto-gc should delete git checkouts and dbs. + + // Returns the short git name of a a checkout. + let short_id = |repo: &git2::Repository| -> String { + let head = repo.revparse_single("HEAD").unwrap(); + let short_id = head.short_id().unwrap(); + short_id.as_str().unwrap().to_owned() + }; + + // Set up a git dependency and fetch it and populate the database, + // 6 months in the past. + let (git_project, git_repo) = git::new_repo("bar", |p| { + p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) + .file("src/lib.rs", "") + }); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = {{ git = '{}' }} + "#, + git_project.url() + ), + ) + .file("src/lib.rs", "") + .build(); + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(6)) + .run(); + let db_names = get_git_db_names(); + assert_eq!(db_names.len(), 1); + let first_short_oid = short_id(&git_repo); + assert_eq!( + get_git_checkout_names(&db_names[0]), + [first_short_oid.clone()] + ); + + // Use a new git checkout, should keep both. + git_project.change_file("src/lib.rs", "// modified"); + git::add(&git_repo); + git::commit(&git_repo); + p.cargo("update -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(6)) + .run(); + assert_eq!(get_git_db_names().len(), 1); + let second_short_oid = short_id(&git_repo); + let mut both = vec![first_short_oid, second_short_oid.clone()]; + both.sort(); + assert_eq!(get_git_checkout_names(&db_names[0]), both); + + // In the future, using the second checkout should delete the first. + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + assert_eq!(get_git_db_names().len(), 1); + assert_eq!( + get_git_checkout_names(&db_names[0]), + [second_short_oid.clone()] + ); + + // After three months, the db should get deleted. + p.change_file("Cargo.toml", &basic_manifest("foo", "0.2.0")); + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + assert_eq!(get_git_db_names().len(), 0); + assert_eq!(get_git_checkout_names(&db_names[0]).len(), 0); +} + +#[cargo_test] +fn auto_gc_various_commands() { + // Checks that auto gc works with a variety of commands. + // + // Auto-gc is only run on a subset of commands. Generally it is run on + // commands that are already doing a lot of work, or heavily involve the + // use of the registry. + Package::new("bar", "1.0.0").publish(); + let cmds = ["check", "fetch"]; + for cmd in cmds { + eprintln!("checking command {cmd}"); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + // Populate the last-use data. + p.cargo(cmd) + .arg("-Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + let config = ConfigBuilder::new().unstable_flag("gc").build(); + let lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let tracker = GlobalCacheTracker::new(&config).unwrap(); + let indexes = tracker.registry_index_all().unwrap(); + assert_eq!(indexes.len(), 1); + let crates = tracker.registry_crate_all().unwrap(); + assert_eq!(crates.len(), 1); + let srcs = tracker.registry_src_all().unwrap(); + assert_eq!(srcs.len(), 1); + drop(lock); + + // After everything is aged out, it should all be deleted. + p.change_file("Cargo.toml", &basic_manifest("foo", "0.2.0")); + p.cargo(cmd) + .arg("-Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + let lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let indexes = tracker.registry_index_all().unwrap(); + assert_eq!(indexes.len(), 0); + let crates = tracker.registry_crate_all().unwrap(); + assert_eq!(crates.len(), 0); + let srcs = tracker.registry_src_all().unwrap(); + assert_eq!(srcs.len(), 0); + drop(tracker); + drop(lock); + paths::home().join(".cargo/registry").rm_rf(); + GlobalCacheTracker::db_path(&config) + .into_path_unlocked() + .rm_rf(); + } +} + +#[cargo_test] +fn updates_last_use_various_commands() { + // Checks that last-use tracking is updated by various commands. + // + // Not *all* commands update the index tracking, even though they + // technically involve reading the index. There isn't a convenient place + // to ensure it gets saved while avoiding saving too often in other + // commands. For the most part, this should be fine, since these commands + // usually aren't run without running one of the commands that does save + // the tracking. Some of the commands are: + // + // - login, owner, yank, search + // - report future-incompatibilities + // - package --no-verify + // - fetch --locked + Package::new("bar", "1.0.0").publish(); + let cmds = [ + // name, expected_crates (0=doesn't download) + ("check", 1), + ("fetch", 1), + ("tree", 1), + ("generate-lockfile", 0), + ("update", 0), + ("metadata", 1), + ("vendor --respect-source-config", 1), + ]; + for (cmd, expected_crates) in cmds { + eprintln!("checking command {cmd}"); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + // Populate the last-use data. + p.cargo(cmd) + .arg("-Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + let config = ConfigBuilder::new().unstable_flag("gc").build(); + let lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let tracker = GlobalCacheTracker::new(&config).unwrap(); + let indexes = tracker.registry_index_all().unwrap(); + assert_eq!(indexes.len(), 1); + let crates = tracker.registry_crate_all().unwrap(); + assert_eq!(crates.len(), expected_crates); + let srcs = tracker.registry_src_all().unwrap(); + assert_eq!(srcs.len(), expected_crates); + drop(tracker); + drop(lock); + paths::home().join(".cargo/registry").rm_rf(); + GlobalCacheTracker::db_path(&config) + .into_path_unlocked() + .rm_rf(); + } +} + +#[cargo_test] +fn both_git_and_http_index_cleans() { + // Checks that either the git or http index cache gets cleaned. + let _crates_io = RegistryBuilder::new().build(); + let _alternative = RegistryBuilder::new().alternative().http_index().build(); + Package::new("from_git", "1.0.0").publish(); + Package::new("from_http", "1.0.0") + .alternative(true) + .publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + from_git = "1.0" + from_http = { version = "1.0", registry = "alternative" } + "#, + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("update -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + let config = ConfigBuilder::new().unstable_flag("gc").build(); + let lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let tracker = GlobalCacheTracker::new(&config).unwrap(); + let indexes = tracker.registry_index_all().unwrap(); + assert_eq!(indexes.len(), 2); + assert_eq!(get_index_names().len(), 2); + drop(lock); + + // Running in the future without these indexes should delete them. + p.change_file("Cargo.toml", &basic_manifest("foo", "0.2.0")); + p.cargo("clean gc -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + let lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let indexes = tracker.registry_index_all().unwrap(); + assert_eq!(indexes.len(), 0); + assert_eq!(get_index_names().len(), 0); + drop(lock); +} + +#[cargo_test] +fn clean_gc_dry_run() { + // Basic `clean --gc --dry-run` test. + let p = basic_foo_bar_project(); + // Populate the last-use data. + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + + let registry_root = paths::home().join(".cargo/registry"); + let glob_registry = |name| -> PathBuf { + let mut paths: Vec<_> = glob::glob(registry_root.join(name).join("*").to_str().unwrap()) + .unwrap() + .map(|p| p.unwrap()) + .collect(); + assert_eq!(paths.len(), 1); + paths.pop().unwrap() + }; + let index = glob_registry("index").ls_r(); + let src = glob_registry("src").ls_r(); + let cache = glob_registry("cache").ls_r(); + let expected_files = index + .iter() + .chain(src.iter()) + .chain(cache.iter()) + .map(|p| p.to_str().unwrap()) + .join("\n"); + + p.cargo("clean gc --dry-run -v -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stdout_unordered(&expected_files) + .with_stderr( + "[SUMMARY] [..] files, [..] total\n\ + [WARNING] no files deleted due to --dry-run", + ) + .run(); + + // Again, make sure the information is still tracked. + p.cargo("clean gc --dry-run -v -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stdout_unordered(&expected_files) + .with_stderr( + "[SUMMARY] [..] files, [..] total\n\ + [WARNING] no files deleted due to --dry-run", + ) + .run(); +} + +#[cargo_test] +fn clean_default_gc() { + // `clean gc` without options should also gc + let p = basic_foo_bar_project(); + // Populate the last-use data. + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + p.cargo("clean gc -v -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr_unordered( + "\ +[REMOVING] [ROOT]/home/.cargo/registry/index/[..] +[REMOVING] [ROOT]/home/.cargo/registry/src/[..] +[REMOVING] [ROOT]/home/.cargo/registry/cache/[..] +[REMOVED] [..] files, [..] total +", + ) + .run(); +} + +#[cargo_test] +fn tracks_sizes() { + // Checks that sizes are properly tracked in the db. + Package::new("dep1", "1.0.0") + .file("src/lib.rs", "") + .publish(); + Package::new("dep2", "1.0.0") + .file("src/lib.rs", "") + .file("data", &"abcdefghijklmnopqrstuvwxyz".repeat(1000)) + .publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + dep1 = "1.0" + dep2 = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + + // Check that the crate sizes are the same as on disk. + let config = ConfigBuilder::new().unstable_flag("gc").build(); + let _lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let tracker = GlobalCacheTracker::new(&config).unwrap(); + let mut crates = tracker.registry_crate_all().unwrap(); + crates.sort_by(|a, b| a.0.crate_filename.cmp(&b.0.crate_filename)); + let db_sizes: Vec<_> = crates.iter().map(|c| c.0.size).collect(); + + let mut actual: Vec<_> = p + .glob(paths::home().join(".cargo/registry/cache/*/*")) + .map(|p| p.unwrap()) + .collect(); + actual.sort(); + let actual_sizes: Vec<_> = actual + .iter() + .map(|path| std::fs::metadata(path).unwrap().len()) + .collect(); + assert_eq!(db_sizes, actual_sizes); + + // Also check the src sizes are computed. + let mut srcs = tracker.registry_src_all().unwrap(); + srcs.sort_by(|a, b| a.0.package_dir.cmp(&b.0.package_dir)); + let db_sizes: Vec<_> = srcs.iter().map(|c| c.0.size.unwrap()).collect(); + let mut actual: Vec<_> = p + .glob(paths::home().join(".cargo/registry/src/*/*")) + .map(|p| p.unwrap()) + .collect(); + actual.sort(); + // .cargo-ok is not tracked in the size. + actual.iter().for_each(|p| p.join(".cargo-ok").rm_rf()); + let actual_sizes: Vec<_> = actual + .iter() + .map(|path| cargo_util::du(path, &[]).unwrap()) + .collect(); + assert_eq!(db_sizes, actual_sizes); + assert!(db_sizes[1] > 26000); +} + +#[cargo_test] +fn max_size() { + // Checks --max-crate-size and --max-src-size with various cleaning thresholds. + let config = ConfigBuilder::new().unstable_flag("gc").build(); + + let test_crates = [ + // name, age, crate_size, src_size + ("a-1.0.0", 5, 1, 1), + ("b-1.0.0", 6, 2, 2), + ("c-1.0.0", 3, 3, 3), + ("d-1.0.0", 2, 4, 4), + ("e-1.0.0", 2, 5, 5), + ("f-1.0.0", 9, 6, 6), + ("g-1.0.0", 1, 1, 1), + ]; + + // Determine the order things get deleted so they can be verified. + let mut names_by_timestamp: Vec<_> = test_crates + .iter() + .map(|(name, age, _, _)| (days_ago_unix(*age), name)) + .collect(); + names_by_timestamp.sort(); + let names_by_timestamp: Vec<_> = names_by_timestamp + .into_iter() + .map(|(_, name)| name) + .collect(); + + // This exercises the different boundary conditions. + for (clean_size, files, bytes) in [ + (22, 0, 0), + (21, 1, 6), + (16, 1, 6), + (15, 2, 8), + (14, 2, 8), + (13, 3, 9), + (12, 4, 12), + (10, 4, 12), + (9, 5, 16), + (6, 5, 16), + (5, 6, 21), + (1, 6, 21), + (0, 7, 22), + ] { + let (removed, kept) = names_by_timestamp.split_at(files); + // --max-crate-size + let (cache_dir, src_dir) = populate_cache(&config, &test_crates); + let mut stderr = String::new(); + for name in removed { + writeln!(stderr, "[REMOVING] [..]{name}.crate").unwrap(); + } + let total_display = if removed.is_empty() { + String::new() + } else { + format!(", {bytes}B total") + }; + let files_display = if files == 1 { + format!("1 file") + } else { + format!("{files} files") + }; + write!(stderr, "[REMOVED] {files_display}{total_display}").unwrap(); + cargo_process(&format!("clean gc -Zgc -v --max-crate-size={clean_size}")) + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr_unordered(&stderr) + .run(); + for name in kept { + assert!(cache_dir.join(format!("{name}.crate")).exists()); + } + for name in removed { + assert!(!cache_dir.join(format!("{name}.crate")).exists()); + } + + // --max-src-size + populate_cache(&config, &test_crates); + let mut stderr = String::new(); + for name in removed { + writeln!(stderr, "[REMOVING] [..]{name}").unwrap(); + } + let total_display = if files == 0 { + String::new() + } else { + format!(", {bytes}B total") + }; + write!(stderr, "[REMOVED] {files_display}{total_display}").unwrap(); + cargo_process(&format!("clean gc -Zgc -v --max-src-size={clean_size}")) + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr_unordered(&stderr) + .run(); + for name in kept { + assert!(src_dir.join(name).exists()); + } + for name in removed { + assert!(!src_dir.join(name).exists()); + } + } +} + +#[cargo_test] +fn max_size_untracked_crate() { + // When a .crate file exists from an older version of cargo that did not + // track sizes, `clean --max-crate-size` should populate the db with the + // sizes. + let config = ConfigBuilder::new().unstable_flag("gc").build(); + let cache = paths::home().join(".cargo/registry/cache/example.com-a6c4a5adcb232b9a"); + cache.mkdir_p(); + paths::home() + .join(".cargo/registry/index/example.com-a6c4a5adcb232b9a") + .mkdir_p(); + // Create the `.crate files. + let test_crates = [ + // name, size + ("a-1.0.0.crate", 1234), + ("b-1.0.0.crate", 42), + ("c-1.0.0.crate", 0), + ]; + for (name, size) in test_crates { + std::fs::write(cache.join(name), "x".repeat(size as usize)).unwrap() + } + // This should scan the directory and populate the db with the size information. + cargo_process("clean gc -Zgc -v --max-crate-size=100000") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr("[REMOVED] 0 files") + .run(); + // Check that it stored the size data. + let _lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let tracker = GlobalCacheTracker::new(&config).unwrap(); + let crates = tracker.registry_crate_all().unwrap(); + let mut actual: Vec<_> = crates + .iter() + .map(|(rc, _time)| (rc.crate_filename.as_str(), rc.size)) + .collect(); + actual.sort(); + assert_eq!(test_crates, actual.as_slice()); +} + +/// Helper to prepare the max-size test. +fn max_size_untracked_prepare() -> (Config, Project) { + // First, publish and download a dependency. + let p = basic_foo_bar_project(); + p.cargo("fetch").run(); + // Pretend it was an older version that did not track last-use. + let config = ConfigBuilder::new().unstable_flag("gc").build(); + GlobalCacheTracker::db_path(&config) + .into_path_unlocked() + .rm_rf(); + (config, p) +} + +/// Helper to verify the max-size test. +fn max_size_untracked_verify(config: &Config) { + let actual: Vec<_> = glob::glob( + paths::home() + .join(".cargo/registry/src/*/*") + .to_str() + .unwrap(), + ) + .unwrap() + .map(|p| p.unwrap()) + .collect(); + assert_eq!(actual.len(), 1); + let actual_size = cargo_util::du(&actual[0], &[]).unwrap(); + let lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let tracker = GlobalCacheTracker::new(&config).unwrap(); + let srcs = tracker.registry_src_all().unwrap(); + assert_eq!(srcs.len(), 1); + assert_eq!(srcs[0].0.size, Some(actual_size)); + drop(lock); +} + +#[cargo_test] +fn max_size_untracked_src_from_use() { + // When a src directory exists from an older version of cargo that did not + // track sizes, doing a build should populate the db with an entry with an + // unknown size. `clean --max-src-size` should then fix the size. + let (config, p) = max_size_untracked_prepare(); + + // Run a command that will update the db with an unknown src size. + p.cargo("tree -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + // Check that it is None. + let lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let tracker = GlobalCacheTracker::new(&config).unwrap(); + let srcs = tracker.registry_src_all().unwrap(); + assert_eq!(srcs.len(), 1); + assert_eq!(srcs[0].0.size, None); + drop(lock); + + // Fix the size. + p.cargo("clean gc -v --max-src-size=10000 -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr("[REMOVED] 0 files") + .run(); + max_size_untracked_verify(&config); +} + +#[cargo_test] +fn max_size_untracked_src_from_clean() { + // When a src directory exists from an older version of cargo that did not + // track sizes, `clean --max-src-size` should populate the db with the + // sizes. + let (config, p) = max_size_untracked_prepare(); + + // Clean should scan the src and update the db. + p.cargo("clean gc -v --max-src-size=10000 -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr("[REMOVED] 0 files") + .run(); + max_size_untracked_verify(&config); +} + +#[cargo_test] +fn max_download_size() { + // --max-download-size + // + // This creates some sample crates of specific sizes, and then tries + // deleting at various specific size thresholds that exercise different + // edge conditions. + let config = ConfigBuilder::new().unstable_flag("gc").build(); + + let test_crates = [ + // name, age, crate_size, src_size + ("d-1.0.0", 4, 4, 5), + ("c-1.0.0", 3, 3, 3), + ("a-1.0.0", 1, 2, 5), + ("b-1.0.0", 1, 1, 7), + ]; + + for (max_size, num_deleted, files_deleted, bytes) in [ + (30, 0, 0, 0), + (29, 1, 1, 5), + (24, 2, 2, 9), + (20, 3, 3, 12), + (1, 7, 7, 29), + (0, 8, 8, 30), + ] { + populate_cache(&config, &test_crates); + // Determine the order things will be deleted. + let delete_order: Vec<String> = test_crates + .iter() + .flat_map(|(name, _, _, _)| [name.to_string(), format!("{name}.crate")]) + .collect(); + let (removed, _kept) = delete_order.split_at(num_deleted); + let mut stderr = String::new(); + for name in removed { + writeln!(stderr, "[REMOVING] [..]{name}").unwrap(); + } + let files_display = if files_deleted == 1 { + format!("1 file") + } else { + format!("{files_deleted} files") + }; + let total_display = if removed.is_empty() { + String::new() + } else { + format!(", {bytes}B total") + }; + write!(stderr, "[REMOVED] {files_display}{total_display}",).unwrap(); + cargo_process(&format!("clean gc -Zgc -v --max-download-size={max_size}")) + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr_unordered(&stderr) + .run(); + } +} + +#[cargo_test] +fn package_cache_lock_during_build() { + // Verifies that a shared lock is held during a build. Resolution and + // downloads should be OK while that is held, but mutation should block. + // + // This works by launching a build with a build script that will pause. + // Then it performs other cargo commands and verifies their behavior. + Package::new("bar", "1.0.0").publish(); + let p_foo = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = "1.0" + "#, + ) + .file("src/lib.rs", "") + .file( + "build.rs", + r#" + fn main() { + std::fs::write("blocking", "").unwrap(); + let path = std::path::Path::new("ready"); + loop { + if path.exists() { + break; + } else { + std::thread::sleep(std::time::Duration::from_millis(100)) + } + } + } + "#, + ) + .build(); + let p_foo2 = project() + .at("foo2") + .file( + "Cargo.toml", + r#" + [package] + name = "foo2" + version = "0.1.0" + + [dependencies] + bar = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + + // Start a build that will pause once the build starts. + let mut foo_child = p_foo + .cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .build_command() + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap(); + + // Wait for it to enter build script. + retry(100, || p_foo.root().join("blocking").exists().then_some(())); + + // Start a build with a different target directory. It should not block, + // even though it gets a download lock, and then a shared lock. + // + // Also verify that auto-gc gets disabled. + p_foo2 + .cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("CARGO_GC_AUTO_FREQUENCY", "always") + .env("CARGO_LOG", "gc=debug") + .with_stderr_contains("[UPDATING] `dummy-registry` index") + .with_stderr_contains("[CHECKING] bar v1.0.0") + .with_stderr_contains("[CHECKING] foo2 v0.1.0 [..]") + .with_stderr_contains("[FINISHED] [..]") + .with_stderr_contains("[..]unable to acquire mutate lock, auto gc disabled") + .run(); + + // Ensure that the first build really blocked. + assert!(matches!(foo_child.try_wait(), Ok(None))); + + // Cleaning while a command is running should block. + let mut clean_cmd = p_foo2 + .cargo("clean gc --max-download-size=0 -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .build_command(); + clean_cmd.stderr(Stdio::piped()); + let mut clean_child = clean_cmd.spawn().unwrap(); + + // Give the clean command a chance to finish (it shouldn't). + sleep_ms(500); + // They should both still be running. + assert!(matches!(foo_child.try_wait(), Ok(None))); + assert!(matches!(clean_child.try_wait(), Ok(None))); + + // Let the original build finish. + p_foo.change_file("ready", ""); + + // Wait for clean to finish. + let thread = std::thread::spawn(|| clean_child.wait_with_output().unwrap()); + let output = thread_wait_timeout(100, thread); + assert!(output.status.success()); + // Validate the output of the clean. + execs() + .with_stderr( + "\ +[BLOCKING] waiting for file lock on package cache mutation +[REMOVED] [..] +", + ) + .run_output(&output); +} + +#[cargo_test] +fn read_only_locking_auto_gc() { + // Tests the behavior for auto-gc on a read-only directory. + let p = basic_foo_bar_project(); + // Populate cache. + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + let cargo_home = paths::home().join(".cargo"); + let mut perms = std::fs::metadata(&cargo_home).unwrap().permissions(); + // Test when it can't update auto-gc db. + perms.set_readonly(true); + std::fs::set_permissions(&cargo_home, perms.clone()).unwrap(); + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[CHECKING] bar v1.0.0 +[CHECKING] foo v0.1.0 [..] +[FINISHED] [..] +", + ) + .run(); + // Try again without the last-use existing (such as if the cache was + // populated by an older version of cargo). + perms.set_readonly(false); + std::fs::set_permissions(&cargo_home, perms.clone()).unwrap(); + let config = ConfigBuilder::new().build(); + GlobalCacheTracker::db_path(&config) + .into_path_unlocked() + .rm_rf(); + perms.set_readonly(true); + std::fs::set_permissions(&cargo_home, perms.clone()).unwrap(); + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr("[FINISHED] [..]") + .run(); + perms.set_readonly(false); + std::fs::set_permissions(&cargo_home, perms).unwrap(); +} + +#[cargo_test] +fn delete_index_also_deletes_crates() { + // Checks that when an index is delete that src and cache directories also get deleted. + let p = basic_foo_bar_project(); + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + + assert_eq!(get_registry_names("src"), ["bar-1.0.0"]); + assert_eq!(get_registry_names("cache"), ["bar-1.0.0.crate"]); + + p.cargo("clean gc") + .arg("--max-index-age=0 days") + .arg("-Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr("[REMOVED] [..]") + .run(); + + assert_eq!(get_registry_names("src").len(), 0); + assert_eq!(get_registry_names("cache").len(), 0); +} + +#[cargo_test] +fn clean_syncs_missing_files() { + // When files go missing in the cache, clean operations that need to track + // the size should also remove them from the database. + Package::new("bar", "1.0.0").publish(); + Package::new("baz", "1.0.0").publish(); + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = "1.0" + baz = "1.0" + "#, + ) + .file("src/lib.rs", "") + .build(); + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + + // Verify things are tracked. + let config = ConfigBuilder::new().unstable_flag("gc").build(); + let lock = config + .acquire_package_cache_lock(CacheLockMode::MutateExclusive) + .unwrap(); + let tracker = GlobalCacheTracker::new(&config).unwrap(); + let crates = tracker.registry_crate_all().unwrap(); + assert_eq!(crates.len(), 2); + let srcs = tracker.registry_src_all().unwrap(); + assert_eq!(srcs.len(), 2); + drop(lock); + + // Remove the files. + for pattern in [ + ".cargo/registry/cache/*/bar-1.0.0.crate", + ".cargo/registry/src/*/bar-1.0.0", + ] { + p.glob(paths::home().join(pattern)) + .map(|p| p.unwrap()) + .next() + .unwrap() + .rm_rf(); + } + + // Clean should update the db. + p.cargo("clean gc -v --max-download-size=1GB -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr("[REMOVED] 0 files") + .run(); + + // Verify + let crates = tracker.registry_crate_all().unwrap(); + assert_eq!(crates.len(), 1); + let srcs = tracker.registry_src_all().unwrap(); + assert_eq!(srcs.len(), 1); +} + +#[cargo_test] +fn offline_doesnt_auto_gc() { + // When running offline, auto-gc shouldn't run. + let p = basic_foo_bar_project(); + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + // Remove the dependency. + p.change_file("Cargo.toml", &basic_manifest("foo", "0.1.0")); + // Run offline, make sure it doesn't delete anything + p.cargo("check --offline -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr("[CHECKING] foo v0.1.0[..]\n[FINISHED][..]") + .run(); + assert_eq!(get_registry_names("src"), ["bar-1.0.0"]); + assert_eq!(get_registry_names("cache"), ["bar-1.0.0.crate"]); + // Run online, make sure auto-gc runs. + p.cargo("check -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr("[FINISHED][..]") + .run(); + assert_eq!(get_registry_names("src"), &[] as &[String]); + assert_eq!(get_registry_names("cache"), &[] as &[String]); +} + +#[cargo_test] +fn can_handle_future_schema() -> anyhow::Result<()> { + // It should work when a future version of cargo has made schema changes + // to the database. + let p = basic_foo_bar_project(); + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + // Modify the schema to pretend this is done by a future version of cargo. + let config = ConfigBuilder::new().build(); + let db_path = GlobalCacheTracker::db_path(&config).into_path_unlocked(); + let conn = rusqlite::Connection::open(&db_path)?; + let user_version: u32 = + conn.query_row("SELECT user_version FROM pragma_user_version", [], |row| { + row.get(0) + })?; + conn.execute("ALTER TABLE global_data ADD COLUMN foo DEFAULT 123", [])?; + conn.pragma_update(None, "user_version", &(user_version + 1))?; + drop(conn); + // Verify it doesn't blow up. + p.cargo("clean gc --max-download-size=0 -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr("[REMOVED] 4 files, [..] total") + .run(); + Ok(()) +} + +#[cargo_test] +fn clean_max_git_age() { + // --max-git-*-age flags + let (git_a, git_a_repo) = git::new_repo("git_a", |p| { + p.file("Cargo.toml", &basic_manifest("git_a", "1.0.0")) + .file("src/lib.rs", "") + }); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + git_a = {{ git = '{}' }} + "#, + git_a.url() + ), + ) + .file("src/lib.rs", "") + .build(); + // Populate last-use tracking. + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(4)) + .run(); + // Update git_a to create a separate checkout. + git_a.change_file("src/lib.rs", "// test"); + git::add(&git_a_repo); + git::commit(&git_a_repo); + // Update last-use tracking, where the first git checkout will stay "old". + p.cargo("update -p git_a -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(2)) + .with_stderr( + "\ +[UPDATING] git repository [..] +[UPDATING] git_a v1.0.0 [..] +", + ) + .run(); + + let db_names = get_git_db_names(); + assert_eq!(db_names.len(), 1); + let db_name = &db_names[0]; + let co_names = get_git_checkout_names(&db_name); + assert_eq!(co_names.len(), 2); + + // Delete the first checkout + p.cargo("clean gc -v -Zgc") + .arg("--max-git-co-age=3 days") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [ROOT]/home/.cargo/git/checkouts/git_a-[..]/[..] +[REMOVED] [..] +", + ) + .run(); + + let db_names = get_git_db_names(); + assert_eq!(db_names.len(), 1); + let co_names = get_git_checkout_names(&db_name); + assert_eq!(co_names.len(), 1); + + // delete the second checkout + p.cargo("clean gc -v -Zgc") + .arg("--max-git-co-age=0 days") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [ROOT]/home/.cargo/git/checkouts/git_a-[..]/[..] +[REMOVED] [..] +", + ) + .run(); + + let db_names = get_git_db_names(); + assert_eq!(db_names.len(), 1); + let co_names = get_git_checkout_names(&db_name); + assert_eq!(co_names.len(), 0); + + // delete the db + p.cargo("clean gc -v -Zgc") + .arg("--max-git-db-age=1 days") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [ROOT]/home/.cargo/git/db/git_a-[..] +[REMOVING] [ROOT]/home/.cargo/git/checkouts/git_a-[..] +[REMOVED] [..] +", + ) + .run(); + + let db_names = get_git_db_names(); + assert_eq!(db_names.len(), 0); + let co_names = get_git_checkout_names(&db_name); + assert_eq!(co_names.len(), 0); +} + +#[cargo_test] +fn clean_max_src_crate_age() { + // --max-src-age and --max-crate-age flags + let p = basic_foo_bar_project(); + // Populate last-use tracking. + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(4)) + .run(); + // Update bar to create a separate copy with a different timestamp. + Package::new("bar", "1.0.1").publish(); + p.cargo("update -p bar -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(2)) + .with_stderr( + "\ +[UPDATING] `dummy-registry` index +[UPDATING] bar v1.0.0 -> v1.0.1 +", + ) + .run(); + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(2)) + .with_stderr( + "\ +[DOWNLOADING] crates ... +[DOWNLOADED] bar v1.0.1 [..] +", + ) + .run(); + + assert_eq!(get_registry_names("src"), ["bar-1.0.0", "bar-1.0.1"]); + assert_eq!( + get_registry_names("cache"), + ["bar-1.0.0.crate", "bar-1.0.1.crate"] + ); + + // Delete the old src. + p.cargo("clean gc -v -Zgc") + .arg("--max-src-age=3 days") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [..]/bar-1.0.0 +[REMOVED] [..] +", + ) + .run(); + + // delete the second src + p.cargo("clean gc -v -Zgc") + .arg("--max-src-age=0 days") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [..]/bar-1.0.1 +[REMOVED] [..] +", + ) + .run(); + + // delete the old crate + p.cargo("clean gc -v -Zgc") + .arg("--max-crate-age=3 days") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [..]/bar-1.0.0.crate +[REMOVED] [..] +", + ) + .run(); + + // delete the seecond crate + p.cargo("clean gc -v -Zgc") + .arg("--max-crate-age=0 days") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [..]/bar-1.0.1.crate +[REMOVED] [..] +", + ) + .run(); +} + +#[cargo_test] +fn clean_max_git_size() { + // clean --max-git-size + // + // Creates two checkouts. The sets a size threshold to delete one. And + // then with 0 max size to delete everything. + let (git_project, git_repo) = git::new_repo("bar", |p| { + p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) + .file("src/lib.rs", "") + }); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = {{ git = '{}' }} + "#, + git_project.url() + ), + ) + .file("src/lib.rs", "") + .build(); + // Fetch and populate db. + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(3)) + .run(); + + // Figure out the name of the first checkout. + let git_root = paths::home().join(".cargo/git"); + let db_names = get_git_db_names(); + assert_eq!(db_names.len(), 1); + let db_name = &db_names[0]; + let co_names = get_git_checkout_names(&db_name); + assert_eq!(co_names.len(), 1); + let first_co_name = &co_names[0]; + + // Make an update and create a new checkout. + git_project.change_file("src/lib.rs", "// modified"); + git::add(&git_repo); + git::commit(&git_repo); + p.cargo("update -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + // Use a different time so that the first checkout timestamp is less + // than the second. + .env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(2)) + .run(); + + // Figure out the threshold to use. + let mut co_names = get_git_checkout_names(&db_name); + assert_eq!(co_names.len(), 2); + co_names.retain(|name| name != first_co_name); + assert_eq!(co_names.len(), 1); + let second_co_name = &co_names[0]; + let second_co_path = git_root + .join("checkouts") + .join(db_name) + .join(second_co_name); + let second_co_size = cargo_util::du(&second_co_path, &["!.git"]).unwrap(); + + let db_size = cargo_util::du(&git_root.join("db").join(db_name), &[]).unwrap(); + + let threshold = db_size + second_co_size; + + p.cargo(&format!("clean gc --max-git-size={threshold} -Zgc -v")) + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr(&format!( + "\ +[REMOVING] [ROOT]/home/.cargo/git/checkouts/{db_name}/{first_co_name} +[REMOVED] [..] +" + )) + .run(); + + // And then try cleaning everything. + p.cargo("clean gc --max-git-size=0 -Zgc -v") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr_unordered(&format!( + "\ +[REMOVING] [ROOT]/home/.cargo/git/checkouts/{db_name}/{second_co_name} +[REMOVING] [ROOT]/home/.cargo/git/db/{db_name} +[REMOVED] [..] +" + )) + .run(); +} + +// Helper for setting up fake git sizes for git size cleaning. +fn setup_fake_git_sizes(db_name: &str, db_size: usize, co_sizes: &[usize]) { + let base_git = paths::home().join(".cargo/git"); + let db_path = base_git.join("db").join(db_name); + db_path.mkdir_p(); + std::fs::write(db_path.join("test"), "x".repeat(db_size)).unwrap(); + let base_co = base_git.join("checkouts").join(db_name); + for (i, size) in co_sizes.iter().enumerate() { + let co_name = format!("co{i}"); + let co_path = base_co.join(co_name); + co_path.mkdir_p(); + std::fs::write(co_path.join("test"), "x".repeat(*size)).unwrap(); + } +} + +#[cargo_test] +fn clean_max_git_size_untracked() { + // If there are git directories that aren't tracked in the database, + // `--max-git-size` should pick it up. + // + // The db_name of "example" depends on the sorting order of the names ("e" + // should be after "c"), so that the db comes after the checkouts. + setup_fake_git_sizes("example", 5000, &[1000, 2000]); + cargo_process(&format!("clean gc -Zgc -v --max-git-size=7000")) + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [ROOT]/home/.cargo/git/checkouts/example/co0 +[REMOVED] [..] +", + ) + .run(); + cargo_process(&format!("clean gc -Zgc -v --max-git-size=5000")) + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [ROOT]/home/.cargo/git/checkouts/example/co1 +[REMOVED] [..] +", + ) + .run(); + cargo_process(&format!("clean gc -Zgc -v --max-git-size=0")) + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [ROOT]/home/.cargo/git/db/example +[REMOVED] [..] +", + ) + .run(); +} + +#[cargo_test] +fn clean_max_git_size_deletes_co_from_db() { + // In the scenario where it thinks it needs to delete the db, it should + // also delete all the checkouts. + // + // The db_name of "abc" depends on the sorting order of the names ("a" + // should be before "c"), so that the db comes before the checkouts. + setup_fake_git_sizes("abc", 5000, &[1000, 2000]); + // This deletes everything because it tries to delete the db, which then + // deletes all checkouts. + cargo_process(&format!("clean gc -Zgc -v --max-git-size=3000")) + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [ROOT]/home/.cargo/git/db/abc +[REMOVING] [ROOT]/home/.cargo/git/checkouts/abc/co1 +[REMOVING] [ROOT]/home/.cargo/git/checkouts/abc/co0 +[REMOVED] [..] +", + ) + .run(); +} + +#[cargo_test] +fn handles_missing_index() { + // Checks behavior when index is missing. + let p = basic_foo_bar_project(); + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + paths::home().join(".cargo/registry/index").rm_rf(); + cargo_process("clean gc -v --max-download-size=0 -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr_unordered( + "\ +[REMOVING] [ROOT]/home/.cargo/registry/cache/[..] +[REMOVING] [ROOT]/home/.cargo/registry/src/[..] +[REMOVED] [..] +", + ) + .run(); +} + +#[cargo_test] +fn handles_missing_git_db() { + // Checks behavior when git db is missing. + let git_project = git::new("bar", |p| { + p.file("Cargo.toml", &basic_manifest("bar", "1.0.0")) + .file("src/lib.rs", "") + }); + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = {{ git = '{}' }} + "#, + git_project.url() + ), + ) + .file("src/lib.rs", "") + .build(); + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .run(); + paths::home().join(".cargo/git/db").rm_rf(); + cargo_process("clean gc -v --max-git-size=0 -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stderr( + "\ +[REMOVING] [ROOT]/home/.cargo/git/checkouts/[..] +[REMOVED] [..] +", + ) + .run(); +} + +#[cargo_test] +fn clean_gc_quiet_is_quiet() { + // Checks that --quiet works with `cargo clean gc`, since there was a + // subtle issue with how the flag is defined as a global flag. + let p = basic_foo_bar_project(); + p.cargo("fetch -Zgc") + .masquerade_as_nightly_cargo(&["gc"]) + .env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4)) + .run(); + p.cargo("clean gc --quiet -Zgc --dry-run") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stdout("") + .with_stderr("") + .run(); + // Verify exact same command without -q would actually display something. + p.cargo("clean gc -Zgc --dry-run") + .masquerade_as_nightly_cargo(&["gc"]) + .with_stdout("") + .with_stderr( + "\ +[SUMMARY] [..] files, [..] total +[WARNING] no files deleted due to --dry-run +", + ) + .run(); +} diff --git a/src/tools/cargo/tests/testsuite/install.rs b/src/tools/cargo/tests/testsuite/install.rs index fd53b607b..16ed32ee7 100644 --- a/src/tools/cargo/tests/testsuite/install.rs +++ b/src/tools/cargo/tests/testsuite/install.rs @@ -3,6 +3,7 @@ use std::fs::{self, OpenOptions}; use std::io::prelude::*; use std::path::Path; +use std::thread; use cargo_test_support::compare; use cargo_test_support::cross_compile; @@ -11,10 +12,10 @@ use cargo_test_support::registry::{self, registry_path, Package}; use cargo_test_support::{ basic_manifest, cargo_process, no_such_file_err_msg, project, project_in, symlink_supported, t, }; -use cargo_util::ProcessError; +use cargo_util::{ProcessBuilder, ProcessError}; use cargo_test_support::install::{ - assert_has_installed_exe, assert_has_not_installed_exe, cargo_home, + assert_has_installed_exe, assert_has_not_installed_exe, cargo_home, exe, }; use cargo_test_support::paths::{self, CargoPathExt}; use std::env; @@ -1010,7 +1011,7 @@ fn compile_failure() { .with_status(101) .with_stderr_contains( "\ -[ERROR] could not compile `foo` (bin \"foo\") due to previous error +[ERROR] could not compile `foo` (bin \"foo\") due to 1 previous error [ERROR] failed to compile `foo v0.0.1 ([..])`, intermediate artifacts can be \ found at `[..]target`.\nTo reuse those artifacts with a future compilation, \ set the environment variable `CARGO_TARGET_DIR` to that path. @@ -2507,3 +2508,118 @@ fn install_incompat_msrv() { ") .with_status(101).run(); } + +fn assert_tracker_noexistence(key: &str) { + let v1_data: toml::Value = + toml::from_str(&fs::read_to_string(cargo_home().join(".crates.toml")).unwrap()).unwrap(); + let v2_data: serde_json::Value = + serde_json::from_str(&fs::read_to_string(cargo_home().join(".crates2.json")).unwrap()) + .unwrap(); + + assert!(v1_data["v1"].get(key).is_none()); + assert!(v2_data["installs"][key].is_null()); +} + +#[cargo_test] +fn uninstall_running_binary() { + use std::io::Write; + + Package::new("foo", "0.0.1") + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + "#, + ) + .file( + "src/main.rs", + r#" + use std::net::TcpStream; + use std::env::var; + use std::io::Read; + fn main() { + for i in 0..2 { + TcpStream::connect(&var("__ADDR__").unwrap()[..]) + .unwrap() + .read_to_end(&mut Vec::new()) + .unwrap(); + } + } + "#, + ) + .publish(); + + cargo_process("install foo") + .with_stderr( + "\ +[UPDATING] `[..]` index +[DOWNLOADING] crates ... +[DOWNLOADED] foo v0.0.1 (registry [..]) +[INSTALLING] foo v0.0.1 +[COMPILING] foo v0.0.1 +[FINISHED] release [optimized] target(s) in [..] +[INSTALLING] [CWD]/home/.cargo/bin/foo[EXE] +[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`) +[WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries +", + ) + .run(); + assert_has_installed_exe(cargo_home(), "foo"); + + let foo_bin = cargo_home().join("bin").join(exe("foo")); + let l = std::net::TcpListener::bind("127.0.0.1:0").unwrap(); + let addr = l.local_addr().unwrap().to_string(); + let t = thread::spawn(move || { + ProcessBuilder::new(foo_bin) + .env("__ADDR__", addr) + .exec() + .unwrap(); + }); + let key = "foo 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)"; + + #[cfg(windows)] + { + // Ensure foo is running before the first `cargo uninstall` call + l.accept().unwrap().0.write_all(&[1]).unwrap(); + cargo_process("uninstall foo") + .with_status(101) + .with_stderr_contains("[ERROR] failed to remove file `[CWD]/home/.cargo/bin/foo[EXE]`") + .run(); + // Ensure foo is stopped before the second `cargo uninstall` call + l.accept().unwrap().0.write_all(&[1]).unwrap(); + t.join().unwrap(); + cargo_process("uninstall foo") + .with_stderr("[REMOVING] [CWD]/home/.cargo/bin/foo[EXE]") + .run(); + }; + + #[cfg(not(windows))] + { + // Ensure foo is running before the first `cargo uninstall` call + l.accept().unwrap().0.write_all(&[1]).unwrap(); + cargo_process("uninstall foo") + .with_stderr("[REMOVING] [CWD]/home/.cargo/bin/foo[EXE]") + .run(); + l.accept().unwrap().0.write_all(&[1]).unwrap(); + t.join().unwrap(); + }; + + assert_has_not_installed_exe(cargo_home(), "foo"); + assert_tracker_noexistence(key); + + cargo_process("install foo") + .with_stderr( + "\ +[UPDATING] `[..]` index +[INSTALLING] foo v0.0.1 +[COMPILING] foo v0.0.1 +[FINISHED] release [optimized] target(s) in [..] +[INSTALLING] [CWD]/home/.cargo/bin/foo[EXE] +[INSTALLED] package `foo v0.0.1` (executable `foo[EXE]`) +[WARNING] be sure to add `[..]` to your PATH to be able to run the installed binaries +", + ) + .run(); +} diff --git a/src/tools/cargo/tests/testsuite/main.rs b/src/tools/cargo/tests/testsuite/main.rs index 07f749e34..8e2d6dedf 100644 --- a/src/tools/cargo/tests/testsuite/main.rs +++ b/src/tools/cargo/tests/testsuite/main.rs @@ -1,6 +1,6 @@ -// See src/cargo/lib.rs for notes on these lint settings. -#![warn(rust_2018_idioms)] -#![allow(clippy::all)] +#![allow(clippy::disallowed_methods)] +#![allow(clippy::print_stderr)] +#![allow(clippy::print_stdout)] #[macro_use] extern crate cargo_test_macro; @@ -98,6 +98,7 @@ mod git_auth; mod git_gc; mod git_shallow; mod glob_targets; +mod global_cache_tracker; mod help; mod https; mod inheritable_workspace_fields; diff --git a/src/tools/cargo/tests/testsuite/messages.rs b/src/tools/cargo/tests/testsuite/messages.rs index 2c534d8f0..fb92593bc 100644 --- a/src/tools/cargo/tests/testsuite/messages.rs +++ b/src/tools/cargo/tests/testsuite/messages.rs @@ -136,7 +136,7 @@ fn deduplicate_errors() { .with_stderr(&format!( "\ [COMPILING] foo v0.0.1 [..] -{}error: could not compile `foo` (lib) due to previous error +{}error: could not compile `foo` (lib) due to 1 previous error ", rustc_message )) diff --git a/src/tools/cargo/tests/testsuite/metabuild.rs b/src/tools/cargo/tests/testsuite/metabuild.rs index 022d0bff0..1c0196c98 100644 --- a/src/tools/cargo/tests/testsuite/metabuild.rs +++ b/src/tools/cargo/tests/testsuite/metabuild.rs @@ -740,6 +740,7 @@ fn metabuild_failed_build_json() { r#" { "message": { + "$message_type": "diagnostic", "children": "{...}", "code": "{...}", "level": "error", diff --git a/src/tools/cargo/tests/testsuite/package.rs b/src/tools/cargo/tests/testsuite/package.rs index 4ec4fc0d6..371157e4e 100644 --- a/src/tools/cargo/tests/testsuite/package.rs +++ b/src/tools/cargo/tests/testsuite/package.rs @@ -5,6 +5,7 @@ use cargo_test_support::publish::validate_crate_contents; use cargo_test_support::registry::{self, Package}; use cargo_test_support::{ basic_manifest, cargo_process, git, path2url, paths, project, symlink_supported, t, + ProjectBuilder, }; use flate2::read::GzDecoder; use std::fs::{self, read_to_string, File}; @@ -54,7 +55,19 @@ src/main.rs ", ) .run(); - p.cargo("package").with_stdout("").run(); + p.cargo("package") + .with_stderr( + "\ +[WARNING] manifest has no documentation[..] +See [..] +[PACKAGING] foo v0.0.1 ([CWD]) +[VERIFYING] foo v0.0.1 ([CWD]) +[COMPILING] foo v0.0.1 ([CWD][..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[PACKAGED] 4 files, [..] ([..] compressed) +", + ) + .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); validate_crate_contents( @@ -695,6 +708,7 @@ fn ignore_nested() { authors = [] license = "MIT" description = "foo" + homepage = "https://example.com/" "#; let main_rs = r#" fn main() { println!("hello"); } @@ -711,8 +725,6 @@ fn ignore_nested() { p.cargo("package") .with_stderr( "\ -[WARNING] manifest has no documentation[..] -See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info. [PACKAGING] foo v0.0.1 ([CWD]) [VERIFYING] foo v0.0.1 ([CWD]) [COMPILING] foo v0.0.1 ([CWD][..]) @@ -732,7 +744,17 @@ src/main.rs ", ) .run(); - p.cargo("package").with_stdout("").run(); + p.cargo("package") + .with_stderr( + "\ +[PACKAGING] foo v0.0.1 ([CWD]) +[VERIFYING] foo v0.0.1 ([CWD]) +[COMPILING] foo v0.0.1 ([CWD][..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[PACKAGED] 4 files, [..] ([..] compressed) +", + ) + .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); validate_crate_contents( @@ -2730,6 +2752,7 @@ fn basic_filesizes() { exclude = ["*.txt"] license = "MIT" description = "foo" + homepage = "https://example.com/" "#; let main_rs_contents = r#"fn main() { println!("🦀"); }"#; let cargo_toml_contents = format!( @@ -2740,6 +2763,7 @@ version = "0.0.1" authors = [] exclude = ["*.txt"] description = "foo" +homepage = "https://example.com/" license = "MIT" "#, cargo::core::package::MANIFEST_PREAMBLE @@ -2775,7 +2799,17 @@ src/main.rs ", ) .run(); - p.cargo("package").with_stdout("").run(); + p.cargo("package") + .with_stderr( + "\ +[PACKAGING] foo v0.0.1 [..] +[VERIFYING] foo v0.0.1 [..] +[COMPILING] foo v0.0.1 [..] +[FINISHED] [..] +[PACKAGED] 4 files[..] +", + ) + .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); let compressed_size = f.metadata().unwrap().len(); @@ -2802,6 +2836,7 @@ fn larger_filesizes() { authors = [] license = "MIT" description = "foo" + documentation = "https://example.com/" "#; let lots_of_crabs = std::iter::repeat("🦀").take(1337).collect::<String>(); let main_rs_contents = format!(r#"fn main() {{ println!("{}"); }}"#, lots_of_crabs); @@ -2820,6 +2855,7 @@ name = "foo" version = "0.0.1" authors = [] description = "foo" +documentation = "https://example.com/" license = "MIT" "#, cargo::core::package::MANIFEST_PREAMBLE @@ -2857,7 +2893,17 @@ src/main.rs ", ) .run(); - p.cargo("package").with_stdout("").run(); + p.cargo("package") + .with_stderr( + "\ +[PACKAGING] foo v0.0.1 [..] +[VERIFYING] foo v0.0.1 [..] +[COMPILING] foo v0.0.1 [..] +[FINISHED] [..] +[PACKAGED] 5 files, [..] +", + ) + .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); let compressed_size = f.metadata().unwrap().len(); @@ -2895,6 +2941,7 @@ fn symlink_filesizes() { authors = [] license = "MIT" description = "foo" + homepage = "https://example.com/" "#; let lots_of_crabs = std::iter::repeat("🦀").take(1337).collect::<String>(); let main_rs_contents = format!(r#"fn main() {{ println!("{}"); }}"#, lots_of_crabs); @@ -2913,6 +2960,7 @@ name = "foo" version = "0.0.1" authors = [] description = "foo" +homepage = "https://example.com/" license = "MIT" "#, cargo::core::package::MANIFEST_PREAMBLE @@ -2955,7 +3003,17 @@ src/main.rs.bak ", ) .run(); - p.cargo("package").with_stdout("").run(); + p.cargo("package") + .with_stderr( + "\ +[PACKAGING] foo v0.0.1 [..] +[VERIFYING] foo v0.0.1 [..] +[COMPILING] foo v0.0.1 [..] +[FINISHED] [..] +[PACKAGED] 7 files, [..] +", + ) + .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); let compressed_size = f.metadata().unwrap().len(); @@ -3031,7 +3089,19 @@ src/main.rs ", ) .run(); - p.cargo("package").with_stdout("").run(); + p.cargo("package") + .with_stderr( + "\ +[WARNING] manifest has no documentation[..] +See [..] +[PACKAGING] foo v0.0.1 ([CWD]) +[VERIFYING] foo v0.0.1 ([CWD]) +[COMPILING] foo v0.0.1 ([CWD][..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[PACKAGED] 4 files, [..] ([..] compressed) +", + ) + .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); validate_crate_contents( @@ -3085,7 +3155,19 @@ src/main.rs ", ) .run(); - p.cargo("package").with_stdout("").run(); + p.cargo("package") + .with_stderr( + "\ +[WARNING] manifest has no documentation[..] +See [..] +[PACKAGING] foo v0.0.1 ([CWD]) +[VERIFYING] foo v0.0.1 ([CWD]) +[COMPILING] foo v0.0.1 ([CWD][..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[PACKAGED] 4 files, [..] ([..] compressed) +", + ) + .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); validate_crate_contents( @@ -3132,3 +3214,142 @@ See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for &[], ); } + +#[cargo_test] +fn include_files_called_target_project() { + // https://github.com/rust-lang/cargo/issues/12790 + // files and folders called "target" should be included, unless they're the actual target directory + let p = init_and_add_inner_target(project()) + .file("target/foo.txt", "") + .build(); + + p.cargo("package -l") + .with_stdout( + "\ +Cargo.lock +Cargo.toml +Cargo.toml.orig +data/not_target +data/target +derp/not_target/foo.txt +derp/target/foo.txt +src/main.rs +", + ) + .run(); +} + +#[cargo_test] +fn include_files_called_target_git() { + // https://github.com/rust-lang/cargo/issues/12790 + // files and folders called "target" should be included, unless they're the actual target directory + let (p, repo) = git::new_repo("foo", |p| init_and_add_inner_target(p)); + // add target folder but not committed. + _ = fs::create_dir(p.build_dir()).unwrap(); + _ = fs::write(p.build_dir().join("foo.txt"), "").unwrap(); + p.cargo("package -l") + .with_stdout( + "\ +.cargo_vcs_info.json +Cargo.lock +Cargo.toml +Cargo.toml.orig +data/not_target +data/target +derp/not_target/foo.txt +derp/target/foo.txt +src/main.rs +", + ) + .run(); + + // if target is committed, it should be include. + git::add(&repo); + git::commit(&repo); + p.cargo("package -l") + .with_stdout( + "\ +.cargo_vcs_info.json +Cargo.lock +Cargo.toml +Cargo.toml.orig +data/not_target +data/target +derp/not_target/foo.txt +derp/target/foo.txt +src/main.rs +target/foo.txt +", + ) + .run(); +} + +fn init_and_add_inner_target(p: ProjectBuilder) -> ProjectBuilder { + p.file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + "#, + ) + .file("src/main.rs", r#"fn main() { println!("hello"); }"#) + // file called target, should be included + .file("data/target", "") + .file("data/not_target", "") + // folder called target, should be included + .file("derp/target/foo.txt", "") + .file("derp/not_target/foo.txt", "") +} + +#[cargo_test] +fn build_script_outside_pkg_root() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + license = "MIT" + description = "foo" + authors = [] + build = "../t_custom_build/custom_build.rs" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + let mut expect_msg = String::from("\ +warning: manifest has no documentation, homepage or repository. +See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info. +error: the source file of build script doesn't appear to exist. +This may cause issue during packaging, as modules resolution and resources included via macros are often relative to the path of source files. +Please update the `build` setting in the manifest at `[CWD]/Cargo.toml` and point to a path inside the root of the package. +"); + // custom_build.rs does not exist + p.cargo("package -l") + .with_status(101) + .with_stderr(&expect_msg) + .run(); + + // custom_build.rs outside the package root + let custom_build_root = paths::root().join("t_custom_build"); + _ = fs::create_dir(&custom_build_root).unwrap(); + _ = fs::write(&custom_build_root.join("custom_build.rs"), "fn main() {}"); + expect_msg = format!( + "\ +warning: manifest has no documentation, homepage or repository. +See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info. +error: the source file of build script doesn't appear to be a path inside of the package. +It is at `{}/t_custom_build/custom_build.rs`, whereas the root the package is `[CWD]`. +This may cause issue during packaging, as modules resolution and resources included via macros are often relative to the path of source files. +Please update the `build` setting in the manifest at `[CWD]/Cargo.toml` and point to a path inside the root of the package. +", paths::root().display()); + p.cargo("package -l") + .with_status(101) + .with_stderr(&expect_msg) + .run(); +} diff --git a/src/tools/cargo/tests/testsuite/patch.rs b/src/tools/cargo/tests/testsuite/patch.rs index a467f60b5..a4522e822 100644 --- a/src/tools/cargo/tests/testsuite/patch.rs +++ b/src/tools/cargo/tests/testsuite/patch.rs @@ -2700,3 +2700,86 @@ perhaps a crate was updated and forgotten to be re-vendored?"#, ) .run(); } + +#[cargo_test] +fn from_config_empty() { + Package::new("bar", "0.1.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + "#, + ) + .file( + ".cargo/config.toml", + r#" + [patch.''] + bar = { path = 'bar' } + "#, + ) + .file("src/lib.rs", "") + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) + .file("bar/src/lib.rs", r#""#) + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr( + "\ +[ERROR] [patch] entry `` should be a URL or registry name + +Caused by: + invalid url ``: relative URL without a base +", + ) + .run(); +} + +#[cargo_test] +fn from_manifest_empty() { + Package::new("bar", "0.1.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies] + bar = "0.1.0" + + [patch.''] + bar = { path = 'bar' } + "#, + ) + .file("src/lib.rs", "") + .file("bar/Cargo.toml", &basic_manifest("bar", "0.1.1")) + .file("bar/src/lib.rs", r#""#) + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + [patch] entry `` should be a URL or registry name + +Caused by: + invalid url ``: relative URL without a base +", + ) + .run(); +} diff --git a/src/tools/cargo/tests/testsuite/path.rs b/src/tools/cargo/tests/testsuite/path.rs index ebbb72f9a..f458717cd 100644 --- a/src/tools/cargo/tests/testsuite/path.rs +++ b/src/tools/cargo/tests/testsuite/path.rs @@ -83,7 +83,12 @@ fn cargo_compile_with_nested_deps_shorthand() { p.process(&p.bin("foo")).with_stdout("test passed\n").run(); println!("cleaning"); - p.cargo("clean -v").with_stdout("").run(); + p.cargo("clean -v") + .with_stderr( + "[REMOVING] [CWD]/target\n\ + [REMOVED] [..]", + ) + .run(); println!("building baz"); p.cargo("build -p baz") .with_stderr( @@ -350,7 +355,7 @@ fn deep_dependencies_trigger_rebuild() { in [..]\n", ) .run(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); // Make sure an update to baz triggers a rebuild of bar // @@ -437,7 +442,7 @@ fn no_rebuild_two_deps() { ) .run(); assert!(p.bin("foo").is_file()); - p.cargo("build").with_stdout("").run(); + p.cargo("build").with_stderr("[FINISHED] [..]").run(); assert!(p.bin("foo").is_file()); } diff --git a/src/tools/cargo/tests/testsuite/pkgid.rs b/src/tools/cargo/tests/testsuite/pkgid.rs index 88d991e80..fee45b215 100644 --- a/src/tools/cargo/tests/testsuite/pkgid.rs +++ b/src/tools/cargo/tests/testsuite/pkgid.rs @@ -1,5 +1,7 @@ //! Tests for the `cargo pkgid` command. +use cargo_test_support::basic_lib_manifest; +use cargo_test_support::git; use cargo_test_support::project; use cargo_test_support::registry::Package; @@ -34,7 +36,10 @@ fn local() { p.cargo("generate-lockfile").run(); p.cargo("pkgid foo") - .with_stdout(format!("file://[..]{}#0.1.0", p.root().to_str().unwrap())) + .with_stdout(format!( + "path+file://[..]{}#0.1.0", + p.root().to_str().unwrap() + )) .run(); // Bad file URL. @@ -89,7 +94,7 @@ fn registry() { p.cargo("generate-lockfile").run(); p.cargo("pkgid crates-io") - .with_stdout("https://github.com/rust-lang/crates.io-index#crates-io@0.1.0") + .with_stdout("registry+https://github.com/rust-lang/crates.io-index#crates-io@0.1.0") .run(); // Bad URL. @@ -143,7 +148,7 @@ fn multiple_versions() { p.cargo("generate-lockfile").run(); p.cargo("pkgid two-ver:0.2.0") - .with_stdout("https://github.com/rust-lang/crates.io-index#two-ver@0.2.0") + .with_stdout("registry+https://github.com/rust-lang/crates.io-index#two-ver@0.2.0") .run(); // Incomplete version. @@ -163,7 +168,7 @@ Please re-run this command with one of the following specifications: p.cargo("pkgid two-ver@0.2") .with_stdout( "\ -https://github.com/rust-lang/crates.io-index#two-ver@0.2.0 +registry+https://github.com/rust-lang/crates.io-index#two-ver@0.2.0 ", ) .run(); @@ -195,3 +200,88 @@ Did you mean one of these? ) .run(); } + +// Not for `cargo pkgid` but the `PackageIdSpec` format +#[cargo_test] +fn multiple_git_same_version() { + // Test what happens if different packages refer to the same git repo with + // different refs, and the package version is the same. + let (xyz_project, xyz_repo) = git::new_repo("xyz", |project| { + project + .file("Cargo.toml", &basic_lib_manifest("xyz")) + .file("src/lib.rs", "fn example() {}") + }); + let rev1 = xyz_repo.revparse_single("HEAD").unwrap().id(); + xyz_project.change_file("src/lib.rs", "pub fn example() {}"); + git::add(&xyz_repo); + let rev2 = git::commit(&xyz_repo); + // Both rev1 and rev2 point to version 0.1.0. + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + name = "foo" + version = "0.1.0" + + [dependencies] + bar = {{ path = "bar" }} + xyz = {{ git = "{}", rev = "{}" }} + + "#, + xyz_project.url(), + rev1 + ), + ) + .file("src/lib.rs", "") + .file( + "bar/Cargo.toml", + &format!( + r#" + [package] + name = "bar" + version = "0.1.0" + + [dependencies] + xyz = {{ git = "{}", rev = "{}" }} + "#, + xyz_project.url(), + rev2 + ), + ) + .file("bar/src/lib.rs", "") + .build(); + + p.cargo("check").run(); + p.cargo("tree") + .with_stdout(&format!( + "\ +foo v0.1.0 ([..]/foo) +├── bar v0.1.0 ([..]/foo/bar) +│ └── xyz v0.5.0 (file://[..]/xyz?rev={}#{}) +└── xyz v0.5.0 (file://[..]/xyz?rev={}#{}) +", + rev2, + &rev2.to_string()[..8], + rev1, + &rev1.to_string()[..8] + )) + .run(); + // FIXME: This fails since xyz is ambiguous, but the + // possible pkgids are also ambiguous. + p.cargo("pkgid xyz") + .with_status(101) + .with_stderr( + "\ +error: There are multiple `xyz` packages in your project, and the specification `xyz` is ambiguous. +Please re-run this command with one of the following specifications: + git+file://[..]/xyz?rev=[..]#0.5.0 + git+file://[..]/xyz?rev=[..]#0.5.0 +", + ) + .run(); + // TODO, what should the `-p` value be here? + //p.cargo("update -p") +} diff --git a/src/tools/cargo/tests/testsuite/profile_config.rs b/src/tools/cargo/tests/testsuite/profile_config.rs index 710a0d8ef..f8a9ae744 100644 --- a/src/tools/cargo/tests/testsuite/profile_config.rs +++ b/src/tools/cargo/tests/testsuite/profile_config.rs @@ -1,6 +1,6 @@ //! Tests for profiles defined in config files. -use cargo::util::toml::schema::TomlDebugInfo; +use cargo::util_schemas::manifest::TomlDebugInfo; use cargo_test_support::paths::CargoPathExt; use cargo_test_support::registry::Package; use cargo_test_support::{basic_lib_manifest, paths, project}; @@ -428,8 +428,8 @@ fn named_config_profile() { let profiles = Profiles::new(&ws, profile_name).unwrap(); let crates_io = cargo::core::SourceId::crates_io(&config).unwrap(); - let a_pkg = PackageId::new("a", "0.1.0", crates_io).unwrap(); - let dep_pkg = PackageId::new("dep", "0.1.0", crates_io).unwrap(); + let a_pkg = PackageId::try_new("a", "0.1.0", crates_io).unwrap(); + let dep_pkg = PackageId::try_new("dep", "0.1.0", crates_io).unwrap(); // normal package let kind = CompileKind::Host; diff --git a/src/tools/cargo/tests/testsuite/profile_custom.rs b/src/tools/cargo/tests/testsuite/profile_custom.rs index f7139e552..cf9828d37 100644 --- a/src/tools/cargo/tests/testsuite/profile_custom.rs +++ b/src/tools/cargo/tests/testsuite/profile_custom.rs @@ -86,6 +86,10 @@ fn invalid_profile_name() { [ERROR] failed to parse manifest at [..] Caused by: + TOML parse error at line 7, column 26 + | + 7 | [profile.'.release-lto'] + | ^^^^^^^^^^^^^^ invalid character `.` in profile name `.release-lto` Allowed characters are letters, numbers, underscore, and hyphen. ", @@ -626,6 +630,7 @@ See https://doc.rust-lang.org/cargo/reference/profiles.html for more on configur ), ); + let highlight = "^".repeat(name.len()); p.cargo("build") .with_status(101) .with_stderr(&format!( @@ -633,11 +638,14 @@ See https://doc.rust-lang.org/cargo/reference/profiles.html for more on configur error: failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: - profile name `{}` is reserved + TOML parse error at line 6, column 30 + | + 6 | [profile.{name}] + | {highlight} + profile name `{name}` is reserved Please choose a different name. See https://doc.rust-lang.org/cargo/reference/profiles.html for more on configuring profiles. ", - name )) .run(); } @@ -663,6 +671,10 @@ Caused by: error: failed to parse manifest at `[ROOT]/foo/Cargo.toml` Caused by: + TOML parse error at line 7, column 25 + | + 7 | [profile.debug] + | ^^^^^ profile name `debug` is reserved To configure the default development profile, use the name `dev` as in [profile.dev] See https://doc.rust-lang.org/cargo/reference/profiles.html for more on configuring profiles. diff --git a/src/tools/cargo/tests/testsuite/profile_trim_paths.rs b/src/tools/cargo/tests/testsuite/profile_trim_paths.rs index 1d24c159b..8a883a004 100644 --- a/src/tools/cargo/tests/testsuite/profile_trim_paths.rs +++ b/src/tools/cargo/tests/testsuite/profile_trim_paths.rs @@ -83,8 +83,8 @@ fn release_profile_default_to_object() { [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..] + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [FINISHED] release [..]", ) .run(); @@ -121,8 +121,8 @@ fn one_option() { [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc [..]\ -Zremap-path-scope={option} \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..] + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [FINISHED] dev [..]", )) .run(); @@ -158,8 +158,8 @@ fn multiple_options() { [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc [..]\ -Zremap-path-scope=diagnostics,macro,object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..] + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [FINISHED] dev [..]", ) .run(); @@ -193,8 +193,8 @@ fn profile_merge_works() { [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc [..]\ -Zremap-path-scope=diagnostics \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..] + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [FINISHED] custom [..]", ) .run(); @@ -238,13 +238,13 @@ fn registry_dependency() { [COMPILING] bar v0.0.1 [RUNNING] `rustc [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix={pkg_remap} [..] + --remap-path-prefix={pkg_remap} \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..] + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [FINISHED] dev [..] [RUNNING] `target/debug/foo[EXE]`" )) @@ -292,13 +292,13 @@ fn git_dependency() { [COMPILING] bar v0.0.1 ({url}[..]) [RUNNING] `rustc [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix={pkg_remap} [..] + --remap-path-prefix={pkg_remap} \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..] + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [FINISHED] dev [..] [RUNNING] `target/debug/foo[EXE]`" )) @@ -338,13 +338,13 @@ fn path_dependency() { [COMPILING] bar v0.0.1 ([..]/cocktail-bar) [RUNNING] `rustc [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..] + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..] + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [FINISHED] dev [..] [RUNNING] `target/debug/foo[EXE]`" )) @@ -387,13 +387,13 @@ fn path_dependency_outside_workspace() { [COMPILING] bar v0.0.1 ([..]/bar) [RUNNING] `rustc [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix={bar_path}=bar-0.0.1 [..] + --remap-path-prefix={bar_path}=bar-0.0.1 \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [COMPILING] foo v0.0.1 ([CWD]) [RUNNING] `rustc [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..] + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [FINISHED] dev [..] [RUNNING] `target/debug/foo[EXE]`" )) @@ -439,31 +439,81 @@ fn diagnostics_works() { "\ [RUNNING] [..]rustc [..]\ -Zremap-path-scope=diagnostics \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix={pkg_remap} [..]", + --remap-path-prefix={pkg_remap} \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]", )) .with_stderr_contains( "\ [RUNNING] [..]rustc [..]\ -Zremap-path-scope=diagnostics \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..]", + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]", ) .run(); } +#[cfg(target_os = "macos")] +mod object_works { + use super::*; + + fn inspect_debuginfo(path: &std::path::Path) -> Vec<u8> { + std::process::Command::new("nm") + .arg("-pa") + .arg(path) + .output() + .expect("nm works") + .stdout + } + + #[cargo_test(requires_nm, nightly, reason = "-Zremap-path-scope is unstable")] + fn with_split_debuginfo_off() { + object_works_helper("off", inspect_debuginfo); + } + + #[cargo_test(requires_nm, nightly, reason = "-Zremap-path-scope is unstable")] + fn with_split_debuginfo_packed() { + object_works_helper("packed", inspect_debuginfo); + } + + #[cargo_test(requires_nm, nightly, reason = "-Zremap-path-scope is unstable")] + fn with_split_debuginfo_unpacked() { + object_works_helper("unpacked", inspect_debuginfo); + } +} + #[cfg(target_os = "linux")] -#[cargo_test(requires_readelf, nightly, reason = "-Zremap-path-scope is unstable")] -fn object_works() { - use std::os::unix::ffi::OsStrExt; +mod object_works { + use super::*; - let run_readelf = |path| { + fn inspect_debuginfo(path: &std::path::Path) -> Vec<u8> { std::process::Command::new("readelf") - .arg("-wi") + .arg("--debug-dump=info") + .arg("--debug-dump=no-follow-links") // older version can't recognized but just a warning .arg(path) .output() .expect("readelf works") - }; + .stdout + } + + #[cargo_test(requires_readelf, nightly, reason = "-Zremap-path-scope is unstable")] + fn with_split_debuginfo_off() { + object_works_helper("off", inspect_debuginfo); + } + + #[cargo_test(requires_readelf, nightly, reason = "-Zremap-path-scope is unstable")] + fn with_split_debuginfo_packed() { + object_works_helper("packed", inspect_debuginfo); + } + + #[cargo_test(requires_readelf, nightly, reason = "-Zremap-path-scope is unstable")] + fn with_split_debuginfo_unpacked() { + object_works_helper("unpacked", inspect_debuginfo); + } +} + +#[cfg(unix)] +fn object_works_helper(split_debuginfo: &str, run: impl Fn(&std::path::Path) -> Vec<u8>) { + use std::os::unix::ffi::OsStrExt; let registry_src = paths::home().join(".cargo/registry/src"); let pkg_remap = format!("{}/[..]/bar-0.0.1=bar-0.0.1", registry_src.display()); @@ -478,14 +528,19 @@ fn object_works() { let p = project() .file( "Cargo.toml", - r#" + &format!( + r#" [package] name = "foo" version = "0.0.1" [dependencies] bar = "0.0.1" - "#, + + [profile.dev] + split-debuginfo = "{split_debuginfo}" + "# + ), ) .file("src/main.rs", "fn main() { bar::f(); }") .build(); @@ -497,7 +552,7 @@ fn object_works() { let bin_path = p.bin("foo"); assert!(bin_path.is_file()); - let stdout = run_readelf(bin_path).stdout; + let stdout = run(&bin_path); // TODO: re-enable this check when rustc bootstrap disables remapping // <https://github.com/rust-lang/cargo/pull/12625#discussion_r1371714791> // assert!(memchr::memmem::find(&stdout, rust_src).is_some()); @@ -506,45 +561,69 @@ fn object_works() { p.cargo("clean").run(); - p.change_file( - "Cargo.toml", - r#" - [package] - name = "foo" - version = "0.0.1" - - [dependencies] - bar = "0.0.1" - - [profile.dev] - trim-paths = "object" - "#, - ); - p.cargo("build --verbose -Ztrim-paths") + .arg("--config") + .arg(r#"profile.dev.trim-paths="object""#) .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) .with_stderr(&format!( "\ [COMPILING] bar v0.0.1 -[RUNNING] `rustc [..]\ +[RUNNING] `rustc [..]-C split-debuginfo={split_debuginfo} [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix={pkg_remap} [..] + --remap-path-prefix={pkg_remap} \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [COMPILING] foo v0.0.1 ([CWD]) -[RUNNING] `rustc [..]\ +[RUNNING] `rustc [..]-C split-debuginfo={split_debuginfo} [..]\ -Zremap-path-scope=object \ - --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] \ - --remap-path-prefix=[CWD]= [..] + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..] [FINISHED] dev [..]", )) .run(); let bin_path = p.bin("foo"); assert!(bin_path.is_file()); - let stdout = run_readelf(bin_path).stdout; + let stdout = run(&bin_path); assert!(memchr::memmem::find(&stdout, rust_src).is_none()); - assert!(memchr::memmem::find(&stdout, registry_src_bytes).is_none()); - assert!(memchr::memmem::find(&stdout, pkg_root).is_none()); + for line in stdout.split(|c| c == &b'\n') { + let registry = memchr::memmem::find(line, registry_src_bytes).is_none(); + let local = memchr::memmem::find(line, pkg_root).is_none(); + if registry && local { + continue; + } + + #[cfg(target_os = "macos")] + { + // `OSO` symbols can't be trimmed at this moment. + // See <https://github.com/rust-lang/rust/issues/116948#issuecomment-1793617018> + if memchr::memmem::find(line, b" OSO ").is_some() { + continue; + } + + // on macOS `SO` symbols are embedded in final binaries and should be trimmed. + // See rust-lang/rust#117652. + if memchr::memmem::find(line, b" SO ").is_some() { + continue; + } + } + + #[cfg(target_os = "linux")] + { + // There is a bug in rustc `-Zremap-path-scope`. + // See rust-lang/rust/pull/118518 + if memchr::memmem::find(line, b"DW_AT_comp_dir").is_some() { + continue; + } + if memchr::memmem::find(line, b"DW_AT_GNU_dwo_name").is_some() { + continue; + } + } + + panic!( + "unexpected untrimmed symbol: {}", + String::from_utf8(line.into()).unwrap() + ); + } } // TODO: might want to move to test/testsuite/build_script.rs once stabilized. @@ -612,3 +691,69 @@ fn custom_build_env_var_trim_paths() { .run(); } } + +#[cfg(unix)] +#[cargo_test(requires_lldb, nightly, reason = "-Zremap-path-scope is unstable")] +fn lldb_works_after_trimmed() { + use cargo_test_support::compare::match_contains; + + let run_lldb = |path| { + std::process::Command::new("lldb") + .args(["-o", "breakpoint set --file src/main.rs --line 4"]) + .args(["-o", "run"]) + .args(["-o", "continue"]) + .args(["-o", "exit"]) + .arg("--no-use-colors") + .arg(path) + .output() + .expect("lldb works") + }; + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + + [profile.dev] + trim-paths = "object" + "#, + ) + .file( + "src/main.rs", + r#" + fn main() { + let msg = "Hello, Ferris!"; + println!("{msg}"); + } + "#, + ) + .build(); + + p.cargo("build --verbose -Ztrim-paths") + .masquerade_as_nightly_cargo(&["-Ztrim-paths"]) + .with_stderr_contains( + "\ +[RUNNING] `rustc [..]\ + -Zremap-path-scope=object \ + --remap-path-prefix=[CWD]=. \ + --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]", + ) + .run(); + + let bin_path = p.bin("foo"); + assert!(bin_path.is_file()); + let stdout = String::from_utf8(run_lldb(bin_path).stdout).unwrap(); + match_contains("[..]stopped[..]", &stdout, None).unwrap(); + match_contains("[..]stop reason = breakpoint[..]", &stdout, None).unwrap(); + match_contains( + "\ +(lldb) continue +Hello, Ferris!", + &stdout, + None, + ) + .unwrap(); +} diff --git a/src/tools/cargo/tests/testsuite/pub_priv.rs b/src/tools/cargo/tests/testsuite/pub_priv.rs index b2160e0fa..b3d87ce4c 100644 --- a/src/tools/cargo/tests/testsuite/pub_priv.rs +++ b/src/tools/cargo/tests/testsuite/pub_priv.rs @@ -199,7 +199,7 @@ Caused by: } #[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")] -fn workspace_dep_made_public() { +fn workspace_pub_disallowed() { Package::new("foo1", "0.1.0") .file("src/lib.rs", "pub struct FromFoo;") .publish(); @@ -244,5 +244,238 @@ fn workspace_dep_made_public() { p.cargo("check") .masquerade_as_nightly_cargo(&["public-dependency"]) + .with_status(101) + .with_stderr( + "\ +error: failed to parse manifest at `[CWD]/Cargo.toml` + +Caused by: + foo2 is public, but workspace dependencies cannot be public +", + ) + .run() +} + +#[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")] +fn allow_priv_in_tests() { + Package::new("priv_dep", "0.1.0") + .file("src/lib.rs", "pub struct FromPriv;") + .publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["public-dependency"] + + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + priv_dep = {version = "0.1.0", public = false} + "#, + ) + .file( + "tests/mod.rs", + " + extern crate priv_dep; + pub fn use_priv(_: priv_dep::FromPriv) {} + ", + ) + .build(); + + p.cargo("check --tests --message-format=short") + .masquerade_as_nightly_cargo(&["public-dependency"]) + .with_stderr( + "\ +[UPDATING] `[..]` index +[DOWNLOADING] crates ... +[DOWNLOADED] priv_dep v0.1.0 ([..]) +[CHECKING] priv_dep v0.1.0 +[CHECKING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run() +} + +#[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")] +fn allow_priv_in_benchs() { + Package::new("priv_dep", "0.1.0") + .file("src/lib.rs", "pub struct FromPriv;") + .publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["public-dependency"] + + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + priv_dep = {version = "0.1.0", public = false} + "#, + ) + .file( + "benches/mod.rs", + " + extern crate priv_dep; + pub fn use_priv(_: priv_dep::FromPriv) {} + ", + ) + .build(); + + p.cargo("check --benches --message-format=short") + .masquerade_as_nightly_cargo(&["public-dependency"]) + .with_stderr( + "\ +[UPDATING] `[..]` index +[DOWNLOADING] crates ... +[DOWNLOADED] priv_dep v0.1.0 ([..]) +[CHECKING] priv_dep v0.1.0 +[CHECKING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run() +} + +#[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")] +fn allow_priv_in_bins() { + Package::new("priv_dep", "0.1.0") + .file("src/lib.rs", "pub struct FromPriv;") + .publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["public-dependency"] + + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + priv_dep = {version = "0.1.0", public = false} + "#, + ) + .file( + "src/main.rs", + " + extern crate priv_dep; + pub fn use_priv(_: priv_dep::FromPriv) {} + fn main() {} + ", + ) + .build(); + + p.cargo("check --bins --message-format=short") + .masquerade_as_nightly_cargo(&["public-dependency"]) + .with_stderr( + "\ +[UPDATING] `[..]` index +[DOWNLOADING] crates ... +[DOWNLOADED] priv_dep v0.1.0 ([..]) +[CHECKING] priv_dep v0.1.0 +[CHECKING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run() +} + +#[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")] +fn allow_priv_in_examples() { + Package::new("priv_dep", "0.1.0") + .file("src/lib.rs", "pub struct FromPriv;") + .publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["public-dependency"] + + [package] + name = "foo" + version = "0.0.1" + + [dependencies] + priv_dep = {version = "0.1.0", public = false} + "#, + ) + .file( + "examples/lib.rs", + " + extern crate priv_dep; + pub fn use_priv(_: priv_dep::FromPriv) {} + fn main() {} + ", + ) + .build(); + + p.cargo("check --examples --message-format=short") + .masquerade_as_nightly_cargo(&["public-dependency"]) + .with_stderr( + "\ +[UPDATING] `[..]` index +[DOWNLOADING] crates ... +[DOWNLOADED] priv_dep v0.1.0 ([..]) +[CHECKING] priv_dep v0.1.0 +[CHECKING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run() +} + +#[cargo_test(nightly, reason = "exported_private_dependencies lint is unstable")] +fn allow_priv_in_custom_build() { + Package::new("priv_dep", "0.1.0") + .file("src/lib.rs", "pub struct FromPriv;") + .publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["public-dependency"] + + [package] + name = "foo" + version = "0.0.1" + + [build-dependencies] + priv_dep = "0.1.0" + "#, + ) + .file("src/main.rs", "fn main() {}") + .file( + "build.rs", + " + extern crate priv_dep; + pub fn use_priv(_: priv_dep::FromPriv) {} + fn main() {} + ", + ) + .build(); + + p.cargo("check --all-targets --message-format=short") + .masquerade_as_nightly_cargo(&["public-dependency"]) + .with_stderr( + "\ +[UPDATING] `[..]` index +[DOWNLOADING] crates ... +[DOWNLOADED] priv_dep v0.1.0 ([..]) +[COMPILING] priv_dep v0.1.0 +[COMPILING] foo v0.0.1 ([CWD]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) .run() } diff --git a/src/tools/cargo/tests/testsuite/publish_lockfile.rs b/src/tools/cargo/tests/testsuite/publish_lockfile.rs index 35da5131f..0a7c23368 100644 --- a/src/tools/cargo/tests/testsuite/publish_lockfile.rs +++ b/src/tools/cargo/tests/testsuite/publish_lockfile.rs @@ -92,7 +92,17 @@ src/main.rs ", ) .run(); - p.cargo("package").with_stdout("").run(); + p.cargo("package") + .with_stderr( + "\ +[PACKAGING] foo v0.0.1 [..] +[VERIFYING] foo v0.0.1 [..] +[COMPILING] foo v0.0.1 [..] +[FINISHED] [..] +[PACKAGED] 4 files, [..] +", + ) + .run(); let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); validate_crate_contents( diff --git a/src/tools/cargo/tests/testsuite/registry.rs b/src/tools/cargo/tests/testsuite/registry.rs index b5dff2746..6107b6f59 100644 --- a/src/tools/cargo/tests/testsuite/registry.rs +++ b/src/tools/cargo/tests/testsuite/registry.rs @@ -549,7 +549,7 @@ fn lockfile_locks() { p.root().move_into_the_past(); Package::new("bar", "0.0.2").publish(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -602,7 +602,7 @@ fn lockfile_locks_transitively() { Package::new("baz", "0.0.2").publish(); Package::new("bar", "0.0.2").dep("baz", "*").publish(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -739,7 +739,7 @@ fn yanks_in_lockfiles_are_ok() { Package::new("bar", "0.0.1").yanked(true).publish(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); p.cargo("update") .with_status(101) @@ -792,7 +792,7 @@ fn yanks_in_lockfiles_are_ok_for_other_update() { Package::new("bar", "0.0.1").yanked(true).publish(); Package::new("baz", "0.0.1").publish(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); Package::new("baz", "0.0.2").publish(); @@ -868,7 +868,18 @@ fn yanks_in_lockfiles_are_ok_with_new_dep() { "#, ); - p.cargo("check").with_stdout("").run(); + p.cargo("check") + .with_stderr( + "\ +[UPDATING] `dummy-registry` index +[DOWNLOADING] crates ... +[DOWNLOADED] baz v0.0.1 (registry `dummy-registry`) +[CHECKING] baz v0.0.1 +[CHECKING] foo v0.0.1 [..] +[FINISHED] [..] +", + ) + .run(); } #[cargo_test] @@ -1272,7 +1283,7 @@ fn git_and_registry_dep() { p.root().move_into_the_past(); println!("second"); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] diff --git a/src/tools/cargo/tests/testsuite/replace.rs b/src/tools/cargo/tests/testsuite/replace.rs index b9de51d2f..6c31a023e 100644 --- a/src/tools/cargo/tests/testsuite/replace.rs +++ b/src/tools/cargo/tests/testsuite/replace.rs @@ -305,7 +305,7 @@ fn transitive() { ) .run(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -354,7 +354,7 @@ fn persists_across_rebuilds() { ) .run(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -530,7 +530,7 @@ fn override_adds_some_deps() { ) .run(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); Package::new("baz", "0.1.2").publish(); p.cargo("update") @@ -550,7 +550,7 @@ fn override_adds_some_deps() { ) .run(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -601,8 +601,8 @@ fn locked_means_locked_yes_no_seriously_i_mean_locked() { p.cargo("check").run(); - p.cargo("check").with_stdout("").run(); - p.cargo("check").with_stdout("").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); + p.cargo("check").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -1399,7 +1399,7 @@ fn override_respects_spec_metadata() { [..] [..] [..] -error: could not compile `foo` (lib) due to previous error +error: could not compile `foo` (lib) due to 1 previous error ", ) .with_status(101) diff --git a/src/tools/cargo/tests/testsuite/rust_version.rs b/src/tools/cargo/tests/testsuite/rust_version.rs index 21321b7c5..d0ea33c83 100644 --- a/src/tools/cargo/tests/testsuite/rust_version.rs +++ b/src/tools/cargo/tests/testsuite/rust_version.rs @@ -245,49 +245,81 @@ fn dependency_rust_version_newer_than_package() { .file("src/main.rs", "fn main(){}") .build(); + p.cargo("check") + .arg("-Zmsrv-policy") + .masquerade_as_nightly_cargo(&["msrv-policy"]) + .run(); p.cargo("check --ignore-rust-version") .arg("-Zmsrv-policy") .masquerade_as_nightly_cargo(&["msrv-policy"]) - // This shouldn't fail - .with_status(101) + .run(); +} + +#[cargo_test] +fn dependency_rust_version_older_and_newer_than_package() { + Package::new("bar", "1.5.0") + .rust_version("1.55.0") + .file("src/lib.rs", "fn other_stuff() {}") + .publish(); + Package::new("bar", "1.6.0") + .rust_version("1.65.0") + .file("src/lib.rs", "fn other_stuff() {}") + .publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + rust-version = "1.60.0" + [dependencies] + bar = "1.0.0" + "#, + ) + .file("src/main.rs", "fn main(){}") + .build(); + + p.cargo("check --ignore-rust-version") + .arg("-Zmsrv-policy") + .masquerade_as_nightly_cargo(&["msrv-policy"]) + // This should pick 1.6.0 .with_stderr( "\ [UPDATING] `dummy-registry` index -[ERROR] failed to select a version for the requirement `bar = \"^1.0.0\"` -candidate versions found which didn't match: 1.6.0 -location searched: `dummy-registry` index (which is replacing registry `crates-io`) -required by package `foo v0.0.1 ([CWD])` -perhaps a crate was updated and forgotten to be re-vendored? +[DOWNLOADING] crates ... +[DOWNLOADED] bar v1.5.0 (registry `dummy-registry`) +[CHECKING] bar v1.5.0 +[CHECKING] [..] +[FINISHED] [..] ", ) .run(); p.cargo("check") .arg("-Zmsrv-policy") .masquerade_as_nightly_cargo(&["msrv-policy"]) - .with_status(101) - // This should have a better error message .with_stderr( "\ -[UPDATING] `dummy-registry` index -[ERROR] failed to select a version for the requirement `bar = \"^1.0.0\"` -candidate versions found which didn't match: 1.6.0 -location searched: `dummy-registry` index (which is replacing registry `crates-io`) -required by package `foo v0.0.1 ([CWD])` -perhaps a crate was updated and forgotten to be re-vendored? +[FINISHED] [..] ", ) .run(); } #[cargo_test] -fn dependency_rust_version_older_and_newer_than_package() { - Package::new("bar", "1.5.0") - .rust_version("1.55.0") +fn dependency_rust_version_backtracking() { + Package::new("has-rust-version", "1.6.0") + .rust_version("1.65.0") .file("src/lib.rs", "fn other_stuff() {}") .publish(); - Package::new("bar", "1.6.0") - .rust_version("1.65.0") + Package::new("no-rust-version", "2.1.0") + .file("src/lib.rs", "fn other_stuff() {}") + .publish(); + Package::new("no-rust-version", "2.2.0") .file("src/lib.rs", "fn other_stuff() {}") + .dep("has-rust-version", "1.6.0") .publish(); let p = project() @@ -300,7 +332,7 @@ fn dependency_rust_version_older_and_newer_than_package() { authors = [] rust-version = "1.60.0" [dependencies] - bar = "1.0.0" + no-rust-version = "2" "#, ) .file("src/main.rs", "fn main(){}") @@ -309,13 +341,14 @@ fn dependency_rust_version_older_and_newer_than_package() { p.cargo("check --ignore-rust-version") .arg("-Zmsrv-policy") .masquerade_as_nightly_cargo(&["msrv-policy"]) - // This should pick 1.6.0 .with_stderr( "\ [UPDATING] `dummy-registry` index [DOWNLOADING] crates ... -[DOWNLOADED] bar v1.5.0 (registry `dummy-registry`) -[CHECKING] bar v1.5.0 +[DOWNLOADED] no-rust-version v2.2.0 (registry `dummy-registry`) +[DOWNLOADED] has-rust-version v1.6.0 (registry `dummy-registry`) +[CHECKING] has-rust-version v1.6.0 +[CHECKING] no-rust-version v2.2.0 [CHECKING] [..] [FINISHED] [..] ", diff --git a/src/tools/cargo/tests/testsuite/rustflags.rs b/src/tools/cargo/tests/testsuite/rustflags.rs index 6677beb04..788889951 100644 --- a/src/tools/cargo/tests/testsuite/rustflags.rs +++ b/src/tools/cargo/tests/testsuite/rustflags.rs @@ -456,7 +456,7 @@ fn env_rustflags_no_recompile() { p.cargo("check").env("RUSTFLAGS", "--cfg foo").run(); p.cargo("check") .env("RUSTFLAGS", "--cfg foo") - .with_stdout("") + .with_stderr("[FINISHED] [..]") .run(); } @@ -944,7 +944,7 @@ fn build_rustflags_no_recompile() { p.cargo("check").env("RUSTFLAGS", "--cfg foo").run(); p.cargo("check") .env("RUSTFLAGS", "--cfg foo") - .with_stdout("") + .with_stderr("[FINISHED] [..]") .run(); } @@ -1658,7 +1658,7 @@ fn host_config_rustflags_with_target() { // regression test for https://github.com/rust-lang/cargo/issues/10206 let p = project() .file("src/lib.rs", "") - .file("build.rs.rs", "fn main() { assert!(cfg!(foo)); }") + .file("build.rs", "fn main() { assert!(cfg!(foo)); }") .file(".cargo/config.toml", "target-applies-to-host = false") .build(); diff --git a/src/tools/cargo/tests/testsuite/test.rs b/src/tools/cargo/tests/testsuite/test.rs index 5f6528109..6357b950c 100644 --- a/src/tools/cargo/tests/testsuite/test.rs +++ b/src/tools/cargo/tests/testsuite/test.rs @@ -1433,7 +1433,7 @@ fn test_then_build() { .with_stdout_contains("running 0 tests") .run(); - p.cargo("build").with_stdout("").run(); + p.cargo("build").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -2423,7 +2423,7 @@ fn dylib_doctest2() { ) .build(); - p.cargo("test").with_stdout("").run(); + p.cargo("test").with_stderr("[FINISHED] [..]").run(); } #[cargo_test] @@ -3556,6 +3556,39 @@ fn cyclic_dev() { } #[cargo_test] +fn cyclical_dep_with_missing_feature() { + // Checks for error handling when a cyclical dev-dependency specify a + // feature that doesn't exist. + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + + [dev-dependencies] + foo = { path = ".", features = ["missing"] } + "#, + ) + .file("src/lib.rs", "") + .build(); + p.cargo("check") + .with_status(101) + .with_stderr( + "error: failed to select a version for `foo`. + ... required by package `foo v0.1.0 ([..]/foo)` +versions that meet the requirements `*` are: 0.1.0 + +the package `foo` depends on `foo`, with features: `missing` but `foo` does not have these features. + + +failed to select a version for `foo` which could resolve this conflict", + ) + .run(); +} + +#[cargo_test] fn publish_a_crate_without_tests() { Package::new("testless", "0.1.0") .file( diff --git a/src/tools/cargo/tests/testsuite/update.rs b/src/tools/cargo/tests/testsuite/update.rs index e636435b0..40bc0b476 100644 --- a/src/tools/cargo/tests/testsuite/update.rs +++ b/src/tools/cargo/tests/testsuite/update.rs @@ -1091,11 +1091,8 @@ rustdns.workspace = true p.cargo("update -p rootcrate") .with_stderr(&format!( "\ -[UPDATING] git repository `{}` [UPDATING] rootcrate v2.29.8 ([CWD]/rootcrate) -> v2.29.81 -[UPDATING] rustdns v0.5.0 ([..]) -> [..] [UPDATING] subcrate v2.29.8 ([CWD]/subcrate) -> v2.29.81", - git_project.url(), )) .run(); } @@ -1182,11 +1179,96 @@ rustdns.workspace = true p.cargo("update -p crate2") .with_stderr(&format!( "\ -[UPDATING] git repository `{}` [UPDATING] crate1 v2.29.8 ([CWD]/crate1) -> v2.29.81 -[UPDATING] crate2 v2.29.8 ([CWD]/crate2) -> v2.29.81 -[UPDATING] rustdns v0.5.0 ([..]) -> [..]", +[UPDATING] crate2 v2.29.8 ([CWD]/crate2) -> v2.29.81", + )) + .run(); +} + +#[cargo_test] +fn update_only_members_with_workspace() { + let git_project = git::new("rustdns", |project| { + project + .file("Cargo.toml", &basic_lib_manifest("rustdns")) + .file("src/lib.rs", "pub fn bar() {}") + }); + + let workspace_toml = format!( + r#" +[workspace.package] +version = "2.29.8" +edition = "2021" +publish = false + +[workspace] +members = [ + "crate2", + "crate1", +] +resolver = "2" + +[workspace.dependencies] +# Internal crates +crate1 = {{ version = "*", path = "./crate1" }} + +# External dependencies +rustdns = {{ version = "0.5.0", default-features = false, git = "{}" }} + "#, + git_project.url() + ); + let p = project() + .file("Cargo.toml", &workspace_toml) + .file( + "crate2/Cargo.toml", + r#" +[package] +name = "crate2" +version.workspace = true +edition.workspace = true +publish.workspace = true + +[dependencies] +crate1.workspace = true +"#, + ) + .file("crate2/src/main.rs", "fn main() {}") + .file( + "crate1/Cargo.toml", + r#" +[package] +name = "crate1" +version.workspace = true +edition.workspace = true +publish.workspace = true + +[dependencies] +rustdns.workspace = true +"#, + ) + .file("crate1/src/lib.rs", "pub foo() {}") + .build(); + + // First time around we should compile both foo and bar + p.cargo("generate-lockfile") + .with_stderr(&format!( + "[UPDATING] git repository `{}`\n", git_project.url(), )) .run(); + // Modify a file manually, shouldn't trigger a recompile + git_project.change_file("src/lib.rs", r#"pub fn bar() { println!("hello!"); }"#); + // Commit the changes and make sure we don't trigger a recompile because the + // lock file says not to change + let repo = git2::Repository::open(&git_project.root()).unwrap(); + git::add(&repo); + git::commit(&repo); + p.change_file("Cargo.toml", &workspace_toml.replace("2.29.8", "2.29.81")); + + p.cargo("update --workspace") + .with_stderr( + "\ +[UPDATING] crate1 v2.29.8 ([CWD]/crate1) -> v2.29.81 +[UPDATING] crate2 v2.29.8 ([CWD]/crate2) -> v2.29.81", + ) + .run(); } diff --git a/src/tools/cargo/tests/testsuite/workspaces.rs b/src/tools/cargo/tests/testsuite/workspaces.rs index 94b5142f4..53ddc1616 100644 --- a/src/tools/cargo/tests/testsuite/workspaces.rs +++ b/src/tools/cargo/tests/testsuite/workspaces.rs @@ -2198,6 +2198,7 @@ fn ws_err_unused() { "[features]", "[target]", "[badges]", + "[lints]", ] { let p = project() .file( |