rtlibs-utils 0.1.6

rtools library: utilities
Documentation
use std::io::BufRead;
use std::io::BufReader;
use std::path::Path;
use std::process::Command;
use std::process::Stdio;

use crate::error::GitError;

pub fn run_command(
    working_dir: &Path,
    command: &str,
) -> Result<(), GitError>
{
    let child = Command::new("bash")
        .current_dir(working_dir)
        .args(["-c", &format!("git {command}")])
        .stdout(Stdio::piped())
        .spawn()?;

    let Some(stdout) = child.stdout
    else
    {
        return Err(GitError::Stdout);
    };

    let lines = BufReader::new(stdout).lines();
    for line in lines.map_while(Result::ok)
    {
        println!("{line}");
    }

    Ok(())
}

/// Clone directory
pub fn clone<P, S>(
    working_dir: P,
    remote_repository: S,
) -> Result<(), GitError>
where
    P: AsRef<Path>,
    S: AsRef<str>,
{
    let inner = |working_dir: &Path, remote_repository: &str| {
        run_command(
            working_dir,
            &format!("clone {remote_repository} ."),
        )
    };

    inner(
        working_dir.as_ref(),
        remote_repository.as_ref(),
    )
}

/// Clone directory
pub fn clone_branch<P, S1, S2>(
    working_dir: P,
    remote_repository: S1,
    branch: S2,
) -> Result<(), GitError>
where
    P: AsRef<Path>,
    S1: AsRef<str>,
    S2: AsRef<str>,
{
    let inner = |working_dir: &Path, remote_repository: &str, branch: &str| {
        run_command(
            working_dir,
            &format!("clone --branch {branch} {remote_repository} ."),
        )
    };

    inner(
        working_dir.as_ref(),
        remote_repository.as_ref(),
        branch.as_ref(),
    )
}

// Checkout branch
// pub fn checkout<P, S>(
//     working_dir: P,
//     branch: S,
// ) -> Result<(), GitError>
// where
//     P: AsRef<Path>,
//     S: AsRef<str>,
// {
//     let inner = |working_dir: &Path, branch: &str| {
//         run_command(
//             working_dir,
//             &format!("checkout {branch}"),
//         )
//     };

//     inner(
//         working_dir.as_ref(),
//         branch.as_ref(),
//     )
// }

/// Checkout branch
pub fn checkout<P, S>(
    working_dir: P,
    branch: S,
) -> Result<(), GitError>
where
    P: AsRef<Path>,
    S: AsRef<str>,
{
    let inner = |working_dir: &Path, branch: &str| {
        run_command(
            working_dir,
            &format!("checkout -b {branch}"),
        )
    };

    inner(
        working_dir.as_ref(),
        branch.as_ref(),
    )
}

/// Config repository user and email
pub fn config<P, S1, S2>(
    working_dir: P,
    user_name: S1,
    user_email: S2,
) -> Result<(), GitError>
where
    P: AsRef<Path>,
    S1: AsRef<str>,
    S2: AsRef<str>,
{
    let inner = |working_dir: &Path, user_name: &str, user_email: &str| {
        run_command(
            working_dir,
            &format!("config user.name \"{user_name}\""),
        )?;
        run_command(
            working_dir,
            &format!("config user.email \"{user_email}\""),
        )?;
        run_command(
            working_dir,
            "config push.autoSetupRemote \"true\"",
        )?;
        Ok(())
    };

    inner(
        working_dir.as_ref(),
        user_name.as_ref(),
        user_email.as_ref(),
    )
}

/// Add all
pub fn add_all<P>(working_dir: P) -> Result<(), GitError>
where
    P: AsRef<Path>,
{
    let inner = |working_dir: &Path| {
        run_command(
            working_dir,
            "add .",
        )
    };

    inner(working_dir.as_ref())
}

/// Commit
pub fn commit<P, S>(
    working_dir: P,
    message: S,
) -> Result<(), GitError>
where
    P: AsRef<Path>,
    S: AsRef<str>,
{
    let inner = |working_dir: &Path, message: &str| {
        run_command(
            working_dir,
            &format!("commit -m \"{message}\""),
        )
    };

    inner(
        working_dir.as_ref(),
        message.as_ref(),
    )
}

/// Push to remote
pub fn push<P>(working_dir: P) -> Result<(), GitError>
where
    P: AsRef<Path>,
{
    let inner = |working_dir: &Path| {
        run_command(
            working_dir,
            "push",
        )
    };

    inner(working_dir.as_ref())
}

/// Add all, commit and push to remote
pub fn add_commit_and_push<P, S>(
    working_dir: P,
    message: S,
) -> Result<(), GitError>
where
    P: AsRef<Path>,
    S: AsRef<str>,
{
    let inner = |working_dir: &Path, message: &str| {
        add_all(working_dir)?;
        commit(
            working_dir,
            message,
        )?;
        push(working_dir)?;
        Ok(())
    };

    inner(
        working_dir.as_ref(),
        message.as_ref(),
    )
}