Skip to content

Commit

Permalink
fix: cardinal editor version mapping (#60)
Browse files Browse the repository at this point in the history
Closes: WORLD-1046

## Overview

Make world cli check cardinal editor version mapping to cardinal editor repo

## Brief Changelog

- Create func to fetch version map

## Testing and Verifying

- Added unit test for new func
- Tested manually using `world cardinal dev` command
  • Loading branch information
zulkhair committed Apr 18, 2024
1 parent 5351040 commit 4964b7c
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 19 deletions.
82 changes: 65 additions & 17 deletions common/teacmd/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"golang.org/x/mod/modfile"

"pkg.world.dev/world-cli/common/globalconfig"
"pkg.world.dev/world-cli/common/logger"
)

const (
Expand All @@ -33,17 +34,18 @@ const (
cardinalGomodPath = "cardinal/go.mod"

cardinalPkgPath = "pkg.world.dev/world-engine/cardinal"

versionMapURL = "https://raw.githubusercontent.com/Argus-Labs/cardinal-editor/main/version_map.json"
)

var (
defaultVersion = "v0.3.0"
// Cardinal : Cardinal Editor version map
// TODO this version map need to store in somewhere that can be accessed online
cardinalVersionMap = map[string]string{
// This is the default value for fallback if cannot get version from repository
defaultCardinalVersionMap = map[string]string{
"v1.2.2-beta": "v0.1.0",
"v1.2.3-beta": "v0.1.0",
"v1.2.4-beta": defaultVersion,
"v1.2.5-beta": defaultVersion,
"v1.2.4-beta": "v0.3.1",
"v1.2.5-beta": "v0.3.1",
}
)

Expand All @@ -57,6 +59,13 @@ type Release struct {
}

func SetupCardinalEditor() error {
// Get the version map
cardinalVersionMap, err := getVersionMap(versionMapURL)
if err != nil {
logger.Warn("Failed to get version map, using default version map")
cardinalVersionMap = defaultCardinalVersionMap
}

// Check version
cardinalVersion, err := getModuleVersion(cardinalGomodPath, cardinalPkgPath)
if err != nil {
Expand All @@ -65,10 +74,6 @@ func SetupCardinalEditor() error {

downloadURL := latestReleaseURL
downloadVersion, versionIsExist := cardinalVersionMap[cardinalVersion]
if !versionIsExist {
// default to defaultVersion
downloadVersion = defaultVersion
}
if versionIsExist {
downloadURL = fmt.Sprintf("%s/tags/%s", releaseURL, downloadVersion)
}
Expand All @@ -90,7 +95,7 @@ func SetupCardinalEditor() error {
return err
}

editorDir, err := downloadReleaseIfNotCached(downloadURL, configDir)
editorDir, downloadVersion, err := downloadReleaseIfNotCached(downloadURL, configDir)
if err != nil {
return err
}
Expand Down Expand Up @@ -118,38 +123,40 @@ func SetupCardinalEditor() error {
return nil
}

func downloadReleaseIfNotCached(downloadURL, configDir string) (string, error) {
// downloadReleaseIfNotCached : downloads the latest release of the Cardinal Editor if it is not already cached.
// returns editor directory path, version and error
func downloadReleaseIfNotCached(downloadURL, configDir string) (string, string, error) {
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, downloadURL, nil)
if err != nil {
return "", err
return "", "", err
}

client := &http.Client{
Timeout: httpTimeout,
}
resp, err := client.Do(req)
if err != nil {
return "", err
return "", "", err
}
defer resp.Body.Close()

var release Release
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
return "", "", err
}
if err = json.Unmarshal(bodyBytes, &release); err != nil {
return "", err
return "", "", err
}

editorDir := filepath.Join(configDir, "editor")

targetDir := filepath.Join(editorDir, release.Name)
if _, err = os.Stat(targetDir); os.IsNotExist(err) {
return targetDir, downloadAndUnzip(release.Assets[0].BrowserDownloadURL, targetDir)
return targetDir, release.Name, downloadAndUnzip(release.Assets[0].BrowserDownloadURL, targetDir)
}

return targetDir, nil
return targetDir, release.Name, nil
}

func downloadAndUnzip(url string, targetDir string) error {
Expand Down Expand Up @@ -371,3 +378,44 @@ func fileExists(filename string) bool {
}
return !info.IsDir()
}

// getVersionMap fetches the JSON data from a URL and unmarshals it into a map[string]string.
func getVersionMap(url string) (map[string]string, error) {
// Make an HTTP GET request
client := &http.Client{
Timeout: httpTimeout,
}

// Create a new request using http
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil)
if err != nil {
return nil, err
}

// Send the request via a client
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

// Check for HTTP error
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP error: %d - %s", resp.StatusCode, resp.Status)
}

// Read the response body
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

// Unmarshal the JSON data into a map
var result map[string]string
err = json.Unmarshal(body, &result)
if err != nil {
return nil, err
}

return result, nil
}
80 changes: 79 additions & 1 deletion common/teacmd/editor_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package teacmd

import (
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
Expand All @@ -18,7 +21,7 @@ func TestSetupCardinalEditor(t *testing.T) {
t.Run("setup cardinal editor", func(t *testing.T) {
cleanUpDir(testDir)

editorDir, err := downloadReleaseIfNotCached(latestReleaseURL, testDir)
editorDir, _, err := downloadReleaseIfNotCached(latestReleaseURL, testDir)
assert.NilError(t, err)

// check if editor directory exists
Expand Down Expand Up @@ -261,3 +264,78 @@ func TestFileExists(t *testing.T) {
t.Errorf("fileExists(%s) = %v, want %v", tempDir, exists, false)
}
}

func TestGetVersionMap(t *testing.T) {
// Define test cases
tests := []struct {
name string
serverResponse string
serverStatus int
want map[string]string
wantErr bool
}{
{
name: "successful response with specific version map",
serverResponse: `{
"v1.2.2-beta": "v0.1.0",
"v1.2.3-beta": "v0.1.0",
"v1.2.4-beta": "v0.3.0"
}`,
serverStatus: http.StatusOK,
want: map[string]string{
"v1.2.2-beta": "v0.1.0",
"v1.2.3-beta": "v0.1.0",
"v1.2.4-beta": "v0.3.0",
},
wantErr: false,
},
{
name: "HTTP error",
serverResponse: `HTTP error occurred`,
serverStatus: http.StatusInternalServerError,
want: nil,
wantErr: true,
},
{
name: "invalid JSON",
serverResponse: `{"invalid": 1, "format": true}`, // invalid JSON for map[string]string
serverStatus: http.StatusOK,
want: nil,
wantErr: true,
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
// Setup a test server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(tc.serverStatus)
fmt.Fprintln(w, tc.serverResponse)
}))
defer server.Close()

// Call the function with the test server URL
got, err := getVersionMap(server.URL)
if (err != nil) != tc.wantErr {
t.Errorf("getVersionMap() error = %v, wantErr %v", err, tc.wantErr)
return
}
if err == nil && !compareMaps(got, tc.want) {
t.Errorf("getVersionMap() got = %v, want %v", got, tc.want)
}
})
}
}

// compareMaps helps in comparing two maps for equality
func compareMaps(a, b map[string]string) bool {
if len(a) != len(b) {
return false
}
for k, v := range a {
if b[k] != v {
return false
}
}
return true
}
2 changes: 1 addition & 1 deletion example-world.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ FAUCET_ADDR="world142fg37yzx04cslgeflezzh83wa4xlmjpms0sg5"
BLOCK_TIME="1s"

[common]
ROUTER_KEY=4a02ea35e37727a2e22b62520c03a3cf0b139418a4401027baedfc93834dc6bd # key to secure router communications.
ROUTER_KEY="4a02ea35e37727a2e22b62520c03a3cf0b139418a4401027baedfc93834dc6bd" # key to secure router communications.

[nakama]
ENABLE_ALLOWLIST="false" # enable nakama's beta key feature. you can generate and claim beta keys by setting this to true

0 comments on commit 4964b7c

Please sign in to comment.