Skip to content

Commit

Permalink
Add the --shell flag
Browse files Browse the repository at this point in the history
  • Loading branch information
vojtechkral committed Feb 29, 2024
1 parent 53dbaef commit c9dcd2f
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ cargo fixture -x sh

This will ready the fixture and then enter a shell, in which you can inspect whether the fixture environment is prepared correctly, interact with it, or even run `cargo test` and interact with the environment post-tests.

Alternatively, the shorthand `cargo fixture --shell` can be used, which is equivalent to `cargo fixture -x "$SHELL"`.

### Platform support

Async runtime: [Tokio](https://tokio.rs/), [smol](https://docs.rs/smol).
Expand Down
14 changes: 13 additions & 1 deletion src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{env, ffi::OsString, process};

use anyhow::Result;
use anyhow::{bail, Result};

use crate::logger::LogLevel;

Expand All @@ -15,6 +15,7 @@ def_flags!(
--fixture [name] parse_value(fixture_name) r#"Name of the fixture setup test (default: "fixture")"#,
-A --arg [arg] append_value_raw(fixture_args) "Pass an argument to the fixture test binary (can be used multiple times)",
-x --exec [args...] take_remaining(exec) "Instead of running cargo test [args...], run the specified command and pass it all remaining arguments",
--shell set_flag(shell) "Instead of running cargo test, run $SHELL",
-L [level] parse_value(log_level) "Stderr logging level (choices: off, info, debug, trace, default: info)",
-h --help help "Print help",
--version version "Print version",
Expand Down Expand Up @@ -55,6 +56,7 @@ pub struct Cli {
pub fixture_name: String,
pub fixture_args: Vec<OsString>,
pub exec: Vec<OsString>,
pub shell: bool,
pub log_level: LogLevel,
pub cargo_common_all: Vec<OsString>,
pub cargo_common_test: Vec<OsString>,
Expand All @@ -63,6 +65,14 @@ pub struct Cli {
}

impl Cli {
pub fn check_conflicts(self) -> Result<Self> {
if self.shell && !self.exec.is_empty() {
bail!("--shell and -x/--exec cannot be used at the same time");
}

Ok(self)
}

fn unknown_flag(&mut self, flag: OsString) {
self.cargo_test_args.push(flag);
}
Expand All @@ -74,6 +84,7 @@ impl Default for Cli {
fixture_name: "fixture".to_string(),
fixture_args: vec![],
exec: vec![],
shell: false,
log_level: LogLevel::default(),
cargo_common_all: vec![],
cargo_common_test: vec![],
Expand All @@ -86,6 +97,7 @@ impl Default for Cli {
pub fn parse() -> Result<Cli> {
Parser::new(FLAGS, CARGO_FLAGS, env::args_os())
.parse()
.and_then(|cli| cli.check_conflicts().map_err(parser::Error::Parsing))
.map_err(|err| {
let usage = Parser::usage();
if err.severity() == 0 {
Expand Down
1 change: 1 addition & 0 deletions src/cli/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ macro_rules! def_flags {
};

// Actions
(@action set_flag($field:ident)) => { &|parser| { parser.set_flag(|cli| { &mut cli.$field }) } };
(@action parse_value($field:ident)) => { &|parser| { parser.parse_value(|cli| { &mut cli.$field }) } };
(@action append_value_raw($field:ident)) => { &|parser| { parser.append_value_raw(|cli| { &mut cli.$field }) } };
(@action forward($field:ident)) => { &|parser| { parser.forward(|cli| { &mut cli.$field }) } };
Expand Down
5 changes: 5 additions & 0 deletions src/cli/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,11 @@ impl Parser {

// flag parse fns

pub fn set_flag(&mut self, field: impl Fn(&mut Cli) -> &mut bool) -> ParseResult<()> {
*field(&mut self.cli) = true;
Ok(())
}

pub fn parse_value<T>(&mut self, field: impl Fn(&mut Cli) -> &mut T) -> ParseResult<()>
where
T: FromStr,
Expand Down
13 changes: 9 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{

mod cargo_meta;

use anyhow::Result;
use anyhow::{anyhow, Result};
use log::debug;

use self::cargo_meta::CargoMetadata;
Expand Down Expand Up @@ -80,8 +80,13 @@ impl Config {
extra_test_args: Vec<String>,
extra_harness_args: Vec<String>,
replace_exec: Vec<String>,
) -> Command {
let mut cmd = if let Some(exec) = self.cli.exec.first() {
) -> Result<Command> {
let mut cmd = if self.cli.shell {
let sh = env::var_os("SHELL").ok_or_else(|| {
anyhow!("The environment variable $SHELL is not set, needed by --shell")
})?;
Command::new(sh)
} else if let Some(exec) = self.cli.exec.first() {
let mut cmd = Command::new(exec);
cmd.args(&self.cli.exec[1..]);
cmd
Expand All @@ -106,6 +111,6 @@ impl Config {

cmd.env("CARGO_FIXTURE_SOCKET", &self.socket_path);

cmd
Ok(cmd)
}
}
2 changes: 1 addition & 1 deletion src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ impl FixtureConnection {
let replace_exec = mem::take(&mut self.replace_exec);
let test_cmd = self
.config
.test_cmd(extra_test_args, extra_harness_args, replace_exec);
.test_cmd(extra_test_args, extra_harness_args, replace_exec)?;
info!("running {}", test_cmd.display());
let status = test_cmd
.into_smol(Stdio::inherit(), Stdio::inherit(), Stdio::inherit())
Expand Down
5 changes: 5 additions & 0 deletions tests/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,8 @@ fn args() {
&["exec-cli-arg1", "exec-cli-arg2"],
);
}

#[test]
fn shell() {
cargo_fixture().run_assert_shell();
}
26 changes: 26 additions & 0 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,32 @@ impl CargoFixture {
);
}

pub fn run_assert_shell(mut self) {
let print_args_exe = self.print_args_exe();

let report = self
.cmd
.args([
"-L",
"debug",
"--fixture",
"fixture_args",
"-A",
"report",
"--shell",
])
.stdin(Stdio::null())
.stdout(Stdio::piped())
.stderr(Stdio::inherit())
.env("SHELL", &print_args_exe)
.output()
.unwrap()
.parse_args_report();

assert!(report.fixture_args.is_empty(), "{report:?}");
assert_eq!(report.test_args, &[print_args_exe.as_str()], "{report:?}");
}

pub fn print_args_exe(&mut self) -> String {
self.print_args_exe
.get_or_insert_with(|| {
Expand Down

0 comments on commit c9dcd2f

Please sign in to comment.