Skip to content

Commit e1850ea

Browse files
committed
fix: check latest version before update
1 parent 0223f7f commit e1850ea

2 files changed

Lines changed: 93 additions & 16 deletions

File tree

internal/commands/cobra.go

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func newRootCmd(version string) *cobra.Command {
5555

5656
root.AddCommand(newAuthCmd())
5757
root.AddCommand(newRepoCmd())
58-
root.AddCommand(newUpdateCmd())
58+
root.AddCommand(newUpdateCmd(version))
5959

6060
root.SetFlagErrorFunc(func(_ *cobra.Command, err error) error {
6161
return usageError(err.Error())
@@ -224,25 +224,13 @@ func newRepoCmd() *cobra.Command {
224224
return repoCmd
225225
}
226226

227-
func newUpdateCmd() *cobra.Command {
227+
func newUpdateCmd(version string) *cobra.Command {
228228
return &cobra.Command{
229229
Use: "update",
230230
Short: "Update to the latest release",
231231
Args: cobra.NoArgs,
232232
RunE: func(cmd *cobra.Command, _ []string) error {
233-
fmt.Print("Proceed with update? [Y/n] ")
234-
var answer string
235-
if _, err := fmt.Scanln(&answer); err != nil {
236-
return nil
237-
}
238-
answer = strings.TrimSpace(strings.ToLower(answer))
239-
if answer != "" && answer != "y" && answer != "yes" {
240-
fmt.Println("To update manually, run:")
241-
fmt.Println(" curl -fsSL https://raw.githubusercontent.com/rishabyd/codeberg-cli/main/install.sh | bash")
242-
return nil
243-
}
244-
245-
return runUpdate()
233+
return checkAndUpdate(version)
246234
},
247235
}
248236
}

internal/commands/update.go

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,100 @@
11
package commands
22

33
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
47
"os"
58
"os/exec"
9+
"strconv"
10+
"strings"
611
)
712

8-
func runUpdate() error {
13+
const latestReleaseURL = "https://api.github.com/repos/rishabyd/codeberg-cli/releases/latest"
14+
15+
type ghRelease struct {
16+
TagName string `json:"tag_name"`
17+
}
18+
19+
func checkAndUpdate(currentVersion string) error {
20+
latest, err := fetchLatestTag()
21+
if err != nil {
22+
fmt.Println("Could not check for updates. Proceeding...")
23+
} else if !isNewer(latest, currentVersion) {
24+
fmt.Printf("Already up to date (v%s)\n", currentVersion)
25+
return nil
26+
} else {
27+
fmt.Printf("A new version is available: %s (current: v%s)\n", latest, currentVersion)
28+
}
29+
30+
fmt.Print("Proceed with update? [Y/n] ")
31+
var answer string
32+
if _, err := fmt.Scanln(&answer); err != nil {
33+
return nil
34+
}
35+
answer = strings.TrimSpace(strings.ToLower(answer))
36+
if answer != "" && answer != "y" && answer != "yes" {
37+
fmt.Println("To update manually, run:")
38+
fmt.Println(" curl -fsSL https://raw.githubusercontent.com/rishabyd/codeberg-cli/main/install.sh | bash")
39+
return nil
40+
}
41+
42+
return execUpdate()
43+
}
44+
45+
func fetchLatestTag() (string, error) {
46+
resp, err := http.Get(latestReleaseURL)
47+
if err != nil {
48+
return "", err
49+
}
50+
defer resp.Body.Close()
51+
52+
if resp.StatusCode != http.StatusOK {
53+
return "", fmt.Errorf("HTTP %d", resp.StatusCode)
54+
}
55+
56+
var release ghRelease
57+
if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
58+
return "", err
59+
}
60+
return release.TagName, nil
61+
}
62+
63+
func isNewer(latest, current string) bool {
64+
l := parseVersion(latest)
65+
c := parseVersion(current)
66+
if l == nil || c == nil {
67+
return true
68+
}
69+
for i := 0; i < 3; i++ {
70+
if l[i] > c[i] {
71+
return true
72+
}
73+
if l[i] < c[i] {
74+
return false
75+
}
76+
}
77+
return false
78+
}
79+
80+
func parseVersion(v string) []int {
81+
v = strings.TrimPrefix(v, "v")
82+
parts := strings.Split(v, ".")
83+
if len(parts) < 3 {
84+
return nil
85+
}
86+
nums := make([]int, 3)
87+
for i := 0; i < 3; i++ {
88+
n, err := strconv.Atoi(parts[i])
89+
if err != nil {
90+
return nil
91+
}
92+
nums[i] = n
93+
}
94+
return nums
95+
}
96+
97+
func execUpdate() error {
998
cmd := exec.Command("bash", "-c",
1099
"curl -fsSL https://raw.githubusercontent.com/rishabyd/codeberg-cli/main/install.sh | bash")
11100
cmd.Stdin = os.Stdin

0 commit comments

Comments
 (0)