Skip to content

Commit

Permalink
Update CheckForNewVersion to use the GitHub location (#18)
Browse files Browse the repository at this point in the history
* Update CheckForNewVersion to use the GitHub location

Add test

* Trim version number from 'v'

* Remove commented io import

* Add and test generateDownloadURL

* Update generateDownloadURL to produce a .zip url for Windows

* Reindent TestGenerateDownloadURL

* Update the log message to be specific to Windows and non-Windows systems

* Add new line at the EOF

* Remove the redundant version compare term

* Fix a bug

* Add v to remote version number
  • Loading branch information
kavir1698 authored Mar 26, 2024
1 parent 15af396 commit aa8c0e4
Show file tree
Hide file tree
Showing 2 changed files with 189 additions and 30 deletions.
86 changes: 56 additions & 30 deletions datasetUtils/checkForNewVersion.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,66 +2,92 @@ package datasetUtils

import (
"bufio"
"io"
"log"
"net/http"
"os"
"runtime"
"strconv"
"strings"

"encoding/json"
version "github.com/mcuadros/go-version"
"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

// check version of program, give hint to update
const DeployLocation = "https://gitlab.psi.ch/scicat/tools/raw/master/" + runtime.GOOS + "/"
var (
GitHubAPI = "https://api.github.com/repos/paulscherrerinstitute/scicat-cli/releases/latest"
DeployLocation = "https://github.com/paulscherrerinstitute/scicat-cli/releases/download"
)

func CheckForNewVersion(client *http.Client, APP string, VERSION string, interactiveFlag bool) {
resp, err := client.Get(DeployLocation + APP + "Version.txt")
type Release struct {
TagName string `json:"tag_name"`
}

func fetchLatestVersion(client *http.Client) (string, error) {
resp, err := client.Get(GitHubAPI)
if err != nil {
log.Println("Can not find info about latest version for this program")
log.Printf("Error: %s\n", err)
return
return "", err
}
defer resp.Body.Close()

if resp.StatusCode != 200 {
log.Println("Can not find info about latest version for this program")
log.Printf("Error: Got %s fetching %s\n", resp.Status, DeployLocation + APP + "Version.txt")
return
return "", fmt.Errorf("got %s fetching %s", resp.Status, GitHubAPI)
}

body, err := io.ReadAll(resp.Body)

var release Release
err = json.NewDecoder(resp.Body).Decode(&release)
if err != nil {
log.Println("Can not read version file for this application")
return
return "", err
}

return strings.TrimSpace(release.TagName), nil
}

latestVersion := strings.TrimSpace(string(body))
// Make sure the version number is stripped of the 'v' prefix. That's required for `strconv.Atoi` to work.
func generateDownloadURL(deployLocation, latestVersion, osName string) string {
if strings.ToLower(osName) == "windows" {
return fmt.Sprintf("%s/v%s/scicat-cli_.%s_%s_x86_64.zip", deployLocation, latestVersion, latestVersion, strings.Title(osName))
}
return fmt.Sprintf("%s/v%s/scicat-cli_.%s_%s_x86_64.tar.gz", deployLocation, latestVersion, latestVersion, strings.Title(osName))
}

majorLatest, err := strconv.Atoi(strings.Split(latestVersion, ".")[0])
func CheckForNewVersion(client *http.Client, APP string, VERSION string, interactiveFlag bool) {
latestVersion, err := fetchLatestVersion(client)
if err != nil {
log.Printf("Can not find info about latest version for this program: %s\n", err)
return
}

latestVersion = strings.TrimPrefix(latestVersion, "v")
_, err = strconv.Atoi(strings.Split(latestVersion, ".")[0])
if err != nil {
log.Fatalf("Illegal latest version number:%v", latestVersion)
}
majorCurrent, err := strconv.Atoi(strings.Split(VERSION, ".")[0])
_, err = strconv.Atoi(strings.Split(VERSION, ".")[0])
if err != nil {
log.Fatalf("Illegal version number:%v", VERSION)
}
log.Printf("Latest version: %s", latestVersion)
if majorLatest > majorCurrent {
log.Println("You must upgrade to a newer version")
log.Println("Current Version: ", VERSION)
log.Println("Latest Version: ", latestVersion)
log.Println("Use the following command to update:")
log.Println("curl -O " + DeployLocation + APP + ";chmod +x " + APP)
log.Fatalf("Execution stopped, please update program now.\n")
} else if version.Compare(latestVersion, VERSION, ">") {

// Get the operating system name
osName := runtime.GOOS

// Generate the download URL
downloadURL := generateDownloadURL(DeployLocation, latestVersion, osName)

if version.Compare(latestVersion, VERSION, ">") {
log.Println("You should upgrade to a newer version")
log.Println("Current Version: ", VERSION)
log.Println("Latest Version: ", latestVersion)
log.Println("Use the following command to update:")
log.Println("curl -O " + DeployLocation + APP + ";chmod +x " + APP)
log.Println("You can either download the file using the browser or use the following command:")

if strings.ToLower(osName) == "windows" {
log.Printf("Browser: %s\nCommand: curl -L -O %s; unzip scicat-cli_.%s_%s_x86_64.zip; cd scicat-cli\n", downloadURL, downloadURL, latestVersion, strings.Title(osName))
} else {
log.Printf("Browser: %s\nCommand: curl -L -O %s; tar xzf scicat-cli_.%s_%s_x86_64.tar.gz; cd scicat-cli; chmod +x %s\n", downloadURL, downloadURL, latestVersion, strings.Title(osName), APP)
}

if interactiveFlag {
log.Print("Do you want to continue with current version (y/N) ? ")
scanner.Scan()
Expand All @@ -72,5 +98,5 @@ func CheckForNewVersion(client *http.Client, APP string, VERSION string, interac
}
} else {
log.Println("Your version of this program is up-to-date")
}
}
}
133 changes: 133 additions & 0 deletions datasetUtils/checkForNewVersion_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package datasetUtils

import (
"net/http"
"net/http/httptest"
"strings"
"testing"
"bytes"
"log"
)

func TestFetchLatestVersion(t *testing.T) {
// Create a mock HTTP server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Return a JSON response similar to the GitHub API
w.Write([]byte(`{"tag_name": "v1.0.0"}`))
}))
defer server.Close()

// Replace GitHubAPI with the URL of the mock server
oldGitHubAPI := GitHubAPI
GitHubAPI = server.URL
defer func() { GitHubAPI = oldGitHubAPI }()

// Create a mock HTTP client
client := server.Client()

// Call fetchLatestVersion
version, err := fetchLatestVersion(client)
if err != nil {
t.Fatalf("Expected no error, got %v", err)
}

// Check the version number
if version != "v1.0.0" {
t.Errorf("Expected version v1.0.0, got %s", version)
}
}

func TestGenerateDownloadURL(t *testing.T) {
deployLocation := "https://github.com/paulscherrerinstitute/scicat-cli/releases/download"
latestVersion := "0.1.0"

testCases := []struct {
osName string
expectedURL string
}{
{
osName: "Linux",
expectedURL: "https://github.com/paulscherrerinstitute/scicat-cli/releases/download/v0.1.0/scicat-cli_.0.1.0_Linux_x86_64.tar.gz",
},
{
osName: "Windows",
expectedURL: "https://github.com/paulscherrerinstitute/scicat-cli/releases/download/v0.1.0/scicat-cli_.0.1.0_Windows_x86_64.zip",
},
{
osName: "Darwin",
expectedURL: "https://github.com/paulscherrerinstitute/scicat-cli/releases/download/v0.1.0/scicat-cli_.0.1.0_Darwin_x86_64.tar.gz",
},
}

for _, testCase := range testCases {
actualURL := generateDownloadURL(deployLocation, latestVersion, testCase.osName)

if actualURL != testCase.expectedURL {
t.Errorf("Expected URL to be %s, but got %s", testCase.expectedURL, actualURL)
}
}
}

func TestCheckForNewVersion(t *testing.T) {
tests := []struct {
name string
currentVersion string
mockResponse string
expectedLog string
}{
{
name: "New version available",
currentVersion: "0.9.0",
mockResponse: `{"tag_name": "v1.0.0"}`,
expectedLog: "You should upgrade to a newer version",
},
{
name: "No new version available",
currentVersion: "1.0.0",
mockResponse: `{"tag_name": "v1.0.0"}`,
expectedLog: "Your version of this program is up-to-date",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create a mock HTTP server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Return a JSON response similar to the GitHub API
w.Write([]byte(tt.mockResponse))
}))
defer server.Close()

// Replace GitHubAPI with the URL of the mock server
oldGitHubAPI := GitHubAPI
GitHubAPI = server.URL
defer func() { GitHubAPI = oldGitHubAPI }()

// Create a mock HTTP client
client := server.Client()

// Call CheckForNewVersion
CheckForNewVersion(client, "test", tt.currentVersion, false)

// Check the log output
logOutput := getLogOutput()
if !strings.Contains(logOutput, tt.expectedLog) {
t.Errorf("Expected log message not found: %s", logOutput)
}

// Clear the log buffer after each test
buf.Reset()
})
}
}

var buf bytes.Buffer

func init() {
// Redirect the output of the logger to buf
log.SetOutput(&buf)
}

func getLogOutput() string {
return buf.String()
}

0 comments on commit aa8c0e4

Please sign in to comment.