Skip to content

Instantly share code, notes, and snippets.

@mahtaran
Created July 10, 2023 15:44
Show Gist options
  • Save mahtaran/654e3387a49f0da62902c152687eb225 to your computer and use it in GitHub Desktop.
Save mahtaran/654e3387a49f0da62902c152687eb225 to your computer and use it in GitHub Desktop.
A PowerShell upgrade script for https://github.com/coreybutler/nvm-windows, which will carry over globally installed npm (and pnpm) packages
if ($args -contains "--help" -or $args.Length -eq 0) {
Write-Host "Usage: .\upgrade-node.ps1 <version> [--help] [--mock] [--no-confirm]"
Write-Host "Example: .\upgrade-node.ps1 20.4.0"
Write-Host "You can still use 'lts' or 'latest' as version"
Write-Host "Example: .\upgrade-node.ps1 latest"
Write-Host "Use the --mock flag to preview the changes without actually making them"
Write-Host "Use the --no-confirm flag to skip confirmation"
exit
}
$newVersion = $args[0]
$mock = $args -contains "--mock"
# Store current version and globally installed packages
$oldVersion = nvm current
$npmRaw = npm ls -g --depth=0 --json | ConvertFrom-Json
$npmPackages = $npmRaw.dependencies | Get-Member -MemberType NoteProperty | ForEach-Object {
[PSCustomObject]@{
name = $_.Name
version = $npmRaw.dependencies.$($_.Name).version
}
}
$npmPackagesString = ($npmPackages | ForEach-Object { "$($_.name)@$($_.version)" }) -join " "
$pnpmRaw = pnpm list -g --depth=0 --json | ConvertFrom-Json
$pnpmPackages = $pnpmRaw.dependencies | Get-Member -MemberType NoteProperty | ForEach-Object {
[PSCustomObject]@{
name = $_.Name
version = $pnpmRaw.dependencies.$($_.Name).version
}
}
$pnpmPackagesString = ($pnpmPackages | ForEach-Object { "$($_.name)@$($_.version)" }) -join " "
# Add a package manager column
$packages = $npmPackages | ForEach-Object { $_ | Add-Member -MemberType NoteProperty -Name "manager" -Value "npm" -PassThru }
$packages += $pnpmPackages | ForEach-Object { $_ | Add-Member -MemberType NoteProperty -Name "manager" -Value "pnpm" -PassThru }
$packages = $packages | Select-Object manager, name, version
Write-Host "We will upgrade node.js from version $oldVersion version $newVersion and reinstall the following packages:"
$packages | Format-Table -AutoSize | Out-String | Write-Host
Write-Host "Do you wish to continue? [Y/n]" -ForegroundColor Blue
$answer = Read-Host
if ($answer -ne "Y" -and $answer -ne "y") {
exit
}
Write-Host "Installing new version of node.js..."
if ($mock) {
Write-Host "nvm install $newVersion" -ForegroundColor Yellow
Write-Host "If the command above failed, the program would have exited here" -ForegroundColor Red
} else {
nvm install $newVersion 2>&1 | Write-Host
}
if (-not $?) {
Write-Host "An error occurred while installing node.js" -ForegroundColor Red
exit
}
Write-Host "Switching to new version of node.js..."
if ($mock) {
Write-Host "nvm use $newVersion" -ForegroundColor Yellow
Write-Host "If the command above failed, the program would have exited here" -ForegroundColor Red
} else {
nvm use $newVersion 2>&1 | Write-Host
}
Write-Host "Reinstalling packages…"
# The location of npm is changed when switching node versions, so we need to use the full path
$root = nvm root | Select-String -Pattern "\s*Current Root: (.*)" | ForEach-Object { $_.Matches.Groups[1].Value }
$current = nvm current
if ($mock) {
$current = "<new version>"
Write-Host "If any of the commands above failed, the program would have exited here" -ForegroundColor Red
if ($npmPackagesString.Length -gt 1) {
Write-Host "Start-Process -FilePath ""$root\$current\npm.cmd"" -ArgumentList ""install -g $npmPackagesString"" -Wait -NoNewWindow" -ForegroundColor Yellow
}
if ($pnpmPackagesString.Length -gt 1) {
Write-Host "Start-Process -FilePath ""$root\$current\pnpm.cmd"" -ArgumentList ""install -g $pnpmPackagesString"" -Wait -NoNewWindow" -ForegroundColor Yellow
}
} else {
if ($npmPackagesString.Length -gt 1) {
Start-Process -FilePath "$root\$current\npm.cmd" -ArgumentList "install -g $npmPackagesString" -Wait -NoNewWindow 2>&1 | Write-Host
}
if ($pnpmPackagesString.Length -gt 1) {
Start-Process -FilePath "$root\$current\pnpm.cmd" -ArgumentList "install -g $pnpmPackagesString" -Wait -NoNewWindow 2>&1 | Write-Host
}
}
if (-not $?) {
Write-Host "An error occurred while reinstalling packages" -ForegroundColor Red
exit
}
Write-Host "If you're missing any packages, you can reinstall them manually using the following command:"
Write-Host "npm install -g $npmPackagesString" -ForegroundColor Yellow
Write-Host "pnpm install -g $pnpmPackagesString" -ForegroundColor Yellow
Write-Host "Should we remove the old version of node.js? [Y/n]" -ForegroundColor Blue
$answer = Read-Host
if ($answer -ne "Y" -and $answer -ne "y") {
exit
}
Write-Host "Uninstalling old version of node.js..."
if ($mock) {
Write-Host "nvm uninstall $oldVersion" -ForegroundColor Yellow
Write-Host "If the command above failed, the program would have exited here" -ForegroundColor Red
} else {
nvm uninstall $oldVersion 2>&1 | Write-Host
}
if (-not $?) {
Write-Host "An error occurred while uninstalling node.js" -ForegroundColor Red
exit
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment