diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index e6c736c..5080066 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,7 +1,7 @@ # These are supported funding model platforms github: [coreybutler] -patreon: coreybutler +patreon: # coreybutler open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE index ed7a4d3..ffb6141 100644 --- a/.github/ISSUE_TEMPLATE +++ b/.github/ISSUE_TEMPLATE @@ -1,51 +1,68 @@ -Make sure you have reviewed the [common issues](https://github.com/coreybutler/nvm-windows/wiki/Common-Issues) and existing issues before submitting a new issue. + + +**NVM4W version:** ### My Environment -- [ ] Windows 7 or below (not truly supported due to EOL - see wiki for details) -- [ ] Windows 8 -- [ ] Windows 8.1 -- [ ] Windows 10 -- [ ] Windows 10 IoT Core -- [ ] Windows Server 2012 -- [ ] Windows Server 2012 R2 -- [ ] Windows Server 2016 + ### Expected Behavior -Fill me in... + ### Actual Behavior -Fill me in... + ### Steps to reproduce the problem: -Fill me in... + diff --git a/README.md b/README.md index 6ae27a1..6272c3e 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,17 @@ -The npm/Microsoft/Google recommended **Node.js version manager for _Windows_**. +The [npm](https://docs.npmjs.com/cli/v7/configuring-npm/install#windows-node-version-managers)/[Microsoft](https://docs.microsoft.com/en-us/windows/nodejs/setup-on-windows)/Google recommended **Node.js version manager for _Windows_**. -# This is not the same thing as [nvm](https://github.com/creationix/nvm), which is a completely separate project for Mac/Linux only. +# This is not the same thing as nvm. +_The original [nvm](https://github.com/nvm-sh/nvm) is a completely separate project for Mac/Linux only._ This project uses an entirely different philosophy and is not just a clone of nvm. Details are listed in the [Why another version manager?](https://github.com/coreybutler/nvm-windows#why-another-version-manager) and [what's the big difference?](https://github.com/coreybutler/nvm-windows#whats-the-big-difference) sections. -Like this project? Let people know with a [tweet](https://twitter.com/intent/tweet?hashtags=nodejs&original_referer=http%3A%2F%2F127.0.0.1%3A91%2F&text=Check%20out%20NVM%20for%20Windows!&tw_p=tweetbutton&url=http%3A%2F%2Fgithub.com%2Fcoreybutler%2Fnvm-windows&via=goldglovecb). - -Better yet, **click the "Sponsor" button** at the top of this screen. Patreon sponsors will receive patron-only update posts. +## Like this project? +Let people know with a [tweet](https://twitter.com/intent/tweet?hashtags=nodejs&original_referer=http%3A%2F%2F127.0.0.1%3A91%2F&text=Check%20out%20NVM%20for%20Windows!&tw_p=tweetbutton&url=http%3A%2F%2Fgithub.com%2Fcoreybutler%2Fnvm-windows&via=goldglovecb). Better yet, **click the "Sponsor" button** at the top of this screen. ## NOTICES -(2019-09-06) I am actively working on new Github actions to build releases. There are several great contributions in master (which contains the to-be-released 1.1.8 version), but I've always had to build these by hand.... and as many of you have noticed, my time has been extremely limited for quite awhile. The time consuming part is preparing the NSIS build, but once that is automated, it should be significantly easier for people to contribute changes _and actually see them released_. +This repository now uses [Github Discussions](https://github.com/coreybutler/nvm-windows/discussions) for updates. Sponsors also receive occasional email updates. The Gitter channel has been retired in favor of these new features. -Older notices have moved to the [notices wiki entry](https://github.com/coreybutler/nvm-windows/wiki/Notices). +Old notices have moved to the [notices wiki entry](https://github.com/coreybutler/nvm-windows/wiki/Notices). ## Common Issues & Resolutions @@ -19,15 +19,11 @@ Please see the [Common Issues](https://github.com/coreybutler/nvm-windows/wiki/C # Node Version Manager (nvm) for Windows -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/coreybutler/nvm-windows?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) (I post development updates here) - -![Issues](https://img.shields.io/github/issues/coreybutler/nvm-windows.svg) -![Stars](https://img.shields.io/github/stars/coreybutler/nvm-windows.svg) [![Open Source Helpers](https://www.codetriage.com/coreybutler/nvm-windows/badges/users.svg)](https://www.codetriage.com/coreybutler/nvm-windows) Manage multiple installations of node.js on a Windows computer. -**tl;dr** [nvm](https://github.com/creationix/nvm), but for Windows, with an installer. [Download Now](https://github.com/coreybutler/nvm-windows/releases)! This has always been a node version manager, not an io.js manager, so there is no back-support for io.js. However, node 4+ is supported. +**tl;dr** Similar (not identical) to [nvm](https://github.com/creationix/nvm), but for Windows. Has an installer. [Download Now](https://github.com/coreybutler/nvm-windows/releases)! This has always been a node version manager, not an io.js manager, so there is no back-support for io.js. However, node 4+ is supported. Remember when running `nvm install` or `nvm use`, you must have Windows administrative rights (to create symlinks). ![NVM for Windows](http://i.imgur.com/BNlcbi4.png) @@ -39,30 +35,29 @@ bleeding edge version without uninstalling the stable version of node, this util ### Installation & Upgrades -#### Uninstall existing node +#### _PREREQUISITE:_ Uninstall existing node & npm -Please note, you need to uninstall any existing versions of node.js before installing NVM for Windows. Also delete any existing nodejs installation directories (e.g., "C:\Program Files\nodejs") that might remain. NVM's generated symlink will not overwrite an existing (even empty) installation directory. +Uninstall any existing versions of Node.js before installing NVM for Windows (otherwise you'll have conflicting versions). Delete any existing Node.js installation directories (e.g., `%ProgramFiles%\nodejs`) that might remain. NVM's generated symlink will not overwrite an existing (even empty) installation directory. -#### Uninstall existing npm - -You should also delete the existing npm install location (e.g. "C:\Users\\<user>\\AppData\Roaming\npm") so that the nvm install location will be correctly used instead. +Backup any global `npmrc` config (e.g. `C:\Users\\AppData\Roaming\npm\etc\npmrc`), or copy the settings to the user config `C:\Users\\.npmrc`. Delete the existing npm install location (e.g. "C:\Users\\<user>\\AppData\Roaming\npm") to prevent global module conflicts. #### Install nvm-windows -nvm-windows comes with an installer (and uninstaller), because getting it should be easy. +[Download the latest installer](https://github.com/coreybutler/nvm/releases) (comes with an uninstaller). There is also a manual option (see [manual installation](https://github.com/coreybutler/nvm-windows/wiki#manual-installation) in the wiki). + +_If NVM4W doesn't appear to work immediately after installation, restart the terminal/powershell._ + +![NVM for Windows Installer](http://i.imgur.com/x8EzjSC.png) #### Reinstall any global utilities -After install, reinstalling global utilities (e.g. gulp) will have to be done for each installed version of node: +After install, reinstalling global utilities (e.g. yarn) will have to be done for each installed version of node: ``` -nvm use 4.4.0 -npm install gulp-cli -g -nvm use 0.10.33 -npm install gulp-cli -g +nvm use 14.0.0 +npm install -g yarn +nvm use 12.0.1 +npm install -g yarn ``` -[Download the latest installer from the releases](https://github.com/coreybutler/nvm/releases). - -![NVM for Windows Installer](http://i.imgur.com/x8EzjSC.png) ### Upgrading nvm-windows @@ -173,6 +168,15 @@ I chose Go because it is cross-platform, felt like less overhead than Java, has MIT. +## Sponsors + + + + + + +
+ ## Thanks Thanks to everyone who has submitted issues on and off Github, made suggestions, and generally helped make this a better project. Special thanks to diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 0000000..75d49ed --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,14 @@ +# Need Help? + +If you're running into problems using NVM4W, try the following resources. + +1. Review the [wiki](https://github.com/coreybutler/nvm-windows/wiki). +1. Join ongoing [discussions](https://github.com/coreybutler/nvm-windows/discussions). +1. Search [closed issues](https://github.com/coreybutler/nvm-windows/issues?q=is%3Aissue+is%3Aclosed) for existing solutions. +1. Search [StackOverflow ([nvm-windows])](https://stackoverflow.com/questions/tagged/nvm-windows) for answers. + +There are also a number of [YouTube videos](https://www.youtube.com/results?search_query=NVM+for+Windows) and blogs online that show how to use NVM for Windows. + +If none of these things help and you suspect a bug, file an issue. + +You can also try reaching out to [@goldglovecb](https://twitter.com/goldglovecb) on Twitter. diff --git a/bin/elevate.cmd b/bin/elevate.cmd index ba1bf4b..e168318 100644 --- a/bin/elevate.cmd +++ b/bin/elevate.cmd @@ -1,5 +1,12 @@ @setlocal @echo off + +:: Try without elevation, in case %NVM_SYMLINK% is a user-owned path and the +:: machine has Windows 10 Developer Mode enabled +%* +if %ERRORLEVEL% LSS 1 goto :EOF + +:: The command failed without elevation, try with elevation set CMD=%* set APP=%1 start wscript //nologo "%~dpn0.vbs" %* diff --git a/build.bat b/build.bat index 4094f4a..600028e 100644 --- a/build.bat +++ b/build.bat @@ -16,13 +16,13 @@ echo Building nvm.exe go build src\nvm.go REM Group the file with the helper binaries -move nvm.exe %GOBIN% +move nvm.exe "%GOBIN%" REM Codesign the executable -.\buildtools\signtools\x64\signtool.exe sign /debug /tr http://timestamp.digicert.com /td sha256 /fd sha256 /a %GOBIN%\nvm.exe +.\buildtools\signtools\x64\signtool.exe sign /debug /tr http://timestamp.digicert.com /td sha256 /fd sha256 /a "%GOBIN%\nvm.exe" -for /f %%i in ('%GOBIN%\nvm.exe version') do set AppVersion=%%i +for /f %%i in ('"%GOBIN%\nvm.exe" version') do set AppVersion=%%i echo nvm.exe v%AppVersion% built. REM Create the distribution folder @@ -38,10 +38,10 @@ REM Create the distribution directory mkdir "%DIST%" REM Create the "no install" zip version -for %%a in (%GOBIN%) do (buildtools\zip -j -9 -r "%DIST%\nvm-noinstall.zip" "%CD%\LICENSE" "%%a\*" -x "%GOBIN%\nodejs.ico") +for %%a in ("%GOBIN%") do (buildtools\zip -j -9 -r "%DIST%\nvm-noinstall.zip" "%CD%\LICENSE" %%a\* -x "%GOBIN%\nodejs.ico") REM Generate the installer (InnoSetup) -buildtools\iscc %INNOSETUP% /o%DIST% +buildtools\iscc "%INNOSETUP%" "/o%DIST%" buildtools\zip -j -9 -r "%DIST%\nvm-setup.zip" "%DIST%\nvm-setup.exe" REM Generate checksums diff --git a/buildtools/Default.isl b/buildtools/Default.isl index a2711fe..ce9b70e 100644 --- a/buildtools/Default.isl +++ b/buildtools/Default.isl @@ -1,7 +1,7 @@ -; *** Inno Setup version 5.5.3+ English messages *** +; *** Inno Setup version 6.1.0+ English messages *** ; ; To download user-contributed translations of this file, go to: -; http://www.jrsoftware.org/files/istrans/ +; https://jrsoftware.org/files/istrans/ ; ; Note: When translating this text, do not add periods (.) to the end of ; messages that didn't have them already, because on those messages Inno @@ -42,6 +42,7 @@ ErrorTitle=Error SetupLdrStartupMessage=This will install %1. Do you wish to continue? LdrCannotCreateTemp=Unable to create a temporary file. Setup aborted LdrCannotExecTemp=Unable to execute file in the temporary directory. Setup aborted +HelpTextNote= ; *** Startup error messages LastErrorMessage=%1.%n%nError %2: %3 @@ -55,7 +56,6 @@ WindowsServicePackRequired=This program requires %1 Service Pack %2 or later. NotOnThisPlatform=This program will not run on %1. OnlyOnThisPlatform=This program must be run on %1. OnlyOnTheseArchitectures=This program can only be installed on versions of Windows designed for the following processor architectures:%n%n%1 -MissingWOW64APIs=The version of Windows you are running does not include functionality required by Setup to perform a 64-bit installation. To correct this problem, please install Service Pack %1. WinVersionTooLowError=This program requires %1 version %2 or later. WinVersionTooHighError=This program cannot be installed on %1 version %2 or later. AdminPrivilegesRequired=You must be logged in as an administrator when installing this program. @@ -63,6 +63,16 @@ PowerUserPrivilegesRequired=You must be logged in as an administrator or as a me SetupAppRunningError=Setup has detected that %1 is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit. UninstallAppRunningError=Uninstall has detected that %1 is currently running.%n%nPlease close all instances of it now, then click OK to continue, or Cancel to exit. +; *** Startup questions +PrivilegesRequiredOverrideTitle=Select Setup Install Mode +PrivilegesRequiredOverrideInstruction=Select install mode +PrivilegesRequiredOverrideText1=%1 can be installed for all users (requires administrative privileges), or for you only. +PrivilegesRequiredOverrideText2=%1 can be installed for you only, or for all users (requires administrative privileges). +PrivilegesRequiredOverrideAllUsers=Install for &all users +PrivilegesRequiredOverrideAllUsersRecommended=Install for &all users (recommended) +PrivilegesRequiredOverrideCurrentUser=Install for &me only +PrivilegesRequiredOverrideCurrentUserRecommended=Install for &me only (recommended) + ; *** Misc. errors ErrorCreatingDir=Setup was unable to create the directory "%1" ErrorTooManyFilesInDir=Unable to create a file in the directory "%1" because it contains too many files @@ -93,7 +103,7 @@ ButtonNewFolder=&Make New Folder ; *** "Select Language" dialog messages SelectLanguageTitle=Select Setup Language -SelectLanguageLabel=Select the language to use during the installation: +SelectLanguageLabel=Select the language to use during the installation. ; *** Common wizard text ClickNext=Click Next to continue, or Cancel to exit Setup. @@ -141,6 +151,7 @@ WizardSelectDir=Select Destination Location SelectDirDesc=Where should [name] be installed? SelectDirLabel3=Setup will install [name] into the following folder. SelectDirBrowseLabel=To continue, click Next. If you would like to select a different folder, click Browse. +DiskSpaceGBLabel=At least [gb] GB of free disk space is required. DiskSpaceMBLabel=At least [mb] MB of free disk space is required. CannotInstallToNetworkDrive=Setup cannot install to a network drive. CannotInstallToUNCPath=Setup cannot install to a UNC path. @@ -168,6 +179,7 @@ NoUninstallWarningTitle=Components Exist NoUninstallWarning=Setup has detected that the following components are already installed on your computer:%n%n%1%n%nDeselecting these components will not uninstall them.%n%nWould you like to continue anyway? ComponentSize1=%1 KB ComponentSize2=%1 MB +ComponentsDiskSpaceGBLabel=Current selection requires at least [gb] GB of disk space. ComponentsDiskSpaceMBLabel=Current selection requires at least [mb] MB of disk space. ; *** "Select Additional Tasks" wizard page @@ -198,6 +210,18 @@ ReadyMemoComponents=Selected components: ReadyMemoGroup=Start Menu folder: ReadyMemoTasks=Additional tasks: +; *** TDownloadWizardPage wizard page and DownloadTemporaryFile +DownloadingLabel=Downloading additional files... +ButtonStopDownload=&Stop download +StopDownload=Are you sure you want to stop the download? +ErrorDownloadAborted=Download aborted +ErrorDownloadFailed=Download failed: %1 %2 +ErrorDownloadSizeFailed=Getting size failed: %1 %2 +ErrorFileHash1=File hash failed: %1 +ErrorFileHash2=Invalid file hash: expected %1, found %2 +ErrorProgress=Invalid progress: %1 of %2 +ErrorFileSize=Invalid file size: expected %1, found %2 + ; *** "Preparing to Install" wizard page WizardPreparing=Preparing to Install PreparingDesc=Setup is preparing to install [name] on your computer. @@ -208,6 +232,7 @@ ApplicationsFound2=The following applications are using files that need to be up CloseApplications=&Automatically close the applications DontCloseApplications=&Do not close the applications ErrorCloseApplications=Setup was unable to automatically close all applications. It is recommended that you close all applications using files that need to be updated by Setup before continuing. +PrepareToInstallNeedsRestart=Setup must restart your computer. After restarting your computer, run Setup again to complete the installation of [name].%n%nWould you like to restart now? ; *** "Installing" wizard page WizardInstalling=Installing @@ -237,7 +262,10 @@ SelectDirectoryLabel=Please specify the location of the next disk. ; *** Installation phase messages SetupAborted=Setup was not completed.%n%nPlease correct the problem and run Setup again. -EntryAbortRetryIgnore=Click Retry to try again, Ignore to proceed anyway, or Abort to cancel installation. +AbortRetryIgnoreSelectAction=Select action +AbortRetryIgnoreRetry=&Try again +AbortRetryIgnoreIgnore=&Ignore the error and continue +AbortRetryIgnoreCancel=Cancel installation ; *** Installation status messages StatusClosingApplications=Closing applications... @@ -268,14 +296,24 @@ ErrorRegWriteKey=Error writing to registry key:%n%1\%2 ErrorIniEntry=Error creating INI entry in file "%1". ; *** File copying errors -FileAbortRetryIgnore=Click Retry to try again, Ignore to skip this file (not recommended), or Abort to cancel installation. -FileAbortRetryIgnore2=Click Retry to try again, Ignore to proceed anyway (not recommended), or Abort to cancel installation. +FileAbortRetryIgnoreSkipNotRecommended=&Skip this file (not recommended) +FileAbortRetryIgnoreIgnoreNotRecommended=&Ignore the error and continue (not recommended) SourceIsCorrupted=The source file is corrupted SourceDoesntExist=The source file "%1" does not exist -ExistingFileReadOnly=The existing file is marked as read-only.%n%nClick Retry to remove the read-only attribute and try again, Ignore to skip this file, or Abort to cancel installation. +ExistingFileReadOnly2=The existing file could not be replaced because it is marked read-only. +ExistingFileReadOnlyRetry=&Remove the read-only attribute and try again +ExistingFileReadOnlyKeepExisting=&Keep the existing file ErrorReadingExistingDest=An error occurred while trying to read the existing file: -FileExists=The file already exists.%n%nWould you like Setup to overwrite it? -ExistingFileNewer=The existing file is newer than the one Setup is trying to install. It is recommended that you keep the existing file.%n%nDo you want to keep the existing file? +FileExistsSelectAction=Select action +FileExists2=The file already exists. +FileExistsOverwriteExisting=&Overwrite the existing file +FileExistsKeepExisting=&Keep the existing file +FileExistsOverwriteOrKeepAll=&Do this for the next conflicts +ExistingFileNewerSelectAction=Select action +ExistingFileNewer2=The existing file is newer than the one Setup is trying to install. +ExistingFileNewerOverwriteExisting=&Overwrite the existing file +ExistingFileNewerKeepExisting=&Keep the existing file (recommended) +ExistingFileNewerOverwriteOrKeepAll=&Do this for the next conflicts ErrorChangingAttr=An error occurred while trying to change the attributes of the existing file: ErrorCreatingTemp=An error occurred while trying to create a file in the destination directory: ErrorReadingSource=An error occurred while trying to read the source file: @@ -287,6 +325,16 @@ ErrorRegisterServer=Unable to register the DLL/OCX: %1 ErrorRegSvr32Failed=RegSvr32 failed with exit code %1 ErrorRegisterTypeLib=Unable to register the type library: %1 +; *** Uninstall display name markings +; used for example as 'My Program (32-bit)' +UninstallDisplayNameMark=%1 (%2) +; used for example as 'My Program (32-bit, All users)' +UninstallDisplayNameMarks=%1 (%2, %3) +UninstallDisplayNameMark32Bit=32-bit +UninstallDisplayNameMark64Bit=64-bit +UninstallDisplayNameMarkAllUsers=All users +UninstallDisplayNameMarkCurrentUser=Current user + ; *** Post-installation errors ErrorOpeningReadme=An error occurred while trying to open the README file. ErrorRestartingComputer=Setup was unable to restart the computer. Please do this manually. diff --git a/buildtools/ISCmplr.dll b/buildtools/ISCmplr.dll index 6b40678..35e8cf4 100644 Binary files a/buildtools/ISCmplr.dll and b/buildtools/ISCmplr.dll differ diff --git a/buildtools/ISPP.dll b/buildtools/ISPP.dll index 5a02b92..42b51a7 100644 Binary files a/buildtools/ISPP.dll and b/buildtools/ISPP.dll differ diff --git a/buildtools/ISPPBuiltins.iss b/buildtools/ISPPBuiltins.iss index d233fb4..f7f6d0d 100644 --- a/buildtools/ISPPBuiltins.iss +++ b/buildtools/ISPPBuiltins.iss @@ -1,15 +1,10 @@ -; BEGIN ISPPBUILTINS.ISS +// Inno Setup Preprocessor // -// Inno Setup Preprocessor 5 +// Inno Setup (C) 1997-2020 Jordan Russell. All Rights Reserved. +// Portions Copyright (C) 2000-2020 Martijn Laan. All Rights Reserved. +// Portions Copyright (C) 2001-2004 Alex Yackimoff. All Rights Reserved. // -// Copyright (C) 2001-2004 Alex Yackimoff. All Rights Reserved. -// Portions by Martijn Laan. -// http://ispp.sourceforge.net -// -// Inno Setup (C) 1997-2009 Jordan Russell. All Rights Reserved. -// Portions by Martijn Laan. -// -// $Id: ISPPBuiltins.iss,v 1.3 2010/12/29 15:20:26 mlaan Exp $ +// See the ISPP help file for more documentation of the functions defined by this file // #if defined(ISPP_INVOKED) && !defined(_BUILTINS_ISS_) // @@ -19,55 +14,37 @@ // #define _BUILTINS_ISS_ // -// =========================================================================== -// -// Default states for options. -// -//#pragma parseroption -b+ ; short circuit boolean evaluation: on -//#pragma parseroption -m- ; short circuit multiplication evaluation (0 * A will not eval A): off -//#pragma parseroption -p+ ; string literals without escape sequences: on -//#pragma parseroption -u- ; allow undeclared identifiers: off -//#pragma option -c+ ; pass script to the compiler: on -//#pragma option -e- ; emit empty lines to translation: off -//#pragma option -v- ; verbose mode: off -// -// --------------------------------------------------------------------------- -// -// Verbose levels: -// 0 - #include and #file acknowledgements -// 1 - information about any temp files created by #file -// 2 - #insert and #append acknowledgements -// 3 - reserved -// 4 - #dim, #define and #undef acknowledgements -// 5 - reserved -// 6 - conditional inclusion acknowledgements -// 7 - reserved -// 8 - show strings emitted with #emit directive -// 9 - macro and functions successfull call acknowledgements -//10 - Local macro array allocation acknowledgements -// -//#pragma verboselevel 0 -// -#ifndef __POPT_P__ -# define private CStrings -# pragma parseroption -p+ +#ifdef __OPT_E__ +# define private EnableOptE +# pragma option -e- #endif -// + +#ifndef __POPT_P__ +# define private DisablePOptP +#else +# pragma parseroption -p- +#endif + +#define NewLine "\n" +#define Tab "\t" + +#pragma parseroption -p+ + #pragma spansymbol "\" -// + #define True 1 #define False 0 #define Yes True #define No False -// -#define MaxInt 0x7FFFFFFFL -#define MinInt 0x80000000L -// + +#define MaxInt 0x7FFFFFFFFFFFFFFFL +#define MinInt 0x8000000000000000L + #define NULL #define void -// + // TypeOf constants -// + #define TYPE_ERROR 0 #define TYPE_NULL 1 #define TYPE_INTEGER 2 @@ -75,15 +52,15 @@ #define TYPE_MACRO 4 #define TYPE_FUNC 5 #define TYPE_ARRAY 6 -// + // Helper macro to find out the type of an array element or expression. TypeOf // standard function only allows identifier as its parameter. Use this macro // to convert an expression to identifier. -// + #define TypeOf2(any Expr) TypeOf(Expr) -// + // ReadReg constants -// + #define HKEY_CLASSES_ROOT 0x80000000UL #define HKEY_CURRENT_USER 0x80000001UL #define HKEY_LOCAL_MACHINE 0x80000002UL @@ -94,7 +71,7 @@ #define HKEY_LOCAL_MACHINE_64 0x82000002UL #define HKEY_USERS_64 0x82000003UL #define HKEY_CURRENT_CONFIG_64 0x82000005UL -// + #define HKCR HKEY_CLASSES_ROOT #define HKCU HKEY_CURRENT_USER #define HKLM HKEY_LOCAL_MACHINE @@ -105,9 +82,9 @@ #define HKLM64 HKEY_LOCAL_MACHINE_64 #define HKU64 HKEY_USERS_64 #define HKCC64 HKEY_CURRENT_CONFIG_64 -// + // Exec constants -// + #define SW_HIDE 0 #define SW_SHOWNORMAL 1 #define SW_NORMAL 1 @@ -122,9 +99,9 @@ #define SW_RESTORE 9 #define SW_SHOWDEFAULT 10 #define SW_MAX 10 -// + // Find constants -// + #define FIND_MATCH 0x00 #define FIND_BEGINS 0x01 #define FIND_ENDS 0x02 @@ -135,9 +112,9 @@ #define FIND_OR 0x08 #define FIND_NOT 0x10 #define FIND_TRIM 0x20 -// + // FindFirst constants -// + #define faReadOnly 0x00000001 #define faHidden 0x00000002 #define faSysFile 0x00000004 @@ -146,9 +123,9 @@ #define faArchive 0x00000020 #define faSymLink 0x00000040 #define faAnyFile 0x0000003F -// + // GetStringFileInfo standard names -// + #define COMPANY_NAME "CompanyName" #define FILE_DESCRIPTION "FileDescription" #define FILE_VERSION "FileVersion" @@ -157,72 +134,77 @@ #define ORIGINAL_FILENAME "OriginalFilename" #define PRODUCT_NAME "ProductName" #define PRODUCT_VERSION "ProductVersion" -// + // GetStringFileInfo helpers -// + #define GetFileCompany(str FileName) GetStringFileInfo(FileName, COMPANY_NAME) -#define GetFileCopyright(str FileName) GetStringFileInfo(FileName, LEGAL_COPYRIGHT) #define GetFileDescription(str FileName) GetStringFileInfo(FileName, FILE_DESCRIPTION) -#define GetFileProductVersion(str FileName) GetStringFileInfo(FileName, PRODUCT_VERSION) #define GetFileVersionString(str FileName) GetStringFileInfo(FileName, FILE_VERSION) -// -// ParseVersion -// -// Macro internally calls GetFileVersion function and parses string returned -// by that function (in form "0.0.0.0"). All four version elements are stored -// in by-reference parameters Major, Minor, Rev, and Build. Macro returns -// string returned by GetFileVersion. -// +#define GetFileCopyright(str FileName) GetStringFileInfo(FileName, LEGAL_COPYRIGHT) +#define GetFileOriginalFilename(str FileName) GetStringFileInfo(FileName, ORIGINAL_FILENAME) +#define GetFileProductVersion(str FileName) GetStringFileInfo(FileName, PRODUCT_VERSION) + #define DeleteToFirstPeriod(str *S) \ Local[1] = Copy(S, 1, (Local[0] = Pos(".", S)) - 1), \ S = Copy(S, Local[0] + 1), \ Local[1] -// -#define ParseVersion(str FileName, *Major, *Minor, *Rev, *Build) \ - Local[1] = Local[0] = GetFileVersion(FileName), \ + +#define GetVersionComponents(str FileName, *Major, *Minor, *Rev, *Build) \ + Local[1] = Local[0] = GetVersionNumbersString(FileName), \ Local[1] == "" ? "" : ( \ Major = Int(DeleteToFirstPeriod(Local[1])), \ Minor = Int(DeleteToFirstPeriod(Local[1])), \ Rev = Int(DeleteToFirstPeriod(Local[1])), \ Build = Int(Local[1]), \ Local[0]) -// -// EncodeVer -// -// Encodes given four version elements to a 32 bit integer number (8 bits for -// each element, i.e. elements must be within 0...255 range). -// + +#define GetPackedVersion(str FileName, *Version) \ + Local[0] = GetVersionComponents(FileName, Local[1], Local[2], Local[3], Local[4]), \ + Version = PackVersionComponents(Local[1], Local[2], Local[3], Local[4]), \ + Local[0] + +#define GetVersionNumbers(str FileName, *MS, *LS) \ + Local[0] = GetPackedVersion(FileName, Local[1]), \ + UnpackVersionNumbers(Local[1], MS, LS), \ + Local[0] + +#define PackVersionNumbers(int VersionMS, int VersionLS) \ + VersionMS << 32 | (VersionLS & 0xFFFFFFFF) + +#define PackVersionComponents(int Major, int Minor, int Rev, int Build) \ + Major << 48 | (Minor & 0xFFFF) << 32 | (Rev & 0xFFFF) << 16 | (Build & 0xFFFF) + +#define UnpackVersionNumbers(int Version, *VersionMS, *VersionLS) \ + VersionMS = Version >> 32, \ + VersionLS = Version & 0xFFFFFFFF, \ + void + +#define UnpackVersionComponents(int Version, *Major, *Minor, *Rev, *Build) \ + Major = Version >> 48, \ + Minor = (Version >> 32) & 0xFFFF, \ + Rev = (Version >> 16) & 0xFFFF, \ + Build = Version & 0xFFFF, \ + void + +#define VersionToStr(int Version) \ + Str(Version >> 48 & 0xFFFF) + "." + Str(Version >> 32 & 0xFFFF) + "." + \ + Str(Version >> 16 & 0xFFFF) + "." + Str(Version & 0xFFFF) + #define EncodeVer(int Major, int Minor, int Revision = 0, int Build = -1) \ - Major << 24 | (Minor & 0xFF) << 16 | (Revision & 0xFF) << 8 | (Build >= 0 ? Build & 0xFF : 0) -// -// DecodeVer -// -// Decodes given 32 bit integer encoded version to its string representation, -// Digits parameter indicates how many elements to show (if the fourth element -// is 0, it won't be shown anyway). -// -#define DecodeVer(int Ver, int Digits = 3) \ - Str(Ver >> 0x18 & 0xFF) + (Digits > 1 ? "." : "") + \ + (Major & 0xFF) << 24 | (Minor & 0xFF) << 16 | (Revision & 0xFF) << 8 | (Build >= 0 ? Build & 0xFF : 0) + +#define DecodeVer(int Version, int Digits = 3) \ + Str(Version >> 24 & 0xFF) + (Digits > 1 ? "." : "") + \ (Digits > 1 ? \ - Str(Ver >> 0x10 & 0xFF) + (Digits > 2 ? "." : "") : "") + \ + Str(Version >> 16 & 0xFF) + (Digits > 2 ? "." : "") : "") + \ (Digits > 2 ? \ - Str(Ver >> 0x08 & 0xFF) + (Digits > 3 && (Local = Ver & 0xFF) ? "." : "") : "") + \ + Str(Version >> 8 & 0xFF) + (Digits > 3 && (Local = Version & 0xFF) ? "." : "") : "") + \ (Digits > 3 && Local ? \ - Str(Ver & 0xFF) : "") -// -// FindSection -// -// Returns index of the line following the header of the section. This macro -// is intended to be used with #insert directive. -// + Str(Version & 0xFF) : "") + #define FindSection(str Section = "Files") \ Find(0, "[" + Section + "]", FIND_MATCH | FIND_TRIM) + 1 -// -// FindSectionEnd -// -// Returns index of the line following last entry of the section. This macro -// is intended to be used with #insert directive. -// + #if VER >= 0x03000000 # define FindNextSection(int Line) \ Find(Line, "[", FIND_BEGINS | FIND_TRIM, "]", FIND_ENDS | FIND_AND) @@ -232,23 +214,12 @@ # define FindSectionEnd(str Section = "Files") \ FindSection(Section) + EntryCount(Section) #endif -// -// FindCode -// -// Returns index of the line (of translation) following either [Code] section -// header, or "program" keyword, if any. -// + #define FindCode() \ Local[1] = FindSection("Code"), \ Local[0] = Find(Local[1] - 1, "program", FIND_BEGINS, ";", FIND_ENDS | FIND_AND), \ (Local[0] < 0 ? Local[1] : Local[0] + 1) -// -// ExtractFilePath -// -// Returns directory portion of the given filename without backslash (unless -// it is a root directory). If PathName doesn't contain directory portion, -// the result is an empty string. -// + #define ExtractFilePath(str PathName) \ (Local[0] = \ !(Local[1] = RPos("\", PathName)) ? \ @@ -258,54 +229,32 @@ ((Local[2] = Len(Local[0])) == 2 && Copy(Local[0], Local[2]) == ":" ? \ "\" : \ "") + #define ExtractFileDir(str PathName) \ RemoveBackslash(ExtractFilePath(PathName)) #define ExtractFileExt(str PathName) \ Local[0] = RPos(".", PathName), \ Copy(PathName, Local[0] + 1) -// -// ExtractFileName -// -// Returns name portion of the given filename. If PathName ends with -// a backslash, the result is an empty string. -// + #define ExtractFileName(str PathName) \ !(Local[0] = RPos("\", PathName)) ? \ PathName : \ Copy(PathName, Local[0] + 1) -// -// ChangeFileExt -// -// Changes extension in FileName with NewExt. NewExt must not contain -// period. -// + #define ChangeFileExt(str FileName, str NewExt) \ !(Local[0] = RPos(".", FileName)) ? \ FileName + "." + NewExt : \ Copy(FileName, 1, Local[0]) + NewExt -// -// RemoveFileExt -// -// Removes extension in FileName. -// + #define RemoveFileExt(str FileName) \ !(Local[0] = RPos(".", FileName)) ? \ FileName : \ Copy(FileName, 1, Local[0] - 1) -// -// AddBackslash -// -// Adds a backslash to the string, if it's not already there. -// + #define AddBackslash(str S) \ Copy(S, Len(S)) == "\" ? S : S + "\" -// -// RemoveBackslash -// -// Removes trailing backslash from the string unless the string points to -// a root directory. -// + #define RemoveBackslash(str S) \ Local[0] = Len(S), \ Local[0] > 0 ? \ @@ -315,52 +264,52 @@ Copy(S, 1, Local[0] - 1)) : \ S : \ "" -// -// Delete -// -// Deletes specified number of characters beginning with Index from S. S is -// passed by reference (therefore is modified). Acts like Delete function in -// Delphi (from System unit). -// + #define Delete(str *S, int Index, int Count = MaxInt) \ S = Copy(S, 1, Index - 1) + Copy(S, Index + Count) -// -// Insert -// -// Inserts specified Substr at Index'th character into S. S is passed by -// reference (therefore is modified). -// + #define Insert(str *S, int Index, str Substr) \ Index > Len(S) + 1 ? \ S : \ S = Copy(S, 1, Index - 1) + SubStr + Copy(S, Index) -// -// YesNo, IsDirSet -// -// Returns nonzero value if given string is "yes", "true" or "1". Intended to -// be used with SetupSetting function. This macro replaces YesNo function -// available in previous releases. -// + #define YesNo(str S) \ (S = LowerCase(S)) == "yes" || S == "true" || S == "1" -// + #define IsDirSet(str SetupDirective) \ YesNo(SetupSetting(SetupDirective)) -// -// + #define Power(int X, int P = 2) \ !P ? 1 : X * Power(X, P - 1) -// + #define Min(int A, int B, int C = MaxInt) \ A < B ? A < C ? Int(A) : Int(C) : Int(B) -// + #define Max(int A, int B, int C = MinInt) \ A > B ? A > C ? Int(A) : Int(C) : Int(B) -// -#ifdef CStrings +#define SameText(str S1, str S2) \ + LowerCase(S1) == LowerCase(S2) + +#define SameStr(str S1, str S2) \ + S1 == S2 + +#define WarnRenamedVersion(str OldName, str NewName) \ + Warning("Function """ + OldName + """ has been renamed. Use """ + NewName + """ instead.") + +#define ParseVersion(str FileName, *Major, *Minor, *Rev, *Build) \ + WarnRenamedVersion("ParseVersion", "GetVersionComponents"), \ + GetVersionComponents(FileName, Major, Minor, Rev, Build) + +#define GetFileVersion(str FileName) \ + WarnRenamedVersion("GetFileVersion", "GetVersionNumbersString"), \ + GetVersionNumbersString(FileName) + +#ifdef DisablePOptP # pragma parseroption -p- #endif -#endif -; END ISPPBUILTINS.ISS +#ifdef EnableOptE +# pragma option -e+ +#endif +#endif \ No newline at end of file diff --git a/buildtools/Setup.e32 b/buildtools/Setup.e32 index e3e9107..7fcf47c 100644 Binary files a/buildtools/Setup.e32 and b/buildtools/Setup.e32 differ diff --git a/buildtools/SetupLdr.e32 b/buildtools/SetupLdr.e32 index d3e577c..9bf36ba 100644 Binary files a/buildtools/SetupLdr.e32 and b/buildtools/SetupLdr.e32 differ diff --git a/buildtools/iscc.exe b/buildtools/iscc.exe index 498c5e6..37c6e1b 100644 Binary files a/buildtools/iscc.exe and b/buildtools/iscc.exe differ diff --git a/buildtools/islzma.dll b/buildtools/islzma.dll index fba2bf8..81fd05a 100644 Binary files a/buildtools/islzma.dll and b/buildtools/islzma.dll differ diff --git a/buildtools/zip.exe b/buildtools/zip.exe index ee3a4c6..aff7be8 100644 Binary files a/buildtools/zip.exe and b/buildtools/zip.exe differ diff --git a/src/nvm.go b/src/nvm.go index aff7b25..36304dc 100644 --- a/src/nvm.go +++ b/src/nvm.go @@ -18,6 +18,7 @@ import ( "./nvm/arch" "./nvm/file" "./nvm/node" + "github.com/blang/semver" "github.com/olekukonko/tablewriter" ) @@ -116,7 +117,16 @@ func main() { env.proxy = detail saveSettings() } - + case "current": + inuse, _ := node.GetCurrentVersion() + v, _ := semver.Make(inuse) + err := v.Validate() + if err == nil { + fmt.Println("v" + inuse) + } else { + fmt.Println(inuse) + } + //case "update": update() case "node_mirror": setNodeMirror(detail) case "npm_mirror": setNpmMirror(detail) @@ -182,18 +192,22 @@ func install(version string, cpuarch string) { cpuarch = arch.Validate(cpuarch) } - // If user specifies "latest" version, find out what version is + // If user specifies "latest" or "lts" (latest LTS) version, find out what version is if version == "latest" { url := web.GetFullNodeUrl("latest/SHASUMS256.txt"); content := web.GetRemoteTextFile(url) re := regexp.MustCompile("node-v(.+)+msi") reg := regexp.MustCompile("node-v|-x.+") version = reg.ReplaceAllString(re.FindString(content),"") + } else if version == "lts" { + _, ltsList, _, _, _, _ := node.GetAvailable() + // ltsList has already been numerically sorted + version = ltsList[0] } // if the user specifies only the major version number then install the latest // version of the major version number - if len(version) == 1 { + if !strings.Contains(version, ".") { version = findLatestSubVersion(version) } else { version = cleanVersion(version) @@ -371,7 +385,15 @@ func findLatestSubVersion(version string) string { } func use(version string, cpuarch string) { - if version == "32" || version == "64" { + if version == "latest" { + installed := node.GetInstalled(env.root) + if len(installed) == 0 { + fmt.Println("No versions of node.js found. Try installing the latest by typing nvm install latest") + return + } + + version = installed[0] + } else if version == "32" || version == "64" { cpuarch = version v, _ := node.GetCurrentVersion() version = v @@ -539,7 +561,7 @@ func list(listtype string) { 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") + fmt.Println("\nThis is a partial list. For a complete list, visit https://nodejs.org/download/releases") } } @@ -577,7 +599,7 @@ func help() { fmt.Println("\nUsage:") fmt.Println(" ") fmt.Println(" nvm arch : Show if node is running in 32 or 64 bit mode.") - fmt.Println(" nvm install [arch] : The version can be a node.js version or \"latest\" for the latest stable version.") + fmt.Println(" nvm install [arch] : The version can be a node.js version, \"latest\" for the latest stable version, or \"lts\" for the latest LTS.") fmt.Println(" Optionally specify whether to install the 32 or 64 bit version (defaults to system arch).") fmt.Println(" Set [arch] to \"all\" to install 32 AND 64 bit versions.") fmt.Println(" Add --insecure to the end of this command to bypass SSL validation of the remote download server.") @@ -590,7 +612,7 @@ func help() { fmt.Println(" nvm npm_mirror [url] : Set the npm mirror. Defaults to https://github.com/npm/cli/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.") + fmt.Println(" nvm use [version] [arch] : Switch to use the specified version or use \"latest\" to switch to the latest installed version. Optionally specify 32/64bit architecture.") fmt.Println(" nvm use will continue using the selected version, but switch to 32/64 bit mode.") fmt.Println(" nvm root [path] : Set the directory where nvm should store different versions of node.js.") fmt.Println(" If is not set, the current root will be displayed.") @@ -728,6 +750,7 @@ func setup() { // Process each line and extract the value var m map[string]string for _, line := range lines { + line = os.ExpandEnv(line) res := strings.Split(strings.TrimSpace(line), ":") if (len(res) != 2) { continue