diff --git a/go.mod b/go.mod index 49fd1b96..b864ecbf 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/nats-io/nats.go v1.9.1 github.com/onsi/ginkgo v1.14.1 // indirect github.com/onsi/gomega v1.10.2 // indirect + github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.1.3 github.com/spf13/viper v1.8.1 diff --git a/utils/error.go b/utils/error.go index 363db99e..76312e7e 100644 --- a/utils/error.go +++ b/utils/error.go @@ -20,8 +20,8 @@ var ( ErrRemoteFileNotFoundCode = "11052" ErrReadingRemoteFileCode = "11053" ErrReadingLocalFileCode = "11054" - - ErrInvalidProtocol = errors.New(ErrInvalidProtocolCode, errors.Alert, []string{"invalid protocol: only http, https and file are valid protocols"}, []string{}, []string{"Network protocol is incorrect"}, []string{"Make sure to specify the right network protocol"}) + ErrGettingLatestReleaseTagCode = "11055" + ErrInvalidProtocol = errors.New(ErrInvalidProtocolCode, errors.Alert, []string{"invalid protocol: only http, https and file are valid protocols"}, []string{}, []string{"Network protocol is incorrect"}, []string{"Make sure to specify the right network protocol"}) ) func ErrUnmarshal(err error) error { @@ -67,3 +67,7 @@ func ErrReadingRemoteFile(err error) error { func ErrReadingLocalFile(err error) error { return errors.New(ErrReadingLocalFileCode, errors.Alert, []string{"error reading local file"}, []string{err.Error()}, []string{"File doesnt exist in the location", "File name is incorrect"}, []string{"Make sure to input the right file name and location"}) } + +func ErrGettingLatestReleaseTag(err error) error { + return errors.New(ErrGettingLatestReleaseTagCode, errors.Alert, []string{"Could not fetch latest stable release from github"}, []string{err.Error()}, []string{"Failed to make GET request to github", "Invalid response recieved on github.com///releases/stable"}, []string{"Make sure Github is reachable", "Make sure a valid response is available on github.com///releases/stable"}) +} diff --git a/utils/utils.go b/utils/utils.go index 7a2ce8bd..7b0bdc0c 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -3,6 +3,7 @@ package utils import ( "bytes" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -10,9 +11,12 @@ import ( "os" "os/user" "path/filepath" + "regexp" "runtime" "strconv" "strings" + + log "github.com/sirupsen/logrus" ) // unmarshal returns parses the JSON config data and stores the value in the reference to result @@ -182,3 +186,37 @@ func ReadLocalFile(location string) (string, error) { return string(data), nil } + +// Gets the latest stable release tag from github for a given org name and repo name(in that org) +func GetLatestReleaseTag(org string, repo string) (string, error) { + var url string = "https://github.com/" + org + "/" + repo + "/releases/latest" + resp, err := http.Get(url) + if err != nil { + return "", ErrGettingLatestReleaseTag(err) + } + defer safeClose(resp.Body) + + if resp.StatusCode != http.StatusOK { + return "", ErrGettingLatestReleaseTag(err) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", ErrGettingLatestReleaseTag(err) + } + re := regexp.MustCompile("/releases/tag/(.*?)\"") + releases := re.FindAllString(string(body), -1) + if len(releases) == 0 { + return "", ErrGettingLatestReleaseTag(errors.New("no release found in this repository")) + } + latest := strings.ReplaceAll(releases[0], "/releases/tag/", "") + latest = strings.ReplaceAll(latest, "\"", "") + return latest, nil +} + +// SafeClose is a helper function help to close the io +func safeClose(co io.Closer) { + if cerr := co.Close(); cerr != nil { + log.Error(cerr) + } +}