mirror of
https://github.com/rust-lang/cargo.git
synced 2025-10-01 11:30:39 +00:00

This changes it so that `cargo package` will make sure the Cargo.lock file is in sync with the Cargo.toml that is generated during packaging. This has several points: - This makes the Cargo.lock more accurately reflect what would be locked if a user runs `cargo install` on the resulting package. - In a workspace, this removes irrelevant packages from the lock file. - This handles `[patch]` dependencies and dual-source dependencies (like path/version). - Warnings are generated for any differences in the lock file compared to the original. This has a significant change in how `cargo package` works. It now unconditionally copies the package to `target/package`. Previously this was only done during the verification step. This is necessary to run the resolver against the new `Cargo.toml` that gets generated.
309 lines
7.7 KiB
Rust
309 lines
7.7 KiB
Rust
use std;
|
|
use std::fs::File;
|
|
|
|
use crate::support::registry::Package;
|
|
use crate::support::{
|
|
basic_manifest, cargo_process, git, paths, project, publish::validate_crate_contents,
|
|
};
|
|
|
|
fn pl_manifest(name: &str, version: &str, extra: &str) -> String {
|
|
format!(
|
|
r#"
|
|
cargo-features = ["publish-lockfile"]
|
|
|
|
[project]
|
|
name = "{}"
|
|
version = "{}"
|
|
authors = []
|
|
license = "MIT"
|
|
description = "foo"
|
|
documentation = "foo"
|
|
homepage = "foo"
|
|
repository = "foo"
|
|
publish-lockfile = true
|
|
|
|
{}
|
|
"#,
|
|
name, version, extra
|
|
)
|
|
}
|
|
|
|
#[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")
|
|
.masquerade_as_nightly_cargo()
|
|
.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 [..]
|
|
",
|
|
)
|
|
.run();
|
|
assert!(p.root().join("target/package/foo-0.0.1.crate").is_file());
|
|
p.cargo("package -l")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stdout(
|
|
"\
|
|
Cargo.lock
|
|
Cargo.toml
|
|
src/main.rs
|
|
",
|
|
)
|
|
.run();
|
|
p.cargo("package")
|
|
.masquerade_as_nightly_cargo()
|
|
.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"],
|
|
&[],
|
|
);
|
|
}
|
|
|
|
#[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())
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stdout(
|
|
"\
|
|
.cargo_vcs_info.json
|
|
Cargo.lock
|
|
Cargo.toml
|
|
src/main.rs
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[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").masquerade_as_nightly_cargo().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"],
|
|
&[],
|
|
);
|
|
}
|
|
|
|
#[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")
|
|
.masquerade_as_nightly_cargo()
|
|
.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"],
|
|
&[],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn warn_resolve_changes() {
|
|
// `multi` has multiple sources (path and registry).
|
|
Package::new("mutli", "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]
|
|
mutli = { path = "mutli", version = "0.1" }
|
|
updated = "1.0"
|
|
patched = "1.0"
|
|
|
|
[patch.crates-io]
|
|
patched = { path = "patched" }
|
|
"#,
|
|
),
|
|
)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.file("mutli/Cargo.toml", &basic_manifest("mutli", "0.1.0"))
|
|
.file("mutli/src/lib.rs", "")
|
|
.file("patched/Cargo.toml", &basic_manifest("patched", "1.0.0"))
|
|
.file("patched/src/lib.rs", "")
|
|
.build();
|
|
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo()
|
|
.run();
|
|
|
|
// Make sure this does not change or warn.
|
|
Package::new("updated", "1.0.1").publish();
|
|
|
|
p.cargo("package --no-verify")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr_unordered(
|
|
"\
|
|
[PACKAGING] foo v0.0.1 ([..])
|
|
[UPDATING] `[..]` index
|
|
[WARNING] package `mutli v0.1.0` added to Cargo.lock, was originally sourced from `[..]/foo/mutli`
|
|
[WARNING] package `patched v1.0.0` added to Cargo.lock, was originally sourced from `[..]/foo/patched`
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[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")
|
|
.masquerade_as_nightly_cargo()
|
|
.run();
|
|
|
|
p.change_file("Cargo.toml", &pl_manifest("foo", "0.2.0", ""));
|
|
|
|
p.cargo("package --no-verify")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr("[PACKAGING] foo v0.2.0 ([..])")
|
|
.run();
|
|
}
|
|
|
|
#[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")
|
|
.masquerade_as_nightly_cargo()
|
|
.run();
|
|
p.cargo("package --no-verify")
|
|
.cwd("a")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr("[PACKAGING] a v0.1.0 ([..])")
|
|
.run();
|
|
}
|
|
|
|
#[test]
|
|
fn out_of_date_lock_warn() {
|
|
// Dependency is force-changed from an out-of-date Cargo.lock.
|
|
Package::new("dep", "1.0.0").publish();
|
|
Package::new("dep", "2.0.0").publish();
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
&pl_manifest(
|
|
"foo",
|
|
"0.0.1",
|
|
r#"
|
|
[dependencies]
|
|
dep = "1.0"
|
|
"#,
|
|
),
|
|
)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.build();
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo()
|
|
.run();
|
|
p.change_file(
|
|
"Cargo.toml",
|
|
&pl_manifest(
|
|
"foo",
|
|
"0.0.1",
|
|
r#"
|
|
[dependencies]
|
|
dep = "2.0"
|
|
"#,
|
|
),
|
|
);
|
|
p.cargo("package --no-verify")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr(
|
|
"\
|
|
[PACKAGING] foo v0.0.1 ([..])
|
|
[UPDATING] `[..]` index
|
|
[WARNING] package `dep v2.0.0` added to Cargo.lock, previous version was `1.0.0`
|
|
",
|
|
)
|
|
.run();
|
|
}
|