pray-core 1.11.0

Core library for Prayfile, the package manager for the language placed before inference
Documentation
use crate::{PrayError, PrayResult};
use std::path::Path;
use std::process::Command;

pub(crate) fn run_git_success(root: &Path, arguments: &[&str]) -> PrayResult<()> {
    let output = run_git_command(root, arguments)?;
    if output.status.success() {
        Ok(())
    } else {
        Err(command_error("git", output))
    }
}

pub(crate) fn run_git_command(root: &Path, arguments: &[&str]) -> PrayResult<std::process::Output> {
    Command::new(git_program())
        .current_dir(root)
        .args(arguments)
        .output()
        .map_err(|error| PrayError::Unsupported(format!("failed to run `git`: {error}")))
}

pub(crate) fn git_program() -> String {
    [
        "/usr/bin/git",
        "/opt/homebrew/bin/git",
        "/usr/local/bin/git",
        "git",
    ]
    .into_iter()
    .find(|candidate| Path::new(candidate).exists() || *candidate == "git")
    .unwrap_or("git")
    .to_string()
}

pub(crate) fn command_error(program: &str, output: std::process::Output) -> PrayError {
    let stderr = String::from_utf8_lossy(&output.stderr).trim().to_string();
    let stdout = String::from_utf8_lossy(&output.stdout).trim().to_string();
    let mut message = format!("{program} failed with status {}", output.status);
    if !stderr.is_empty() {
        message.push_str(&format!(": {stderr}"));
    } else if !stdout.is_empty() {
        message.push_str(&format!(": {stdout}"));
    }
    PrayError::Resolution(message)
}