From 10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:41:41 +0200 Subject: Merging upstream version 1.70.0+dfsg2. Signed-off-by: Daniel Baumann --- .../cargo/tests/testsuite/publish_lockfile.rs | 592 +++++++++++++++++++++ 1 file changed, 592 insertions(+) create mode 100644 src/tools/cargo/tests/testsuite/publish_lockfile.rs (limited to 'src/tools/cargo/tests/testsuite/publish_lockfile.rs') diff --git a/src/tools/cargo/tests/testsuite/publish_lockfile.rs b/src/tools/cargo/tests/testsuite/publish_lockfile.rs new file mode 100644 index 000000000..35da5131f --- /dev/null +++ b/src/tools/cargo/tests/testsuite/publish_lockfile.rs @@ -0,0 +1,592 @@ +//! Tests for including `Cargo.lock` when publishing/packaging. + +use std::fs::File; + +use cargo_test_support::registry::Package; +use cargo_test_support::{ + basic_manifest, cargo_process, git, paths, project, publish::validate_crate_contents, +}; + +fn pl_manifest(name: &str, version: &str, extra: &str) -> String { + format!( + r#" + [package] + name = "{}" + version = "{}" + authors = [] + license = "MIT" + description = "foo" + documentation = "foo" + homepage = "foo" + repository = "foo" + + {} + "#, + name, version, extra + ) +} + +#[cargo_test] +fn removed() { + let p = project() + .file( + "Cargo.toml", + r#" + cargo-features = ["publish-lockfile"] + [package] + name = "foo" + version = "0.1.0" + publish-lockfile = true + license = "MIT" + description = "foo" + documentation = "foo" + homepage = "foo" + repository = "foo" + "#, + ) + .file("src/lib.rs", "") + .build(); + p.cargo("package") + .masquerade_as_nightly_cargo(&["publish-lockfile"]) + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to parse manifest at [..] + +Caused by: + the cargo feature `publish-lockfile` has been removed in the 1.37 release + + Remove the feature from Cargo.toml to remove this error. + See https://doc.rust-lang.org/[..]cargo/reference/unstable.html#publish-lockfile [..] +", + ) + .run(); +} + +#[cargo_test] +fn package_lockfile() { + let p = project() + .file("Cargo.toml", &pl_manifest("foo", "0.0.1", "")) + .file("src/main.rs", "fn main() {}") + .build(); + + 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] [..] files, [..] ([..] compressed) +", + ) + .run(); + assert!(p.root().join("target/package/foo-0.0.1.crate").is_file()); + p.cargo("package -l") + .with_stdout( + "\ +Cargo.lock +Cargo.toml +Cargo.toml.orig +src/main.rs +", + ) + .run(); + p.cargo("package").with_stdout("").run(); + + let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "Cargo.lock", "src/main.rs"], + &[], + ); +} + +#[cargo_test] +fn package_lockfile_git_repo() { + // Create a Git repository containing a minimal Rust project. + let g = git::repo(&paths::root().join("foo")) + .file("Cargo.toml", &pl_manifest("foo", "0.0.1", "")) + .file("src/main.rs", "fn main() {}") + .build(); + cargo_process("package -l") + .cwd(g.root()) + .with_stdout( + "\ +.cargo_vcs_info.json +Cargo.lock +Cargo.toml +Cargo.toml.orig +src/main.rs +", + ) + .run(); + cargo_process("package -v") + .cwd(g.root()) + .with_stderr( + "\ +[PACKAGING] foo v0.0.1 ([..]) +[ARCHIVING] .cargo_vcs_info.json +[ARCHIVING] Cargo.lock +[ARCHIVING] Cargo.toml +[ARCHIVING] Cargo.toml.orig +[ARCHIVING] src/main.rs +[VERIFYING] foo v0.0.1 ([..]) +[COMPILING] foo v0.0.1 ([..]) +[RUNNING] `rustc --crate-name foo src/main.rs [..] +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[PACKAGED] 5 files, [..] ([..] compressed) +", + ) + .run(); +} + +#[cargo_test] +fn no_lock_file_with_library() { + let p = project() + .file("Cargo.toml", &pl_manifest("foo", "0.0.1", "")) + .file("src/lib.rs", "") + .build(); + + p.cargo("package").run(); + + let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/lib.rs"], + &[], + ); +} + +#[cargo_test] +fn lock_file_and_workspace() { + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + members = ["foo"] + "#, + ) + .file("foo/Cargo.toml", &pl_manifest("foo", "0.0.1", "")) + .file("foo/src/main.rs", "fn main() {}") + .build(); + + p.cargo("package").cwd("foo").run(); + + let f = File::open(&p.root().join("target/package/foo-0.0.1.crate")).unwrap(); + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.toml", "Cargo.toml.orig", "src/main.rs", "Cargo.lock"], + &[], + ); +} + +#[cargo_test] +fn note_resolve_changes() { + // `multi` has multiple sources (path and registry). + Package::new("multi", "0.1.0").publish(); + // `updated` is always from registry, but should not change. + Package::new("updated", "1.0.0").publish(); + // `patched` is [patch]ed. + Package::new("patched", "1.0.0").publish(); + + let p = project() + .file( + "Cargo.toml", + &pl_manifest( + "foo", + "0.0.1", + r#" + [dependencies] + multi = { path = "multi", version = "0.1" } + updated = "1.0" + patched = "1.0" + + [patch.crates-io] + patched = { path = "patched" } + "#, + ), + ) + .file("src/main.rs", "fn main() {}") + .file("multi/Cargo.toml", &basic_manifest("multi", "0.1.0")) + .file("multi/src/lib.rs", "") + .file("patched/Cargo.toml", &basic_manifest("patched", "1.0.0")) + .file("patched/src/lib.rs", "") + .build(); + + p.cargo("generate-lockfile").run(); + + // Make sure this does not change or warn. + Package::new("updated", "1.0.1").publish(); + + p.cargo("package --no-verify -v --allow-dirty") + .with_stderr_unordered( + "\ +[PACKAGING] foo v0.0.1 ([..]) +[ARCHIVING] Cargo.lock +[ARCHIVING] Cargo.toml +[ARCHIVING] Cargo.toml.orig +[ARCHIVING] src/main.rs +[UPDATING] `[..]` index +[NOTE] package `multi v0.1.0` added to the packaged Cargo.lock file, was originally sourced from `[..]/foo/multi` +[NOTE] package `patched v1.0.0` added to the packaged Cargo.lock file, was originally sourced from `[..]/foo/patched` +[PACKAGED] [..] files, [..] ([..] compressed) +", + ) + .run(); +} + +#[cargo_test] +fn outdated_lock_version_change_does_not_warn() { + // If the version of the package being packaged changes, but Cargo.lock is + // not updated, don't bother warning about it. + let p = project() + .file("Cargo.toml", &pl_manifest("foo", "0.1.0", "")) + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("generate-lockfile").run(); + + p.change_file("Cargo.toml", &pl_manifest("foo", "0.2.0", "")); + + p.cargo("package --no-verify") + .with_stderr( + "\ +[PACKAGING] foo v0.2.0 ([..]) +[PACKAGED] [..] files, [..] ([..] compressed) +", + ) + .run(); +} + +#[cargo_test] +fn no_warn_workspace_extras() { + // Other entries in workspace lock file should be ignored. + Package::new("dep1", "1.0.0").publish(); + Package::new("dep2", "1.0.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [workspace] + members = ["a", "b"] + "#, + ) + .file( + "a/Cargo.toml", + &pl_manifest( + "a", + "0.1.0", + r#" + [dependencies] + dep1 = "1.0" + "#, + ), + ) + .file("a/src/main.rs", "fn main() {}") + .file( + "b/Cargo.toml", + &pl_manifest( + "b", + "0.1.0", + r#" + [dependencies] + dep2 = "1.0" + "#, + ), + ) + .file("b/src/main.rs", "fn main() {}") + .build(); + p.cargo("generate-lockfile").run(); + p.cargo("package --no-verify") + .cwd("a") + .with_stderr( + "\ +[PACKAGING] a v0.1.0 ([..]) +[UPDATING] `[..]` index +[PACKAGED] [..] files, [..] ([..] compressed) +", + ) + .run(); +} + +#[cargo_test] +fn warn_package_with_yanked() { + Package::new("bar", "0.1.0").publish(); + let p = project() + .file( + "Cargo.toml", + &pl_manifest( + "foo", + "0.0.1", + r#" + [dependencies] + bar = "0.1" + "#, + ), + ) + .file("src/main.rs", "fn main() {}") + .build(); + p.cargo("generate-lockfile").run(); + Package::new("bar", "0.1.0").yanked(true).publish(); + // Make sure it sticks with the locked (yanked) version. + Package::new("bar", "0.1.1").publish(); + p.cargo("package --no-verify") + .with_stderr( + "\ +[PACKAGING] foo v0.0.1 ([..]) +[UPDATING] `[..]` index +[WARNING] package `bar v0.1.0` in Cargo.lock is yanked in registry \ + `crates-io`, consider updating to a version that is not yanked +[PACKAGED] [..] files, [..] ([..] compressed) +", + ) + .run(); +} + +#[cargo_test] +fn warn_install_with_yanked() { + Package::new("bar", "0.1.0").yanked(true).publish(); + Package::new("bar", "0.1.1").publish(); + Package::new("foo", "0.1.0") + .dep("bar", "0.1") + .file("src/main.rs", "fn main() {}") + .file( + "Cargo.lock", + r#" +[[package]] +name = "bar" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "foo" +version = "0.1.0" +dependencies = [ + "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + "#, + ) + .publish(); + + cargo_process("install --locked foo") + .with_stderr( + "\ +[UPDATING] `[..]` index +[DOWNLOADING] crates ... +[DOWNLOADED] foo v0.1.0 (registry `[..]`) +[INSTALLING] foo v0.1.0 +[WARNING] package `bar v0.1.0` in Cargo.lock is yanked in registry \ + `crates-io`, consider running without --locked +[DOWNLOADING] crates ... +[DOWNLOADED] bar v0.1.0 (registry `[..]`) +[COMPILING] bar v0.1.0 +[COMPILING] foo v0.1.0 +[FINISHED] release [optimized] target(s) in [..] +[INSTALLING] [..]/.cargo/bin/foo[EXE] +[INSTALLED] package `foo v0.1.0` (executable `foo[EXE]`) +[WARNING] be sure to add [..] +", + ) + .run(); + + // Try again without --locked, make sure it uses 0.1.1 and does not warn. + cargo_process("install --force foo") + .with_stderr( + "\ +[UPDATING] `[..]` index +[INSTALLING] foo v0.1.0 +[DOWNLOADING] crates ... +[DOWNLOADED] bar v0.1.1 (registry `[..]`) +[COMPILING] bar v0.1.1 +[COMPILING] foo v0.1.0 +[FINISHED] release [optimized] target(s) in [..] +[REPLACING] [..]/.cargo/bin/foo[EXE] +[REPLACED] package `foo v0.1.0` with `foo v0.1.0` (executable `foo[EXE]`) +[WARNING] be sure to add [..] +", + ) + .run(); +} + +#[cargo_test] +fn ignore_lockfile() { + // With an explicit `include` list, but Cargo.lock in .gitignore, don't + // complain about `Cargo.lock` being ignored. Note that it is still + // included in the packaged regardless. + let p = git::new("foo", |p| { + p.file( + "Cargo.toml", + &pl_manifest( + "foo", + "0.0.1", + r#" + include = [ + "src/main.rs" + ] + "#, + ), + ) + .file("src/main.rs", "fn main() {}") + .file(".gitignore", "Cargo.lock") + }); + p.cargo("package -l") + .with_stdout( + "\ +.cargo_vcs_info.json +Cargo.lock +Cargo.toml +Cargo.toml.orig +src/main.rs +", + ) + .run(); + p.cargo("generate-lockfile").run(); + p.cargo("package -v") + .with_stderr( + "\ +[PACKAGING] foo v0.0.1 ([..]) +[ARCHIVING] .cargo_vcs_info.json +[ARCHIVING] Cargo.lock +[ARCHIVING] Cargo.toml +[ARCHIVING] Cargo.toml.orig +[ARCHIVING] src/main.rs +[VERIFYING] foo v0.0.1 ([..]) +[COMPILING] foo v0.0.1 ([..]) +[RUNNING] `rustc --crate-name foo src/main.rs [..] +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[PACKAGED] 5 files, [..] ([..] compressed) +", + ) + .run(); +} + +#[cargo_test] +fn ignore_lockfile_inner() { + // Ignore `Cargo.lock` if in .gitignore in a git subdirectory. + let p = git::new("foo", |p| { + p.no_manifest() + .file("bar/Cargo.toml", &pl_manifest("bar", "0.0.1", "")) + .file("bar/src/main.rs", "fn main() {}") + .file("bar/.gitignore", "Cargo.lock") + }); + p.cargo("generate-lockfile").cwd("bar").run(); + p.cargo("package -v --no-verify") + .cwd("bar") + .with_stderr( + "\ +[PACKAGING] bar v0.0.1 ([..]) +[ARCHIVING] .cargo_vcs_info.json +[ARCHIVING] .gitignore +[ARCHIVING] Cargo.lock +[ARCHIVING] Cargo.toml +[ARCHIVING] Cargo.toml.orig +[ARCHIVING] src/main.rs +[PACKAGED] 6 files, [..] ([..] compressed) +", + ) + .run(); +} + +#[cargo_test] +fn use_workspace_root_lockfile() { + // Issue #11148 + // Workspace members should use `Cargo.lock` at workspace root + + Package::new("serde", "0.2.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + license = "MIT" + description = "foo" + + [dependencies] + serde = "0.2" + + [workspace] + members = ["bar"] + "#, + ) + .file("src/main.rs", "fn main() {}") + .file( + "bar/Cargo.toml", + r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + license = "MIT" + description = "bar" + workspace = ".." + + [dependencies] + serde = "0.2" + "#, + ) + .file("bar/src/main.rs", "fn main() {}") + .build(); + + // Create `Cargo.lock` in the workspace root. + p.cargo("generate-lockfile").run(); + + // Now, add a newer version of `serde`. + Package::new("serde", "0.2.1").publish(); + + // Expect: package `bar` uses `serde v0.2.0` as required by workspace `Cargo.lock`. + p.cargo("package --workspace") + .with_stderr( + "\ +[WARNING] manifest has no documentation, [..] +See [..] +[PACKAGING] bar v0.0.1 ([CWD]/bar) +[UPDATING] `dummy-registry` index +[VERIFYING] bar v0.0.1 ([CWD]/bar) +[DOWNLOADING] crates ... +[DOWNLOADED] serde v0.2.0 ([..]) +[COMPILING] serde v0.2.0 +[COMPILING] bar v0.0.1 ([CWD][..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[PACKAGED] 4 files, [..] +[WARNING] manifest has no documentation, [..] +See [..] +[PACKAGING] foo v0.0.1 ([CWD]) +[VERIFYING] foo v0.0.1 ([CWD]) +[COMPILING] serde v0.2.0 +[COMPILING] foo v0.0.1 ([CWD][..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +[PACKAGED] 4 files, [..] +", + ) + .run(); + + let package_path = p.root().join("target/package/foo-0.0.1.crate"); + assert!(package_path.is_file()); + let f = File::open(&package_path).unwrap(); + validate_crate_contents( + f, + "foo-0.0.1.crate", + &["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + &[], + ); + + let package_path = p.root().join("target/package/bar-0.0.1.crate"); + assert!(package_path.is_file()); + let f = File::open(&package_path).unwrap(); + validate_crate_contents( + f, + "bar-0.0.1.crate", + &["Cargo.lock", "Cargo.toml", "Cargo.toml.orig", "src/main.rs"], + &[], + ); +} -- cgit v1.2.3