gmsg 0.1.0

AI-powered commit message generator with a TUI editor
Documentation
pub mod gmsg;

pub mod ai;
pub mod editor;
pub mod git;
use crate::ai::GenerateCommitMsg;
use crate::editor::Editor;
use anyhow::Context;
use arboard::Clipboard;
use clap::Parser;
use git2::Repository;
use std::path::PathBuf;
use std::thread;
use std::time::Duration;

use crate::gmsg::Gmsg;

pub async fn run() -> anyhow::Result<()> {
    let cli = Gmsg::parse();

    let wdir: PathBuf = if let Some(path) = cli.path.as_ref() {
        eprintln!("Path supplied ,{:?}", &path);
        path.to_owned()
    } else {
        let dir = std::env::current_dir().context("Failed to open current working directory")?;
        eprintln!("No path supplied ,using current directory ,{:?}", &dir);
        dir
    };

    let repository =
        Repository::discover(wdir)
        .context("Failed to open a git repository in the specified directory,Check if it exists or if you have neccessary permisions")?;

    let diff = git::get_diff(&repository)?;
    let agent = ai::build_commit_agent(None).context("Could not Bootstrap Agent")?;
    let mut out = strip_backtick(&agent.generate_commit_msg(&diff).await?);

    if cli.interactive | cli.amend.is_some() {
        let instruction = cli.amend.unwrap_or_default();
        let mut terminal = ratatui::init();
        out = Editor::from(out)
            .run(&mut terminal)
            .context("Failed to initialize inline editor")?;
        ratatui::restore();
        if out.is_empty() {
            eprintln!("Aborted commit operation");
            return Ok(());
        }
    }
    if !std::io::IsTerminal::is_terminal(&std::io::stdout()) {
        println!("{}", out);
        return Ok(());
    }
    if cli.copy {
        let mut clipboard = Clipboard::new().context("Failed to get system clipboard")?;
        clipboard
            .set_text(&out)
            .context("Failed to set clipboard")?;
        thread::sleep(Duration::from_secs(2));
        eprintln!("Set Clipboard witht text{}", out);

        return Ok(());
    }
    match git::commit(&repository, &out) {
        Ok(_) => {
            eprintln!("Committed wih message: \n{}", out);
        }
        Err(e) => {
            eprintln!("Encountered Error While commiting {:?}", e);
        }
    }

    Ok(())
}

fn strip_backtick(input: &str) -> String {
    input.replace('`', "")
}