Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions internal/updater/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,13 @@ type UserConfig struct {
AutoUpdate AutoUpdateMode `json:"autoupdate"`
}

// LoadUserConfig returns the user's update preference from
// ~/.openboot/config.json. The default is AutoUpdateNotify: we surface a
// one-line "new version available" message but never auto-upgrade the binary
// during a normal command. Users who want silent upgrades can opt in by
// setting "autoupdate": "true"; users who want silence can set "false".
func LoadUserConfig() UserConfig {
cfg := UserConfig{AutoUpdate: AutoUpdateEnabled}
cfg := UserConfig{AutoUpdate: AutoUpdateNotify}
path, err := getUserConfigPath()
if err != nil {
return cfg
Expand All @@ -66,7 +71,7 @@ func LoadUserConfig() UserConfig {
return cfg
}
if cfg.AutoUpdate == "" {
cfg.AutoUpdate = AutoUpdateEnabled
cfg.AutoUpdate = AutoUpdateNotify
}
return cfg
}
Expand Down Expand Up @@ -98,15 +103,16 @@ func IsHomebrewInstall() bool {
return isHomebrewPath(exe)
}

// AutoUpgrade checks for a newer version and upgrades if appropriate.
// AutoUpgrade checks for a newer version and, by default, only prints a notice.
// Silent self-upgrades are opt-in via ~/.openboot/config.json.
//
// Flow:
// 1. Kill switch: OPENBOOT_DISABLE_AUTOUPDATE=1
// 2. Dev guard: currentVersion == "dev"
// 3. UserConfig (applies to ALL install methods):
// disabled → exit, notify → show message, enabled → upgrade
// disabled → exit, notify (default) → show message, enabled → upgrade
// 4. resolveLatestVersion: uses 24h cache, falls back to sync GitHub API
// 5. Upgrade method: Homebrew → brew upgrade, Direct → download binary
// 5. Upgrade method (enabled mode only): Homebrew → brew upgrade, Direct → download binary
func AutoUpgrade(currentVersion string) {
if os.Getenv("OPENBOOT_DISABLE_AUTOUPDATE") == "1" {
return
Expand Down
4 changes: 2 additions & 2 deletions internal/updater/updater_extra_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,13 @@ func TestIsNewerVersion_ExtendedCases(t *testing.T) {
}

// ---------------------------------------------------------------------------
// LoadUserConfig — AutoUpdate empty field defaults to Enabled
// LoadUserConfig — AutoUpdate empty field defaults to Notify
// ---------------------------------------------------------------------------

func TestLoadUserConfig_DefaultWhenMissing(t *testing.T) {
t.Setenv("HOME", t.TempDir())
cfg := LoadUserConfig()
assert.Equal(t, AutoUpdateEnabled, cfg.AutoUpdate)
assert.Equal(t, AutoUpdateNotify, cfg.AutoUpdate)
}

// ---------------------------------------------------------------------------
Expand Down
6 changes: 3 additions & 3 deletions internal/updater/updater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func TestGetUserConfigPath(t *testing.T) {
func TestLoadUserConfig_Default_NoFile(t *testing.T) {
t.Setenv("HOME", t.TempDir())
cfg := LoadUserConfig()
assert.Equal(t, AutoUpdateEnabled, cfg.AutoUpdate)
assert.Equal(t, AutoUpdateNotify, cfg.AutoUpdate)
}

func TestLoadUserConfig_FromFile(t *testing.T) {
Expand All @@ -236,7 +236,7 @@ func TestLoadUserConfig_InvalidJSON(t *testing.T) {
require.NoError(t, os.WriteFile(filepath.Join(cfgDir, "config.json"), []byte("{bad json"), 0644))

cfg := LoadUserConfig()
assert.Equal(t, AutoUpdateEnabled, cfg.AutoUpdate)
assert.Equal(t, AutoUpdateNotify, cfg.AutoUpdate)
}

func TestLoadUserConfig_EmptyAutoUpdate(t *testing.T) {
Expand All @@ -247,7 +247,7 @@ func TestLoadUserConfig_EmptyAutoUpdate(t *testing.T) {
require.NoError(t, os.WriteFile(filepath.Join(cfgDir, "config.json"), []byte(`{"autoupdate":""}`), 0644))

cfg := LoadUserConfig()
assert.Equal(t, AutoUpdateEnabled, cfg.AutoUpdate)
assert.Equal(t, AutoUpdateNotify, cfg.AutoUpdate)
}

func TestLoadUserConfig_DisabledMode(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions test/integration/updater_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ func TestIntegration_Updater_LoadUserConfig_Default(t *testing.T) {
// When: we load user config
cfg := updater.LoadUserConfig()

// Then: defaults to auto-update enabled
assert.Equal(t, updater.AutoUpdateEnabled, cfg.AutoUpdate)
// Then: defaults to notify-only (no silent self-upgrades).
assert.Equal(t, updater.AutoUpdateNotify, cfg.AutoUpdate)
}

func TestIntegration_Updater_LoadUserConfig_AllModes(t *testing.T) {
Expand Down
Loading