forked from imjerrybao/apex
/
upgrade.go
88 lines (74 loc) · 1.81 KB
/
upgrade.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
// Package upgrade fetches the latest Apex binary, if any, for the current platform.
package upgrade
import (
"errors"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"runtime"
"github.com/apex/log"
"github.com/google/go-github/github"
)
// Upgrade the current `version` of apex to the latest.
func Upgrade(version string) error {
log.Infof("current release is v%s", version)
// fetch releases
gh := github.NewClient(nil)
releases, _, err := gh.Repositories.ListReleases("apex", "apex", nil)
if err != nil {
return err
}
// see if it's new
latest := releases[0]
log.Infof("latest release is %s", *latest.TagName)
if (*latest.TagName)[1:] == version {
log.Infof("you're up to date :)")
return nil
}
asset := findAsset(&latest)
if asset == nil {
return errors.New("cannot find binary for your system")
}
// create tmp file
tmpPath := filepath.Join(os.TempDir(), "apex-upgrade")
f, err := os.OpenFile(tmpPath, os.O_CREATE|os.O_TRUNC|os.O_RDWR, 0755)
if err != nil {
return err
}
// download binary
log.Infof("downloading %s", *asset.BrowserDownloadURL)
res, err := http.Get(*asset.BrowserDownloadURL)
if err != nil {
return err
}
defer res.Body.Close()
// copy it down
_, err = io.Copy(f, res.Body)
if err != nil {
return err
}
// replace it
cmdPath, err := exec.LookPath("apex")
if err != nil {
return err
}
log.Infof("replacing %s", cmdPath)
err = os.Rename(tmpPath, cmdPath)
if err != nil {
return err
}
log.Infof("visit https://github.com/apex/apex/releases for the changelog")
return nil
}
// findAsset returns the binary for this platform.
func findAsset(release *github.RepositoryRelease) *github.ReleaseAsset {
for _, asset := range release.Assets {
if *asset.Name == fmt.Sprintf("apex_%s_%s", runtime.GOOS, runtime.GOARCH) {
return &asset
}
}
return nil
}