diff --git a/Makefile b/Makefile index 4051ca4..add7e34 100644 --- a/Makefile +++ b/Makefile @@ -4,4 +4,4 @@ cmd: godep go build -o build/deploy ./cmd/deploy release: - goxc -bc="linux,darwin" -d build -pv="0.0.3" + ./scripts/release $(VERSION) diff --git a/deploy.go b/deploy.go index 724554a..27b46e1 100644 --- a/deploy.go +++ b/deploy.go @@ -69,6 +69,10 @@ var flags = []cli.Flag{ Name: "quiet, q", Usage: "Silence any output to STDOUT.", }, + cli.BoolFlag{ + Name: "update, u", + Usage: "Update the binary", + }, } var ProtectedEnvironments = map[string]bool{ @@ -83,6 +87,16 @@ func NewApp() *cli.App { app.Usage = Usage app.Flags = flags app.Action = func(c *cli.Context) { + if c.Bool("update") { + updater := NewUpdater() + if err := updater.Update(); err != nil { + fmt.Println(err) + os.Exit(-1) + } else { + os.Exit(0) + } + } + if err := RunDeploy(c); err != nil { msg := err.Error() if err, ok := err.(*github.ErrorResponse); ok { diff --git a/scripts/release b/scripts/release new file mode 100755 index 0000000..2bb4939 --- /dev/null +++ b/scripts/release @@ -0,0 +1,11 @@ +#!/bin/bash + +if [ -z "$1" ]; then + echo "need version number. make release VERSION=0.0.3" + exit +fi + +goxc -bc="linux,darwin" -d build -pv="$1" -tasks-=package + +find $(dirname $0)/../build/$1/* -type d -exec mv -n -- {}/deploy {}_deploy \; +rm -R -- $(dirname $0)/../build/$1/*/ diff --git a/updater.go b/updater.go new file mode 100644 index 0000000..5ed92ab --- /dev/null +++ b/updater.go @@ -0,0 +1,78 @@ +package deploy + +import ( + "fmt" + "runtime" + "strings" + + "github.com/remind101/deploy/Godeps/_workspace/src/github.com/inconshreveable/go-update" + "github.com/remind101/deploy/Godeps/_workspace/src/github.com/octokit/go-octokit/octokit" +) + +const GitHubHost = "github.com" + +type Updater struct { + Host string + CurrentVersion string +} + +func NewUpdater() *Updater { + version := Version + return &Updater{ + Host: GitHubHost, + CurrentVersion: version, + } +} + +func (updater *Updater) Update() (err error) { + releaseName, version := updater.latestReleaseNameAndVersion() + + if version == "" { + fmt.Println("There is no newer version of Deploy available.") + return + } + + if version == updater.CurrentVersion { + fmt.Printf("You're already on the latest version: %s\n", version) + } else { + err = updater.updateTo(releaseName, version) + } + + return +} + +func (updater *Updater) updateTo(releaseName, version string) (err error) { + downloadURL := fmt.Sprintf("https://%s/remind101/deploy/releases/download/%s/%s_%s_deploy", updater.Host, releaseName, runtime.GOOS, runtime.GOARCH) + + fmt.Printf("Downloading %s...", version) + err, _ = update.New().FromUrl(downloadURL) + if err != nil { + fmt.Printf("Update failed: %v\n", err) + } + + return +} + +func (updater *Updater) latestReleaseNameAndVersion() (name, version string) { + client := octokit.NewClient(nil) + + url, err := octokit.ReleasesURL.Expand(octokit.M{"owner": "remind101", "repo": "deploy"}) + if err != nil { + return + } + + releases, result := client.Releases(url).All() + if result.HasError() { + err = fmt.Errorf("Error getting Deploy release: %s", result.Err) + return + } + + if len(releases) == 0 { + err = fmt.Errorf("No Deploy release is available") + return + } + + name = releases[0].TagName + version = strings.TrimPrefix(name, "v") + return +}