wsb 0.225.4660

Workspace - A tool suite for file operations, version management, and development workflow automation
Documentation
use crate::fleet::git::SubmoduleStatus;
use crate::prelude::*;
use colored::*;

pub struct Formatter;

impl Formatter {
    pub fn print_status(statuses: &[SubmoduleStatus]) {
        println!("\n{}", "Git Status:".bold().underline());
        println!();

        for status in statuses {
            let indent = "  ".repeat(status.depth);
            if !status.exists {
                println!(
                    "  {}{} {} {}",
                    indent,
                    "●".red(),
                    status.name.bold(),
                    "[NOT INITIALIZED]".red()
                );
                continue;
            }

            // Green means nothing to do here; yellow means something needs
            // attention, whether that is local changes, drift from the remote, or
            // a detached HEAD. Which one it is, is spelled out on the lines below.
            let indicator = if status.is_clean && status.ahead == 0 && status.behind == 0 {
                "●".green()
            } else {
                "●".yellow()
            };

            print!("  {}{} {}", indent, indicator, status.name.bold());

            if let Some(ref branch) = status.current_branch {
                print!(" ({})", branch.cyan());
            } else if status.is_detached {
                print!(" {}", "[DETACHED HEAD]".red());
            }

            println!();

            if !status.is_clean {
                println!(
                    "    {}{} {} uncommitted file(s)",
                    indent,
                    "!".yellow(),
                    status.uncommitted_files.len()
                );
            }

            if status.ahead > 0 {
                println!(
                    "    {}{} {} commit(s) ahead",
                    indent,
                    "↑".green(),
                    status.ahead
                );
            }

            if status.behind > 0 {
                println!(
                    "    {}{} {} commit(s) behind",
                    indent,
                    "↓".red(),
                    status.behind
                );
            }
        }

        println!();
    }

    pub fn print_success(message: &str) {
        println!("{} {}", "✓".green(), message);
    }

    pub fn print_error(message: &str) {
        eprintln!("{} {}", "✗".red(), message);
    }

    pub fn print_warning(message: &str) {
        println!("{} {}", "!".yellow(), message);
    }

    pub fn print_info(message: &str) {
        println!("{} {}", "ℹ".cyan(), message);
    }

    pub fn print_submodule_header(name: &str) {
        println!("\n{} {}...", "→".cyan(), name.bold());
    }

    pub fn print_summary(successful: usize, failed: usize, skipped: usize) {
        println!("\n{}", "Summary:".bold().underline());
        println!(
            "  {} successful, {} failed, {} skipped",
            successful.to_string().green(),
            failed.to_string().red(),
            skipped.to_string().yellow()
        );
    }

    pub fn print_branches(submodule_name: &str, branches: &[String], current: Option<&str>) {
        println!("\n{}", submodule_name.bold());
        for branch in branches {
            if Some(branch.as_str()) == current {
                println!("  {} {}", "*".green(), branch.green());
            } else {
                println!("    {}", branch);
            }
        }
    }
}