Skip to content

Commit 96c2fb2

Browse files
authored
Merge pull request #340 from lets-cli/codex/implement-issue-338
Prevent self upgrade on Homebrew installs
2 parents fbc52f3 + d0b9709 commit 96c2fb2

3 files changed

Lines changed: 47 additions & 0 deletions

File tree

docs/docs/changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ title: Changelog
55

66
## [Unreleased](https://github.com/lets-cli/lets/releases/tag/v0.0.X)
77

8+
* `[Fixed]` Prevent `lets self upgrade` from overwriting Homebrew-managed installs. Issue [#338](https://github.com/lets-cli/lets/issues/338)
9+
810
## [0.0.60](https://github.com/lets-cli/lets/releases/tag/v0.0.60)
911

1012
* `[Dependency]` update go to `1.26`

internal/upgrade/upgrade.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ func NewBinaryUpgrader(reg registry.RepoRegistry, currentVersion string) (*Binar
4141
}
4242

4343
func (up *BinaryUpgrader) Upgrade(ctx context.Context) error {
44+
if isHomebrewInstall(up.binaryPath) {
45+
return fmt.Errorf("homebrew-managed lets install must be upgraded with %q", "brew upgrade lets-cli/tap/lets")
46+
}
47+
4448
latestVersion, err := up.registry.GetLatestRelease(ctx)
4549
if err != nil {
4650
return fmt.Errorf("failed to get latest release version: %w", err)

internal/upgrade/upgrade_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"os"
77
"path"
8+
"strings"
89
"testing"
910
"time"
1011

@@ -144,4 +145,44 @@ func TestSelfUpgrade(t *testing.T) {
144145
t.Errorf("binary must not been updated")
145146
}
146147
})
148+
149+
t.Run("should not self-upgrade homebrew-managed binary", func(t *testing.T) {
150+
currentVersion := "v0.0.1"
151+
latestVersion := "v0.0.2"
152+
153+
tempDir := t.TempDir()
154+
binaryPath := path.Join(tempDir, "Cellar", "lets", currentVersion, "bin", "lets")
155+
if err := os.MkdirAll(path.Dir(binaryPath), 0o755); err != nil {
156+
t.Fatalf("failed to create homebrew binary dir: %s", err)
157+
}
158+
159+
if err := os.WriteFile(binaryPath, []byte(currentVersion), 0o755); err != nil {
160+
t.Fatalf("failed to write homebrew binary: %s", err)
161+
}
162+
163+
upgrader := &BinaryUpgrader{
164+
registry: &MockRegistry{latestVersion: latestVersion},
165+
currentVersion: currentVersion,
166+
binaryPath: binaryPath,
167+
downloadPath: path.Join(tempDir, "lets.download"),
168+
backupPath: path.Join(tempDir, "lets.backup"),
169+
}
170+
171+
err := upgrader.Upgrade(context.Background())
172+
if err == nil {
173+
t.Fatal("expected homebrew upgrade error")
174+
}
175+
176+
if !strings.Contains(err.Error(), "brew upgrade lets-cli/tap/lets") {
177+
t.Fatalf("expected homebrew upgrade command in error, got %q", err.Error())
178+
}
179+
180+
if !testVersion(binaryPath, currentVersion) {
181+
t.Errorf("expected version %s", currentVersion)
182+
}
183+
184+
if _, err := os.Stat(upgrader.downloadPath); !os.IsNotExist(err) {
185+
t.Fatalf("expected no downloaded binary, got err %v", err)
186+
}
187+
})
147188
}

0 commit comments

Comments
 (0)