Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check for new releases #463

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/aws/aws-sdk-go v1.55.5
github.com/dustin/go-humanize v1.0.1
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/hashicorp/go-version v1.7.0
github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743
github.com/johannesboyne/gofakes3 v0.0.0-20220627085814-c3ac35da23b2
github.com/manifoldco/promptui v0.9.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743 h1:X3Xxno5Ji8idrNiUoFc7QyXpqhSYlDRYQmc7mlpMBzU=
github.com/inhies/go-bytesize v0.0.0-20210819104631-275770b98743/go.mod h1:KrtyD5PFj++GKkFS/7/RRrfnRhAMGQwy75GLCHWrCNs=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
log "github.com/sirupsen/logrus"
)

var Version = "development"
var Version = "0-development"

var Usage = `USAGE: %s <command> [command-args]

Expand Down
84 changes: 84 additions & 0 deletions version/version.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
package version

import (
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"net/http"
"os"
"time"

"github.com/hashicorp/go-version"
)

// Help text and command line flags.
Expand All @@ -26,11 +33,88 @@ var ArgHelp = `
// main program help
var Args = flag.NewFlagSet("version", flag.ExitOnError)

type ghResponse struct {
Name string `json:"name"`
Published string `json:"published_at"`
URL string `json:"html_url"`
}

// this is just so we can mock bad internet connection
var url = "https://api.github.com/repos/NBISweden/sda-cli/releases/latest"
var timeout = 30 * time.Second

// Returns the version of the sda-cli tool.
func Version(ver string) error {
if len(Args.Args()) > 0 {
return errors.New("version does not take any arguments")
}

req, err := http.NewRequest(http.MethodGet, url, http.NoBody)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to initiate request")
fmt.Println("sda-cli version: ", ver)

return nil
}
req.Header.Add("X-GitHub-Api-Version", "2022-11-28")
req.Header.Add("Accept", "application/vnd.github+json")

client := &http.Client{Timeout: timeout}
resp, err := client.Do(req)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to fetch releases, reson: %s\n", err.Error())
fmt.Println("sda-cli version: ", ver)

return nil
}
if resp.StatusCode >= 400 {
fmt.Fprintf(os.Stderr, "failed to fetch releases, reson: %s\n", resp.Status)
fmt.Println("sda-cli version: ", ver)

return nil
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Fprintln(os.Stderr, "failed to read response")
fmt.Println("sda-cli version: ", ver)

return nil
}

ghVersion := ghResponse{}
if err := json.Unmarshal(body, &ghVersion); err != nil {
fmt.Fprintln(os.Stderr, "failed to unmarshal response")
fmt.Println("sda-cli version: ", ver)

return nil
}

appVer, err := version.NewVersion(ver)
if err != nil {
fmt.Fprintln(os.Stderr, "faile to parse app version")
fmt.Println("sda-cli version: ", ver)

return nil
}
ghVer, err := version.NewVersion(ghVersion.Name)
if err != nil {
fmt.Fprintln(os.Stderr, "faile to parse release version")
fmt.Println("sda-cli version: ", ver)

return nil
}

if appVer.LessThan(ghVer) {
pt, _ := time.Parse(time.RFC3339, ghVersion.Published)
fmt.Printf("Newer version if sda-cli is avaiable, %s\n", ghVersion.Name)
fmt.Printf("Published: %s\n", pt.Format(time.DateTime))
fmt.Printf("Download it from here: %s\n", ghVersion.URL)

return nil
}

fmt.Println("sda-cli version: ", ver)

return nil
Expand Down
79 changes: 77 additions & 2 deletions version/version_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package version

import (
"io"
"net/http"
"net/http/httptest"
"os"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
Expand All @@ -16,9 +21,79 @@ func TestVersionTestSuite(t *testing.T) {
}

func (suite *VersionTests) TestGetVersion() {
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"html_url": "https://github.com/NBISweden/sda-cli/releases/tag/v0.1.3","name": "v0.1.3","published_at": "2024-09-19T09:23:33Z"}`))
}))
defer mockServer.Close()
url = mockServer.URL

// get version
err := Version("development")
err := Version("1.0.0")
assert.NoError(suite.T(), err)
}

func (suite *VersionTests) TestGetVersion_newerAvailable() {
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"html_url": "https://github.com/NBISweden/sda-cli/releases/tag/v0.1.3","name": "v0.1.3","published_at": "2024-09-19T09:23:33Z"}`))
}))
defer mockServer.Close()
url = mockServer.URL

storeStdout := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w

err := Version("0.0.1")
assert.NoError(suite.T(), err)

w.Close()
out, _ := io.ReadAll(r)
os.Stdout = storeStdout

assert.Contains(suite.T(), string(out), "Newer version if sda-cli is avaiable")
}

func (suite *VersionTests) TestGetVersion_badGateway() {
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusBadGateway)
}))
defer mockServer.Close()
url = mockServer.URL

storeStderr := os.Stderr
r, w, _ := os.Pipe()
os.Stderr = w

err := Version("0.0.3")
assert.NoError(suite.T(), err)

w.Close()
out, _ := io.ReadAll(r)
os.Stderr = storeStderr

assert.Equal(suite.T(), string(out), "failed to fetch releases, reson: 502 Bad Gateway\n")
}

func (suite *VersionTests) TestGetVersion_networkTimeout() {
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
time.Sleep(20 * time.Millisecond)
w.WriteHeader(http.StatusOK)
}))
defer mockServer.Close()
url = mockServer.URL
timeout = 10 * time.Millisecond

storeStderr := os.Stderr
r, w, _ := os.Pipe()
os.Stderr = w

err := Version("0.0.3")
assert.NoError(suite.T(), err)

w.Close()
out, _ := io.ReadAll(r)
os.Stderr = storeStderr

assert.Contains(suite.T(), string(out), "context deadline exceeded")
}
Loading