diff --git a/README.md b/README.md index 15f4948..9dcc677 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,8 @@ fn main() { .option(ConanScope::Package("barlib/1.0"), "zoom", "True") .config("tools.build:skip_test", "True") // Add some Conan configs .remote("conancenter") // The default Conan remote, just to test `--remote` + .arg("--core-conf") + .arg("core:non_interactive=True") .run() .parse() .emit(); diff --git a/src/lib.rs b/src/lib.rs index 8d4a886..3aa6de7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,6 +69,8 @@ //! .option(ConanScope::Package("barlib/1.0"), "zoom", "True") //! .config("tools.build:skip_test", "True") // Add some Conan configs //! .remote("conancenter") // The default Conan remote, just to test `--remote` +//! .arg("--core-conf") +//! .arg("core:non_interactive=True") //! .run() //! .parse() //! .emit(); @@ -210,6 +212,8 @@ pub struct ConanInstall { options: Vec<(String, String, String)>, /// Conan output verbosity level verbosity: ConanVerbosity, + /// Extra `conan install` arguments + extra_args: Vec, } /// `conan install` command output data @@ -378,6 +382,15 @@ impl ConanInstall { self } + /// Adds one extra command line argument to the final `conan install` run. + /// + /// Can be called multiple times per Conan invocation. + /// This method is a proxy for [`std::process::Command::arg()`]. + pub fn arg(&mut self, arg: &str) -> &mut ConanInstall { + self.extra_args.push(arg.to_owned()); + self + } + /// Runs the `conan install` command and captures its JSON-formatted output. /// /// # Panics @@ -450,6 +463,10 @@ impl ConanInstall { command.arg(format!("{key}={value}")); } + self.extra_args.iter().for_each(|x| { + command.arg(x); + }); + let output = command .output() .expect("failed to run the Conan executable"); diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 6c123c5..f3e3b19 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -18,6 +18,8 @@ fn run_conan_install() { .option(ConanScope::Package("libxml2/2.15.0"), "programs", "False") .config("tools.build:skip_test", "True") .remote("conancenter") // The default Conan remote, just to test `--remote` + .arg("--core-conf") + .arg("core:non_interactive=True") .run(); // Fallback for test debugging @@ -86,6 +88,25 @@ fn fail_no_profile() { assert!(output.stderr().starts_with(b"ERROR: Profile not found: ")); } +#[test] +fn fail_unknown_args() { + let output = ConanInstall::with_recipe(Path::new("tests/conanfile.txt")) + .output_folder(Path::new(env!("CARGO_TARGET_TMPDIR"))) + .arg("--no-such-argument") + .verbosity(ConanVerbosity::Debug) + .run(); + + std::io::stderr().write_all(output.stderr()).unwrap(); + + assert!(!output.is_success()); + assert_eq!(output.status_code(), 2); + assert_eq!(output.stdout().len(), 0); + assert!(!output.stderr().is_empty()); + assert!(str::from_utf8(output.stderr()) + .unwrap() + .contains("error: unrecognized arguments: --no-such-argument")); +} + #[test] fn detect_custom_profile() { let output = ConanInstall::with_recipe(Path::new("tests/conanfile.txt"))