Skip to content

Instantly share code, notes, and snippets.

@karfau
Last active March 7, 2025 11:04
Show Gist options
  • Save karfau/dcf98c6eefc2f2132c160f5c14d2112f to your computer and use it in GitHub Desktop.
Save karfau/dcf98c6eefc2f2132c160f5c14d2112f to your computer and use it in GitHub Desktop.
A script that can be sourced in shell scripts to enable nvm support
# shellcheck shell=sh
# https://gist.github.com/karfau/dcf98c6eefc2f2132c160f5c14d2112f
# v2025.3.7
# needs to be sourced as part of your script
# 1. tries to configure nvm and run `nvm install`
# 2. checks if the node version is correct based on .nvmrc or .node-version
# if both doesn't work, exits with code 1 and some helpful messages
# Sometimes we prefer `nvm use` over `nvm install`
# you can basically put anything you want here, but the default is `install`
NVM_SETUP_COMMAND=${NVM_SETUP_COMMAND:-install}
NVM_DIR=${NVM_DIR:-$HOME/.nvm}
# https://unix.stackexchange.com/a/184512/194420
# https://github.com/nvm-sh/nvm/issues/1290
if [ -f "${NVM_DIR}/nvm.sh" ]; then
echo "sourcing nvm from NVM_DIR:${NVM_DIR}"
. "${NVM_DIR}/nvm.sh"
elif command -v brew; then
# https://docs.brew.sh/Manpage#--prefix-formula
BREW_PREFIX=$(brew --prefix nvm)
if [ -f "$BREW_PREFIX/nvm.sh" ]; then
echo "sourcing nvm from brew ($BREW_PREFIX)"
. "${BREW_PREFIX}/nvm.sh"
fi
fi
if command -v nvm ; then
echo "NVM_SETUP_COMMAND is ${NVM_SETUP_COMMAND}"
nvm ${NVM_SETUP_COMMAND}
else
echo "WARN: not able to configure nvm"
fi
if [ -f .nvmrc ]; then
NODE_VERSION="$(cat .nvmrc | sed 's/^v//')"
fi
if [ -f .node-version ]; then
NODE_VERSION="$(cat .node-version | sed 's/^v//')"
fi
which node
ACTIVE_VERSION="$(node --version | sed 's/^v//')"
GLOBAL_NPM=$(which npm || echo "not found on PATH")
# .nvmrc or .node-version can contain only major or major.minor or full version
# so we replace active version with NODE_VERSION and anything afterwards
# if something is left, it's not a match
if [ "${ACTIVE_VERSION%%$NODE_VERSION*}" ] || [ ! -e "$GLOBAL_NPM" ]; then
echo "expected node '$NODE_VERSION' and npm on path"
echo "but was '$ACTIVE_VERSION' and npm:'$GLOBAL_NPM'"
return 1
fi
@cakemanny
Copy link

Line 15 fails when the parent shell has set -u (error on unset variables)

I would suggest this:

@@ -9,6 +9,7 @@
 # Sometimes we prefer `nvm use` over `nvm install`
 # you can basically put anything you want here, but the default is `install`
 NVM_SETUP_COMMAND=${NVM_SETUP_COMMAND:-install}
+: ${NVM_DIR=$HOME/.nvm}
 
 # https://unix.stackexchange.com/a/184512/194420
 # https://github.com/nvm-sh/nvm/issues/1290

i.e. set a default. that default is implied by the last line of the nvm help message

Note:
to remove, delete, or uninstall nvm - just remove the $NVM_DIR folder (usually ~/.nvm)

@karfau
Copy link
Author

karfau commented Mar 28, 2024

Makes total sense, especially if nvm is installed via brew in which case NVM_DIR might not be set.
Update: changed it with a small tweak to keep the original value if it is present, in the same way it is done for NVM_INSTALL_COMMAND

@karfau
Copy link
Author

karfau commented Aug 12, 2024

The most recent improvement supports .nvmrc containing version with out without the v prefix by eliminating it from both the nvmrc content and the current node version before comparing.
Thx @cakemanny for the suggestion including the implementation details.

@karfau
Copy link
Author

karfau commented Aug 14, 2024

2024.8.14 fixes a syntax error and introduces a version comment, so it's easier to spot updates

@karfau
Copy link
Author

karfau commented Mar 7, 2025

2025.3.7 adds support for .node-version file, which wins if both files are present.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment