use std::sync::OnceLock;
static TOKEN_CACHE: OnceLock<(Option<String>, &'static str)> = OnceLock::new();
pub fn discover_token() -> Option<&'static str> {
TOKEN_CACHE
.get_or_init(discover_with_source)
.0
.as_deref()
}
pub fn discover_token_source() -> &'static str {
TOKEN_CACHE.get_or_init(discover_with_source).1
}
fn discover_with_source() -> (Option<String>, &'static str) {
if let Ok(t) = std::env::var("GITHUB_TOKEN") {
if !t.is_empty() {
return (Some(t), "env:GITHUB_TOKEN");
}
}
if let Ok(t) = std::env::var("GH_TOKEN") {
if !t.is_empty() {
return (Some(t), "env:GH_TOKEN");
}
}
let Some(out) = std::process::Command::new("gh")
.args(["auth", "token"])
.output()
.ok()
else {
return (None, "none");
};
if !out.status.success() {
return (None, "none");
}
let Some(s) = String::from_utf8(out.stdout).ok().map(|s| s.trim().to_string()) else {
return (None, "none");
};
if s.is_empty() {
(None, "none")
} else {
(Some(s), "gh")
}
}
pub fn discover_token_uncached() -> Option<String> {
discover_with_source().0
}