Skip to content

Commit ef3de24

Browse files
Replace auto-update with notify + manual update command
- Remove silent auto-update mechanism, replace with update check that notifies users when a new version is available - Add `deepsource update` subcommand for explicit manual updates - Remove AutoUpdate config option since updates are now user-initiated - Rename ShouldAutoUpdate to ShouldCheckForUpdate to reflect new behavior
1 parent d444ee5 commit ef3de24

File tree

6 files changed

+82
-37
lines changed

6 files changed

+82
-37
lines changed

cmd/deepsource/main.go

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -71,28 +71,19 @@ func mainRun() (exitCode int) {
7171
func run() int {
7272
v.SetBuildInfo(version, Date, buildMode)
7373

74-
// Two-phase auto-update: apply pending update or check for new one
75-
if update.ShouldAutoUpdate() {
74+
// Check for available updates and notify
75+
if update.ShouldCheckForUpdate() {
76+
client := &http.Client{Timeout: 3 * time.Second}
77+
if err := update.CheckForUpdate(client); err != nil {
78+
debug.Log("update: %v", err)
79+
}
80+
7681
state, err := update.ReadUpdateState()
7782
if err != nil {
7883
debug.Log("update: %v", err)
7984
}
80-
8185
if state != nil {
82-
// Phase 2: a previous run found a newer version — apply it now
83-
client := &http.Client{Timeout: 30 * time.Second}
84-
newVer, err := update.ApplyUpdate(client)
85-
if err != nil {
86-
debug.Log("update: %v", err)
87-
} else if newVer != "" {
88-
fmt.Fprintf(os.Stderr, "%s\n", style.Yellow("Updated DeepSource CLI to v%s", newVer))
89-
}
90-
} else {
91-
// Phase 1: check manifest and write state file for next run
92-
client := &http.Client{Timeout: 3 * time.Second}
93-
if err := update.CheckForUpdate(client); err != nil {
94-
debug.Log("update: %v", err)
95-
}
86+
fmt.Fprintf(os.Stderr, "Update available: v%s — run 'deepsource update' to install.\n", state.Version)
9687
}
9788
}
9889

command/root.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/deepsourcelabs/cli/buildinfo"
99
"github.com/deepsourcelabs/cli/command/auth"
1010
completionCmd "github.com/deepsourcelabs/cli/command/completion"
11+
updateCmd "github.com/deepsourcelabs/cli/command/update"
1112
"github.com/deepsourcelabs/cli/command/issues"
1213
"github.com/deepsourcelabs/cli/command/metrics"
1314
"github.com/deepsourcelabs/cli/command/report"
@@ -89,6 +90,10 @@ func NewCmdRoot() *cobra.Command {
8990
completionC.GroupID = "setup"
9091
cmd.AddCommand(completionC)
9192

93+
updateC := updateCmd.NewCmdUpdate()
94+
updateC.GroupID = "setup"
95+
cmd.AddCommand(updateC)
96+
9297
cmd.PersistentFlags().Bool("skip-tls-verify", false, "Skip TLS certificate verification (for self-signed certs)")
9398

9499
cmd.InitDefaultHelpFlag()

command/update/update.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package update
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"os"
7+
"time"
8+
9+
"github.com/deepsourcelabs/cli/buildinfo"
10+
"github.com/deepsourcelabs/cli/internal/cli/style"
11+
"github.com/deepsourcelabs/cli/internal/update"
12+
"github.com/spf13/cobra"
13+
)
14+
15+
func NewCmdUpdate() *cobra.Command {
16+
return &cobra.Command{
17+
Use: "update",
18+
Short: "Update DeepSource CLI to the latest version",
19+
RunE: func(cmd *cobra.Command, _ []string) error {
20+
return runUpdate(cmd)
21+
},
22+
}
23+
}
24+
25+
func runUpdate(cmd *cobra.Command) error {
26+
w := cmd.ErrOrStderr()
27+
28+
// Check for the latest version
29+
checkClient := &http.Client{Timeout: 10 * time.Second}
30+
if err := update.CheckForUpdate(checkClient); err != nil {
31+
return fmt.Errorf("checking for updates: %w", err)
32+
}
33+
34+
state, err := update.ReadUpdateState()
35+
if err != nil {
36+
return fmt.Errorf("reading update state: %w", err)
37+
}
38+
39+
if state == nil {
40+
bi := buildinfo.GetBuildInfo()
41+
style.Successf(w, "Already up to date (v%s)", bi.Version)
42+
return nil
43+
}
44+
45+
fmt.Fprintf(w, "Updating to v%s...\n", state.Version)
46+
47+
applyClient := &http.Client{Timeout: 30 * time.Second}
48+
newVer, err := update.ApplyUpdate(applyClient)
49+
if err != nil {
50+
return fmt.Errorf("applying update: %w", err)
51+
}
52+
53+
if newVer != "" {
54+
style.Successf(os.Stderr, "Updated DeepSource CLI to v%s", newVer)
55+
}
56+
57+
return nil
58+
}

config/config.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ type CLIConfig struct {
1616
User string `toml:"user"`
1717
Token string `toml:"token"`
1818
TokenExpiresIn time.Time `toml:"token_expires_in,omitempty"`
19-
AutoUpdate *bool `toml:"auto_update,omitempty"`
20-
SkipTLSVerify bool `toml:"skip_tls_verify,omitempty"`
19+
SkipTLSVerify bool `toml:"skip_tls_verify,omitempty"`
2120
TokenFromEnv bool `toml:"-"`
2221
}
2322

internal/update/updater.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"time"
2020

2121
"github.com/deepsourcelabs/cli/buildinfo"
22-
"github.com/deepsourcelabs/cli/config"
2322
"github.com/deepsourcelabs/cli/internal/debug"
2423
)
2524

@@ -179,8 +178,8 @@ func ApplyUpdate(client *http.Client) (string, error) {
179178
return state.Version, nil
180179
}
181180

182-
// ShouldAutoUpdate reports whether the auto-updater should run.
183-
func ShouldAutoUpdate() bool {
181+
// ShouldCheckForUpdate reports whether the update check should run.
182+
func ShouldCheckForUpdate() bool {
184183
bi := buildinfo.GetBuildInfo()
185184
if bi == nil {
186185
return false
@@ -204,13 +203,6 @@ func ShouldAutoUpdate() bool {
204203
}
205204
}
206205

207-
// Check config
208-
cfg, err := config.GetConfig()
209-
if err == nil && cfg.AutoUpdate != nil && !*cfg.AutoUpdate {
210-
debug.Log("update: skipping (disabled in config)")
211-
return false
212-
}
213-
214206
return true
215207
}
216208

internal/update/updater_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func TestReplaceBinary(t *testing.T) {
100100
}
101101
}
102102

103-
func TestShouldAutoUpdate_DevBuild(t *testing.T) {
103+
func TestShouldCheckForUpdate_DevBuild(t *testing.T) {
104104
buildinfo.SetBuildInfo("2.0.3", "", "dev")
105105

106106
// Clear CI vars so they don't interfere
@@ -109,27 +109,27 @@ func TestShouldAutoUpdate_DevBuild(t *testing.T) {
109109
t.Setenv(v, "")
110110
}
111111

112-
if !ShouldAutoUpdate() {
112+
if !ShouldCheckForUpdate() {
113113
t.Error("expected true for dev build with real version")
114114
}
115115
}
116116

117-
func TestShouldAutoUpdate_DevelopmentVersion(t *testing.T) {
117+
func TestShouldCheckForUpdate_DevelopmentVersion(t *testing.T) {
118118
buildinfo.SetBuildInfo("development", "", "")
119-
if ShouldAutoUpdate() {
119+
if ShouldCheckForUpdate() {
120120
t.Error("expected false for development version")
121121
}
122122
}
123123

124-
func TestShouldAutoUpdate_CI(t *testing.T) {
124+
func TestShouldCheckForUpdate_CI(t *testing.T) {
125125
buildinfo.SetBuildInfo("2.0.3", "", "prod")
126126
t.Setenv("CI", "true")
127-
if ShouldAutoUpdate() {
127+
if ShouldCheckForUpdate() {
128128
t.Error("expected false in CI")
129129
}
130130
}
131131

132-
func TestShouldAutoUpdate_Prod(t *testing.T) {
132+
func TestShouldCheckForUpdate_Prod(t *testing.T) {
133133
buildinfo.SetBuildInfo("2.0.3", "", "prod")
134134

135135
// Clear CI vars
@@ -138,7 +138,7 @@ func TestShouldAutoUpdate_Prod(t *testing.T) {
138138
t.Setenv(v, "")
139139
}
140140

141-
if !ShouldAutoUpdate() {
141+
if !ShouldCheckForUpdate() {
142142
t.Error("expected true for prod build outside CI")
143143
}
144144
}

0 commit comments

Comments
 (0)