forked from voidint/g
-
Notifications
You must be signed in to change notification settings - Fork 0
/
self_update.go
95 lines (84 loc) · 2.26 KB
/
self_update.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package cli
import (
"bufio"
"fmt"
"net/http"
"runtime"
"strings"
"github.com/Masterminds/semver/v3"
"github.com/urfave/cli/v2"
"github.com/voidint/g/build"
"github.com/voidint/g/pkg/checksum"
"github.com/voidint/g/pkg/errs"
httppkg "github.com/voidint/g/pkg/http"
"github.com/voidint/g/pkg/sdk/github"
)
func selfUpdate(*cli.Context) (err error) {
up := github.NewReleaseUpdater()
// 检查更新
latest, yes, err := up.CheckForUpdates(semver.MustParse(build.ShortVersion), "voidint", "g")
if err != nil {
return cli.Exit(errstring(err), 1)
}
if !yes {
fmt.Printf("You are up to date! g v%s is the latest version.\n", build.ShortVersion)
return nil
}
fmt.Printf("A new version of g(%s) is available\n", latest.TagName)
// 应用更新
if err = up.Apply(latest, findAsset, findChecksum); err != nil {
return cli.Exit(errstring(err), 1)
}
fmt.Println("Update completed")
return nil
}
func findAsset(items []github.Asset) (idx int) {
ext := "tar.gz"
if runtime.GOOS == "windows" {
ext = "zip"
}
suffix := fmt.Sprintf("%s-%s.%s", runtime.GOOS, runtime.GOARCH, ext)
for i := range items {
if strings.HasSuffix(items[i].BrowserDownloadURL, suffix) {
return i
}
}
return -1
}
func findChecksum(items []github.Asset) (algo checksum.Algorithm, expectedChecksum string, err error) {
ext := "tar.gz"
if runtime.GOOS == "windows" {
ext = "zip"
}
suffix := fmt.Sprintf("%s-%s.%s", runtime.GOOS, runtime.GOARCH, ext)
var checksumFileURL string
for i := range items {
if items[i].Name == "sha256sum.txt" {
checksumFileURL = items[i].BrowserDownloadURL
break
}
}
if checksumFileURL == "" {
return checksum.SHA256, "", errs.ErrChecksumFileNotFound
}
resp, err := http.Get(checksumFileURL)
if err != nil {
return checksum.SHA256, "", err
}
defer resp.Body.Close()
if !httppkg.IsSuccess(resp.StatusCode) {
return "", "", errs.NewURLUnreachableError(checksumFileURL, fmt.Errorf("%d", resp.StatusCode))
}
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
line := scanner.Text()
if !strings.HasSuffix(line, suffix) {
continue
}
return checksum.SHA256, strings.Fields(line)[0], nil
}
if err = scanner.Err(); err != nil {
return checksum.SHA256, "", err
}
return checksum.SHA256, "", errs.ErrChecksumFileNotFound
}