From 1278f43b5de25e177d089f9a1dc0b67592c2fc16 Mon Sep 17 00:00:00 2001 From: Matt Van Horn Date: Sat, 7 Mar 2026 16:22:14 -0800 Subject: [PATCH 1/2] fix(versioncheck): detect mise install for update command When the binary is installed via mise, show `mise upgrade entire` instead of the curl command. Detection is path-based (checking for /mise/ in the resolved binary path), consistent with the existing Homebrew detection. Closes #432 Co-Authored-By: Claude Opus 4.6 --- cmd/entire/cli/versioncheck/versioncheck.go | 4 ++++ cmd/entire/cli/versioncheck/versioncheck_test.go | 1 + 2 files changed, 5 insertions(+) diff --git a/cmd/entire/cli/versioncheck/versioncheck.go b/cmd/entire/cli/versioncheck/versioncheck.go index 2b6469f4c..be971d42e 100644 --- a/cmd/entire/cli/versioncheck/versioncheck.go +++ b/cmd/entire/cli/versioncheck/versioncheck.go @@ -260,6 +260,10 @@ func updateCommand() string { return "brew upgrade entire" } + if strings.Contains(realPath, "/mise/") { + return "mise upgrade entire" + } + return "curl -fsSL https://entire.io/install.sh | bash" } diff --git a/cmd/entire/cli/versioncheck/versioncheck_test.go b/cmd/entire/cli/versioncheck/versioncheck_test.go index 4dcc87a18..5a1378fe3 100644 --- a/cmd/entire/cli/versioncheck/versioncheck_test.go +++ b/cmd/entire/cli/versioncheck/versioncheck_test.go @@ -238,6 +238,7 @@ func TestUpdateCommand(t *testing.T) { validCommands := map[string]bool{ "brew upgrade entire": true, + "mise upgrade entire": true, "curl -fsSL https://entire.io/install.sh | bash": true, } From 5233863ff39fd743cbf18da2327dca59ecf8fdec Mon Sep 17 00:00:00 2001 From: Stefan Haubold Date: Tue, 10 Mar 2026 11:55:03 +0000 Subject: [PATCH 2/2] improve tests to not dependend on local setup Entire-Checkpoint: 46875b53634f --- cmd/entire/cli/versioncheck/versioncheck.go | 10 ++- .../cli/versioncheck/versioncheck_test.go | 65 ++++++++++++++++--- 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/cmd/entire/cli/versioncheck/versioncheck.go b/cmd/entire/cli/versioncheck/versioncheck.go index be971d42e..a70549934 100644 --- a/cmd/entire/cli/versioncheck/versioncheck.go +++ b/cmd/entire/cli/versioncheck/versioncheck.go @@ -243,9 +243,13 @@ func isOutdated(current, latest string) bool { return semver.Compare(current, latest) < 0 } +// executablePath is the function used to get the current executable path. +// It's a variable so tests can override it. +var executablePath = os.Executable + // updateCommand returns the appropriate update instruction based on how the binary was installed. func updateCommand() string { - execPath, err := os.Executable() + execPath, err := executablePath() if err != nil { return "curl -fsSL https://entire.io/install.sh | bash" } @@ -256,11 +260,11 @@ func updateCommand() string { realPath = execPath } - if strings.Contains(realPath, "/Cellar/") || strings.Contains(realPath, "/homebrew/") { + if strings.Contains(realPath, "/Cellar/") || strings.Contains(realPath, "/opt/homebrew/") || strings.Contains(realPath, "/linuxbrew/") { return "brew upgrade entire" } - if strings.Contains(realPath, "/mise/") { + if strings.Contains(realPath, "/mise/installs/") { return "mise upgrade entire" } diff --git a/cmd/entire/cli/versioncheck/versioncheck_test.go b/cmd/entire/cli/versioncheck/versioncheck_test.go index 5a1378fe3..7fa861365 100644 --- a/cmd/entire/cli/versioncheck/versioncheck_test.go +++ b/cmd/entire/cli/versioncheck/versioncheck_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "encoding/json" + "fmt" "net/http" "net/http/httptest" "os" @@ -233,17 +234,63 @@ func TestParseGitHubRelease(t *testing.T) { } func TestUpdateCommand(t *testing.T) { - // updateCommand should return one of the two valid update commands - cmd := updateCommand() - - validCommands := map[string]bool{ - "brew upgrade entire": true, - "mise upgrade entire": true, - "curl -fsSL https://entire.io/install.sh | bash": true, + tests := []struct { + name string + execPath func() (string, error) + want string + }{ + { + name: "homebrew cellar path", + execPath: func() (string, error) { return "/opt/homebrew/Cellar/entire/1.0.0/bin/entire", nil }, + want: "brew upgrade entire", + }, + { + name: "homebrew opt path", + execPath: func() (string, error) { return "/opt/homebrew/bin/entire", nil }, + want: "brew upgrade entire", + }, + { + name: "linuxbrew path", + execPath: func() (string, error) { return "/home/linuxbrew/.linuxbrew/bin/entire", nil }, + want: "brew upgrade entire", + }, + { + name: "mise path", + execPath: func() (string, error) { return "/home/user/.local/share/mise/installs/entire/1.0.0/bin/entire", nil }, + want: "mise upgrade entire", + }, + { + name: "username mise not detected as mise install", + execPath: func() (string, error) { return "/home/mise/bin/entire", nil }, + want: "curl -fsSL https://entire.io/install.sh | bash", + }, + { + name: "username homebrew not detected as brew install", + execPath: func() (string, error) { return "/home/homebrew/bin/entire", nil }, + want: "curl -fsSL https://entire.io/install.sh | bash", + }, + { + name: "unknown path falls back to curl", + execPath: func() (string, error) { return "/usr/local/bin/entire", nil }, + want: "curl -fsSL https://entire.io/install.sh | bash", + }, + { + name: "executable error falls back to curl", + execPath: func() (string, error) { return "", fmt.Errorf("not found") }, + want: "curl -fsSL https://entire.io/install.sh | bash", + }, } - if !validCommands[cmd] { - t.Errorf("updateCommand() = %q, want one of %v", cmd, validCommands) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + original := executablePath + executablePath = tt.execPath + t.Cleanup(func() { executablePath = original }) + + if got := updateCommand(); got != tt.want { + t.Errorf("updateCommand() = %q, want %q", got, tt.want) + } + }) } }