cli/commands/update/check_update.go

95 lines
2.6 KiB
Go

package update
import (
"fmt"
"strings"
"gitlab.com/gitlab-org/cli/pkg/utils"
"gitlab.com/gitlab-org/cli/commands/cmdutils"
"github.com/hashicorp/go-version"
"github.com/spf13/cobra"
"github.com/xanzy/go-gitlab"
)
const (
defaultProjectURL = "https://gitlab.com/gitlab-org/cli"
commandUse = "check-update"
)
var commandAliases = []string{"update"}
func NewCheckUpdateCmd(f *cmdutils.Factory, version string) *cobra.Command {
cmd := &cobra.Command{
Use: commandUse,
Short: "Check for latest glab releases",
Long: ``,
Aliases: commandAliases,
RunE: func(cmd *cobra.Command, args []string) error {
return CheckUpdate(f, version, false, "")
},
}
return cmd
}
func CheckUpdate(f *cmdutils.Factory, version string, silentSuccess bool, previousCommand string) error {
// Don't CheckUpdate if previous command is CheckUpdate
if previousCommand == commandUse || utils.PresentInStringSlice(commandAliases, previousCommand) {
return nil
}
// We set the project to the `glab` project to check for `glab` updates
err := f.RepoOverride(defaultProjectURL)
if err != nil {
return err
}
repo, err := f.BaseRepo()
if err != nil {
return err
}
apiClient, err := f.HttpClient()
if err != nil {
return err
}
// Since the `gitlab.com/gitlab-org/cli` is public, we remove the token for this single request, so when users have
// a `GITLAB_TOKEN` set with a token for their self-managed instance, we don't use it to authenticate to gitlab.com
releases, _, err := apiClient.Releases.ListReleases(
repo.FullName(), &gitlab.ListReleasesOptions{ListOptions: gitlab.ListOptions{Page: 1, PerPage: 1}}, gitlab.WithToken(gitlab.PrivateToken, ""))
if err != nil {
return fmt.Errorf("failed checking for glab updates: %s", err.Error())
}
if len(releases) < 1 {
return fmt.Errorf("no release found for glab")
}
latestRelease := releases[0]
releaseURL := fmt.Sprintf("%s/-/releases/%s", defaultProjectURL, latestRelease.TagName)
c := f.IO.Color()
if isOlderVersion(latestRelease.Name, version) {
fmt.Fprintf(f.IO.StdErr, "%s %s -> %s\n%s\n",
c.Yellow("A new version of glab has been released:"),
c.Red(version), c.Green(latestRelease.TagName),
releaseURL)
} else {
if silentSuccess {
return nil
}
fmt.Fprintf(f.IO.StdErr, "%v",
c.Green("You are already using the latest version of glab\n"))
}
return nil
}
func isOlderVersion(latestVersion, appVersion string) bool {
latestVersion = strings.TrimSpace(latestVersion)
appVersion = strings.TrimSpace(appVersion)
vv, ve := version.NewVersion(latestVersion)
vw, we := version.NewVersion(appVersion)
return ve == nil && we == nil && vv.GreaterThan(vw)
}