Skip to content

Commit b5a19b3

Browse files
William Pagecompenguy
William Page
authored andcommitted
Add '--directory,-C' flag for changing current dir before build
This implements the suggestion in rust-lang#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 rust-lang#2930.
1 parent a40a64b commit b5a19b3

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

src/bin/cargo/cli.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::anyhow;
1+
use anyhow::{anyhow, Context as _};
22
use cargo::core::shell::Shell;
33
use cargo::core::{features, CliUnstable};
44
use cargo::{self, drop_print, drop_println, CliResult, Config};
@@ -27,6 +27,11 @@ lazy_static::lazy_static! {
2727
pub fn main(config: &mut LazyConfig) -> CliResult {
2828
let args = cli().try_get_matches()?;
2929

30+
// Update the process-level notion of cwd
31+
if let Some(new_cwd) = args.get_one::<std::path::PathBuf>("directory") {
32+
std::env::set_current_dir(&new_cwd).context("could not change to requested directory")?;
33+
}
34+
3035
// CAUTION: Be careful with using `config` until it is configured below.
3136
// In general, try to avoid loading config values unless necessary (like
3237
// the [alias] table).
@@ -467,6 +472,13 @@ See 'cargo help <command>' for more information on a specific command.\n",
467472
.value_name("WHEN")
468473
.global(true),
469474
)
475+
.arg(
476+
opt("directory", "Change to DIRECTORY before doing anything")
477+
.short('C')
478+
.value_name("DIRECTORY")
479+
.value_hint(clap::ValueHint::DirPath)
480+
.value_parser(clap::builder::ValueParser::path_buf()),
481+
)
470482
.arg(flag("frozen", "Require Cargo.lock and cache are up to date").global(true))
471483
.arg(flag("locked", "Require Cargo.lock is up to date").global(true))
472484
.arg(flag("offline", "Run without accessing the network").global(true))

tests/testsuite/build.rs

+38
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,44 @@ fn cargo_compile_manifest_path() {
159159
assert!(p.bin("foo").is_file());
160160
}
161161

162+
#[cargo_test]
163+
fn cargo_compile_directory_not_cwd() {
164+
let p = project()
165+
.file("Cargo.toml", &basic_bin_manifest("foo"))
166+
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
167+
.file(".cargo/config.toml", &"")
168+
.build();
169+
170+
p.cargo("-C foo build")
171+
.cwd(p.root().parent().unwrap())
172+
.run();
173+
assert!(p.bin("foo").is_file());
174+
}
175+
176+
#[cargo_test]
177+
fn cargo_compile_directory_not_cwd_with_invalid_config() {
178+
let p = project()
179+
.file("Cargo.toml", &basic_bin_manifest("foo"))
180+
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
181+
.file(".cargo/config.toml", &"!")
182+
.build();
183+
184+
p.cargo("-C foo build")
185+
.cwd(p.root().parent().unwrap())
186+
.with_status(101)
187+
.with_stderr_contains(
188+
"\
189+
Caused by:
190+
TOML parse error at line 1, column 1
191+
|
192+
1 | !
193+
| ^
194+
Unexpected `!`
195+
Expected key or end of input",
196+
)
197+
.run();
198+
}
199+
162200
#[cargo_test]
163201
fn cargo_compile_with_invalid_manifest() {
164202
let p = project().file("Cargo.toml", "").build();

0 commit comments

Comments
 (0)