mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
421 lines
12 KiB
Rust
421 lines
12 KiB
Rust
//! Tests for `lockfile-path` flag
|
|
|
|
use std::fs;
|
|
|
|
use cargo_test_support::registry::RegistryBuilder;
|
|
use cargo_test_support::{
|
|
basic_bin_manifest, cargo_test, project, symlink_supported, Execs, ProjectBuilder,
|
|
};
|
|
|
|
const VALID_LOCKFILE: &str = r#"# Test lockfile
|
|
version = 3
|
|
|
|
[[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_basic_project() -> ProjectBuilder {
|
|
return project()
|
|
.file("Cargo.toml", &basic_bin_manifest("test_foo"))
|
|
.file("src/main.rs", "fn main() {}");
|
|
}
|
|
|
|
fn make_basic_command(execs: &mut Execs, lockfile_path_argument: String) -> &mut Execs {
|
|
return execs
|
|
.masquerade_as_nightly_cargo(&["unstable-options"])
|
|
.arg("-Zunstable-options")
|
|
.arg("--lockfile-path")
|
|
.arg(lockfile_path_argument);
|
|
}
|
|
|
|
fn lockfile_must_exist(command: &str) -> bool {
|
|
return command == "pkgid" || command == "publish" || command == "package";
|
|
}
|
|
|
|
fn assert_lockfile_created(
|
|
command: &str,
|
|
make_execs: impl Fn(&mut Execs, String) -> &mut Execs,
|
|
make_project: impl FnOnce() -> ProjectBuilder,
|
|
) {
|
|
if lockfile_must_exist(command) {
|
|
return;
|
|
}
|
|
|
|
let lockfile_path_argument = "mylockfile/is/burried/Cargo.lock";
|
|
let p = make_project().build();
|
|
let registry = RegistryBuilder::new().http_api().http_index().build();
|
|
|
|
make_execs(&mut p.cargo(command), lockfile_path_argument.to_string())
|
|
.replace_crates_io(registry.index_url())
|
|
.run();
|
|
assert!(!p.root().join("Cargo.lock").is_file());
|
|
assert!(p.root().join(lockfile_path_argument).is_file());
|
|
}
|
|
|
|
fn assert_lockfile_read(
|
|
command: &str,
|
|
make_execs: impl Fn(&mut Execs, String) -> &mut Execs,
|
|
make_project: impl FnOnce() -> ProjectBuilder,
|
|
) {
|
|
let lockfile_path_argument = "mylockfile/Cargo.lock";
|
|
let p = make_project()
|
|
.file("mylockfile/Cargo.lock", VALID_LOCKFILE)
|
|
.build();
|
|
let registry = RegistryBuilder::new().http_api().http_index().build();
|
|
|
|
make_execs(&mut p.cargo(command), lockfile_path_argument.to_string())
|
|
.replace_crates_io(registry.index_url())
|
|
.run();
|
|
|
|
assert!(!p.root().join("Cargo.lock").is_file());
|
|
assert!(p.root().join(lockfile_path_argument).is_file());
|
|
}
|
|
|
|
fn assert_lockfile_override(
|
|
command: &str,
|
|
make_execs: impl Fn(&mut Execs, String) -> &mut Execs,
|
|
make_project: impl FnOnce() -> ProjectBuilder,
|
|
) {
|
|
if lockfile_must_exist(command) {
|
|
return;
|
|
}
|
|
|
|
let lockfile_path_argument = "mylockfile/Cargo.lock";
|
|
let p = make_project()
|
|
.file("Cargo.lock", "This is an invalid lock file!")
|
|
.build();
|
|
let registry = RegistryBuilder::new().http_api().http_index().build();
|
|
|
|
make_execs(&mut p.cargo(command), lockfile_path_argument.to_string())
|
|
.replace_crates_io(registry.index_url())
|
|
.run();
|
|
|
|
assert!(p.root().join(lockfile_path_argument).is_file());
|
|
}
|
|
|
|
fn assert_symlink_in_path(
|
|
command: &str,
|
|
make_execs: impl Fn(&mut Execs, String) -> &mut Execs,
|
|
make_project: impl FnOnce() -> ProjectBuilder,
|
|
) {
|
|
if !symlink_supported() || lockfile_must_exist(command) {
|
|
return;
|
|
}
|
|
|
|
let dst = "dst";
|
|
let src = "somedir/link";
|
|
let lockfile_path_argument = format!("{src}/Cargo.lock");
|
|
|
|
let p = make_project().symlink_dir(dst, src).build();
|
|
let registry = RegistryBuilder::new().http_api().http_index().build();
|
|
|
|
fs::create_dir(p.root().join("dst"))
|
|
.unwrap_or_else(|e| panic!("could not create directory {}", e));
|
|
assert!(p.root().join(src).is_dir());
|
|
|
|
make_execs(&mut p.cargo(command), lockfile_path_argument.to_string())
|
|
.replace_crates_io(registry.index_url())
|
|
.run();
|
|
|
|
assert!(p.root().join(format!("{src}/Cargo.lock")).is_file());
|
|
assert!(p.root().join(lockfile_path_argument).is_file());
|
|
assert!(p.root().join(dst).join("Cargo.lock").is_file());
|
|
}
|
|
|
|
fn assert_symlink_lockfile(
|
|
command: &str,
|
|
make_execs: impl Fn(&mut Execs, String) -> &mut Execs,
|
|
make_project: impl FnOnce() -> ProjectBuilder,
|
|
) {
|
|
if !symlink_supported() {
|
|
return;
|
|
}
|
|
|
|
let lockfile_path_argument = "dst/Cargo.lock";
|
|
let src = "somedir/link";
|
|
let lock_body = VALID_LOCKFILE;
|
|
|
|
let p = make_project()
|
|
.file(lockfile_path_argument, lock_body)
|
|
.symlink(lockfile_path_argument, src)
|
|
.build();
|
|
let registry = RegistryBuilder::new().http_api().http_index().build();
|
|
|
|
assert!(p.root().join(src).is_file());
|
|
|
|
make_execs(&mut p.cargo(command), lockfile_path_argument.to_string())
|
|
.replace_crates_io(registry.index_url())
|
|
.run();
|
|
|
|
assert!(!p.root().join("Cargo.lock").is_file());
|
|
}
|
|
|
|
fn assert_broken_symlink(
|
|
command: &str,
|
|
make_execs: impl Fn(&mut Execs, String) -> &mut Execs,
|
|
make_project: impl FnOnce() -> ProjectBuilder,
|
|
) {
|
|
if !symlink_supported() {
|
|
return;
|
|
}
|
|
|
|
let invalid_dst = "invalid_path";
|
|
let src = "somedir/link";
|
|
let lockfile_path_argument = format!("{src}/Cargo.lock");
|
|
|
|
let p = make_project().symlink_dir(invalid_dst, src).build();
|
|
assert!(!p.root().join(src).is_dir());
|
|
let registry = RegistryBuilder::new().http_api().http_index().build();
|
|
|
|
let err_msg = if !cfg!(windows) {
|
|
"File exists (os error 17)"
|
|
} else {
|
|
"Cannot create a file when that file already exists. (os error 183)"
|
|
};
|
|
|
|
make_execs(&mut p.cargo(command), lockfile_path_argument.to_string())
|
|
.with_status(101)
|
|
.with_stderr_data(&format!(
|
|
r#"[ERROR] failed to create directory `somedir/link`
|
|
|
|
Caused by:
|
|
{}
|
|
"#,
|
|
err_msg
|
|
))
|
|
.replace_crates_io(registry.index_url())
|
|
.run();
|
|
}
|
|
|
|
fn assert_loop_symlink(
|
|
command: &str,
|
|
make_execs: impl Fn(&mut Execs, String) -> &mut Execs,
|
|
make_project: impl FnOnce() -> ProjectBuilder,
|
|
) {
|
|
if !symlink_supported() {
|
|
return;
|
|
}
|
|
|
|
let loop_link = "loop";
|
|
let src = "somedir/link";
|
|
let lockfile_path_argument = 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());
|
|
let registry = RegistryBuilder::new().http_api().http_index().build();
|
|
|
|
let err_msg = if cfg!(windows) {
|
|
"Cannot create a file when that file already exists. (os error 183)"
|
|
} else {
|
|
"File exists (os error 17)"
|
|
};
|
|
|
|
make_execs(&mut p.cargo(command), lockfile_path_argument.to_string())
|
|
.with_status(101)
|
|
.with_stderr_data(&format!(
|
|
r#"[ERROR] failed to create directory `somedir/link`
|
|
|
|
Caused by:
|
|
{}
|
|
"#,
|
|
err_msg
|
|
))
|
|
.replace_crates_io(registry.index_url())
|
|
.run();
|
|
}
|
|
|
|
/////////////////////
|
|
//// Generic tests
|
|
/////////////////////
|
|
|
|
macro_rules! tests {
|
|
($name: ident, $cmd_name:expr, $make_command:expr, $setup_test:expr) => {
|
|
#[cfg(test)]
|
|
mod $name {
|
|
use super::*;
|
|
|
|
#[cargo_test(nightly, reason = "--lockfile-path is unstable")]
|
|
fn test_lockfile_created() {
|
|
assert_lockfile_created($cmd_name, $make_command, $setup_test);
|
|
}
|
|
|
|
#[cargo_test(nightly, reason = "--lockfile-path is unstable")]
|
|
fn test_lockfile_read() {
|
|
assert_lockfile_read($cmd_name, $make_command, $setup_test);
|
|
}
|
|
|
|
#[cargo_test(nightly, reason = "--lockfile-path is unstable")]
|
|
fn test_lockfile_override() {
|
|
assert_lockfile_override($cmd_name, $make_command, $setup_test);
|
|
}
|
|
|
|
#[cargo_test(nightly, reason = "--lockfile-path is unstable")]
|
|
fn test_symlink_in_path() {
|
|
assert_symlink_in_path($cmd_name, $make_command, $setup_test);
|
|
}
|
|
|
|
#[cargo_test(nightly, reason = "--lockfile-path is unstable")]
|
|
fn test_symlink_lockfile() {
|
|
assert_symlink_lockfile($cmd_name, $make_command, $setup_test);
|
|
}
|
|
|
|
#[cargo_test(nightly, reason = "--lockfile-path is unstable")]
|
|
fn test_broken_symlink() {
|
|
assert_broken_symlink($cmd_name, $make_command, $setup_test);
|
|
}
|
|
|
|
#[cargo_test(nightly, reason = "--lockfile-path is unstable")]
|
|
fn test_loop_symlink() {
|
|
assert_loop_symlink($cmd_name, $make_command, $setup_test);
|
|
}
|
|
}
|
|
};
|
|
|
|
($name: ident, $cmd_name:expr) => {
|
|
tests!($name, $cmd_name, make_basic_command, make_basic_project);
|
|
};
|
|
}
|
|
|
|
fn make_add_command(execs: &mut Execs, lockfile_path_argument: String) -> &mut Execs {
|
|
return make_basic_command(execs, lockfile_path_argument)
|
|
.arg("--path")
|
|
.arg("../bar");
|
|
}
|
|
|
|
fn make_add_project() -> ProjectBuilder {
|
|
return make_basic_project()
|
|
.file("../bar/Cargo.toml", LIB_TOML)
|
|
.file("../bar/src/main.rs", "fn main() {}");
|
|
}
|
|
|
|
fn make_clean_command(execs: &mut Execs, lockfile_path_argument: String) -> &mut Execs {
|
|
return make_basic_command(execs, lockfile_path_argument)
|
|
.arg("--package")
|
|
.arg("test_foo");
|
|
}
|
|
|
|
fn make_fix_command(execs: &mut Execs, lockfile_path_argument: String) -> &mut Execs {
|
|
return make_basic_command(execs, lockfile_path_argument)
|
|
.arg("--package")
|
|
.arg("test_foo")
|
|
.arg("--allow-no-vcs");
|
|
}
|
|
|
|
fn make_remove_project() -> ProjectBuilder {
|
|
let mut manifest = basic_bin_manifest("test_foo");
|
|
manifest.push_str(
|
|
r#"#
|
|
[dependencies]
|
|
test_bar = { version = "0.1.0", path = "../bar" }
|
|
"#,
|
|
);
|
|
|
|
return project()
|
|
.file("Cargo.toml", &manifest)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.file("../bar/Cargo.toml", LIB_TOML)
|
|
.file("../bar/src/main.rs", "fn main() {}");
|
|
}
|
|
|
|
fn make_remove_command(execs: &mut Execs, lockfile_path_argument: String) -> &mut Execs {
|
|
return make_basic_command(execs, lockfile_path_argument).arg("test_bar");
|
|
}
|
|
|
|
tests!(add, "add", make_add_command, make_add_project);
|
|
tests!(bench, "bench");
|
|
tests!(build, "build");
|
|
tests!(check, "check");
|
|
tests!(clean, "clean", make_clean_command, make_basic_project);
|
|
tests!(doc, "doc");
|
|
tests!(fetch, "fetch");
|
|
tests!(fix, "fix", make_fix_command, make_basic_project);
|
|
tests!(generate_lockfile, "generate-lockfile");
|
|
tests!(metadata, "metadata");
|
|
tests!(package, "package");
|
|
tests!(pkgid, "pkgid");
|
|
tests!(publish, "publish");
|
|
tests!(remove, "remove", make_remove_command, make_remove_project);
|
|
tests!(run, "run");
|
|
tests!(rustc, "rustc");
|
|
tests!(rustdoc, "rustdoc");
|
|
tests!(test, "test");
|
|
tests!(tree, "tree");
|
|
tests!(update, "update");
|
|
tests!(vendor, "vendor");
|
|
|
|
#[cfg(test)]
|
|
mod package_extra {
|
|
use crate::lockfile_path::make_basic_command;
|
|
use cargo_test_support::{cargo_test, project};
|
|
use std::fs;
|
|
|
|
#[cargo_test(nightly, reason = "--lockfile-path is unstable")]
|
|
fn assert_respect_pinned_version_from_lockfile_path() {
|
|
const PINNED_VERSION: &str = r#"# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
version = 3
|
|
|
|
[[package]]
|
|
name = "hello"
|
|
version = "1.0.2"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "2b94f16c310ebbd9efcca5a5a17131d70bd454876f2af007f3da211afadff4fc"
|
|
|
|
[[package]]
|
|
name = "test_foo"
|
|
version = "0.5.0"
|
|
dependencies = [
|
|
"hello",
|
|
]
|
|
"#;
|
|
const TOML: &str = r#"#
|
|
[package]
|
|
|
|
name = "test_foo"
|
|
version = "0.5.0"
|
|
authors = ["wycats@example.com"]
|
|
edition = "2015"
|
|
|
|
[[bin]]
|
|
|
|
name = "test_foo"
|
|
|
|
[dependencies]
|
|
hello = "1.0.0"
|
|
"#;
|
|
|
|
let lockfile_path_argument = "mylockfile/Cargo.lock";
|
|
let p = project()
|
|
.file("Cargo.toml", TOML)
|
|
.file("src/main.rs", "fn main() {}")
|
|
.file("mylockfile/Cargo.lock", PINNED_VERSION)
|
|
.build();
|
|
|
|
make_basic_command(&mut p.cargo("package"), lockfile_path_argument.to_string()).run();
|
|
|
|
assert!(!p.root().join("Cargo.lock").is_file());
|
|
assert!(p.root().join(lockfile_path_argument).is_file());
|
|
|
|
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_eq!(contents, PINNED_VERSION);
|
|
}
|
|
}
|