diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-23 17:34:01 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-23 17:42:49 +0300 |
| commit | ec2924d0d1f21417802c3efd0ed46b9db2c00582 (patch) | |
| tree | 00432d4dbb46bb82328dfb583e36293c1603bc81 /src/update.rs | |
| parent | 0d2c20a46235ae2535d4fdef59b9529e44faa98f (diff) | |
feat: add optional nix flake support
refs #208
refs #221
refs #264
Diffstat (limited to 'src/update.rs')
| -rw-r--r-- | src/update.rs | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/src/update.rs b/src/update.rs index f37a9265..2a2776fa 100644 --- a/src/update.rs +++ b/src/update.rs @@ -21,6 +21,7 @@ const UPDATE_MANIFEST_URL: &str = "https://herdr.dev/latest.json"; const HOMEBREW_FORMULA_API_URL: &str = "https://formulae.brew.sh/api/formula/herdr.json"; const HERDR_UPDATE_COMMAND: &str = "herdr update"; const HOMEBREW_UPDATE_COMMAND: &str = "brew update && brew upgrade herdr"; +const NIX_UPDATE_COMMAND: &str = "update through Nix"; const CURRENT_VERSION: &str = env!("CARGO_PKG_VERSION"); const FAKE_UPDATE_VERSION_ENV: &str = "HERDR_FAKE_UPDATE_VERSION"; const FAKE_UPDATE_NOTES_VERSION_ENV: &str = "HERDR_FAKE_UPDATE_NOTES_VERSION"; @@ -678,6 +679,8 @@ fn wait_for_server_shutdown(timeout: Duration) -> Result<(), String> { pub(crate) fn update_install_command() -> &'static str { if is_homebrew_managed_install() { HOMEBREW_UPDATE_COMMAND + } else if is_nix_managed_install() { + NIX_UPDATE_COMMAND } else { HERDR_UPDATE_COMMAND } @@ -697,6 +700,24 @@ fn is_homebrew_managed_install() -> bool { .is_ok_and(|path| is_homebrew_managed_exe_path(&path)) } +fn is_nix_managed_install() -> bool { + let Ok(current_exe) = env::current_exe() else { + return false; + }; + + if is_nix_store_exe_path(¤t_exe) { + return true; + } + + current_exe + .canonicalize() + .is_ok_and(|path| is_nix_store_exe_path(&path)) +} + +fn is_nix_store_exe_path(path: &Path) -> bool { + path.starts_with("/nix/store") +} + fn is_homebrew_managed_exe_path(path: &Path) -> bool { homebrew_cellar_keg_root(path).is_some() } @@ -991,6 +1012,12 @@ pub fn self_update() -> Result<Version, String> { )); } + if is_nix_managed_install() { + return Err( + "self-update is disabled for Nix installs; update with `nix profile upgrade` or update the flake input that provides Herdr".into(), + ); + } + if running_inside_herdr() { return Err("run `herdr update` outside herdr after detaching from the session".into()); } @@ -1075,6 +1102,8 @@ pub fn auto_update(events: tokio::sync::mpsc::Sender<crate::events::AppEvent>) { return; } + let nix_managed_install = is_nix_managed_install(); + let release = match check_latest() { Ok(Some(r)) => r, Ok(None) => return, @@ -1103,9 +1132,15 @@ pub fn auto_update(events: tokio::sync::mpsc::Sender<crate::events::AppEvent>) { ); // Notify the TUI — blocking_send is safe from a std::thread + let install_command = if nix_managed_install { + NIX_UPDATE_COMMAND + } else { + HERDR_UPDATE_COMMAND + }; + let _ = events.blocking_send(crate::events::AppEvent::UpdateReady { version: release.version.to_string(), - install_command: HERDR_UPDATE_COMMAND.to_string(), + install_command: install_command.to_string(), }); } @@ -1288,6 +1323,20 @@ mod tests { } #[test] + fn nix_store_path_is_detected() { + let path = Path::new("/nix/store/abc123-herdr-0.6.1/bin/herdr"); + + assert!(is_nix_store_exe_path(path)); + } + + #[test] + fn non_nix_store_path_is_not_detected() { + let path = Path::new("/usr/local/bin/herdr"); + + assert!(!is_nix_store_exe_path(path)); + } + + #[test] fn parse_homebrew_formula_stable_version_reads_versions_stable() { let version = parse_homebrew_formula_stable_version( br#"{"versions":{"stable":"0.5.10","head":"HEAD","bottle":true}}"#, |
