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

Update CheckForNewVersion to use the GitHub location #18

Merged
merged 11 commits into from
Mar 26, 2024
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) {
minottic marked this conversation as resolved.
Show resolved Hide resolved
t.Errorf("Expected log message not found: %s", logOutput)
}

// Clear the log buffer after each test
buf.Reset()
minottic marked this conversation as resolved.
Show resolved Hide resolved
})
}
}

var buf bytes.Buffer

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

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