mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-07 17:09:13 -10:00
fix(update): never self-update the desktop app's Engine
Add InstallMethod::DesktopApp for an Engine inside a macOS `*.app/Contents/MacOS/` bundle or the desktop app's pinned `<CODEWHALE_HOME>/gpui/engine/` store. It does not support self-update, so `codewhale update`, target validation and `uninstall` refuse to write there, and the CLI, /update and the TUI notice say to use Codewhale > Check for Updates instead of printing GitHub migration help. Verified on a Linux Boat VM against origin/main plus this series (debug build): cargo build -p codewhale-cli and cargo check --workspace --all-targets --locked clean (0 errors, 0 warnings); cargo test -p codewhale-release 57 passed; codewhale-cli update:: 109 passed. Fixture in a temp HOME: `update` from X/Codewhale.app/Contents/MacOS/codewhale prints the desktop message and exits 1, `uninstall` names the app, bundle bytes unchanged. Not exercised: a real signed desktop bundle on macOS. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
b2eb6f331c
commit
e5283cb022
4 files changed
+35
-1
No files matched your search
@@ -317,6 +317,9 @@ fn managed_install_warning(method: InstallMethod) -> Option<String> {
|
||||
if method.supports_self_update() {
|
||||
return None;
|
||||
}
|
||||
if method == InstallMethod::DesktopApp {
|
||||
return Some(codewhale_release::install::DESKTOP_APP_UPDATE_HELP.to_string());
|
||||
}
|
||||
Some(format!(
|
||||
"This executable is managed by {label}; in-place self-update is disabled.\n\n\
|
||||
{GITHUB_MIGRATION_HELP}\n\n\
|
||||
|
||||
@@ -41,6 +41,10 @@ Keep the chosen PATH directory in your shell profile after verifying it.
|
||||
Windows: https://github.com/codewhale-hq/CodeWhale/releases/latest
|
||||
PATH and migration: https://github.com/codewhale-hq/CodeWhale/blob/main/docs/INSTALL.md"#;
|
||||
|
||||
pub const DESKTOP_APP_UPDATE: &str = "Codewhale > Check for Updates";
|
||||
|
||||
pub const DESKTOP_APP_UPDATE_HELP: &str = "The Codewhale app updates this copy together with the app. Use Codewhale > Check for Updates. `codewhale update` never writes inside the app.";
|
||||
|
||||
/// The package manager (if any) that owns the running executable.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum InstallMethod {
|
||||
@@ -56,6 +60,7 @@ pub enum InstallMethod {
|
||||
Scoop,
|
||||
/// A WinGet portable package under `Microsoft/WinGet/Packages`.
|
||||
WinGet,
|
||||
DesktopApp,
|
||||
/// A release binary the user placed on disk themselves. The default, and
|
||||
/// the only case where in-place self-update is correct.
|
||||
Binary,
|
||||
@@ -130,6 +135,16 @@ impl InstallMethod {
|
||||
|
||||
let has = |name: &str| components.iter().any(|c| c == name);
|
||||
|
||||
if components
|
||||
.windows(3)
|
||||
.any(|parts| parts[0].ends_with(".app") && parts[1] == "contents" && parts[2] == "macos")
|
||||
|| components
|
||||
.windows(2)
|
||||
.any(|pair| pair[0] == "gpui" && pair[1] == "engine")
|
||||
{
|
||||
return Self::DesktopApp;
|
||||
}
|
||||
|
||||
// npm is checked first: a `node_modules` install *inside* a Homebrew
|
||||
// or Termux prefix is still npm's to update.
|
||||
if has("node_modules") {
|
||||
@@ -168,6 +183,7 @@ impl InstallMethod {
|
||||
"omarchy" => Some(Self::Omarchy),
|
||||
"scoop" => Some(Self::Scoop),
|
||||
"winget" => Some(Self::WinGet),
|
||||
"desktop" | "app" => Some(Self::DesktopApp),
|
||||
"binary" | "release" => Some(Self::Binary),
|
||||
_ => None,
|
||||
}
|
||||
@@ -188,6 +204,7 @@ impl InstallMethod {
|
||||
Self::Omarchy => "omarchy update",
|
||||
Self::Scoop => "scoop update codewhale",
|
||||
Self::WinGet => "winget upgrade --id HunterBown.CodeWhale",
|
||||
Self::DesktopApp => DESKTOP_APP_UPDATE,
|
||||
Self::Binary => "codewhale update",
|
||||
}
|
||||
}
|
||||
@@ -205,6 +222,7 @@ impl InstallMethod {
|
||||
}
|
||||
Self::Scoop => "scoop uninstall codewhale",
|
||||
Self::WinGet => "winget uninstall --id HunterBown.CodeWhale",
|
||||
Self::DesktopApp => "remove the Codewhale app; this Engine is part of it",
|
||||
Self::Binary => "codewhale uninstall --yes",
|
||||
}
|
||||
}
|
||||
@@ -228,6 +246,7 @@ impl InstallMethod {
|
||||
Self::Omarchy => "Omarchy",
|
||||
Self::Scoop => "Scoop",
|
||||
Self::WinGet => "WinGet",
|
||||
Self::DesktopApp => "the Codewhale app",
|
||||
Self::Binary => "release binary",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +129,9 @@ pub(super) fn resolve_updater(
|
||||
|
||||
/// Instructions for an install this command must not update in place.
|
||||
pub(super) fn managed_install_message(method: InstallMethod) -> String {
|
||||
if method == InstallMethod::DesktopApp {
|
||||
return codewhale_release::install::DESKTOP_APP_UPDATE_HELP.to_string();
|
||||
}
|
||||
format!(
|
||||
"Codewhale was installed with {label}, which owns this binary.\n\
|
||||
{migration_help}\n\n\
|
||||
|
||||
@@ -1414,6 +1414,13 @@ impl UpdateNotice {
|
||||
/// Short line for the transient status toast, naming the command that
|
||||
/// actually updates *this* install.
|
||||
fn toast_line(&self, install: InstallMethod) -> String {
|
||||
if install == InstallMethod::DesktopApp {
|
||||
return format!(
|
||||
"v{latest} available - use {command}",
|
||||
latest = self.latest,
|
||||
command = install.update_command()
|
||||
);
|
||||
}
|
||||
format!(
|
||||
"v{latest} available - run `{command}` and restart",
|
||||
latest = self.latest,
|
||||
@@ -1437,7 +1444,9 @@ impl UpdateNotice {
|
||||
/// Homebrew or npm owns leaves the manager's metadata lying about what is
|
||||
/// on disk, and the next upgrade silently reverts the user.
|
||||
fn notice_block(&self, install: InstallMethod) -> String {
|
||||
let action = if install.supports_self_update() {
|
||||
let action = if install == InstallMethod::DesktopApp {
|
||||
codewhale_release::install::DESKTOP_APP_UPDATE_HELP.to_string()
|
||||
} else if install.supports_self_update() {
|
||||
"Run `/update install` here (preview it with a bare `/update`), or `codewhale update` in a shell, then restart Codewhale."
|
||||
.to_string()
|
||||
} else {
|
||||
|
||||
Reference in new issue
Block a user