Skip to content

Commit

Permalink
added better error message for non-existant versions
Browse files Browse the repository at this point in the history
  • Loading branch information
coreybutler committed Dec 29, 2024
1 parent 487bfff commit 12c9aa3
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 76 deletions.
8 changes: 6 additions & 2 deletions src/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,19 @@ func GetAvailable() ([]string, []string, []string, []string, []string, map[strin
url := web.GetFullNodeUrl("index.json")

// Check the service to make sure the version is available
text := web.GetRemoteTextFile(url)
text, err := web.GetRemoteTextFile(url)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if len(text) == 0 {
fmt.Println("Error retrieving version list: \"" + url + "\" returned blank results. This can happen when the remote file is being updated. Please try again in a few minutes.")
os.Exit(0)
}

// Parse
var data = make([]map[string]interface{}, 0)
err := json.Unmarshal([]byte(text), &data)
err = json.Unmarshal([]byte(text), &data)
if err != nil {
fmt.Printf("Error retrieving versions from \"%s\": %v", url, err.Error())
os.Exit(1)
Expand Down
132 changes: 70 additions & 62 deletions src/nvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,10 @@ type Environment struct {

var home = filepath.Clean(os.Getenv("NVM_HOME") + "\\settings.txt")
var symlink = filepath.Clean(os.Getenv("NVM_SYMLINK"))
var root = filepath.Clean(os.Getenv("NVM_HOME"))

var env = &Environment{
settings: home,
root: root,
root: "",
symlink: symlink,
arch: strings.ToLower(os.Getenv("PROCESSOR_ARCHITECTURE")),
node_mirror: "",
Expand Down Expand Up @@ -228,23 +227,23 @@ func main() {
} else {
fmt.Println("\nCurrent Root: " + env.root)
}
case "-version":
case "v":
fallthrough
case "--version":
fallthrough
case "-version":
fallthrough
case "--v":
fallthrough
case "-v":
fallthrough
case "v":
fallthrough
case "version":
fmt.Println(NvmVersion)
case "arch":
if strings.Trim(detail, " \r\n") != "" {
detail = strings.Trim(detail, " \r\n")
if detail != "32" && detail != "64" && detail != "arm64" {
fmt.Println("\"" + detail + "\" is an invalid architecture. Use 32 or 64 or arm64.")
fmt.Println("\"" + detail + "\" is an invalid architecture. Use 32, 64, or arm64.")
return
}
env.arch = detail
Expand Down Expand Up @@ -314,8 +313,8 @@ func getVersion(version string, cpuarch string, localInstallsOnly ...bool) (stri
cpuarch = strings.ToLower(cpuarch)

if cpuarch != "" {
if cpuarch != "32" && cpuarch != "arm64" && cpuarch != "64" && cpuarch != "all" {
return version, cpuarch, errors.New("\"" + cpuarch + "\" is not a valid CPU architecture. Must be 32 or 64 or arm64.")
if cpuarch != "32" && cpuarch != "64" && cpuarch != "arm64" && cpuarch != "all" {
return version, cpuarch, errors.New("\"" + cpuarch + "\" is not a valid CPU architecture. Must be 32, 64, or arm64.")
}
} else {
cpuarch = env.arch
Expand Down Expand Up @@ -348,7 +347,7 @@ func getVersion(version string, cpuarch string, localInstallsOnly ...bool) (stri
version = installed[0]
}

if version == "32" || version == "arm64" || version == "64" {
if version == "32" || version == "64" || version == "arm64" {
cpuarch = version
v, _ := node.GetCurrentVersion()
version = v
Expand Down Expand Up @@ -541,17 +540,19 @@ func install(version string, cpuarch string) {
fmt.Println("Rollback complete.")
}

if cpuarch == "arm64" && !web.IsNodeArm64bitAvailable(version) {
fmt.Println("Node.js v" + version + " is only available in 64 and 32-bit.")
return
}
if cpuarch == "arm64" && !web.IsNodeArm64bitAvailable(version) {
status <- Status{Err: fmt.Errorf("Node.js v%s is only available in 32-bit and 64-bit.", version)}
}

// Check to see if the version is already installed
if !node.IsVersionInstalled(env.root, version, cpuarch) {
if !node.IsVersionAvailable(version) {
url := web.GetFullNodeUrl("index.json")
fmt.Println("\nVersion " + version + " is not available.\n\nThe complete list of available versions can be found at " + url)
return
if !node.IsVersionInstalled(env.root, version, cpuarch) {
if !node.IsVersionAvailable(version) {
url := web.GetFullNodeUrl("index.json")
status <- Status{Err: fmt.Errorf("Version %s is not available.\n\nThe complete list of available versions can be found at %s", version, url)}
}
}

return
}
}
}()

Expand Down Expand Up @@ -610,32 +611,24 @@ func install(version string, cpuarch string) {
}
}

// Download node
if (cpuarch == "arm64") && !node.IsVersionInstalled(env.root, version, "arm64") {
success := web.GetNodeJS(env.root, version, "arm64", false)
if !success {
os.RemoveAll(filepath.Join(env.root, "v"+version, "node_modules"))
fmt.Println("Could not download node.js v" + version + " arm64-bit executable.")
return
}
} else {
append32 := node.IsVersionInstalled(env.root, version, "64")
append64 := node.IsVersionInstalled(env.root, version, "32")
if (cpuarch == "32" || cpuarch == "all") && !node.IsVersionInstalled(env.root, version, "32") {
success := web.GetNodeJS(env.root, version, "32", append32)
if !success {
os.RemoveAll(filepath.Join(env.root, "v"+version, "node_modules"))
fmt.Println("Could not download node.js v" + version + " 32-bit executable.")
return
if err != nil {
if strings.Contains(err.Error(), "No Major.Minor.Patch") {
sv, sverr := semver.Make(version)
if sverr == nil {
sverr = sv.Validate()
}
}
if (cpuarch == "64" || cpuarch == "all") && !node.IsVersionInstalled(env.root, version, "64") {
success := web.GetNodeJS(env.root, version, "64", append64)
if !success {
os.RemoveAll(filepath.Join(env.root, "v"+version, "node_modules"))
fmt.Println("Could not download node.js v" + version + " 64-bit executable.")
return
if sverr != nil {
version = findLatestSubVersion(version)
if len(version) == 0 {
sverr = errors.New("Unrecognized version: \"" + requestedVersion + "\"")
}
}
err = sverr
}

if err != nil {
status <- Status{Err: err, Help: true}
return
}
}

Expand Down Expand Up @@ -929,7 +922,12 @@ func versionNumberFrom(version string) string {
if reg.MatchString(version[:1]) {
if version[0:1] != "v" {
url := web.GetFullNodeUrl("latest-" + version + "/SHASUMS256.txt")
content := strings.Split(web.GetRemoteTextFile(url), "\n")[0]
remoteContent, err := web.GetRemoteTextFile(url)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
content := strings.Split(remoteContent, "\n")[0]
if strings.Contains(content, "node") {
parts := strings.Split(content, "-")
if len(parts) > 1 {
Expand Down Expand Up @@ -1014,7 +1012,15 @@ func findLatestSubVersion(version string, localOnly ...bool) string {
}

url := web.GetFullNodeUrl("latest-v" + version + ".x" + "/SHASUMS256.txt")
content := web.GetRemoteTextFile(url)
content, err := web.GetRemoteTextFile(url)
if err != nil {
if strings.Contains(err.Error(), "HTTP Status 404") {
fmt.Printf("\"%s\" is not a valid version number (or partial version number).\n\nIf you are trying to install a version that was just announced within the last few minutes, it may not be available for download yet (try again in 15 minutes).\n", version)
} else {
fmt.Println(err)
}
os.Exit(1)
}
re := regexp.MustCompile("node-v(.+)+msi")
reg := regexp.MustCompile("node-v|-[xa].+")
latest := reg.ReplaceAllString(re.FindString(content), "")
Expand Down Expand Up @@ -1053,19 +1059,10 @@ func use(version string, cpuarch string, reload ...bool) {
notifications = true
}

// Check if a change is needed
curVersion, curCpuarch := node.GetCurrentVersion()
if version == curVersion && cpuarch == curCpuarch {
fmt.Println("node v" + version + " (" + cpuarch + "-bit) is already in use.")
return
}

// Make sure the version is installed. If not, warn.
if !node.IsVersionInstalled(env.root, version, cpuarch) {
fmt.Println("node v" + version + " (" + cpuarch + "-bit) is not installed.")
if cpuarch == "32" {
if node.IsVersionInstalled(env.root, version, "64") {
fmt.Println("\nDid you mean node v" + version + " (64-bit)?\nIf so, type \"nvm use " + version + " 64\" to use it.")
go func() {
defer func() {
if notifications {
time.Sleep(1 * time.Second)
}
wg.Done()
}()
Expand Down Expand Up @@ -1251,11 +1248,11 @@ func useArchitecture(a string) {
fmt.Println("This computer only supports 32-bit processing.")
return
}
if strings.Contains("arm64",strings.ToLower(os.Getenv("PROCESSOR_ARCHITECTURE"))) {
if strings.Contains("arm64", strings.ToLower(os.Getenv("PROCESSOR_ARCHITECTURE"))) {
fmt.Println("This computer only supports arm64-bit processing.")
return
}
if a == "32" || a == "64" || a == "arm64" {
if a == "32" || a == "64" {
env.arch = a
saveSettings()
fmt.Println("Set to " + a + "-bit mode")
Expand Down Expand Up @@ -1717,7 +1714,11 @@ func help() {
func checkVersionExceedsLatest(version string) bool {
//content := web.GetRemoteTextFile("http://nodejs.org/dist/latest/SHASUMS256.txt")
url := web.GetFullNodeUrl("latest/SHASUMS256.txt")
content := web.GetRemoteTextFile(url)
content, err := web.GetRemoteTextFile(url)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
re := regexp.MustCompile("node-v(.+)+msi")
reg := regexp.MustCompile("node-v|-[xa].+")
latest := reg.ReplaceAllString(re.FindString(content), "")
Expand Down Expand Up @@ -1766,7 +1767,11 @@ func getNpmVersion(nodeversion string) string {

func getLatest() string {
url := web.GetFullNodeUrl("latest/SHASUMS256.txt")
content := web.GetRemoteTextFile(url)
content, err := web.GetRemoteTextFile(url)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
re := regexp.MustCompile("node-v(.+)+msi")
reg := regexp.MustCompile("node-v|-[xa].+")
return reg.ReplaceAllString(re.FindString(content), "")
Expand Down Expand Up @@ -1945,6 +1950,9 @@ func setup() {
m[res[0]] = strings.TrimSpace(strings.Join(res[1:], ":"))
}

if val, ok := m["root"]; ok {
env.root = filepath.Clean(val)
}
if val, ok := m["originalpath"]; ok {
env.originalpath = filepath.Clean(val)
}
Expand Down
20 changes: 8 additions & 12 deletions src/web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,28 +319,24 @@ func GetNpm(root string, v string) bool {
}
}

func GetRemoteTextFile(url string) string {
func GetRemoteTextFile(url string) (string, error) {
response, httperr := client.Get(url)
if httperr != nil {
fmt.Println("\nCould not retrieve " + url + ".\n\n")
fmt.Printf("%s", httperr)
os.Exit(1)
return "", fmt.Errorf("Could not retrieve %v: %v", url, httperr)
}

if response.StatusCode != 200 {
fmt.Printf("Error retrieving \"%s\": HTTP Status %v\n", url, response.StatusCode)
os.Exit(0)
return "", fmt.Errorf("Error retrieving \"%s\": HTTP Status %v\n", url, response.StatusCode)
}

defer response.Body.Close()

contents, readerr := ioutil.ReadAll(response.Body)
if readerr != nil {
fmt.Printf("%s", readerr)
os.Exit(1)
return "", fmt.Errorf("error reading HTTP request body: %v", readerr)
}

return string(contents)
return string(contents), nil
}

func IsNode64bitAvailable(v string) bool {
Expand Down Expand Up @@ -369,14 +365,14 @@ func IsNodeArm64bitAvailable(v string) bool {
vers := strings.Fields(strings.Replace(v, ".", " ", -1))
main, _ := strconv.ParseInt(vers[0], 0, 0)
minor, _ := strconv.ParseInt(vers[1], 0, 0)
fmt.Println("main "+ strconv.FormatInt(main,10) + " minor "+strconv.FormatInt(minor,10))
fmt.Println("main " + strconv.FormatInt(main, 10) + " minor " + strconv.FormatInt(minor, 10))
if main < 19 {
return false
}
if main == 19 && minor < 9{
if main == 19 && minor < 9 {
return false
}

// TODO: fixme. Assume a 64 bit version exists
return true
}
Expand Down

0 comments on commit 12c9aa3

Please sign in to comment.