proc_cli/commands/
orphans.rs1use crate::core::{apply_filters, Process};
10use crate::error::Result;
11use crate::ui::{plural, Printer};
12use clap::Args;
13use dialoguer::Confirm;
14
15#[derive(Args, Debug)]
17pub struct OrphansCommand {
18 #[arg(long, short = 'k')]
20 pub kill: bool,
21
22 #[arg(long)]
24 pub dry_run: bool,
25
26 #[arg(long, short = 'y')]
28 pub yes: bool,
29
30 #[arg(long, short = 'j')]
32 pub json: bool,
33
34 #[arg(long, short = 'v')]
36 pub verbose: bool,
37
38 #[arg(long = "in", short = 'i', num_args = 0..=1, default_missing_value = ".")]
40 pub in_dir: Option<String>,
41
42 #[arg(long = "by", short = 'b')]
44 pub by_name: Option<String>,
45}
46
47impl OrphansCommand {
48 pub fn execute(&self) -> Result<()> {
50 let printer = Printer::from_flags(self.json, self.verbose);
51
52 let mut processes = Process::find_orphans()?;
53
54 apply_filters(&mut processes, &self.in_dir, &self.by_name);
56
57 if processes.is_empty() {
58 printer.print_empty_result("orphans", "No orphaned processes found");
59 return Ok(());
60 }
61
62 printer.warning(&format!(
63 "Found {} orphaned process{}",
64 processes.len(),
65 plural(processes.len())
66 ));
67
68 if !self.kill {
69 printer.print_processes_as("orphans", &processes, None);
70 return Ok(());
71 }
72
73 if self.dry_run {
75 printer.print_dry_run_with(
76 "orphans",
77 &processes,
78 &format!(
79 "Dry run: would kill {} orphaned process{}",
80 processes.len(),
81 plural(processes.len())
82 ),
83 );
84 return Ok(());
85 }
86
87 if !self.json {
89 printer.print_processes_as("orphans", &processes, None);
90 }
91
92 if !self.yes && !self.json {
93 let confirmed = Confirm::new()
94 .with_prompt(format!(
95 "Kill {} orphaned process{}?",
96 processes.len(),
97 plural(processes.len())
98 ))
99 .default(false)
100 .interact()?;
101
102 if !confirmed {
103 printer.warning("Cancelled");
104 return Ok(());
105 }
106 }
107
108 let mut killed = Vec::new();
109 let mut failed = Vec::new();
110
111 for proc in processes {
112 match proc.kill_and_wait() {
113 Ok(_) => killed.push(proc),
114 Err(e) => failed.push((proc, e.to_string())),
115 }
116 }
117
118 printer.print_action_result_as("orphans", "kill", &killed, &failed)
119 }
120}