diff --git a/src/bin/cargo/commands/add.rs b/src/bin/cargo/commands/add.rs index 30956b004..da821f328 100644 --- a/src/bin/cargo/commands/add.rs +++ b/src/bin/cargo/commands/add.rs @@ -87,6 +87,7 @@ Example uses: - Depend on crates with the same name from different registries"), ]) .arg_manifest_path_without_unsupported_path_tip() + .arg_lockfile_path() .arg_package("Package to modify") .arg_ignore_rust_version() .arg_dry_run("Don't actually write the manifest") diff --git a/src/bin/cargo/commands/bench.rs b/src/bin/cargo/commands/bench.rs index c79d7cb35..1f4c8df80 100644 --- a/src/bin/cargo/commands/bench.rs +++ b/src/bin/cargo/commands/bench.rs @@ -50,6 +50,7 @@ pub fn cli() -> Command { .arg_unit_graph() .arg_timings() .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version() .after_help(color_print::cstr!( "Run `cargo help bench` for more detailed information.\n" diff --git a/src/bin/cargo/commands/build.rs b/src/bin/cargo/commands/build.rs index 26f7af316..86d477cca 100644 --- a/src/bin/cargo/commands/build.rs +++ b/src/bin/cargo/commands/build.rs @@ -39,6 +39,7 @@ pub fn cli() -> Command { .arg_unit_graph() .arg_timings() .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version() .after_help(color_print::cstr!( "Run `cargo help build` for more detailed information.\n" diff --git a/src/bin/cargo/commands/check.rs b/src/bin/cargo/commands/check.rs index 56f274eff..66f378c3e 100644 --- a/src/bin/cargo/commands/check.rs +++ b/src/bin/cargo/commands/check.rs @@ -36,6 +36,7 @@ pub fn cli() -> Command { .arg_unit_graph() .arg_timings() .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version() .after_help(color_print::cstr!( "Run `cargo help check` for more detailed information.\n" diff --git a/src/bin/cargo/commands/clean.rs b/src/bin/cargo/commands/clean.rs index 1764c0bca..d9414b4d1 100644 --- a/src/bin/cargo/commands/clean.rs +++ b/src/bin/cargo/commands/clean.rs @@ -19,6 +19,7 @@ pub fn cli() -> Command { .arg_target_triple("Target triple to clean output for") .arg_target_dir() .arg_manifest_path() + .arg_lockfile_path() .arg_dry_run("Display what would be deleted without deleting anything") .args_conflicts_with_subcommands(true) .subcommand( diff --git a/src/bin/cargo/commands/doc.rs b/src/bin/cargo/commands/doc.rs index 2603b3cb7..6707364d9 100644 --- a/src/bin/cargo/commands/doc.rs +++ b/src/bin/cargo/commands/doc.rs @@ -39,6 +39,7 @@ pub fn cli() -> Command { .arg_unit_graph() .arg_timings() .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version() .after_help(color_print::cstr!( "Run `cargo help doc` for more detailed information.\n" diff --git a/src/bin/cargo/commands/fetch.rs b/src/bin/cargo/commands/fetch.rs index f60ed61b8..2fdba80ba 100644 --- a/src/bin/cargo/commands/fetch.rs +++ b/src/bin/cargo/commands/fetch.rs @@ -9,6 +9,7 @@ pub fn cli() -> Command { .arg_silent_suggestion() .arg_target_triple("Fetch dependencies for the target triple") .arg_manifest_path() + .arg_lockfile_path() .after_help(color_print::cstr!( "Run `cargo help fetch` for more detailed information.\n" )) diff --git a/src/bin/cargo/commands/fix.rs b/src/bin/cargo/commands/fix.rs index 8190cf07e..ae00635ca 100644 --- a/src/bin/cargo/commands/fix.rs +++ b/src/bin/cargo/commands/fix.rs @@ -1,6 +1,5 @@ use crate::command_prelude::*; -use cargo::core::Workspace; use cargo::ops; pub fn cli() -> Command { @@ -54,6 +53,7 @@ pub fn cli() -> Command { .arg_target_dir() .arg_timings() .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version() .after_help(color_print::cstr!( "Run `cargo help fix` for more detailed information.\n" @@ -71,8 +71,7 @@ pub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult { // Unlike other commands default `cargo fix` to all targets to fix as much // code as we can. let root_manifest = args.root_manifest(gctx)?; - let mut ws = Workspace::new(&root_manifest, gctx)?; - ws.set_resolve_honors_rust_version(args.honor_rust_version()); + let ws = args.workspace(gctx)?; let mut opts = args.compile_options(gctx, mode, Some(&ws), ProfileChecking::LegacyTestOnly)?; if !opts.filter.is_specific() { diff --git a/src/bin/cargo/commands/generate_lockfile.rs b/src/bin/cargo/commands/generate_lockfile.rs index a2ddac61d..3ad858daa 100644 --- a/src/bin/cargo/commands/generate_lockfile.rs +++ b/src/bin/cargo/commands/generate_lockfile.rs @@ -7,6 +7,7 @@ pub fn cli() -> Command { .about("Generate the lockfile for a package") .arg_silent_suggestion() .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version_with_help( "Ignore `rust-version` specification in packages (unstable)", ) diff --git a/src/bin/cargo/commands/package.rs b/src/bin/cargo/commands/package.rs index 42b3ac3d0..251fa286e 100644 --- a/src/bin/cargo/commands/package.rs +++ b/src/bin/cargo/commands/package.rs @@ -37,6 +37,7 @@ pub fn cli() -> Command { .arg_target_dir() .arg_parallel() .arg_manifest_path() + .arg_lockfile_path() .after_help(color_print::cstr!( "Run `cargo help package` for more detailed information.\n" )) diff --git a/src/bin/cargo/commands/pkgid.rs b/src/bin/cargo/commands/pkgid.rs index 72abbfc07..5fcf85b8f 100644 --- a/src/bin/cargo/commands/pkgid.rs +++ b/src/bin/cargo/commands/pkgid.rs @@ -10,6 +10,7 @@ pub fn cli() -> Command { .arg_silent_suggestion() .arg_package("Argument to get the package ID specifier for") .arg_manifest_path() + .arg_lockfile_path() .after_help(color_print::cstr!( "Run `cargo help pkgid` for more detailed information.\n" )) diff --git a/src/bin/cargo/commands/publish.rs b/src/bin/cargo/commands/publish.rs index 3b497e1ed..df1c4654f 100644 --- a/src/bin/cargo/commands/publish.rs +++ b/src/bin/cargo/commands/publish.rs @@ -24,6 +24,7 @@ pub fn cli() -> Command { .arg_target_triple("Build for the target triple") .arg_target_dir() .arg_manifest_path() + .arg_lockfile_path() .after_help(color_print::cstr!( "Run `cargo help publish` for more detailed information.\n" )) diff --git a/src/bin/cargo/commands/remove.rs b/src/bin/cargo/commands/remove.rs index b5695e599..e74f53d64 100644 --- a/src/bin/cargo/commands/remove.rs +++ b/src/bin/cargo/commands/remove.rs @@ -51,6 +51,7 @@ pub fn cli() -> clap::Command { ]) .arg_package("Package to remove from") .arg_manifest_path() + .arg_lockfile_path() .after_help(color_print::cstr!( "Run `cargo help remove` for more detailed information.\n" )) diff --git a/src/bin/cargo/commands/run.rs b/src/bin/cargo/commands/run.rs index 74eb1450b..c9e59770a 100644 --- a/src/bin/cargo/commands/run.rs +++ b/src/bin/cargo/commands/run.rs @@ -38,6 +38,7 @@ pub fn cli() -> Command { .arg_target_triple("Build for the target triple") .arg_target_dir() .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version() .arg_unit_graph() .arg_timings() diff --git a/src/bin/cargo/commands/rustc.rs b/src/bin/cargo/commands/rustc.rs index 2f52c6b59..999f8d64c 100644 --- a/src/bin/cargo/commands/rustc.rs +++ b/src/bin/cargo/commands/rustc.rs @@ -52,6 +52,7 @@ pub fn cli() -> Command { .arg_unit_graph() .arg_timings() .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version() .after_help(color_print::cstr!( "Run `cargo help rustc` for more detailed information.\n" diff --git a/src/bin/cargo/commands/rustdoc.rs b/src/bin/cargo/commands/rustdoc.rs index 6535ca405..f9c290bf5 100644 --- a/src/bin/cargo/commands/rustdoc.rs +++ b/src/bin/cargo/commands/rustdoc.rs @@ -45,6 +45,7 @@ pub fn cli() -> Command { .arg_unit_graph() .arg_timings() .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version() .after_help(color_print::cstr!( "Run `cargo help rustdoc` for more detailed information.\n" diff --git a/src/bin/cargo/commands/test.rs b/src/bin/cargo/commands/test.rs index c2657a78f..73c350510 100644 --- a/src/bin/cargo/commands/test.rs +++ b/src/bin/cargo/commands/test.rs @@ -60,6 +60,7 @@ pub fn cli() -> Command { .arg_unit_graph() .arg_timings() .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version() .after_help(color_print::cstr!( "Run `cargo help test` for more detailed information.\n\ diff --git a/src/bin/cargo/commands/tree.rs b/src/bin/cargo/commands/tree.rs index 6d83f8e8e..b0f35370e 100644 --- a/src/bin/cargo/commands/tree.rs +++ b/src/bin/cargo/commands/tree.rs @@ -95,6 +95,7 @@ pub fn cli() -> Command { Pass `all` to include all targets.", ) .arg_manifest_path() + .arg_lockfile_path() .after_help(color_print::cstr!( "Run `cargo help tree` for more detailed information.\n" )) diff --git a/src/bin/cargo/commands/update.rs b/src/bin/cargo/commands/update.rs index 492be07c7..4c19bcb27 100644 --- a/src/bin/cargo/commands/update.rs +++ b/src/bin/cargo/commands/update.rs @@ -49,6 +49,7 @@ pub fn cli() -> Command { .help_heading(heading::PACKAGE_SELECTION), ) .arg_manifest_path() + .arg_lockfile_path() .arg_ignore_rust_version_with_help( "Ignore `rust-version` specification in packages (unstable)", ) diff --git a/src/bin/cargo/commands/vendor.rs b/src/bin/cargo/commands/vendor.rs index efa1f1bb7..96b306767 100644 --- a/src/bin/cargo/commands/vendor.rs +++ b/src/bin/cargo/commands/vendor.rs @@ -37,6 +37,7 @@ pub fn cli() -> Command { .arg(unsupported("only-git-deps")) .arg(unsupported("disallow-duplicates")) .arg_manifest_path() + .arg_lockfile_path() .after_help(color_print::cstr!( "Run `cargo help vendor` for more detailed information.\n" )) diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 459e780f3..cb14dabef 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -248,7 +248,12 @@ pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult ProjectBuilder { - return project() - .file("Cargo.toml", &basic_bin_manifest("test_foo")) - .file("src/main.rs", "fn main() {}"); -} +use snapbox::str; -fn run_basic_command(p: &Project, command: &str, lockfile_path_argument: &str) { - p.cargo(command) - .masquerade_as_nightly_cargo(&["unstable-options"]) - .arg("-Zunstable-options") - .arg("--lockfile-path") - .arg(lockfile_path_argument) - .run(); -} +use cargo_test_support::paths::CargoPathExt; +use cargo_test_support::registry::RegistryBuilder; +use cargo_test_support::{ + basic_bin_manifest, basic_lib_manifest, cargo_test, paths, project, symlink_supported, Execs, + Project, ProjectBuilder, +}; -#[track_caller] -fn assert_lockfile_created(command: &str) { - let lockfile_path_argument = "mylockfile/Cargo.lock"; - let p = basic_project().build(); - - for _ in 1..=2 { - run_basic_command(&p, command, lockfile_path_argument); - assert!(p.root().join(lockfile_path_argument).is_file()); - assert!(!p.root().join("Cargo.lock").is_file()); - } - - p.root() - .join(lockfile_path_argument) - .parent() - .unwrap() - .rm_rf(); - - run_basic_command(&p, command, lockfile_path_argument); - assert!(p.root().join(lockfile_path_argument).is_file()); - assert!(!p.root().join("Cargo.lock").is_file()); -} - -fn assert_embed(command: &str) { - let lockfile_path_argument = "mylockfile/Cargo.lock"; - let embed = r#"#!/usr/bin/env cargo - -//! ```cargo -//! [dependencies] -//! clap = { version = "4.2", features = ["derive"] } -//! ``` - -use clap::Parser; - -#[derive(Parser, Debug)] -#[clap(version)] -struct Args { - #[clap(short, long, help = "Path to config")] - config: Option, -} - -fn main() { - let args = Args::parse(); - println!("{:?}", args); -}"#; - let p = project() - .file("src/main.rs", &embed) - .build(); - - p.cargo(command) - .masquerade_as_nightly_cargo(&["unstable-options"]) - .arg("-Zunstable-options") - .arg("--lockfile-path") - .arg(lockfile_path_argument) - .arg("--manifest-path") - .arg("src/main.rs") - .arg("-Zscript") - .run(); - - assert!(p.root().join(lockfile_path_argument).is_file()); - assert!(!p.root().join("Cargo.lock").is_file()); -} - -fn assert_lockfile_override(command: &str) { - let lockfile_path_argument = "mylockfile/Cargo.lock"; - let p = basic_project() - .file("Cargo.lock", "This is an invalid lock file!") - .build(); - - run_basic_command(&p, command, lockfile_path_argument); - - assert!(p.root().join(lockfile_path_argument).is_file()); -} - -fn assert_symlink_in_path(command: &str) { - if !symlink_supported() { - return; - } - - let dst = "dst"; - let src = "somedir/link"; - let lockfile_path_argument = format!("{src}/Cargo.lock"); - - let p = basic_project().symlink_dir(dst, src).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()); - - run_basic_command(&p, command, lockfile_path_argument.as_str()); - - 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) { - if !symlink_supported() { - return; - } - - let lockfile_path_argument = "dst/Cargo.lock"; - let src = "somedir/link"; - let lock_body = r#"# This file is automatically @generated by Cargo. -# It is not intended for manual editing. +const VALID_LOCKFILE: &str = r#"# Test lockfile version = 3 [[package]] @@ -133,19 +19,154 @@ name = "test_foo" version = "0.5.0" "#; - let p = basic_project() +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"; +} + +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/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()); - run_basic_command(&p, command, lockfile_path_argument); + 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) { +fn assert_broken_symlink( + command: &str, + make_execs: impl Fn(&mut Execs, String) -> &mut Execs, + make_project: impl FnOnce() -> ProjectBuilder, +) { if !symlink_supported() { return; } @@ -154,14 +175,11 @@ fn assert_broken_symlink(command: &str) { let src = "somedir/link"; let lockfile_path_argument = format!("{src}/Cargo.lock"); - let p = basic_project().symlink_dir(invalid_dst, src).build(); + 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(); - p.cargo(command) - .masquerade_as_nightly_cargo(&["unstable-options"]) - .arg("-Zunstable-options") - .arg("--lockfile-path") - .arg(lockfile_path_argument) + make_execs(&mut p.cargo(command), lockfile_path_argument.to_string()) .with_status(101) .with_stderr_data(str![[r#" [ERROR] Failed to create lockfile-path parent directory somedir/link @@ -170,10 +188,15 @@ Caused by: File exists (os error 17) "#]]) + .replace_crates_io(registry.index_url()) .run(); } -fn assert_loop_symlink(command: &str) { +fn assert_loop_symlink( + command: &str, + make_execs: impl Fn(&mut Execs, String) -> &mut Execs, + make_project: impl FnOnce() -> ProjectBuilder, +) { if !symlink_supported() { return; } @@ -182,17 +205,14 @@ fn assert_loop_symlink(command: &str) { let src = "somedir/link"; let lockfile_path_argument = format!("{src}/Cargo.lock"); - let p = basic_project() + 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(); - p.cargo(command) - .masquerade_as_nightly_cargo(&["unstable-options"]) - .arg("-Zunstable-options") - .arg("--lockfile-path") - .arg(lockfile_path_argument) + make_execs(&mut p.cargo(command), lockfile_path_argument.to_string()) .with_status(101) .with_stderr_data(str![[r#" [ERROR] Failed to fetch lock file's parent path metadata somedir/link @@ -201,40 +221,125 @@ Caused by: Too many levels of symbolic links (os error 40) "#]]) + .replace_crates_io(registry.index_url()) .run(); } -#[cargo_test(nightly, reason = "--lockfile-path is unstable")] -fn metadata_lockfile_created() { - assert_lockfile_created("metadata"); +///////////////////// +//// 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); + }; } -#[cargo_test(nightly, reason = "--lockfile-path is unstable")] -fn metadata_embed() { - assert_embed("metadata"); +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"); } -#[cargo_test(nightly, reason = "--lockfile-path is unstable")] -fn metadata_lockfile_override() { - assert_lockfile_override("metadata"); +fn make_add_project() -> ProjectBuilder { + return make_basic_project() + .file("../bar/Cargo.toml", LIB_TOML) + .file("../bar/src/main.rs", "fn main() {}"); } -#[cargo_test(nightly, reason = "--lockfile-path is unstable")] -fn metadata_symlink_in_path() { - assert_symlink_in_path("metadata"); +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"); } -#[cargo_test(nightly, reason = "--lockfile-path is unstable")] -fn metadata_symlink_lockfile() { - assert_symlink_lockfile("metadata"); +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"); } -#[cargo_test(nightly, reason = "--lockfile-path is unstable")] -fn metadata_broken_symlink() { - assert_broken_symlink("metadata"); +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() {}"); } -#[cargo_test(nightly, reason = "--lockfile-path is unstable")] -fn metadata_loop_symlink() { - assert_loop_symlink("metadata"); +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"); // TODO: check why lockfile is not generated +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");