use std::io::Write;
use std::path::Path;
use std::process::{Command, Stdio};
pub fn stdout(args: &[&str]) -> Option<String> {
let out = Command::new("git")
.args(args)
.stderr(Stdio::null())
.output()
.ok()?;
if !out.status.success() {
return None;
}
let text = String::from_utf8_lossy(&out.stdout).trim().to_string();
(!text.is_empty()).then_some(text)
}
pub fn succeeds(args: &[&str]) -> bool {
exit_code(args) == Some(0)
}
pub fn succeeds_in(dir: &Path, args: &[&str]) -> bool {
Command::new("git")
.current_dir(dir)
.args(args)
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.map(|s| s.success())
.unwrap_or(false)
}
pub fn exit_code(args: &[&str]) -> Option<i32> {
Command::new("git")
.args(args)
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.ok()?
.code()
}
pub fn stdout_bytes_in(dir: &Path, args: &[&str]) -> Option<Vec<u8>> {
let out = Command::new("git")
.current_dir(dir)
.args(args)
.stdin(Stdio::null())
.stderr(Stdio::null())
.output()
.ok()?;
out.status.success().then_some(out.stdout)
}
pub fn stdout_with_input_in(dir: &Path, args: &[&str], input: &[u8]) -> Option<String> {
let mut child = Command::new("git")
.current_dir(dir)
.args(args)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::null())
.spawn()
.ok()?;
{
let mut stdin = child.stdin.take()?;
stdin.write_all(input).ok()?;
}
let out = child.wait_with_output().ok()?;
if !out.status.success() {
return None;
}
Some(String::from_utf8_lossy(&out.stdout).trim().to_string())
}