use clap::Parser;
use clap_complete::Shell;
use gflow::build_info::version;
#[derive(Debug, Parser)]
#[command(
name = "gcancel",
author,
version=version(),
about = "Controls job states in the gflow scheduler."
)]
#[command(styles=gflow::utils::STYLES)]
pub struct GCancel {
#[command(subcommand)]
pub command: Option<Commands>,
#[command(flatten)]
pub cancel_args: CancelArgs,
#[arg(long, global = true, help = "Path to the config file", hide = true)]
pub config: Option<std::path::PathBuf>,
}
#[derive(Debug, Parser)]
pub enum Commands {
Completion {
#[arg(value_enum)]
shell: Shell,
},
}
#[derive(Debug, Parser)]
pub struct CancelArgs {
#[arg(long = "cancel", visible_alias = "kill", hide = true)]
pub cancel: bool,
#[arg(long, hide = true)]
pub finish: Option<u32>,
#[arg(long, hide = true)]
pub fail: Option<u32>,
#[arg(value_hint = clap::ValueHint::Other)]
pub ids: Option<String>,
#[arg(long)]
pub dry_run: bool,
}
#[derive(Debug)]
pub enum CancelCommand {
Cancel { ids: String, dry_run: bool },
Finish { id: u32 },
Fail { id: u32 },
}
impl CancelArgs {
pub fn get_command(&self) -> anyhow::Result<CancelCommand> {
if let Some(job_id) = self.finish {
Ok(CancelCommand::Finish { id: job_id })
} else if let Some(job_id) = self.fail {
Ok(CancelCommand::Fail { id: job_id })
} else if let Some(ref ids) = self.ids {
Ok(CancelCommand::Cancel {
ids: ids.clone(),
dry_run: self.dry_run,
})
} else {
anyhow::bail!("No command specified. Use --finish <id>, --fail <id>, or provide job IDs to cancel")
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_kill_alias_with_ids() {
let args = GCancel::try_parse_from(["gcancel", "--kill", "1,2,3"])
.expect("should parse --kill alias");
assert!(args.cancel_args.cancel);
assert_eq!(args.cancel_args.ids.as_deref(), Some("1,2,3"));
}
}