diff --git a/Makefile b/Makefile index e7d0af4ad..1954c23a5 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,18 @@ .DEFAULT_GOAL := help SHELL = bash -RHOAS_VERSION ?= $(shell git describe --tags 2>/dev/null || git rev-parse --short HEAD) +# see internal/build.go on build configurations +RHOAS_VERSION ?= "dev" +REPOSITORY_OWNER ?= "redhat-developer" +REPOSITORY_NAME ?= "app-services-cli" +TERMS_REVIEW_EVENT_CODE ?= "onlineService" +TERMS_REVIEW_SITE_CODE ?= "ocm" GO_LDFLAGS := -X github.com/redhat-developer/app-services-cli/internal/build.Version=$(RHOAS_VERSION) $(GO_LDFLAGS) +GO_LDFLAGS := -X github.com/redhat-developer/app-services-cli/internal/build.RepositoryOwner=$(REPOSITORY_OWNER) $(GO_LDFLAGS) +GO_LDFLAGS := -X github.com/redhat-developer/app-services-cli/internal/build.RepositoryName=$(REPOSITORY_NAME) $(GO_LDFLAGS) +GO_LDFLAGS := -X github.com/redhat-developer/app-services-cli/internal/build.TermsReviewEventCode=$(TERMS_REVIEW_EVENT_CODE) $(GO_LDFLAGS) +GO_LDFLAGS := -X github.com/redhat-developer/app-services-cli/internal/build.TermsReviewSiteCode=$(TERMS_REVIEW_SITE_CODE) $(GO_LDFLAGS) BUILDFLAGS := diff --git a/cmd/rhoas/main.go b/cmd/rhoas/main.go index 038600e8c..428e67986 100644 --- a/cmd/rhoas/main.go +++ b/cmd/rhoas/main.go @@ -1,13 +1,15 @@ package main import ( + "context" "encoding/json" "fmt" + "os" + "github.com/markbates/pkger" "github.com/redhat-developer/app-services-cli/pkg/api/kas" "github.com/redhat-developer/app-services-cli/pkg/doc" "github.com/redhat-developer/app-services-cli/pkg/dump" - "os" "github.com/redhat-developer/app-services-cli/pkg/cmdutil" @@ -67,7 +69,11 @@ func main() { os.Exit(0) } - if err = rootCmd.Execute(); err == nil { + err = rootCmd.Execute() + if debug.Enabled() { + build.CheckForUpdate(context.Background(), logger) + } + if err == nil { return } diff --git a/go.mod b/go.mod index d52ac6d9d..508c962eb 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,8 @@ require ( github.com/fatih/color v1.10.0 github.com/gobuffalo/here v0.6.2 // indirect github.com/golang/protobuf v1.5.1 // indirect + github.com/google/go-github v17.0.0+incompatible + github.com/google/go-querystring v1.0.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/kataras/tablewriter v0.0.0-20180708051242-e063d29b7c23 // indirect github.com/landoop/tableprinter v0.0.0-20201125135848-89e81fc956e7 diff --git a/go.sum b/go.sum index 89d42d5c8..fe3be6e85 100644 --- a/go.sum +++ b/go.sum @@ -234,6 +234,10 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= +github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/internal/build/build.go b/internal/build/build.go index 4634a562f..539f0d4c1 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -1,17 +1,89 @@ package build import ( + "context" + "regexp" "runtime/debug" + + "github.com/google/go-github/github" + "github.com/redhat-developer/app-services-cli/pkg/color" + "github.com/redhat-developer/app-services-cli/pkg/logging" ) -// Version is dynamically set by the toolchain or overridden by the Makefile. -var Version = "dev" -var Language = "en" +// Define public variables here which you wish to be configurable at build time +var ( + // Version is dynamically set by the toolchain or overridden by the Makefile. + Version = "dev" + + // Language used, can be overridden by Makefile or CI + Language = "en" + + // RepositoryOwner is the remote GitHub organization for the releases + RepositoryOwner = "redhat-developer" + + // RepositoryName is the remote GitHub repository for the releases + RepositoryName = "app-services-cli" + + // TermsReviewEventCode is the event code used when checking the terms review + TermsReviewEventCode = "onlineService" + + // TermsReviewSiteCode is the site code used when checking the terms review + TermsReviewSiteCode = "ocm" +) func init() { - if Version == "dev" { + if isDevBuild() { if info, ok := debug.ReadBuildInfo(); ok && info.Main.Version != "(devel)" { Version = info.Main.Version } } } + +// CheckForUpdate checks if there is a newer version of the CLI than +// the version currently being used. If so, it logs this information +// to the console. +func CheckForUpdate(ctx context.Context, logger logging.Logger) { + latest, err := getLatestVersion(ctx) + if err != nil { + logger.Debug("Could not check latest version:", err) + return + } + + latestVersion := latest.TagName + + // if the user is using a dev or pre-release version, do not check for if an update is available + if isDevBuild() || isPreRelease(Version) { + return + } + + if latestVersion != &Version { + logger.Info() + logger.Info(color.Info("A new version of rhoas is available:"), color.CodeSnippet(*latestVersion)) + logger.Info(color.Info(latest.GetHTMLURL())) + logger.Info() + } +} + +// Get the latest version of the CLI +func getLatestVersion(ctx context.Context) (*github.RepositoryRelease, error) { + client := github.NewClient(nil) + + latest, _, err := client.Repositories.GetLatestRelease(ctx, RepositoryOwner, RepositoryName) + if err != nil { + return nil, err + } + + return latest, nil +} + +// isDevBuild returns true if the current build is "dev" (dev build) +func isDevBuild() bool { + return Version == "dev" +} + +// check if the tag is a pre-release tag +// true it if contains anything other than MAJOR.MINOR.PATCH +func isPreRelease(tag string) bool { + match, _ := regexp.MatchString("^[0-9]+\\.[0-9]+\\.[0-9]+$", tag) + return !match +} diff --git a/pkg/cmd/kafka/create/create.go b/pkg/cmd/kafka/create/create.go index 2efde9781..e6a8ff49d 100644 --- a/pkg/cmd/kafka/create/create.go +++ b/pkg/cmd/kafka/create/create.go @@ -13,6 +13,7 @@ import ( "github.com/redhat-developer/app-services-cli/pkg/connection" "github.com/redhat-developer/app-services-cli/pkg/kafka" + "github.com/redhat-developer/app-services-cli/internal/build" "github.com/redhat-developer/app-services-cli/internal/localizer" kasclient "github.com/redhat-developer/app-services-cli/pkg/api/kas/client" @@ -305,14 +306,11 @@ func checkTermsAccepted(connFunc factory.ConnectionFunc) (accepted bool, redirec return false, "", err } - eventCode := "onlineService" - siteCode := "ocm" - termsReview, _, err := conn.API().AccountMgmt(). ApiAuthorizationsV1SelfTermsReviewPost(context.Background()). SelfTermsReview(amsclient.SelfTermsReview{ - EventCode: &eventCode, - SiteCode: &siteCode, + EventCode: &build.TermsReviewEventCode, + SiteCode: &build.TermsReviewSiteCode, }). Execute() if err != nil { diff --git a/pkg/cmd/login/login.go b/pkg/cmd/login/login.go index 5bb22a3af..90b0eda09 100644 --- a/pkg/cmd/login/login.go +++ b/pkg/cmd/login/login.go @@ -9,11 +9,14 @@ import ( "net/http" "net/url" + "github.com/redhat-developer/app-services-cli/internal/build" + "github.com/redhat-developer/app-services-cli/pkg/auth/login" "github.com/redhat-developer/app-services-cli/pkg/auth/token" "github.com/redhat-developer/app-services-cli/internal/config" "github.com/redhat-developer/app-services-cli/internal/localizer" + "github.com/redhat-developer/app-services-cli/pkg/cmd/debug" "github.com/redhat-developer/app-services-cli/pkg/cmd/factory" "github.com/redhat-developer/app-services-cli/pkg/httputil" "github.com/redhat-developer/app-services-cli/pkg/iostreams" @@ -195,6 +198,12 @@ func runLogin(opts *Options) (err error) { })) } + // debug mode checks this for a version update also. + // so we check if is enabled first so as not to print it twice + if !debug.Enabled() { + build.CheckForUpdate(context.Background(), logger) + } + return nil } diff --git a/pkg/cmd/version/version.go b/pkg/cmd/version/version.go index 38546ade8..d5b688d5f 100644 --- a/pkg/cmd/version/version.go +++ b/pkg/cmd/version/version.go @@ -1,22 +1,27 @@ package version import ( + "context" "fmt" "github.com/redhat-developer/app-services-cli/internal/build" "github.com/redhat-developer/app-services-cli/internal/localizer" + "github.com/redhat-developer/app-services-cli/pkg/cmd/debug" "github.com/redhat-developer/app-services-cli/pkg/cmd/factory" "github.com/redhat-developer/app-services-cli/pkg/iostreams" + "github.com/redhat-developer/app-services-cli/pkg/logging" "github.com/spf13/cobra" ) type Options struct { - IO *iostreams.IOStreams + IO *iostreams.IOStreams + Logger func() (logging.Logger, error) } func NewVersionCmd(f *factory.Factory) *cobra.Command { opts := &Options{ - IO: f.IOStreams, + IO: f.IOStreams, + Logger: f.Logger, } cmd := &cobra.Command{ @@ -40,5 +45,16 @@ func runCmd(opts *Options) (err error) { "Version": build.Version, }, })) + + logger, err := opts.Logger() + if err != nil { + return nil + } + + // debug mode checks this for a version update also. + // so we check if is enabled first so as not to print it twice + if !debug.Enabled() { + build.CheckForUpdate(context.Background(), logger) + } return nil }