From 7a4544317a35251ed40aa7c59b3f99b8c3a8f2c8 Mon Sep 17 00:00:00 2001 From: Corey Butler Date: Fri, 1 Jul 2016 19:34:56 -0500 Subject: [PATCH] Cleaned up PR's, added formatting for ls, updated installer to 1.1.1 --- LICENSE | 3 +- build.bat | 58 ++++++++++++------------ nvm.iss | 6 +-- src/nvm.go | 103 ++++++++++++++++++++++++++++++------------- src/nvm/node/node.go | 82 +++++++++++++++++++++++++++++----- 5 files changed, 180 insertions(+), 72 deletions(-) diff --git a/LICENSE b/LICENSE index 9aedf9a..e66cb5e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Corey Butler +Copyright (c) 2014 Corey Butler and contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/build.bat b/build.bat index ad95e17..166b842 100644 --- a/build.bat +++ b/build.bat @@ -4,53 +4,57 @@ SET ORIG=%CD% SET GOPATH=%CD%\src SET GOBIN=%CD%\bin SET GOARCH=386 +SET version=1.1.1 REM Get the version number from the setup file -for /f "tokens=*" %%i in ('findstr /n . %INNOSETUP% ^| findstr ^4:#define') do set L=%%i -set version=%L:~24,-1% +REM for /f "tokens=*" %%i in ('findstr /n . %INNOSETUP% ^| findstr ^4:#define') do set L=%%i +REM set version=%L:~24,-1% REM Get the version number from the core executable -for /f "tokens=*" %%i in ('findstr /n . %GOPATH%\nvm.go ^| findstr ^NvmVersion^| findstr ^21^') do set L=%%i -set goversion=%L:~19,-1% +REM for /f "tokens=*" %%i in ('findstr /n . %GOPATH%\nvm.go ^| findstr ^NvmVersion^| findstr ^21^') do set L=%%i +REM set goversion=%L:~19,-1% -IF NOT %version%==%goversion% GOTO VERSIONMISMATCH +REM IF NOT %version%==%goversion% GOTO VERSIONMISMATCH SET DIST=%CD%\dist\%version% REM Build the executable echo Building NVM for Windows -rm %GOBIN%\nvm.exe -cd %GOPATH% +REM rm %GOBIN%\nvm.exe +REM cd %GOPATH% echo "=========================================>" -echo %GOBIN% -goxc -arch="386" -os="windows" -n="nvm" -d="%GOBIN%" -o="%GOBIN%\nvm{{.Ext}}" -tasks-=package -cd %ORIG% -rm %GOBIN%\src.exe -rm %GOPATH%\src.exe -rm %GOPATH%\nvm.exe +REM echo %GOBIN% +REM goxc -arch="386" -os="windows" -n="nvm" -d="%GOBIN%" -o="%GOBIN%\nvm{{.Ext}}" -tasks-=package + +REM cd %ORIG% +REM rm %GOBIN%\src.exe +REM rm %GOPATH%\src.exe +REM rm %GOPATH%\nvm.exe REM Clean the dist directory rm -rf "%DIST%" mkdir "%DIST%" -REM Create the "noinstall" zip -echo Generating nvm-noinstall.zip +echo Creating distribution in %DIST% + +if exist src\nvm.exe ( + rm src\nvm.exe +) + +echo "Building nvm.exe...." + +go build src\nvm.go +mv nvm.exe %GOBIN% + +echo Building "noinstall" zip... for /d %%a in (%GOBIN%) do (buildtools\zip -j -9 -r "%DIST%\nvm-noinstall.zip" "%CD%\LICENSE" "%%a\*" -x "%GOBIN%\nodejs.ico") -REM Create the installer -echo Generating nvm-setup.zip +echo "Building the primary installer..." buildtools\iscc %INNOSETUP% /o%DIST% buildtools\zip -j -9 -r "%DIST%\nvm-setup.zip" "%DIST%\nvm-setup.exe" -REM rm "%DIST%\nvm-setup.exe" -echo -------------------------- -echo Release %version% available in %DIST% -GOTO COMPLETE -:VERSIONMISMATCH -echo The version number in nvm.iss does not match the version in src\nvm.go -echo - nvm.iss line #4: %version% -echo - nvm.go line #21: %goversion% -EXIT /B +echo "Distribution created. Now cleaning up...." +rm %GOBIN%/nvm.exe -:COMPLETE +echo "Done." @echo on diff --git a/nvm.iss b/nvm.iss index 54b20f8..83a7b83 100644 --- a/nvm.iss +++ b/nvm.iss @@ -1,8 +1,8 @@ #define MyAppName "NVM for Windows" #define MyAppShortName "nvm" #define MyAppLCShortName "nvm" -#define MyAppVersion "1.1.0" -#define MyAppPublisher "Ecor Ventures, LLC" +#define MyAppVersion "1.1.1" +#define MyAppPublisher "Ecor Ventures LLC" #define MyAppURL "http://github.com/coreybutler/nvm" #define MyAppExeName "nvm.exe" #define MyIcon "bin\nodejs.ico" @@ -35,7 +35,7 @@ ChangesEnvironment=yes DisableProgramGroupPage=yes ArchitecturesInstallIn64BitMode=x64 ia64 UninstallDisplayIcon={app}\{#MyIcon} -AppCopyright=Copyright (C) 2014 Corey Butler. +AppCopyright=Copyright (C) 2016 Corey Butler and contributors. [Languages] Name: "english"; MessagesFile: "compiler:Default.isl" diff --git a/src/nvm.go b/src/nvm.go index faca7c3..adc1053 100644 --- a/src/nvm.go +++ b/src/nvm.go @@ -8,16 +8,15 @@ import ( "io/ioutil" "regexp" "bytes" - "strconv" "./nvm/web" "./nvm/arch" "./nvm/file" "./nvm/node" -// "./ansi" + "github.com/olekukonko/tablewriter" ) const ( - NvmVersion = "1.1.0" + NvmVersion = "1.1.1" ) type Environment struct { @@ -159,7 +158,7 @@ func install(version string, cpuarch string) { if cpuarch != "all" { cpuarch = arch.Validate(cpuarch) } - + // If user specifies "latest" version, find out what version is if version == "latest" { url := web.GetFullNodeUrl("latest/SHASUMS256.txt"); @@ -173,7 +172,7 @@ func install(version string, cpuarch string) { fmt.Println("Node.js v"+version+" is not yet released or available.") return } - + if cpuarch == "64" && !web.IsNode64bitAvailable(version) { fmt.Println("Node.js v"+version+" is only available in 32-bit.") return @@ -262,6 +261,8 @@ func uninstall(version string) { return } + version = cleanVersion(version) + // Determine if the version exists and skip if it doesn't if node.IsVersionInstalled(env.root,version,"32") || node.IsVersionInstalled(env.root,version,"64") { fmt.Printf("Uninstalling node v"+version+"...") @@ -283,8 +284,25 @@ func uninstall(version string) { return } -func use(version string, cpuarch string) { +func cleanVersion(version string) string { + re := regexp.MustCompile("\\d+.\\d+.\\d+") + matched := re.FindString(version) + if len(matched) == 0 { + re = regexp.MustCompile("\\d+.\\d+") + matched = re.FindString(version) + if len(matched) == 0 { + matched = version + ".0.0" + } else { + matched = matched + ".0" + } + fmt.Println(matched) + } + + return matched +} + +func use(version string, cpuarch string) { if version == "32" || version == "64" { cpuarch = version v, _ := node.GetCurrentVersion() @@ -293,6 +311,10 @@ func use(version string, cpuarch string) { cpuarch = arch.Validate(cpuarch) + re := regexp.MustCompile("\\d+.\\d+.\\d+") + + version = cleanVersion(version) + // 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.") @@ -407,35 +429,56 @@ func list(listtype string) { fmt.Println("No installations recognized.") } } else { - _, lts, stable, _ := node.GetAvailable() + _, lts, current, stable, unstable, _ := node.GetAvailable() - releases := len(stable) - - fmt.Println("\nShowing the "+strconv.Itoa(releases)+" latest available releases.\n") - - fmt.Println(" LTS | STABLE ") - fmt.Println(" ---------------------------") + releases := 20 + data := make([][]string, releases, releases + 5) for i := 0; i < releases; i++ { - str := " " - if len(lts) > i { - str = "v"+lts[i] - for ii := 10-len(str); ii > 0; ii-- { - str = " "+str - } - } + release := make([]string, 4, 6) - str2 := "" - if len(stable) > i { - str2 = "v"+stable[i] - for ii := 10-len(str2); ii > 0; ii-- { - str2 = " "+str2 + release[0] = "" + release[1] = "" + release[2] = "" + release[3] = "" + + if len(current) > i { + if len(current[i]) > 0 { + release[0] = current[i] } } - fmt.Println(" "+str + " | " + str2) + + if len(lts) > i { + if len(lts[i]) > 0 { + release[1] = lts[i] + } + } + + if len(stable) > i { + if len(stable[i]) > 0 { + release[2] = stable[i] + } + } + + if len(unstable) > i { + if len(unstable[i]) > 0 { + release[3] = unstable[i] + } + } + + data[i] = release } - fmt.Println("\nFor a complete list, visit https://nodejs.org/download/release") + fmt.Println("") + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader([]string{" Current ", " LTS ", " Old Stable ", "Old Unstable"}) + table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false}) + table.SetAlignment(tablewriter.ALIGN_CENTER) + table.SetCenterSeparator("|") + table.AppendBulk(data) // Add Bulk Data + table.Render() + + fmt.Println("\nThis is a partial list. For a complete list, visit https://nodejs.org/download/release") } } @@ -477,8 +520,8 @@ func help() { fmt.Println(" nvm off : Disable node.js version management.") fmt.Println(" nvm proxy [url] : Set a proxy to use for downloads. Leave [url] blank to see the current proxy.") fmt.Println(" Set [url] to \"none\" to remove the proxy.") - fmt.Println(" nvm node_mirror [url] : Set a mirror to https://nodejs.org/dist/. Leave [url] blank to use default url.") - fmt.Println(" nvm npm_mirror [url] : Set a mirror to https://github.com/npm/npm/archive/. Leave [url] blank to default url.") + fmt.Println(" nvm node_mirror [url] : Set the node mirror. Defaults to https://nodejs.org/dist/. Leave [url] blank to use default url.") + fmt.Println(" nvm npm_mirror [url] : Set the npm mirror. Defaults to https://github.com/npm/npm/archive/. Leave [url] blank to default url.") fmt.Println(" nvm uninstall : The version must be a specific version.") // fmt.Println(" nvm update : Automatically update nvm to the latest version.") fmt.Println(" nvm use [version] [arch] : Switch to use the specified version. Optionally specify 32/64bit architecture.") @@ -492,7 +535,7 @@ func help() { // Given a node.js version, returns the associated npm version func getNpmVersion(nodeversion string) string { - _, _, _, npm := node.GetAvailable() + _, _, _, _, _, npm := node.GetAvailable() return npm[nodeversion] } diff --git a/src/nvm/node/node.go b/src/nvm/node/node.go index cc69525..d7268b2 100644 --- a/src/nvm/node/node.go +++ b/src/nvm/node/node.go @@ -69,7 +69,7 @@ func IsVersionInstalled(root string, version string, cpu string) bool { func IsVersionAvailable(v string) bool { // Check the service to make sure the version is available - avail, _, _, _ := GetAvailable() + avail, _, _, _, _, _ := GetAvailable() for _, b := range avail { if b == v { @@ -107,12 +107,73 @@ func (s BySemanticVersion) Less(i, j int) bool { return v1.GTE(v2) } -func GetAvailable() ([]string, []string, []string, map[string]string) { +// Identifies a version as "LTS" +func isLTS(element map[string]interface{}) bool { + switch datatype := element["lts"].(type) { + case bool: + return datatype + case string: + return true + } + return false +} + +// Identifies a version as "current" +func isCurrent(element map[string]interface{}) bool { + if isLTS(element) { + return false + } + + version, _ := semver.New(element["version"].(string)[1:]) + benchmark, _ := semver.New("1.0.0") + + if version.LT(benchmark) { + return false + } + + return version.Major%2 == 0 +} + +// Identifies a stable old version. +func isStable(element map[string]interface{}) bool { + if isCurrent(element) { + return false + } + + version, _ := semver.New(element["version"].(string)[1:]) + + if (version.Major != 0) { + return false + } + + return version.Minor%2 == 0 +} + +// Identifies an unstable old version. +func isUnstable(element map[string]interface{}) bool { + if isStable(element) { + return false + } + + version, _ := semver.New(element["version"].(string)[1:]) + + if (version.Major != 0) { + return false + } + + return version.Minor%2 != 0 +} + +// Retrieve the remotely available versions +func GetAvailable() ([]string, []string, []string, []string, []string, map[string]string) { all := make([]string,0) lts := make([]string,0) + current := make([]string,0) stable := make([]string,0) + unstable := make([]string,0) npm := make(map[string]string) url := web.GetFullNodeUrl("index.json") + // Check the service to make sure the version is available text := web.GetRemoteTextFile(url) @@ -120,7 +181,7 @@ func GetAvailable() ([]string, []string, []string, map[string]string) { var data = make([]map[string]interface{}, 0) json.Unmarshal([]byte(text), &data); - for _,element := range data { + for _, element := range data { var version = element["version"].(string)[1:] all = append(all, version) @@ -129,15 +190,16 @@ func GetAvailable() ([]string, []string, []string, map[string]string) { npm[version] = val } - switch v := element["lts"].(type) { - case bool: - if v == false { - stable = append(stable, version) - } - case string: + if isLTS(element) { lts = append(lts, version) + } else if isCurrent(element) { + current = append(current, version) + } else if isStable(element) { + stable = append(stable, version) + } else if isUnstable(element) { + unstable = append(unstable, version) } } - return all, lts, stable, npm + return all, lts, current, stable, unstable, npm }