ferro_cli/commands/
clean.rs1use std::process::Command;
2
3pub fn run(sweep_days: Option<u32>) {
6 match sweep_days {
7 Some(days) => run_sweep(days),
8 None => run_cargo_clean(),
9 }
10}
11
12fn run_cargo_clean() {
13 println!("Cleaning build artifacts...");
14
15 let output = match Command::new("cargo").arg("clean").output() {
16 Ok(o) => o,
17 Err(e) => {
18 eprintln!("Failed to run cargo clean: {e}");
19 return;
20 }
21 };
22
23 if output.status.success() {
24 println!("Build artifacts removed.");
25 } else {
26 let stderr = String::from_utf8_lossy(&output.stderr);
27 eprintln!("cargo clean failed: {stderr}");
28 }
29}
30
31fn run_sweep(days: u32) {
32 if !is_sweep_installed() {
33 eprintln!("cargo-sweep is required for time-based cleanup.");
34 eprintln!("Install it with: cargo install cargo-sweep");
35 return;
36 }
37
38 println!("Cleaning build artifacts older than {days} days...");
39
40 let output = match Command::new("cargo")
41 .args(["sweep", "--time", &days.to_string()])
42 .output()
43 {
44 Ok(o) => o,
45 Err(e) => {
46 eprintln!("Failed to run cargo sweep: {e}");
47 return;
48 }
49 };
50
51 if output.status.success() {
52 let stdout = String::from_utf8_lossy(&output.stdout);
53 if let Some(cleaned) = parse_sweep_output(&stdout) {
54 println!("{cleaned}");
55 } else {
56 println!("Cleanup complete.");
57 }
58 } else {
59 let stderr = String::from_utf8_lossy(&output.stderr);
60 eprintln!("Sweep failed: {stderr}");
61 }
62}
63
64pub fn run_silent(days: u32) -> Option<String> {
66 if !is_sweep_installed() {
67 return None;
68 }
69
70 let output = Command::new("cargo")
71 .args(["sweep", "--time", &days.to_string()])
72 .output()
73 .ok()?;
74
75 if output.status.success() {
76 let stdout = String::from_utf8_lossy(&output.stdout);
77 parse_sweep_output(&stdout)
78 } else {
79 None
80 }
81}
82
83fn is_sweep_installed() -> bool {
84 Command::new("cargo")
85 .args(["sweep", "--version"])
86 .output()
87 .map(|o| o.status.success())
88 .unwrap_or(false)
89}
90
91fn parse_sweep_output(output: &str) -> Option<String> {
92 for line in output.lines() {
93 if line.contains("Cleaned")
94 && (line.contains("GiB") || line.contains("MiB") || line.contains("KiB"))
95 {
96 if let Some(start) = line.find("Cleaned") {
97 let size_part = &line[start..];
98 return Some(size_part.to_string());
99 }
100 }
101 }
102 None
103}