This repository has been archived by the owner on Nov 9, 2017. It is now read-only.
/
selfupdate.go
120 lines (110 loc) · 2.5 KB
/
selfupdate.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package main
import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"runtime"
"strings"
"time"
"bitbucket.org/kardianos/osext"
)
// TODO: checksum downloads
var showUpdateNoticeCh = make(chan bool, 1)
func init() {
if Version == "dev" || (len(os.Args) > 1 && os.Args[1] == "selfupdate") {
showUpdateNoticeCh <- false
return
}
go func() {
shouldUpdate, err := checkForUpdate()
if err == nil && shouldUpdate {
showUpdateNoticeCh <- true
return
}
showUpdateNoticeCh <- false
}()
}
func showUpdateNotice() {
select {
case show := <-showUpdateNoticeCh:
if show {
fmt.Fprintln(os.Stderr, "\033[32mNew version is available. Run `grid selfupdate` to get it. \033[39m")
}
case <-time.After(time.Second):
}
}
var cmdSelfUpdate = &Command{
Run: runSelfUpdate,
Usage: "selfupdate",
Short: "update the grid tool",
Long: `Checks for an update and downloads a new version if available`,
}
func runSelfUpdate(cmd *Command, args []string) {
if len(args) != 0 {
cmd.printUsage()
os.Exit(2)
}
if Version != "dev" {
shouldUpdate, err := checkForUpdate()
assert(err)
if !shouldUpdate {
fmt.Println("Already up to date.")
return
}
}
updateSelf()
}
func checkForUpdate() (bool, error) {
resp, err := http.Get("https://s3.amazonaws.com/progrium-flynn/flynn-grid/dev/version")
if err != nil {
return false, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
if strings.TrimSpace(string(body)) != Version {
return true, nil
}
return false, nil
}
func updateSelf() {
fmt.Println("Downloading latest version...")
resp, err := http.Get("https://s3.amazonaws.com/progrium-flynn/flynn-grid/dev/grid-cli_" + runtime.GOOS + "_" + runtime.GOARCH + ".tgz")
assert(err)
defer resp.Body.Close()
z, err := gzip.NewReader(resp.Body)
assert(err)
defer z.Close()
t := tar.NewReader(z)
hdr, err := t.Next()
assert(err)
if hdr.Name != "grid" {
log.Fatal("grid binary not found in tarball")
}
defer t.Next()
selfpath, err := osext.Executable()
assert(err)
info, err := os.Stat(selfpath)
assert(err)
assert(os.Rename(selfpath, selfpath+".old"))
f, err := os.OpenFile(selfpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, info.Mode().Perm())
if err != nil {
assert(os.Rename(selfpath+".old", selfpath))
assert(err)
}
defer f.Close()
_, err = io.Copy(f, t)
if err != nil {
assert(os.Rename(selfpath+".old", selfpath))
assert(err)
}
assert(os.Remove(selfpath + ".old"))
fmt.Println("Updated.")
}