use std::path::Path;
pub fn replace_binary(new_binary_path: &Path) -> anyhow::Result<()> {
let current_exe = std::env::current_exe()
.map_err(|e| anyhow::anyhow!("Failed to determine current executable path: {}", e))?;
let current_exe = current_exe
.canonicalize()
.map_err(|e| anyhow::anyhow!("Failed to resolve current executable path: {}", e))?;
let backup_path = current_exe.with_extension("bak");
std::fs::rename(¤t_exe, &backup_path).map_err(|e| {
anyhow::anyhow!(
"Failed to rename {} to {}: {}",
current_exe.display(),
backup_path.display(),
e
)
})?;
if let Err(e) = std::fs::copy(new_binary_path, ¤t_exe) {
let _ = std::fs::rename(&backup_path, ¤t_exe);
return Err(anyhow::anyhow!(
"Failed to install new binary to {}: {}",
current_exe.display(),
e
));
}
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let perms = std::fs::Permissions::from_mode(0o755);
std::fs::set_permissions(¤t_exe, perms).map_err(|e| {
anyhow::anyhow!(
"Failed to set permissions on {}: {}",
current_exe.display(),
e
)
})?;
}
let _ = std::fs::remove_file(&backup_path);
if let Some(parent) = new_binary_path.parent() {
let _ = std::fs::remove_dir_all(parent);
}
Ok(())
}