cargo-c-build 0.9.3

An AI-enhanced git automation tool that builds and commits Rust projects with AI-generated commit messages for every build run.
use std::env;
use std::process::{Command, Stdio};
use std::io::{self};

mod cmclient;
use cmclient::ClientMessageClient;

#[tokio::main]
async fn main() -> io::Result<()> {
    let args: Vec<String> = env::args()
    .skip(1)
    .filter(|arg| arg != "c-build")
    .collect(); // Skips 1 because we dont care about the binary also skips c-build.

    let mut message_to_commit = String::new();

    let branch_status = Command::new("git")
        .arg("status")
        .output()?;

    let status_output = String::from_utf8_lossy(&branch_status.stdout);

    if !has_changes(&status_output) {
        println!("No Commit Being made.");
    } else {
        println!("Building Commit Message.");

        let request_context = Command::new("git")
                                        .arg("diff")
                                        .output()?;

        let mut client = ClientMessageClient::create_client();
        match client.create_commit_message(String::from_utf8_lossy(&request_context.stdout).to_string()).await {
            Ok(msg) => {
                message_to_commit = msg.clone();
                println!("{}", format!("{:?}", msg))
            },
            Err(e) => eprintln!("Error generating commit message: {}", e),
        }
    }

    let mut build = Command::new("cargo")
        .arg("build")
        .args(&args)
        .stdout(Stdio::inherit())
        .stderr(Stdio::inherit())
        .spawn()?;

    let build_status = build.wait()?;

    if build_status.success() {
        if !message_to_commit.is_empty() {
            commit_message(message_to_commit.to_string()).await;
        }
    } else {
        eprintln!("Build failed with code: {:?}", build_status.code());
        eprintln!("Not committing.");
    }
    
    Ok(())
}

async fn commit_message(msg: String) {
    let add_status = Command::new("git")
        .arg("add")
        .arg(".")
        .status()
        .expect("Failed to execute git add");

    if !add_status.success() {
        eprintln!("git add failed");
        return;
    }

    let commit_status = Command::new("git")
        .arg("commit")
        .arg("-m")
        .arg(msg)
        .status()
        .expect("Failed to execute git commit");

    if commit_status.success() {
        println!("Commit successful");
    } else {
        eprintln!("Commit failed");
    }
}

// Move At Somepoint
fn has_changes(status_output: &str) -> bool {
    status_output.contains("modified:")
        || status_output.contains("Untracked files")
        || status_output.contains("deleted:")
        || status_output.contains("renamed:")
        || status_output.contains("new file:")
}