use std::process::Command;
pub fn run(args: &[&str]) -> Result<(), String> {
let output = Command::new("git")
.args(args)
.output()
.map_err(|error| format!("could not run git: {error}"))?;
if output.status.success() {
Ok(())
} else {
Err(String::from_utf8_lossy(&output.stderr).trim().to_string())
}
}
pub fn output(args: &[&str]) -> Option<String> {
let output = Command::new("git").args(args).output().ok()?;
if !output.status.success() {
return None;
}
let value = String::from_utf8(output.stdout).ok()?.trim().to_string();
(!value.is_empty()).then_some(value)
}
pub fn remote_https_url(url: &str) -> Option<String> {
let url = url.trim().trim_end_matches(".git");
if url.starts_with("http://") || url.starts_with("https://") {
Some(url.to_string())
} else if let Some(rest) = url.strip_prefix("ssh://git@") {
Some(format!("https://{rest}"))
} else if let Some(rest) = url.strip_prefix("git@") {
let (host, path) = rest.split_once(':')?;
Some(format!("https://{host}/{path}"))
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn normalizes_remote_urls_to_https() {
assert_eq!(
remote_https_url("https://github.com/luaupm/cli.git").as_deref(),
Some("https://github.com/luaupm/cli")
);
assert_eq!(
remote_https_url("git@github.com:luaupm/cli.git").as_deref(),
Some("https://github.com/luaupm/cli")
);
assert_eq!(
remote_https_url("ssh://git@github.com/luaupm/cli").as_deref(),
Some("https://github.com/luaupm/cli")
);
assert_eq!(remote_https_url("ftp://example.com/a/b"), None);
}
#[test]
fn failed_commands_report_nothing() {
assert_eq!(output(&["--not-a-real-flag"]), None);
assert!(run(&["--not-a-real-flag"]).is_err());
}
}