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

This commit makes lockfile version 4 the default version when Cargo tries to write to a lockfile. The lockfile version 4 has been stabilized since 1.78.0, and will become default in 1.83.0. the length of transition period is pretty similar as before. One caveat is that in other output from Cargo, e.g., `cargo metatada`, status messages, `SourceID` will display in the v4 URL encoded format. This shouldn't affect the majority of Rust users, as `SourceId` representation should be opaque to them, unless comparing `SourceId` across different version of toolchains.
463 lines
12 KiB
Rust
463 lines
12 KiB
Rust
//! Tests for `lockfile-path` flag
|
|
|
|
use std::fs;
|
|
|
|
use snapbox::str;
|
|
|
|
use cargo_test_support::compare::assert_e2e;
|
|
use cargo_test_support::registry::{Package, RegistryBuilder};
|
|
use cargo_test_support::{
|
|
basic_bin_manifest, cargo_test, project, symlink_supported, ProjectBuilder,
|
|
};
|
|
|
|
///////////////////////////////
|
|
//// Unstable feature tests start
|
|
///////////////////////////////
|
|
|
|
#[cargo_test]
|
|
fn must_have_unstable_options() {
|
|
let lockfile_path = "mylockfile/is/burried/Cargo.lock";
|
|
let p = make_project().build();
|
|
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.with_stderr_data(str![[
|
|
r#"[ERROR] the `--lockfile-path` flag is unstable, pass `-Z unstable-options` to enable it
|
|
See https://github.com/rust-lang/cargo/issues/14421 for more information about the `--lockfile-path` flag.
|
|
|
|
"#]])
|
|
.with_status(101)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn must_be_nightly() {
|
|
let lockfile_path = "mylockfile/is/burried/Cargo.lock";
|
|
let p = make_project().build();
|
|
|
|
p.cargo("generate-lockfile")
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.with_stderr_data(str![[
|
|
r#"[ERROR] the `-Z` flag is only accepted on the nightly channel of Cargo, but this is the `stable` channel
|
|
See https://doc.rust-lang.org/book/appendix-07-nightly-rust.html for more information about Rust release channels.
|
|
|
|
"#]])
|
|
.with_status(101)
|
|
.run();
|
|
}
|
|
|
|
///////////////////////////////
|
|
//// Unstable feature tests end
|
|
///////////////////////////////
|
|
|
|
#[cargo_test]
|
|
fn basic_lockfile_created() {
|
|
let lockfile_path = "mylockfile/is/burried/Cargo.lock";
|
|
let p = make_project().build();
|
|
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.run();
|
|
assert!(!p.root().join("Cargo.lock").exists());
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn basic_lockfile_read() {
|
|
let lockfile_path = "mylockfile/Cargo.lock";
|
|
let p = make_project().file(lockfile_path, VALID_LOCKFILE).build();
|
|
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.run();
|
|
|
|
assert!(!p.root().join("Cargo.lock").exists());
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn basic_lockfile_override() {
|
|
let lockfile_path = "mylockfile/Cargo.lock";
|
|
let p = make_project()
|
|
.file("Cargo.lock", "This is an invalid lock file!")
|
|
.build();
|
|
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.run();
|
|
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
}
|
|
|
|
//////////////////////
|
|
///// Symlink tests
|
|
//////////////////////
|
|
|
|
#[cargo_test]
|
|
fn symlink_in_path() {
|
|
if !symlink_supported() {
|
|
return;
|
|
}
|
|
|
|
let dst = "dst";
|
|
let src = "somedir/link";
|
|
let lockfile_path = format!("{src}/Cargo.lock");
|
|
|
|
let p = make_project().symlink_dir(dst, src).build();
|
|
|
|
fs::create_dir(p.root().join("dst")).unwrap();
|
|
assert!(p.root().join(src).is_dir());
|
|
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path.as_str())
|
|
.run();
|
|
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
assert!(p.root().join(dst).join("Cargo.lock").is_file());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn symlink_lockfile() {
|
|
if !symlink_supported() {
|
|
return;
|
|
}
|
|
|
|
let lockfile_path = "dst/Cargo.lock";
|
|
let src = "somedir/link";
|
|
let lock_body = VALID_LOCKFILE;
|
|
|
|
let p = make_project()
|
|
.file(lockfile_path, lock_body)
|
|
.symlink(lockfile_path, src)
|
|
.build();
|
|
|
|
assert!(p.root().join(src).is_file());
|
|
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.run();
|
|
|
|
assert!(!p.root().join("Cargo.lock").exists());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn broken_symlink() {
|
|
if !symlink_supported() {
|
|
return;
|
|
}
|
|
|
|
let invalid_dst = "invalid_path";
|
|
let src = "somedir/link";
|
|
let lockfile_path = format!("{src}/Cargo.lock");
|
|
|
|
let p = make_project().symlink_dir(invalid_dst, src).build();
|
|
assert!(!p.root().join(src).is_dir());
|
|
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.with_status(101)
|
|
.with_stderr_data(str![[
|
|
r#"[ERROR] failed to create directory `[ROOT]/foo/somedir/link`
|
|
|
|
...
|
|
|
|
"#
|
|
]])
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn loop_symlink() {
|
|
if !symlink_supported() {
|
|
return;
|
|
}
|
|
|
|
let loop_link = "loop";
|
|
let src = "somedir/link";
|
|
let lockfile_path = format!("{src}/Cargo.lock");
|
|
|
|
let p = make_project()
|
|
.symlink_dir(loop_link, src)
|
|
.symlink_dir(src, loop_link)
|
|
.build();
|
|
assert!(!p.root().join(src).is_dir());
|
|
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.with_status(101)
|
|
.with_stderr_data(str![[
|
|
r#"[ERROR] failed to create directory `[ROOT]/foo/somedir/link`
|
|
|
|
...
|
|
|
|
"#
|
|
]])
|
|
.run();
|
|
}
|
|
|
|
/////////////////////////
|
|
//// Commands tests
|
|
/////////////////////////
|
|
|
|
#[cargo_test]
|
|
fn add_lockfile_override() {
|
|
let lockfile_path = "mylockfile/Cargo.lock";
|
|
project()
|
|
.at("bar")
|
|
.file("Cargo.toml", LIB_TOML)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.build();
|
|
let p = make_project()
|
|
.file("Cargo.lock", "This is an invalid lock file!")
|
|
.build();
|
|
p.cargo("add")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.arg("--path")
|
|
.arg("../bar")
|
|
.run();
|
|
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn clean_lockfile_override() {
|
|
let lockfile_path = "mylockfile/Cargo.lock";
|
|
let p = make_project()
|
|
.file("Cargo.lock", "This is an invalid lock file!")
|
|
.build();
|
|
p.cargo("clean")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.arg("--package")
|
|
.arg("test_foo")
|
|
.run();
|
|
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn fix_lockfile_override() {
|
|
let lockfile_path = "mylockfile/Cargo.lock";
|
|
let p = make_project()
|
|
.file("Cargo.lock", "This is an invalid lock file!")
|
|
.build();
|
|
p.cargo("fix")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.arg("--package")
|
|
.arg("test_foo")
|
|
.arg("--allow-no-vcs")
|
|
.run();
|
|
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn publish_lockfile_read() {
|
|
let lockfile_path = "mylockfile/Cargo.lock";
|
|
let p = make_project().file(lockfile_path, VALID_LOCKFILE).build();
|
|
let registry = RegistryBuilder::new().http_api().http_index().build();
|
|
|
|
p.cargo("publish")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.replace_crates_io(registry.index_url())
|
|
.run();
|
|
|
|
assert!(!p.root().join("Cargo.lock").exists());
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn remove_lockfile_override() {
|
|
let lockfile_path = "mylockfile/Cargo.lock";
|
|
let manifest = r#"
|
|
[package]
|
|
|
|
name = "foo"
|
|
version = "0.5.0"
|
|
authors = ["wycats@example.com"]
|
|
edition = "2015"
|
|
|
|
[[bin]]
|
|
|
|
name = "foo"
|
|
|
|
[dependencies]
|
|
test_bar = { version = "0.1.0", path = "../bar" }
|
|
"#;
|
|
|
|
project()
|
|
.at("bar")
|
|
.file("Cargo.toml", LIB_TOML)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.build();
|
|
|
|
let p = project()
|
|
.file("Cargo.toml", &manifest)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.file("Cargo.lock", "This is an invalid lock file!")
|
|
.build();
|
|
p.cargo("remove")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.arg("test_bar")
|
|
.run();
|
|
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn assert_respect_pinned_version_from_lockfile_path() {
|
|
let lockfile_path = "mylockfile/Cargo.lock";
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"#
|
|
[package]
|
|
|
|
name = "test_foo"
|
|
version = "0.5.0"
|
|
authors = ["wycats@example.com"]
|
|
edition = "2015"
|
|
|
|
[[bin]]
|
|
|
|
name = "test_foo"
|
|
|
|
[dependencies]
|
|
bar = "0.1.0"
|
|
"#,
|
|
)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.build();
|
|
|
|
Package::new("bar", "0.1.0").publish();
|
|
p.cargo("generate-lockfile")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.run();
|
|
|
|
assert!(!p.root().join("Cargo.lock").exists());
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
|
|
let lockfile_original = fs::read_to_string(p.root().join(lockfile_path)).unwrap();
|
|
|
|
Package::new("bar", "0.1.1").publish();
|
|
p.cargo("package")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.run();
|
|
|
|
assert!(p
|
|
.root()
|
|
.join("target/package/test_foo-0.5.0/Cargo.lock")
|
|
.is_file());
|
|
|
|
let path = p.root().join("target/package/test_foo-0.5.0/Cargo.lock");
|
|
let contents = fs::read_to_string(path).unwrap();
|
|
|
|
assert_e2e().eq(contents, lockfile_original);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn run_embed() {
|
|
let lockfile_path = "mylockfile/Cargo.lock";
|
|
let invalid_lockfile = "Cargo.lock";
|
|
let p = project()
|
|
.file("src/main.rs", "fn main() {}")
|
|
.file("Cargo.lock", "This is an invalid lock file!")
|
|
.build();
|
|
|
|
p.cargo("run")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("-Zscript")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path)
|
|
.arg("--manifest-path")
|
|
.arg("src/main.rs")
|
|
.run();
|
|
|
|
assert!(p.root().join(lockfile_path).is_file());
|
|
|
|
p.cargo("run")
|
|
.masquerade_as_nightly_cargo(&["lockfile-path"])
|
|
.arg("-Zunstable-options")
|
|
.arg("-Zscript")
|
|
.arg("--lockfile-path")
|
|
.arg(invalid_lockfile)
|
|
.arg("--manifest-path")
|
|
.arg("src/main.rs")
|
|
.with_status(101)
|
|
.with_stderr_data(str![[
|
|
r#"[WARNING] `package.edition` is unspecified, defaulting to `2021`
|
|
[ERROR] failed to parse lock file at: [ROOT]/foo/Cargo.lock
|
|
|
|
...
|
|
"#
|
|
]])
|
|
.run();
|
|
}
|
|
|
|
const VALID_LOCKFILE: &str = r#"# Test lockfile
|
|
version = 4
|
|
|
|
[[package]]
|
|
name = "test_foo"
|
|
version = "0.5.0"
|
|
"#;
|
|
|
|
const LIB_TOML: &str = r#"
|
|
[package]
|
|
name = "test_bar"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
"#;
|
|
|
|
fn make_project() -> ProjectBuilder {
|
|
project()
|
|
.file("Cargo.toml", &basic_bin_manifest("test_foo"))
|
|
.file("src/main.rs", "fn main() {}")
|
|
}
|