use std::path::Path;
pub fn gh_available() -> bool {
std::process::Command::new("gh")
.args(["auth", "status"])
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.map(|s| s.success())
.unwrap_or(false)
}
pub async fn create_pr(
title: &str,
body: &str,
draft: bool,
base: Option<&str>,
workspace: &Path,
) -> crate::errors::Result<String> {
let mut cmd = tokio::process::Command::new("gh");
cmd.args(["pr", "create", "--title", title, "--body", body]);
if draft {
cmd.arg("--draft");
}
if let Some(b) = base {
cmd.args(["--base", b]);
}
cmd.current_dir(workspace);
let out = cmd
.output()
.await
.map_err(|e| crate::errors::RalphError::ToolFailed {
tool: "create_pr".to_string(),
message: e.to_string(),
})?;
if out.status.success() {
Ok(String::from_utf8_lossy(&out.stdout).trim().to_string())
} else {
Err(crate::errors::RalphError::ToolFailed {
tool: "create_pr".to_string(),
message: String::from_utf8_lossy(&out.stderr).trim().to_string(),
})
}
}
pub async fn get_ci_status(
branch: Option<&str>,
workspace: &Path,
) -> crate::errors::Result<String> {
let mut cmd = tokio::process::Command::new("gh");
cmd.args(["run", "list", "--limit", "5"]);
if let Some(b) = branch {
cmd.args(["--branch", b]);
}
cmd.current_dir(workspace);
let out = cmd
.output()
.await
.map_err(|e| crate::errors::RalphError::ToolFailed {
tool: "get_ci_status".to_string(),
message: e.to_string(),
})?;
if !out.status.success() {
return Err(crate::errors::RalphError::ToolFailed {
tool: "get_ci_status".to_string(),
message: String::from_utf8_lossy(&out.stderr).trim().to_string(),
});
}
let text = String::from_utf8_lossy(&out.stdout).to_string();
if text.trim().is_empty() {
Ok("No recent CI runs found for this branch.".to_string())
} else {
Ok(text)
}
}