use std::env;
use std::path::Path;
use std::process::Command;
use anyhow::{Context, Result, bail};
pub(super) fn git_program() -> String {
env::var("SHIPPER_GIT_BIN").unwrap_or_else(|_| "git".to_string())
}
pub(super) fn is_repo_root(repo_root: &Path, git_program: &str) -> bool {
Command::new(git_program)
.arg("rev-parse")
.arg("--git-dir")
.current_dir(repo_root)
.output()
.map(|out| out.status.success())
.unwrap_or(false)
}
pub(super) fn local_is_git_clean(repo_root: &Path, git_program: &str) -> Result<bool> {
let out = Command::new(git_program)
.arg("status")
.arg("--porcelain")
.current_dir(repo_root)
.output()
.context("failed to execute git status; is git installed?")?;
if !out.status.success() {
bail!(
"git status failed: {}",
String::from_utf8_lossy(&out.stderr).trim()
);
}
Ok(String::from_utf8_lossy(&out.stdout).trim().is_empty())
}
pub(super) fn get_git_commit(repo_root: &Path, git_program: &str) -> Option<String> {
let output = Command::new(git_program)
.arg("rev-parse")
.arg("HEAD")
.current_dir(repo_root)
.output()
.ok()?;
if output.status.success() {
Some(String::from_utf8_lossy(&output.stdout).trim().to_string())
} else {
None
}
}
pub(super) fn get_git_branch(repo_root: &Path, git_program: &str) -> Option<String> {
let output = Command::new(git_program)
.arg("rev-parse")
.arg("--abbrev-ref")
.arg("HEAD")
.current_dir(repo_root)
.output()
.ok()?;
if output.status.success() {
let branch = String::from_utf8_lossy(&output.stdout).trim().to_string();
if branch == "HEAD" { None } else { Some(branch) }
} else {
None
}
}
pub(super) fn get_git_tag(repo_root: &Path, git_program: &str) -> Option<String> {
let output = Command::new(git_program)
.arg("describe")
.arg("--tags")
.arg("--exact-match")
.current_dir(repo_root)
.output()
.ok()?;
if output.status.success() {
Some(String::from_utf8_lossy(&output.stdout).trim().to_string())
} else {
None
}
}
pub(super) fn get_git_dirty_status(repo_root: &Path, git_program: &str) -> Option<bool> {
let output = Command::new(git_program)
.arg("status")
.arg("--porcelain")
.current_dir(repo_root)
.output()
.ok()?;
if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
Some(!stdout.trim().is_empty())
} else {
None
}
}