From efcc0d80d016ec9ff2927530b06f4eaa9bce6ef9 Mon Sep 17 00:00:00 2001 From: Lukas Jost Date: Wed, 6 May 2026 13:15:24 +0200 Subject: [PATCH] fix: detect homebrew cask installs --- internal/version/install_method.go | 11 +++++- internal/version/install_method_test.go | 46 ++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/internal/version/install_method.go b/internal/version/install_method.go index e0e57ab..dc97632 100644 --- a/internal/version/install_method.go +++ b/internal/version/install_method.go @@ -21,13 +21,22 @@ type InstallInfo struct { } const rawInstallCommand = "curl -sSL https://github.com/groundsgg/grounds-cli/releases/latest/download/install.sh | bash" +const homebrewFormulaUpdateCommand = "brew upgrade groundsgg/tap/grounds" +const homebrewCaskUpdateCommand = "brew upgrade --cask groundsgg/tap/grounds" func DetectInstallMethod(executablePath, homeDir string) InstallInfo { normalized := normalizePath(executablePath) + if resolved, err := filepath.EvalSymlinks(executablePath); err == nil { + normalized = normalizePath(resolved) + } home := normalizePath(homeDir) if strings.Contains(normalized, "/homebrew/cellar/") || strings.Contains(normalized, "/cellar/grounds/") { - return InstallInfo{Method: InstallHomebrew, UpdateCommand: "brew upgrade groundsgg/tap/grounds"} + return InstallInfo{Method: InstallHomebrew, UpdateCommand: homebrewFormulaUpdateCommand} + } + + if strings.Contains(normalized, "/caskroom/grounds/") { + return InstallInfo{Method: InstallHomebrew, UpdateCommand: homebrewCaskUpdateCommand} } if strings.Contains(normalized, "/scoop/apps/grounds/") { diff --git a/internal/version/install_method_test.go b/internal/version/install_method_test.go index 16306a2..5174ff9 100644 --- a/internal/version/install_method_test.go +++ b/internal/version/install_method_test.go @@ -1,6 +1,10 @@ package version -import "testing" +import ( + "os" + "path/filepath" + "testing" +) func TestDetectInstallMethod(t *testing.T) { tests := []struct { @@ -16,6 +20,17 @@ func TestDetectInstallMethod(t *testing.T) { wantMethod: InstallHomebrew, wantCommand: "brew upgrade groundsgg/tap/grounds", }, + { + name: "homebrew cask linux target", + path: "/home/linuxbrew/.linuxbrew/Caskroom/grounds/0.1.14/grounds", + wantMethod: InstallHomebrew, + wantCommand: "brew upgrade --cask groundsgg/tap/grounds", + }, + { + name: "homebrew prefix bin path without resolved target is unknown", + path: "/tmp/nonexistent-homebrew-prefix/bin/grounds", + wantMethod: InstallUnknown, + }, { name: "scoop", path: `C:\Users\Lukas\scoop\apps\grounds\current\grounds.exe`, @@ -67,3 +82,32 @@ func TestDetectInstallMethod(t *testing.T) { }) } } + +func TestDetectInstallMethodResolvesHomebrewCaskSymlink(t *testing.T) { + root := t.TempDir() + targetDir := filepath.Join(root, "Caskroom", "grounds", "0.1.14") + if err := os.MkdirAll(targetDir, 0o755); err != nil { + t.Fatalf("create target dir: %v", err) + } + target := filepath.Join(targetDir, "grounds") + if err := os.WriteFile(target, []byte("binary"), 0o755); err != nil { + t.Fatalf("create target: %v", err) + } + + binDir := filepath.Join(root, "bin") + if err := os.MkdirAll(binDir, 0o755); err != nil { + t.Fatalf("create bin dir: %v", err) + } + link := filepath.Join(binDir, "grounds") + if err := os.Symlink(target, link); err != nil { + t.Fatalf("create symlink: %v", err) + } + + got := DetectInstallMethod(link, "") + if got.Method != InstallHomebrew { + t.Fatalf("method = %q, want %q", got.Method, InstallHomebrew) + } + if got.UpdateCommand != homebrewCaskUpdateCommand { + t.Fatalf("update command = %q, want %q", got.UpdateCommand, homebrewCaskUpdateCommand) + } +}