Add '-C' flag for changing current dir before build

This implements the suggestion in #10098 to make cargo change cwd before
completing config processing and starting the build. It is also an
alternative to --manifest-path that resolves the issue described
in #2930.
This commit is contained in:
Will Page 2023-02-10 07:42:37 -08:00
parent a40a64bc22
commit 4de2c96021
2 changed files with 52 additions and 1 deletions

View File

@ -1,4 +1,4 @@
use anyhow::anyhow; use anyhow::{anyhow, Context as _};
use cargo::core::shell::Shell; use cargo::core::shell::Shell;
use cargo::core::{features, CliUnstable}; use cargo::core::{features, CliUnstable};
use cargo::{self, drop_print, drop_println, CliResult, Config}; use cargo::{self, drop_print, drop_println, CliResult, Config};
@ -27,6 +27,11 @@ lazy_static::lazy_static! {
pub fn main(config: &mut LazyConfig) -> CliResult { pub fn main(config: &mut LazyConfig) -> CliResult {
let args = cli().try_get_matches()?; let args = cli().try_get_matches()?;
// Update the process-level notion of cwd
if let Some(new_cwd) = args.get_one::<std::path::PathBuf>("directory") {
std::env::set_current_dir(&new_cwd).context("could not change to requested directory")?;
}
// CAUTION: Be careful with using `config` until it is configured below. // CAUTION: Be careful with using `config` until it is configured below.
// In general, try to avoid loading config values unless necessary (like // In general, try to avoid loading config values unless necessary (like
// the [alias] table). // the [alias] table).
@ -467,6 +472,14 @@ See 'cargo help <command>' for more information on a specific command.\n",
.value_name("WHEN") .value_name("WHEN")
.global(true), .global(true),
) )
.arg(
Arg::new("directory")
.help("Change to DIRECTORY before doing anything")
.short('C')
.value_name("DIRECTORY")
.value_hint(clap::ValueHint::DirPath)
.value_parser(clap::builder::ValueParser::path_buf()),
)
.arg(flag("frozen", "Require Cargo.lock and cache are up to date").global(true)) .arg(flag("frozen", "Require Cargo.lock and cache are up to date").global(true))
.arg(flag("locked", "Require Cargo.lock is up to date").global(true)) .arg(flag("locked", "Require Cargo.lock is up to date").global(true))
.arg(flag("offline", "Run without accessing the network").global(true)) .arg(flag("offline", "Run without accessing the network").global(true))

View File

@ -159,6 +159,44 @@ fn cargo_compile_manifest_path() {
assert!(p.bin("foo").is_file()); assert!(p.bin("foo").is_file());
} }
#[cargo_test]
fn cargo_compile_directory_not_cwd() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.file(".cargo/config.toml", &"")
.build();
p.cargo("-C foo build")
.cwd(p.root().parent().unwrap())
.run();
assert!(p.bin("foo").is_file());
}
#[cargo_test]
fn cargo_compile_directory_not_cwd_with_invalid_config() {
let p = project()
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.file(".cargo/config.toml", &"!")
.build();
p.cargo("-C foo build")
.cwd(p.root().parent().unwrap())
.with_status(101)
.with_stderr_contains(
"\
Caused by:
TOML parse error at line 1, column 1
|
1 | !
| ^
Unexpected `!`
Expected key or end of input",
)
.run();
}
#[cargo_test] #[cargo_test]
fn cargo_compile_with_invalid_manifest() { fn cargo_compile_with_invalid_manifest() {
let p = project().file("Cargo.toml", "").build(); let p = project().file("Cargo.toml", "").build();