use crate::core::{
apply_filters, apply_to_each, flatten_targets, resolve_targets_excluding_self, NameMatch,
Process,
};
use crate::error::{ProcError, Result};
use crate::ui::Printer;
use clap::Args;
#[derive(Args, Debug)]
pub struct KillCommand {
#[arg(required = true, num_args = 1.., value_parser = crate::core::validate_target_arg)]
pub target: Vec<String>,
#[arg(long, short = 'y')]
pub yes: bool,
#[arg(long)]
pub dry_run: bool,
#[arg(long, short = 'j')]
pub json: bool,
#[arg(long, short = 'v')]
pub verbose: bool,
#[arg(long, short = 'g')]
pub graceful: bool,
#[arg(long = "in", short = 'i', num_args = 0..=1, default_missing_value = ".")]
pub in_dir: Option<String>,
#[arg(long = "by", short = 'b')]
pub by_name: Option<String>,
#[arg(long)]
pub cmd: bool,
}
impl KillCommand {
pub fn execute(&self) -> Result<()> {
let printer = Printer::from_flags(self.json, self.verbose);
let targets = flatten_targets(&self.target);
let mode = NameMatch::from_flag(self.cmd);
let resolved = resolve_targets_excluding_self(&targets, mode);
if let Some(warning) = resolved.warning() {
printer.warning(&warning);
}
let printer = printer.with_not_found(&resolved.not_found);
let mut processes = resolved.processes;
apply_filters(&mut processes, &self.in_dir, &self.by_name, mode);
if self.dry_run || !self.yes {
Process::measure_cpu(&mut processes);
}
if processes.is_empty() {
return Err(ProcError::ProcessNotFound(self.target.join(" ")));
}
if self.dry_run {
printer.print_dry_run("kill", &processes);
return Ok(());
}
if !printer.ask_confirm("kill", &processes, self.yes)? {
return Ok(());
}
let (killed, failed) = apply_to_each(&processes, |proc| {
if self.graceful {
proc.terminate()
} else {
proc.kill()
}
});
printer.print_action_result("kill", &killed, &failed)
}
}