Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cargo runner support in order to work with cross #193

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Other crates that might be useful in testing command line programs.
* [`assert_fs`][assert_fs] for filesystem fixtures and assertions.
* or [tempfile][tempfile] for scratchpad directories.
* [dir-diff][dir-diff] for testing file side-effects.
* [cross][cross] for cross-platform testing.

[escargot]: http://docs.rs/escargot
[rexpect]: https://crates.io/crates/rexpect
Expand All @@ -41,6 +42,7 @@ Other crates that might be useful in testing command line programs.
[duct]: https://crates.io/crates/duct
[assert_fs]: https://crates.io/crates/assert_fs
[commandspec]: https://crates.io/crates/commandspec
[cross]: https://github.com/cross-rs/cross

## License

Expand All @@ -58,13 +60,13 @@ fitzgen
>
> bravo bravo WG-cli

passcod
passcod
> Running commands and dealing with output can be complex in many many ways, so assert_cmd smoothing that is excellent, very much welcome, and improves ergonomics significantly.

volks73
volks73
> I have used [assert_cmd] in other projects and I am extremely pleased with it

coreyja
coreyja
> [assert_cmd] pretty much IS my testing strategy so far, though my app under test is pretty small.
>
> This library has made it really easy to add some test coverage to my project, even when I am just learning how to write Rust!
Expand Down
16 changes: 16 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::env;
use std::fs;
use std::io::Write;
use std::path;

fn main() {
println!("cargo:rerun-if-changed=build.rs");

// env::ARCH doesn't include full triplet, and AFAIK there isn't a nicer way of getting the full triplet
// (see lib.rs for the rest of this hack)
let out = path::PathBuf::from(env::var_os("OUT_DIR").expect("run within cargo"))
.join("current_target.txt");
let default_target = env::var("TARGET").expect("run as cargo build script");
let mut file = fs::File::create(out).unwrap();
file.write_all(default_target.as_bytes()).unwrap();
}
26 changes: 25 additions & 1 deletion src/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ where
///
/// See the [`cargo` module documentation][crate::cargo] for caveats and workarounds.
///
/// The [`Command`] created with this method may run the binary through a runner, as configured
/// in the `CARGO_TARGET_<TRIPLET>_RUNNER` environment variable. This is useful for running
/// binaries that can't be launched directly, such as cross-compiled binaries. When using
/// this method with [cross](https://github.com/cross-rs/cross), no extra configuration is
/// needed.
///
/// # Examples
///
/// ```rust,no_run
Expand Down Expand Up @@ -132,12 +138,27 @@ impl CommandCargoExt for process::Command {
pub(crate) fn cargo_bin_cmd<S: AsRef<str>>(name: S) -> Result<process::Command, CargoError> {
let path = cargo_bin(name);
if path.is_file() {
Ok(process::Command::new(path))
if let Some(runner) = cargo_runner() {
epage marked this conversation as resolved.
Show resolved Hide resolved
let mut cmd = process::Command::new(&runner[0]);
cmd.args(&runner[1..]).arg(path);
Ok(cmd)
} else {
Ok(process::Command::new(path))
}
} else {
Err(CargoError::with_cause(NotFoundError { path }))
}
}

pub(crate) fn cargo_runner() -> Option<Vec<String>> {
let runner_env = format!(
"CARGO_TARGET_{}_RUNNER",
CURRENT_TARGET.replace('-', "_").to_uppercase()
);
let runner = std::env::var(runner_env).ok()?;
Some(runner.split(' ').map(str::to_string).collect())
}

/// Error when finding crate binary.
#[derive(Debug)]
pub struct CargoError {
Expand Down Expand Up @@ -206,3 +227,6 @@ fn cargo_bin_str(name: &str) -> path::PathBuf {
.map(|p| p.into())
.unwrap_or_else(|| target_dir().join(format!("{}{}", name, env::consts::EXE_SUFFIX)))
}

/// The current process' target triplet.
const CURRENT_TARGET: &str = include_str!(concat!(env!("OUT_DIR"), "/current_target.txt"));
27 changes: 18 additions & 9 deletions tests/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::process;
use std::process::Command;

use assert_cmd::prelude::*;
use escargot::CURRENT_TARGET;

#[test]
fn cargo_binary() {
Expand All @@ -19,15 +20,23 @@ fn cargo_binary_with_empty_env() {

#[test]
fn mod_example() {
let bin_under_test = escargot::CargoBuild::new()
.bin("bin_fixture")
.current_release()
.current_target()
.run()
.unwrap();
let mut cmd = bin_under_test.command();
let output = cmd.unwrap();
println!("{:?}", output);
let runner_env = format!(
"CARGO_TARGET_{}_RUNNER",
CURRENT_TARGET.replace('-', "_").to_uppercase()
);
if std::env::var(runner_env).is_ok() {
// not running this test on cross because escargot doesn't support the cargo target runner yet
} else {
let bin_under_test = escargot::CargoBuild::new()
.bin("bin_fixture")
.current_release()
.current_target()
.run()
.unwrap();
let mut cmd = bin_under_test.command();
let output = cmd.unwrap();
println!("{:?}", output);
}
}

#[test]
Expand Down
Loading