use anyhow::Result;
use clap::{Parser, Subcommand};
use commandeer_test::{exit_with_code, output_invocation, record_command, replay_command};
use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "commandeer")]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Record {
#[arg(long, default_value = "recordings.json")]
file: PathBuf,
#[arg(long)]
truncate: bool,
#[arg(long)]
command: String,
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
args: Vec<String>,
},
Replay {
#[arg(long, default_value = "recordings.json")]
file: PathBuf,
#[arg(long)]
command: String,
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
args: Vec<String>,
},
}
async fn record_mode(
truncate: bool,
file_path: PathBuf,
command: String,
args: Vec<String>,
) -> Result<()> {
let invocation = record_command(truncate, file_path, command, args).await?;
output_invocation(&invocation);
exit_with_code(invocation.exit_code);
}
async fn replay_mode(file_path: PathBuf, command: String, args: Vec<String>) -> Result<()> {
match replay_command(file_path, command.clone(), args.clone()).await? {
Some(invocation) => {
output_invocation(&invocation);
exit_with_code(invocation.exit_code);
}
None => {
eprintln!(
"No recorded invocation found for: {command} {}",
args.join(" ")
);
exit_with_code(1);
}
}
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Record {
file,
command,
args,
truncate,
} => {
record_mode(truncate, file, command, args).await?;
}
Commands::Replay {
file,
command,
args,
} => {
replay_mode(file, command, args).await?;
}
}
Ok(())
}