Skip to content

Commit b3a290c

Browse files
committedFeb 19, 2024
feat: add cargo runner support in order to work with cross
don't run the mod_example test when using cross it depends on escargot also supporting cross, which it doesn't at this time document the runner configuration usage and how to not change anything to run with cross close: #139
1 parent 19da72b commit b3a290c

File tree

4 files changed

+64
-13
lines changed

4 files changed

+64
-13
lines changed
 

‎README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Other crates that might be useful in testing command line programs.
3333
* [`assert_fs`][assert_fs] for filesystem fixtures and assertions.
3434
* or [tempfile][tempfile] for scratchpad directories.
3535
* [dir-diff][dir-diff] for testing file side-effects.
36+
* [cross][cross] for cross-platform testing.
3637

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

4547
## License
4648

@@ -58,13 +60,13 @@ fitzgen
5860
>
5961
> bravo bravo WG-cli
6062
61-
passcod
63+
passcod
6264
> 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.
6365
64-
volks73
66+
volks73
6567
> I have used [assert_cmd] in other projects and I am extremely pleased with it
6668
67-
coreyja
69+
coreyja
6870
> [assert_cmd] pretty much IS my testing strategy so far, though my app under test is pretty small.
6971
>
7072
> 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!

‎build.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use std::env;
2+
use std::fs;
3+
use std::io::Write;
4+
use std::path;
5+
6+
fn main() {
7+
println!("cargo:rerun-if-changed=build.rs");
8+
9+
// env::ARCH doesn't include full triplet, and AFAIK there isn't a nicer way of getting the full triplet
10+
// (see lib.rs for the rest of this hack)
11+
let out = path::PathBuf::from(env::var_os("OUT_DIR").expect("run within cargo"))
12+
.join("current_target.txt");
13+
let default_target = env::var("TARGET").expect("run as cargo build script");
14+
let mut file = fs::File::create(out).unwrap();
15+
file.write_all(default_target.as_bytes()).unwrap();
16+
}

‎src/cargo.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@ where
8989
///
9090
/// See the [`cargo` module documentation][crate::cargo] for caveats and workarounds.
9191
///
92+
/// The [`Command`] created with this method may run the binary through a runner, as configured
93+
/// in the `CARGO_TARGET_<TRIPLET>_RUNNER` environment variable. This is useful for running
94+
/// binaries that can't be launched directly, such as cross-compiled binaries. When using
95+
/// this method with [cross](https://github.com/cross-rs/cross), no extra configuration is
96+
/// needed.
97+
///
9298
/// # Examples
9399
///
94100
/// ```rust,no_run
@@ -132,12 +138,27 @@ impl CommandCargoExt for process::Command {
132138
pub(crate) fn cargo_bin_cmd<S: AsRef<str>>(name: S) -> Result<process::Command, CargoError> {
133139
let path = cargo_bin(name);
134140
if path.is_file() {
135-
Ok(process::Command::new(path))
141+
if let Some(runner) = cargo_runner() {
142+
let mut cmd = process::Command::new(&runner[0]);
143+
cmd.args(&runner[1..]).arg(path);
144+
Ok(cmd)
145+
} else {
146+
Ok(process::Command::new(path))
147+
}
136148
} else {
137149
Err(CargoError::with_cause(NotFoundError { path }))
138150
}
139151
}
140152

153+
pub(crate) fn cargo_runner() -> Option<Vec<String>> {
154+
let runner_env = format!(
155+
"CARGO_TARGET_{}_RUNNER",
156+
CURRENT_TARGET.replace('-', "_").to_uppercase()
157+
);
158+
let runner = std::env::var(runner_env).ok()?;
159+
Some(runner.split(' ').map(str::to_string).collect())
160+
}
161+
141162
/// Error when finding crate binary.
142163
#[derive(Debug)]
143164
pub struct CargoError {
@@ -206,3 +227,6 @@ fn cargo_bin_str(name: &str) -> path::PathBuf {
206227
.map(|p| p.into())
207228
.unwrap_or_else(|| target_dir().join(format!("{}{}", name, env::consts::EXE_SUFFIX)))
208229
}
230+
231+
/// The current process' target triplet.
232+
const CURRENT_TARGET: &str = include_str!(concat!(env!("OUT_DIR"), "/current_target.txt"));

‎tests/cargo.rs

+18-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::process;
22
use std::process::Command;
33

44
use assert_cmd::prelude::*;
5+
use escargot::CURRENT_TARGET;
56

67
#[test]
78
fn cargo_binary() {
@@ -19,15 +20,23 @@ fn cargo_binary_with_empty_env() {
1920

2021
#[test]
2122
fn mod_example() {
22-
let bin_under_test = escargot::CargoBuild::new()
23-
.bin("bin_fixture")
24-
.current_release()
25-
.current_target()
26-
.run()
27-
.unwrap();
28-
let mut cmd = bin_under_test.command();
29-
let output = cmd.unwrap();
30-
println!("{:?}", output);
23+
let runner_env = format!(
24+
"CARGO_TARGET_{}_RUNNER",
25+
CURRENT_TARGET.replace('-', "_").to_uppercase()
26+
);
27+
if std::env::var(runner_env).is_ok() {
28+
// not running this test on cross because escargot doesn't support the cargo target runner yet
29+
} else {
30+
let bin_under_test = escargot::CargoBuild::new()
31+
.bin("bin_fixture")
32+
.current_release()
33+
.current_target()
34+
.run()
35+
.unwrap();
36+
let mut cmd = bin_under_test.command();
37+
let output = cmd.unwrap();
38+
println!("{:?}", output);
39+
}
3140
}
3241

3342
#[test]

0 commit comments

Comments
 (0)
Failed to load comments.