use anyhow::Result;
use super::git_output;
use crate::redact::redact_url_credentials;
pub fn parse_github_remote(url: &str) -> Option<(String, String)> {
let url = url.trim();
if url.is_empty() {
return None;
}
let url = url.strip_suffix(".git").unwrap_or(url);
if let Some(path) = url.strip_prefix("https://github.com/") {
let parts: Vec<&str> = path.splitn(3, '/').collect();
if parts.len() >= 2 && !parts[0].is_empty() && !parts[1].is_empty() {
return Some((parts[0].to_string(), parts[1].to_string()));
}
}
if let Some(path) = url.strip_prefix("git@github.com:") {
let parts: Vec<&str> = path.splitn(3, '/').collect();
if parts.len() >= 2 && !parts[0].is_empty() && !parts[1].is_empty() {
return Some((parts[0].to_string(), parts[1].to_string()));
}
}
None
}
pub fn detect_github_repo() -> Result<(String, String)> {
let url = git_output(&["remote", "get-url", "origin"])?;
parse_github_remote(&url).ok_or_else(|| {
let safe = redact_url_credentials(&url);
anyhow::anyhow!(
"could not parse GitHub owner/repo from remote URL: {}",
safe
)
})
}
pub fn parse_remote_owner_repo(url: &str) -> Option<(String, String)> {
let url = url.trim();
if url.is_empty() {
return None;
}
let url = url.strip_suffix(".git").unwrap_or(url);
if url.starts_with("https://") || url.starts_with("http://") {
let after_scheme = if let Some(rest) = url.strip_prefix("https://") {
rest
} else {
url.strip_prefix("http://")?
};
let after_host = after_scheme.find('/').map(|i| &after_scheme[i + 1..])?;
let last_slash = after_host.rfind('/')?;
let owner = &after_host[..last_slash];
let repo = &after_host[last_slash + 1..];
if !owner.is_empty() && !repo.is_empty() {
return Some((owner.to_string(), repo.to_string()));
}
}
if let Some(colon_pos) = url.find(':') {
let before_colon = &url[..colon_pos];
if before_colon.contains('@') && !before_colon.contains("//") {
let path = &url[colon_pos + 1..];
let last_slash = path.rfind('/')?;
let owner = &path[..last_slash];
let repo = &path[last_slash + 1..];
if !owner.is_empty() && !repo.is_empty() {
return Some((owner.to_string(), repo.to_string()));
}
}
}
None
}
pub fn detect_owner_repo() -> Result<(String, String)> {
let url = git_output(&["remote", "get-url", "origin"])?;
parse_remote_owner_repo(&url).ok_or_else(|| {
let safe = redact_url_credentials(&url);
anyhow::anyhow!("could not parse owner/repo from remote URL: {}", safe)
})
}