-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathcmd_selfupdate.go
72 lines (60 loc) · 1.98 KB
/
cmd_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
package notes
import (
"fmt"
"github.com/blang/semver"
"github.com/pkg/errors"
"github.com/rhysd/go-github-selfupdate/selfupdate"
"gopkg.in/alecthomas/kingpin.v2"
"io"
"os"
)
// SelfupdateCmd represents `notes selfupdate` subcommand.
type SelfupdateCmd struct {
cli *kingpin.CmdClause
// Dry is a flag equivalent to --dry
Dry bool
// Slug is a "user/repo" string where releases are put. This field is useful when you forked
// notes-cli into your own repository.
Slug string
// Out is a writer to write output of this command. Kind of stdout is expected
Out io.Writer
}
func (cmd *SelfupdateCmd) defineCLI(app *kingpin.Application) {
cmd.cli = app.Command("selfupdate", "Update myself to the latest version. It downloads the latest version executable and replaces current executable with it")
cmd.cli.Flag("dry", "Dry run update. Only check the newer version is available").Short('d').BoolVar(&cmd.Dry)
}
func (cmd *SelfupdateCmd) matchesCmdline(cmdline string) bool {
return cmd.cli.FullCommand() == cmdline
}
// Do method checks the newer version binary. If new version is available, it updates myself with
// the latest binary.
func (cmd *SelfupdateCmd) Do() error {
slug := cmd.Slug
if slug == "" {
slug = "rhysd/notes-cli"
}
latest, found, err := selfupdate.DetectLatest(slug)
if err != nil {
return errors.Wrap(err, "Cannot detect version from GitHub")
}
v := semver.MustParse(Version)
if !found || latest.Version.LTE(v) {
fmt.Fprintln(cmd.Out, "Current version is the latest")
return nil
}
yellow.Fprintf(cmd.Out, "New version v%s\n\n", latest.Version)
fmt.Fprintf(cmd.Out, "Release Note:\n%s\n", latest.ReleaseNotes)
if cmd.Dry {
return nil
}
fmt.Fprint(cmd.Out, "\nDownloading and unarchiving the new release asset...")
exe, err := os.Executable()
if err != nil {
return errors.Wrap(err, "Cannot get path to executable to update")
}
if err := selfupdate.UpdateTo(latest.AssetURL, exe); err != nil {
return err
}
fmt.Fprintln(cmd.Out, "Done.")
return nil
}