use std::io::Write;
use brush_core::{
ErrorKind, ExecutionExitCode, ExecutionParameters, ExecutionResult, Shell, builtins, tests,
};
use clap::Parser;
#[derive(Parser)]
#[clap(disable_help_flag = true, disable_version_flag = true)]
pub(crate) struct TestCommand {
#[clap(allow_hyphen_values = true)]
args: Vec<String>,
}
impl builtins::Command for TestCommand {
type Error = brush_core::Error;
fn new<I>(args: I) -> Result<Self, clap::Error>
where
I: IntoIterator<Item = String>,
{
let (mut this, rest_args) = brush_core::builtins::try_parse_known::<Self>(args)?;
if let Some(args) = rest_args {
this.args.extend(args);
}
Ok(this)
}
async fn execute<SE: brush_core::ShellExtensions>(
&self,
context: brush_core::ExecutionContext<'_, SE>,
) -> Result<brush_core::ExecutionResult, Self::Error> {
let mut args = self.args.as_slice();
if context.command_name == "[" {
match args.last() {
Some(s) if s == "]" => (),
None | Some(_) => {
writeln!(context.stderr(), "[: missing ']'")?;
return Ok(ExecutionExitCode::InvalidUsage.into());
},
}
args = &args[0..args.len() - 1];
}
if execute_test(context.shell, &context.params, args)? {
Ok(ExecutionResult::success())
} else {
Ok(ExecutionResult::general_error())
}
}
}
fn execute_test(
shell: &mut Shell<impl brush_core::ShellExtensions>,
params: &ExecutionParameters,
args: &[String],
) -> Result<bool, brush_core::Error> {
let test_command =
brush_parser::test_command::parse(args).map_err(ErrorKind::TestCommandParseError)?;
tests::eval_expr(&test_command, shell, params)
}