use std::process::{Command, Stdio};
const INSTALL_SCRIPT_URL: &str =
"https://raw.githubusercontent.com/zenitheditor/zenith/main/scripts/install.sh";
pub fn run(pre: bool, version: Option<&str>) -> Result<(), String> {
let mut sh_args: Vec<String> = vec!["-s".to_string(), "--".to_string()];
if pre {
sh_args.push("--pre".to_string());
}
if let Some(v) = version {
let tag = if v.starts_with('v') {
v.to_string()
} else {
format!("v{v}")
};
sh_args.push("--version".to_string());
sh_args.push(tag);
}
let (dl_cmd, dl_args): (&str, &[&str]) = if which("curl") {
("curl", &["-fsSL", INSTALL_SCRIPT_URL])
} else if which("wget") {
("wget", &["-qO-", INSTALL_SCRIPT_URL])
} else {
return Err("curl or wget is required for self-update".to_string());
};
let mut downloader = Command::new(dl_cmd)
.args(dl_args)
.stdout(Stdio::piped())
.spawn()
.map_err(|e| format!("failed to start {dl_cmd}: {e}"))?;
let pipe = downloader
.stdout
.take()
.ok_or_else(|| "failed to capture the download stream".to_string())?;
let status = Command::new("sh")
.args(&sh_args)
.stdin(pipe)
.status()
.map_err(|e| format!("failed to run the install script: {e}"))?;
let _ = downloader.wait();
if status.success() {
Ok(())
} else {
Err("the install script failed".to_string())
}
}
fn which(cmd: &str) -> bool {
Command::new("sh")
.arg("-c")
.arg(format!("command -v {cmd}"))
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.map(|s| s.success())
.unwrap_or(false)
}