git_x/
clean_branches.rs

1use std::process::Command;
2
3pub fn run(dry_run: bool) {
4    let output = Command::new("git")
5        .args(get_git_branch_args())
6        .output()
7        .expect("Failed to list merged branches");
8
9    let stdout = String::from_utf8_lossy(&output.stdout);
10    let branches: Vec<String> = stdout
11        .lines()
12        .map(clean_branch_name)
13        .filter(|branch| !is_protected_branch(branch))
14        .collect();
15
16    let mut deleted = Vec::new();
17
18    for branch in branches {
19        if dry_run {
20            println!("{}", format_dry_run_message(&branch));
21            deleted.push(branch);
22        } else {
23            let delete_args = get_git_delete_args(&branch);
24            let status = Command::new("git")
25                .args(delete_args)
26                .status()
27                .expect("Failed to delete branch");
28
29            if status.success() {
30                deleted.push(branch);
31            }
32        }
33    }
34
35    if deleted.is_empty() {
36        println!("{}", format_no_branches_message());
37    } else {
38        println!("{}", format_deletion_summary(deleted.len(), dry_run));
39        for branch in deleted {
40            println!("  {branch}");
41        }
42    }
43}
44
45// Helper function to get git branch args
46pub fn get_git_branch_args() -> [&'static str; 2] {
47    ["branch", "--merged"]
48}
49
50// Helper function to get protected branches
51const PROTECTED_BRANCHES: &[&str] = &["main", "master", "develop"];
52
53pub fn get_protected_branches() -> &'static [&'static str] {
54    PROTECTED_BRANCHES
55}
56
57// Helper function to clean branch name
58pub fn clean_branch_name(line: &str) -> String {
59    line.trim().trim_start_matches('*').trim().to_string()
60}
61
62// Helper function to is_protected_branch
63pub fn is_protected_branch(branch: &str) -> bool {
64    PROTECTED_BRANCHES.contains(&branch)
65}
66
67// Helper function to get git delete args
68pub fn get_git_delete_args(branch: &str) -> [&str; 3] {
69    ["branch", "-d", branch]
70}
71
72// Helper function to format dry run message
73pub fn format_dry_run_message(branch: &str) -> String {
74    format!("(dry run) Would delete: {branch}")
75}
76
77// Helper function to format no branches message
78pub fn format_no_branches_message() -> &'static str {
79    "No merged branches to delete."
80}
81
82// Helper function to format deletion summary
83pub fn format_deletion_summary(count: usize, dry_run: bool) -> String {
84    if dry_run {
85        format!("🧪 (dry run) {count} branches would be deleted:")
86    } else {
87        format!("🧹 Deleted {count} merged branches:")
88    }
89}