g-cli 0.1.0

Git that talks back. A human-friendly CLI wrapper for Git.
use colored::Colorize;

use crate::git;

pub fn run() {
    let branch = git::current_branch();
    println!();
    println!("  You're on branch: {}", branch.bold().cyan());
    println!();

    let files = git::parse_status();

    if files.is_empty() {
        println!("  {} Clean working directory", "".green());
        println!();
    } else {
        let staged: Vec<&git::FileStatus> = files.iter().filter(|f| f.staged).collect();
        let unstaged: Vec<&git::FileStatus> = files.iter().filter(|f| !f.staged).collect();

        if !staged.is_empty() {
            println!("  {}:", "Staged changes".green().bold());
            for f in &staged {
                println!(
                    "    {} {:<12} {}",
                    f.kind.icon().green(),
                    f.kind.label().green(),
                    f.path
                );
            }
            println!();
        }

        if !unstaged.is_empty() {
            println!("  {}:", "Unstaged changes".yellow().bold());
            for f in &unstaged {
                let (icon, label) = match f.kind {
                    git::FileChangeKind::Untracked => (f.kind.icon().bright_blue(), f.kind.label().bright_blue()),
                    _ => (f.kind.icon().yellow(), f.kind.label().yellow()),
                };
                println!("    {} {:<12} {}", icon, label, f.path);
            }
            println!();
        }

        println!(
            "  Staged: {}  Unstaged: {}",
            format!("{} file(s)", staged.len()).green(),
            format!("{} file(s)", unstaged.len()).yellow()
        );
        println!();
    }

    // Ahead / behind
    if let Some((ahead, behind)) = git::ahead_behind() {
        if ahead > 0 || behind > 0 {
            let mut warnings = vec![];
            if ahead > 0 {
                warnings.push(format!(
                    "You're {} ahead of remote",
                    format!("{} commit(s)", ahead).bold()
                ));
            }
            if behind > 0 {
                warnings.push(format!(
                    "You're {} behind remote",
                    format!("{} commit(s)", behind).bold()
                ));
            }
            for w in &warnings {
                println!("  {} {}", "".yellow(), w);
            }
            println!();
        }
    }

    // Suggestions
    let files = git::parse_status();
    if !files.is_empty() {
        println!("  {}:", "Suggested next steps".dimmed().bold());
        println!(
            "    {} {}",
            "".dimmed(),
            "g save \"describe your changes\"".cyan()
        );
        println!("    {} {}", "".dimmed(), "g undo  (undo last action)".cyan());
        println!();
    }
}