Skip to content

Commit

Permalink
Merge pull request #26 from CircleCI-Public/update
Browse files Browse the repository at this point in the history
Add an `update check` command to check for updates.
  • Loading branch information
eric-hu authored Jul 26, 2018
2 parents 0357eb2 + 99e5198 commit e92eacf
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 3 deletions.
2 changes: 1 addition & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func NewClient(endpoint string, logger *logger.Logger) *graphql.Client {
func NewAuthorizedRequest(token, query string) *graphql.Request {
req := graphql.NewRequest(query)
req.Header.Set("Authorization", token)
req.Header.Set("User-Agent", fmt.Sprintf("circleci-cli/%s-%s", version.Version, version.Commit))
req.Header.Set("User-Agent", version.UserAgent())
return req
}

Expand Down
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func MakeCommands() *cobra.Command {
rootCmd.AddCommand(newOrbCommand())
rootCmd.AddCommand(newBuildCommand())
rootCmd.AddCommand(newVersionCommand())
rootCmd.AddCommand(newUpdateCommand())
rootCmd.PersistentFlags().BoolP("verbose", "v", false, "Enable verbose logging.")
rootCmd.PersistentFlags().StringP("endpoint", "e", defaultEndpoint, "the endpoint of your CircleCI GraphQL API")
rootCmd.PersistentFlags().StringP("token", "t", "", "your token for using CircleCI")
Expand Down
2 changes: 1 addition & 1 deletion cmd/root_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ var _ = Describe("Root", func() {

It("can create commands", func() {
commands := cmd.MakeCommands()
Expect(len(commands.Commands())).To(Equal(8))
Expect(len(commands.Commands())).To(Equal(9))
})

})
Expand Down
81 changes: 81 additions & 0 deletions cmd/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package cmd

import (
"encoding/json"
"io/ioutil"
"net/http"
"unicode/utf8"

"github.com/CircleCI-Public/circleci-cli/version"
"github.com/spf13/cobra"
)

func newUpdateCommand() *cobra.Command {
update := &cobra.Command{
Use: "update",
Short: "Update the tool",
}

update.AddCommand(&cobra.Command{
Use: "check",
Short: "Check if there are any updates available",
RunE: checkForUpdates,
})

return update
}

func trimFirstRune(s string) string {
_, i := utf8.DecodeRuneInString(s)
return s[i:]
}

func checkForUpdates(cmd *cobra.Command, args []string) error {

url := "https://api.github.com/repos/CircleCI-Public/circleci-cli/releases/latest"

req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return err
}

req.Header.Set("User-Agent", version.UserAgent())

client := http.Client{}
res, err := client.Do(req)
if err != nil {
return err
}

body, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}

var release struct {
// There are other fields in this response that we could use to download the
// binaries on behalf of the user.
// https://developer.github.com/v3/repos/releases/#get-the-latest-release
HTML string `json:"html_url"`
Tag string `json:"tag_name"`
}

if err := json.Unmarshal(body, &release); err != nil {
return err
}

latest := trimFirstRune(release.Tag)

Logger.Debug("Latest version: %s", latest)
Logger.Debug("Current Version: %s", version.Version)

if latest == version.Version {
Logger.Info("Already up-to-date.")
} else {
Logger.Infof("A new release is available (%s)", release.Tag)
Logger.Infof("You are running %s", version.Version)
Logger.Infof("You can download it from %s", release.HTML)
}

return nil
}
1 change: 0 additions & 1 deletion cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,4 @@ func newVersionCommand() *cobra.Command {
Logger.Infof("%s (%s)", version.Version, version.Commit)
},
}

}
9 changes: 9 additions & 0 deletions version/version.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
package version

import (
"fmt"
)

// These vars set by `goreleaser`:
var (
// Version is the current Git tag (the v prefix is stripped) or the name of the snapshot, if you’re using the --snapshot flag
Version = "local-dev-build"
// Commit is the current git commit SHA
Commit = "dirty-local-tree"
)

// UserAgent returns the user agent that should be user for external requests
func UserAgent() string {
return fmt.Sprintf("circleci-cli/%s-%s", Version, Commit)
}

0 comments on commit e92eacf

Please sign in to comment.