use std::process::Command;
use crate::message::Message;
use super::cli::Cli;
use super::command_choice::tcr;
use super::command_choice::trc;
use super::gamble_result::GambleError;
use super::gamble_result::GambleResult;
use super::repository::Repository;
pub fn gamble(opt: Cli) -> GambleResult {
let gamble_strategy = if opt.pass { tcr } else { trc };
let maybe_test_command = reformat_command(opt.test_command.clone());
maybe_test_command
.ok_or_else(|| {
let invalid_test_command = opt.test_command.join(" ");
log::error!("Can't parse test command \"{invalid_test_command}\"");
GambleError {
messages: vec![Message::Error(format!(
"Can't parse test command \"{invalid_test_command}\""
))],
code: 1,
}
})
.and_then(|test_command| {
let repository =
Repository::new(opt.repository_path.as_path(), opt.dry_run, opt.no_verify);
let hook_gambled = if opt.pass { "pass" } else { "fail" };
repository
.run_hook("pre-gamble", &[hook_gambled])
.map_err(|error| {
error.add_message(Message::Warn(
"No tests have been run, and nothing has been committed or reverted"
.to_string(),
))
})
.and_then(|()| repository.command(&["add", "--all"]))
.and_then(|()| {
let status = Command::new(&test_command[0])
.args(&test_command[1..])
.status()
.expect("failed to run tests"); let command_choice = gamble_strategy(status);
command_choice(&opt, &repository)
})
})
}
fn reformat_command(command: Vec<String>) -> Option<Vec<String>> {
if command.len() == 1 {
shlex::split(command[0].as_str())
} else {
Some(command)
}
}