lean_ctx/core/patterns/
composer.rs1pub fn compress(cmd: &str, output: &str) -> Option<String> {
2 let trimmed = output.trim();
3 if trimmed.is_empty() {
4 return Some("ok".to_string());
5 }
6
7 if cmd.contains("install") || cmd.contains("update") || cmd.contains("require") {
8 return Some(compress_install(trimmed));
9 }
10 if cmd.contains("outdated") {
11 return Some(compress_outdated(trimmed));
12 }
13 if cmd.contains("show") || cmd.contains("info") {
14 return Some(compact_lines(trimmed, 15));
15 }
16
17 Some(compact_lines(trimmed, 15))
18}
19
20fn compress_install(output: &str) -> String {
21 let mut installed = 0u32;
22 let mut updated = 0u32;
23 let mut removed = 0u32;
24 let mut loading = false;
25
26 for line in output.lines() {
27 let trimmed = line.trim();
28 if trimmed.starts_with("- Installing") || trimmed.starts_with("- Downloading") {
29 installed += 1;
30 }
31 if trimmed.starts_with("- Updating") || trimmed.starts_with("- Upgrading") {
32 updated += 1;
33 }
34 if trimmed.starts_with("- Removing") {
35 removed += 1;
36 }
37 if trimmed.starts_with("Loading composer") {
38 loading = true;
39 }
40 }
41
42 if !loading && installed == 0 && updated == 0 {
43 return compact_lines(output, 10);
44 }
45
46 let mut parts = Vec::new();
47 if installed > 0 {
48 parts.push(format!("{installed} installed"));
49 }
50 if updated > 0 {
51 parts.push(format!("{updated} updated"));
52 }
53 if removed > 0 {
54 parts.push(format!("{removed} removed"));
55 }
56
57 let summary = output
58 .lines()
59 .rev()
60 .find(|l| l.contains("Package operations") || l.contains("Nothing to install"));
61 let mut result = format!("composer: {}", parts.join(", "));
62 if let Some(s) = summary {
63 result.push_str(&format!("\n {}", s.trim()));
64 }
65 result
66}
67
68fn compress_outdated(output: &str) -> String {
69 let lines: Vec<&str> = output
70 .lines()
71 .filter(|l| {
72 let t = l.trim();
73 !t.is_empty() && !t.starts_with("Color legend")
74 })
75 .collect();
76
77 if lines.is_empty() {
78 return "all up to date".to_string();
79 }
80 if lines.len() <= 20 {
81 return lines.join("\n");
82 }
83 format!(
84 "{} outdated packages:\n{}\n... ({} more)",
85 lines.len(),
86 lines[..15].join("\n"),
87 lines.len() - 15
88 )
89}
90
91fn compact_lines(text: &str, max: usize) -> String {
92 let lines: Vec<&str> = text.lines().filter(|l| !l.trim().is_empty()).collect();
93 if lines.len() <= max {
94 return lines.join("\n");
95 }
96 format!(
97 "{}\n... ({} more lines)",
98 lines[..max].join("\n"),
99 lines.len() - max
100 )
101}