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