agent-manager v0.2.0 : gestionnaire d'agents IA locaux
- CLI Rust (am) : list/install/uninstall/update/start/stop/restart/run/status/search/info/config/doctor/completion/export/import/self-update + shell interactif (Tab, historique) - 9 methodes d'installation (npm, pip, uv, cargo, go, bun, curl, binary, git) - catalogue de 72 agents, dependances, processus, securite (dry-run, checksums) - sondes de version paralleles + cache (am list ~25 ms a chaud) - installateurs one-liner : install.sh, install.ps1
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
//! self-update: download a newer agent-manager binary from GitHub Releases.
|
||||
|
||||
use super::*;
|
||||
use crate::download;
|
||||
use anyhow::{anyhow, bail, Context, Result};
|
||||
use std::cmp::Ordering;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn run(app: &App, check: bool, to: Option<&Path>) -> Result<i32> {
|
||||
let Some(repo) = app.config.settings.self_update_repo.clone() else {
|
||||
bail!(
|
||||
"self-update is not configured: set 'settings.self_update_repo: \"owner/repo\"' in your config"
|
||||
);
|
||||
};
|
||||
let current = env!("CARGO_PKG_VERSION");
|
||||
let release = download::latest_release(&repo)?;
|
||||
let tag = release.tag_name.trim_start_matches('v').to_string();
|
||||
|
||||
if check {
|
||||
match crate::version::compare(&tag, current) {
|
||||
Some(Ordering::Greater) => {
|
||||
println!("update available: {current} -> {tag}");
|
||||
Ok(0)
|
||||
}
|
||||
_ => {
|
||||
println!("agent-manager {current} is up to date");
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if crate::version::compare(&tag, current) != Some(Ordering::Greater) {
|
||||
app.log.success(&format!(
|
||||
"agent-manager {current} is already the latest version"
|
||||
));
|
||||
return Ok(0);
|
||||
}
|
||||
if app.dry_run() {
|
||||
app.log
|
||||
.dry(format!("would download agent-manager {tag}"));
|
||||
return Ok(0);
|
||||
}
|
||||
let picked = download::pick_asset(&release, &[], &[], None)
|
||||
.ok_or_else(|| anyhow!("no release asset of '{repo}' matches this platform"))?;
|
||||
app.log.info(&format!(
|
||||
"downloading agent-manager {tag} ({})",
|
||||
picked.name
|
||||
));
|
||||
let current_exe = std::env::current_exe()?;
|
||||
let dest = to.map(|p| p.to_path_buf()).unwrap_or_else(|| current_exe.clone());
|
||||
let tmpdir = tempfile::tempdir()?;
|
||||
let tmp = tmpdir.path().join("am.new");
|
||||
download::download(&picked.url, &tmp, None, true)?;
|
||||
if dest == current_exe && cfg!(windows) {
|
||||
// The running executable is locked on Windows.
|
||||
let new_path = current_exe.with_extension("exe.new");
|
||||
std::fs::copy(&tmp, &new_path)
|
||||
.with_context(|| format!("cannot write {}", new_path.display()))?;
|
||||
app.log.success(&format!(
|
||||
"downloaded {tag} to {} — replace the running binary manually",
|
||||
new_path.display()
|
||||
));
|
||||
} else {
|
||||
std::fs::copy(&tmp, &dest)
|
||||
.with_context(|| format!("cannot write {}", dest.display()))?;
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let _ = std::fs::set_permissions(
|
||||
&dest,
|
||||
std::fs::Permissions::from_mode(0o755),
|
||||
);
|
||||
}
|
||||
app.log
|
||||
.success(&format!("updated agent-manager to {tag} ({})", dest.display()));
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user