Skip to content

Commit

Permalink
Latest Version Check (#93)
Browse files Browse the repository at this point in the history
* Add an HTTP check to see if user has the latest version, alerts them if it's out of date

* Add missing period
  • Loading branch information
Jonesy committed Dec 6, 2023
1 parent 5b1712a commit e0a1b9b
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ func NewRootCommand(ctx *pkg.AppContext) *cobra.Command {
SilenceUsage: true,
Long: `GWA CLI helps manage gateway resources in a declarative fashion.`,
Version: ctx.Version,
PersistentPostRun: func(_ *cobra.Command, _ []string) {
pkg.CheckForVersion(ctx)
},
}
rootCmd.AddCommand(NewConfigCmd(ctx))
rootCmd.AddCommand(NewInit(ctx))
Expand Down
92 changes: 92 additions & 0 deletions pkg/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package pkg

import (
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"strings"

"github.com/MakeNowJust/heredoc/v2"
"github.com/charmbracelet/lipgloss"
)

var (
box = lipgloss.NewStyle().Foreground(lipgloss.Color("3")).
MarginTop(1).
PaddingLeft(2).
PaddingRight(2).
PaddingTop(1).
Align(lipgloss.Center).
Border(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color("3"))
)

type ReleaseJson struct {
TagName string `json:"tag_name"`
}

const releaseUrl = "https://api.github.com/repos/bcgov/gwa-cli/releases/latest"

func requestPublishedVersion() (string, error) {
req, err := http.NewRequest("GET", releaseUrl, nil)
if err != nil {
return "", err
}
client := new(http.Client)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accepts", "application/json")

response, err := client.Do(req)
if err != nil {
return "", err
}

body, err := io.ReadAll(response.Body)
defer response.Body.Close()

var data = ReleaseJson{}
if response.StatusCode == http.StatusOK {
json.Unmarshal(body, &data)
return data.TagName, nil
}

return "", err
}

func convertVersion(input string) int {
cleanNumber := strings.TrimPrefix(input, "v")
parts := strings.Split(cleanNumber, ".")

major, _ := strconv.Atoi(parts[0])
minor, _ := strconv.Atoi(parts[1])
patch, _ := strconv.Atoi(parts[2])

return major*10000 + minor*100 + patch
}

func isOutdated(local string, published string) bool {
latestVersion := convertVersion(published)
installedVersion := convertVersion(local)

return installedVersion < latestVersion
}

func CheckForVersion(ctx *AppContext) {
tagName, err := requestPublishedVersion()
if err != nil {
fmt.Println(fmt.Errorf("err %v", err))
}

if isOutdated(ctx.Version, tagName) {
title := fmt.Sprintf("A new version (%s) is available.", tagName)
titleEl := lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("6")).Render(title)
fmt.Println(box.Render(heredoc.Docf(`
%s
You have %s installed.
Please download the latest version to continue access to our services.
`, titleEl, ctx.Version)))
}
}
45 changes: 45 additions & 0 deletions pkg/update_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package pkg

import (
"net/http"
"testing"

"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
"github.com/zenizh/go-capturer"
)

func TestConvertVersion(t *testing.T) {
assert.Equal(t, 10200, convertVersion("v1.2.0"))
assert.Equal(t, 101905, convertVersion("v10.19.5"))
}

func TestCompareVersion(t *testing.T) {
assert.True(t, isOutdated("v1.2.0", "v10.3.0"))
assert.False(t, isOutdated("v1.3.0", "v1.3.0"))
}

func TestCheckForVersion(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()

httpmock.RegisterResponder("GET", releaseUrl, func(r *http.Request) (*http.Response, error) {
return httpmock.NewJsonResponse(200, map[string]interface{}{
"tag_name": "v1.2.0",
})
})
out := capturer.CaptureStdout(func() {
ctx := AppContext{
Version: "v1.1.1",
}
CheckForVersion(&ctx)
})
assert.Contains(t, out, "A new version (v1.2.0) is available.")
empty := capturer.CaptureStdout(func() {
ctx := AppContext{
Version: "v1.2.0",
}
CheckForVersion(&ctx)
})
assert.Equal(t, empty, "")
}

0 comments on commit e0a1b9b

Please sign in to comment.