g-cli 0.1.0

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

use crate::git;

pub fn run() {
    let branch = git::current_branch();

    // Check if there's an upstream
    let has_upstream = git::ahead_behind().is_some();

    println!();

    if !has_upstream {
        println!("  No upstream set for '{}'.", branch.cyan());
        println!();
        println!("  This will push and set upstream to {}",
            format!("origin/{}", branch).cyan()
        );
        println!();

        let confirm = Confirm::new()
            .with_prompt("  Proceed?")
            .default(true)
            .interact();

        match confirm {
            Ok(true) => {}
            _ => {
                println!("  Cancelled.");
                println!();
                return;
            }
        }

        println!();
        let result = git::run(&["push", "-u", "origin", &branch]);
        if result.success {
            println!("  {} Pushed and set upstream for '{}'.", "".green().bold(), branch.cyan());
        } else {
            println!("  {} Failed: {}", "".red(), result.stderr);
        }
        println!();
        return;
    }

    // Show preview
    let (ahead, _behind) = git::ahead_behind().unwrap_or((0, 0));

    if ahead == 0 {
        println!("  {} Nothing to push — you're up to date with remote.", "".green());
        println!();
        return;
    }

    println!("  {}:", "You're about to push".bold());
    println!();
    println!("    Branch:      {}", branch.cyan());
    println!("    Commits:     {}", format!("{}", ahead).bold());
    println!("    Destination: {}", format!("origin/{}", branch).dimmed());
    println!();

    // Show the commits being pushed
    let n = format!("-{}", ahead);
    let log_result = git::run(&["log", &n, "--pretty=format:    - %s"]);
    if log_result.success && !log_result.stdout.is_empty() {
        println!("  {}:", "Summary".dimmed());
        println!("{}", log_result.stdout);
        println!();
    }

    let confirm = Confirm::new()
        .with_prompt("  Proceed?")
        .default(true)
        .interact();

    match confirm {
        Ok(true) => {}
        _ => {
            println!("  Cancelled.");
            println!();
            return;
        }
    }

    println!();
    let result = git::run(&["push"]);
    if result.success {
        println!(
            "  {} Pushed {} commit(s) to origin/{}.",
            "".green().bold(),
            ahead,
            branch
        );
    } else {
        println!("  {} Failed: {}", "".red(), result.stderr);
    }
    println!();
}