Last active
March 4, 2024 13:56
-
-
Save euaaron/8b0a2497244b3711e65ad798bdc5873f to your computer and use it in GitHub Desktop.
Windows CLI - Powershell script to download and switch between different Nodejs versions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -------------------------------------------- | |
# Nodejs Version Manager Powershell (nmp) | |
# v1.0.2 | |
# Author: Aaron Carneiro <@euaaron> | |
# Email: nmp@aaroncarneiro.com | |
# GitHub: https://github.com/euaaron | |
# This File: https://gist.github.com/euaaron/8b0a2497244b3711e65ad798bdc5873f | |
# -------------------------------------------- | |
$nmpVersion = "v1.0.2" | |
$silentInit = $false | |
# To install just paste the code below to your Powershell $profile file and run: | |
# nmp -init -dir "C:\path\to\install" | |
# If you face Execution Policy error, try uncomment the line below or copy the code and run it on Powershell | |
# Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUser | |
# Learn more at https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-7.3 | |
# NMP depends on CreateDir and Test-CommandExists functions which are right below. | |
# These functions are also available for you to use on your Powershell if you want. | |
# If you don't want them to be exposed, just move them to inside nmp function | |
function CreateDir { | |
param( | |
[string] $Dir = "" | |
) | |
if (-Not $Dir -Contains "*:\") { | |
$tempDir = $Dir; | |
$Dir = ([System.Environment]::CurrentDirectory) | |
$Dir += "\" | |
$Dir += $tempDir; | |
} | |
if (-Not (Test-Path $Dir)) { | |
$dirPath = $Dir.Split("\"); | |
$currentPath = "" | |
$count = 0; | |
$dirPath | ForEach { | |
if (-Not ($dirPath[$count] -Eq "") -Or -Not ($dirPath[$count] -Eq "\")) { | |
$currentPath += $dirPath[$count] | |
$currentPath += "\" | |
$currentPath = $currentPath.Replace("\\", "\"); | |
if (-Not (Test-Path $currentPath) -And -Not ($currentPath -Eq "")) { | |
mkdir $currentPath | |
} | |
} | |
if (-Not ($dirPath.Length - 1 -Eq $count)) { | |
$count += 1; | |
} else { | |
Write-Host "Directory '$currentPath' has been created suceessfully!" | |
return; | |
} | |
} | |
} else { | |
Write-Host "Error! '$dir' already exists!" | |
} | |
return; | |
} | |
Function Test-CommandExists { | |
Param ($command, [switch] $silent) | |
$oldPreference = $ErrorActionPreference | |
$ErrorActionPreference = 'stop' | |
$exists = $false; | |
try { | |
if(Get-Command $command){ | |
$exists = $true | |
if (-Not $silent) { | |
Write-Host "Command $command exists!" | |
} | |
} | |
} | |
Catch { | |
$exists = $false | |
if (-Not $silent) { | |
Write-Host "Command $command was not found!" | |
} | |
} | |
$ErrorActionPreference=$oldPreference | |
return $exists; | |
} | |
function nmp { | |
param( | |
[string] $change = "", | |
[string] $arch = "win-x64", | |
[switch] $force, | |
[switch] $version, | |
[switch] $list, | |
[switch] $remote, | |
[switch] $help, | |
[switch] $init, | |
# Directory to install Nodejs versions | |
[string] $dir = "C:\Softwares\nodejs\", | |
# Default Nodejs version to use | |
[string] $default = "18" | |
) | |
function nInit { | |
# Creates this directory if not exists | |
if (-Not (Test-Path $dir)) { | |
CreateDir -Dir $dir | |
} | |
# Directory of Default Node Version | |
# If you already have Nodejs installed, set this path with your nodejs dir. It might be "C:\Program Files\nodejs\" | |
$defaultNodeDir = $dir + $default; | |
# This will change default installed Nodejs version with the new one in the path (also npm and npx that come pre-installed with nodejs) | |
$systemPath = $env:Path | |
$systemPath = $systemPath.Replace('C:\Program Files\nodejs\;', $defaultNodeDir + "\;"); | |
$env:Path = $systemPath; | |
# If you don't had NodeJs installed previously, remove the three lines above and uncomment the line bellow | |
# $env:Path += $defaultNodeDir; | |
} | |
# This function will switch current terminal to use a different Nodejs version. | |
# It will first check at $dir, if not found it will try to install directly from nodejs.org. | |
function nChange { | |
param ( | |
[string] $version = '', | |
[string] $arch = "win-x64", | |
$force = $false | |
) | |
if ($version -ne '') { | |
$versionDir = $dir + $version + "\"; | |
if (-Not (Test-Path $versionDir) -Or $force) { | |
$remoteNodeVersions = (Invoke-WebRequest -Uri "https://nodejs.org/dist/").Links.Href; | |
if ($remoteNodeVersions -like "latest-v$version.*") { | |
$temp = $dir + "temp"; | |
if (Test-Path $temp) { | |
rm -r -Force $temp | |
} | |
if (Test-Path $versionDir) { | |
rm -r -Force $versionDir | |
} | |
mkdir $temp | |
$downloadUrl = "https://nodejs.org/dist/latest-v$version.x/"; | |
(Invoke-WebRequest -Uri $downloadUrl).Links.Href | ForEach { | |
if ($_ -like "node-v$version.*" -and $_ -like "*-$arch.zip") { | |
$downloadUrl = $downloadUrl + $_ | |
} | |
} | |
Write-Host "Downloading Nodejs $version from $downloadUrl" | |
Invoke-WebRequest -Uri $downloadUrl -OutFile "$temp\$version.zip" | |
Write-Host "Downloaded Nodejs $version to $temp\$version.zip" | |
Write-Host "Extracting $temp\$version.zip to $versionDir" | |
Expand-Archive -Path $temp\$version.zip -DestinationPath $versionDir | |
mv "$versionDir\node-v$version.*\*" $versionDir | |
rm -r -Force "$versionDir\node-v$version.*" | |
Write-Host "Removing temp folder." | |
rm -r -Force $temp | |
} else { | |
Throw "Version $version is invalid! Please, run nmp -list -remote to see available versions and run this command again. Ex.: nmp -change 16" | |
} | |
} | |
Write-Host "Setting Nodejs $version the current active version." | |
$currentVersion = (node -v).Replace('v', '').Split('.')[0] | |
$replaceVersionDir = $dir + $currentVersion + '\;' | |
$systemPath = $env:Path | |
$systemPath = $systemPath.Replace($replaceVersionDir, "$versionDir;"); | |
$env:Path = $systemPath; | |
node -v | |
} else { | |
$env:Path = $defaultNodeDir; | |
if (Test-CommandExists -command node -silent) { | |
node -v | |
} else { | |
Write-Host "You need to restart your terminal to see the changes." | |
} | |
} | |
} | |
# This lists all Nodejs versions that are possible to install by running nChange | |
function nList { | |
param ( | |
[switch] $remote | |
) | |
if ($remote.IsPresent) { | |
(Invoke-WebRequest -Uri "https://nodejs.org/dist/").Links.Href | ForEach { | |
if ($_ -like "latest-v*" -and -not ($_ -like "latest-v0*")) { | |
$version = $_.Replace('latest-', '').Replace('.x/', ''); | |
Write-Host $version | |
} | |
} | |
Write-Host "These are current available Nodejs versions (latest)" | |
} else { | |
ls $dir | |
} | |
} | |
function nVersion { | |
Write-Host "Nodejs Version Manager Powershell (nmp)" | |
Write-Host $nmpVersion | |
Write-Host "---------------------------------------" | |
if (Test-CommandExists node -silent) { | |
$nodeV = (node -v) | |
Write-Host "Node $nodeV" | |
} else { | |
Write-Host "Node.js is not installed! Run nmp -help to see how to install Node.js using nmp." | |
} | |
} | |
# Displays all available functions | |
function nHelp { | |
Write-Host 'Node Version Manager Powershell - Help' | |
Write-Host '' | |
Write-Host '-version | Display current nmp and node versions.' | |
Write-Host '-list | List all Nodejs versions currently installed.' | |
Write-Host ' -remote | List all Nodejs versions available to install.' | |
Write-Host '-change $number | Changes Nodejs version ($number). If not installed, it will download it.' | |
Write-Host ' Ex. nmp -change 18 will install latest v18, like 18.13.0.' -ForegroundColor Yellow | |
Write-Host ' -force | Will attempt to override a current version.' | |
Write-Host ' Usefull to update versions from 18.0.4 to 18.4.1, for example.' -ForegroundColor Yellow | |
Write-Host ' -arch | Default to "win-x64", can also be "win-x86".' | |
Write-Host '-help | Display this help page.' | |
} | |
if ($help.IsPresent) { | |
nHelp | |
} else { | |
if ($list.IsPresent) { | |
if (-Not $remote.IsPresent) { | |
nList | |
} else { | |
nList -remote | |
} | |
} | |
if (-Not ($change -Eq "")) { | |
nChange -version $change -arch $arch -force $force.IsPresent | |
} | |
if ($version.IsPresent) { | |
nVersion | |
} | |
if ($init.IsPresent -Or $PSBoundParameters.ContainsKey('dir')) { | |
try { | |
nInit | |
if (-Not $silentInit) { | |
nVersion | |
} | |
} | |
catch { | |
Write-host "Could not load nmp, you may need to ajust some configs in your Powershell Profile." | |
} | |
} | |
} | |
} | |
nmp -init |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment