use std::{env, io::Cursor};
use eyre::{Result, bail};
const S3_BUCKET: &str = "cli.simulator.termina.technology";
pub async fn update() -> Result<()> {
let s3_key = platform_key()?;
let url = format!("https://{S3_BUCKET}/{s3_key}");
println!("Downloading {url} ...");
let bytes = reqwest::get(&url)
.await?
.error_for_status()?
.bytes()
.await?;
let current_exe = env::current_exe()?.canonicalize()?;
let parent = current_exe
.parent()
.ok_or_else(|| eyre::eyre!("could not determine parent directory of current executable"))?;
let tmp = tempfile::NamedTempFile::new_in(parent)?;
let tmp_path = tmp.path().to_owned();
let gz = flate2::read::GzDecoder::new(Cursor::new(&bytes));
let mut archive = tar::Archive::new(gz);
let mut found = false;
for entry in archive.entries()? {
let mut entry = entry?;
if entry.path()?.ends_with("sim") {
entry.unpack(&tmp_path)?;
found = true;
break;
}
}
if !found {
bail!("sim binary not found in archive");
}
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
std::fs::set_permissions(&tmp_path, std::fs::Permissions::from_mode(0o755))?;
}
std::fs::rename(&tmp_path, ¤t_exe)?;
println!("Updated: {}", current_exe.display());
Ok(())
}
fn platform_key() -> Result<&'static str> {
match (env::consts::OS, env::consts::ARCH) {
("linux", "x86_64") => Ok("sim-linux-x86_64.tar.gz"),
("macos", "aarch64") => Ok("sim-darwin-aarch64.tar.gz"),
(os, arch) => bail!("unsupported platform: {os}-{arch}"),
}
}