Skip to content

Instantly share code, notes, and snippets.

@larzconwell
Created July 5, 2012 01:02
Show Gist options
  • Save larzconwell/3050364 to your computer and use it in GitHub Desktop.
Save larzconwell/3050364 to your computer and use it in GitHub Desktop.
#!/bin/bash
PREFIX=${PREFIX-/usr/local}
NVM_DIR="$PREFIX/lib/nvm"
VERSIONS_DIR="$NVM_DIR/versions"
CURRENT_NVM="$NVM_DIR/current"
LOGPATH="/tmp/nvm.log"
# Exit with message
abort() {
echo -e "\n\033[31mError:\033[0m $@" && exit 1
}
# Setup the GET var and create versions directory
setup() {
# Test sudo permissions
sudo -v > /dev/null 2>&1 || abort "You will need sudo permissions to use NVM"
[[ -f "$LOGPATH" ]] && sudo rm -rf "$LOGPATH" && touch "$LOGPATH"
# Create nvm directory if doesn't exists
[[ ! -d "$NVM_DIR" ]] && mkdir -p "$NVM_DIR"
# Create directories and files needed for basic use
[[ ! -d "$VERSIONS_DIR" ]] && mkdir -p "$VERSIONS_DIR"
[[ ! -d "$CURRENT_NVM" ]] && mkdir -p "$CURRENT_NVM"
[[ ! -f "$VERSIONS_DIR/versions" ]] && touch "$VERSIONS_DIR/versions"
# Set up Curl or Wget support
if [[ -f "$(which curl)" ]]; then
# Use Curl
GET="curl -# -L"
elif [[ -f "$(which wget)" ]]; then
# Use Wget
GET="wget --no-check-certificate -q -O-"
else
abort "Curl or Wget are required to use NVM"
fi
}
# Display the help diaecho
help() {
cat <<-help
Node Version Management(NVM)
Usage:
nvm [options/commands] [arguments]
Commands:
latest # Install and Use the latest Node release
stable # Install and Use the latest stable Node release
install [version] # Install the given Node version
use [version] # Use the given Node version
- Will install if not installed
remove [version] [args] # Remove the given Node version
- Arguments: 'system(s)' uninstalls the Node version
currently in use
list [args] # List the Node versions from the given argument
- Arguments: 'all(a), installed(i)'
Options:
--help, -h Display the help information
help
exit 0
}
# Use a Node version as the global install
use_version() {
local version="$@"
# remove "v" if it's there
version=${version#v}
# Uninstall old Node version if it exists
if [[ -f "$CURRENT_NVM/version" ]]; then
local old_version=`cat "$CURRENT_NVM/version"`
# Uninstall old version
if [[ -d "$CURRENT_NVM/$old_version" ]]; then
cd "$CURRENT_NVM/$old_version" \
&& make uninstall >> $LOGPATH 2>&1 | echo "Uninstalling old Node version..."
fi
# Delete files that exist
rm -rf "$CURRENT_NVM/*"
fi
# If version is installed then use it otherwise installed it then use it
if [[ -d "$VERSIONS_DIR/$version" ]]; then
# Copy version to current directory
cp -r "$VERSIONS_DIR/$version" "$CURRENT_NVM"
# Write version to current version file
echo "$version" > "$CURRENT_NVM/version"
# Install globally
cd "$CURRENT_NVM/$version" \
&& ./configure >> $LOGPATH 2>&1 | echo "Configuring Node $version..." \
&& make >> $LOGPATH 2>&1 | echo "Compiling Node $version..." \
&& make install >> $LOGPATH 2>&1 | echo "Setting Node $version..." \
#cd "$CURRENT_NVM/$version" && make install >> $LOGPATH 2>&1 | echo "Setting Node $version..."
echo "Node $version is now being used..."
else
# Install version then use it
install "$version"
use_version "$version"
fi
}
# Install and use the latest Node version
install_latest() {
local version=`$GET 2> /dev/null http://nodejs.org/dist/ \
| egrep -o '[0-9]+\.[0-9]+\.[0-9]+' \
| sort -u -k 1,1n -k 2,2n -k 3,3n -t . \
| tail -n1`
# Install and use version
install "$version"
use_version "$version"
}
# Install and use the latest stable Node version
install_stable() {
local version=`$GET 2> /dev/null http://nodejs.org/dist/ \
| egrep -o '[0-9]+\.\d*[02468]\.[0-9]+' \
| sort -u -k 1,1n -k 2,2n -k 3,3n -t . \
| tail -n1`
# Install and use version
install "$version"
use_version "$version"
}
# Install a Node version or if multiple versions are given install them all
install() {
for version in $@; do
# Remove "v" if used
version=${version#v}
# Only install it if it's not installed
if [[ ! -d "$VERSIONS_DIR/$version" ]]; then
echo -e "Installing Node $version...\n"
# Write version to the list of versions
sed -i '/^ *$/d' "$VERSIONS_DIR/versions" # Fix empty lines
echo "$version" >> "$VERSIONS_DIR/versions"
mkdir -p "$VERSIONS_DIR/$version" # Create directory for version
# Files and location to download
local tar="node-v$version.tar.gz"
local url="http://nodejs.org/dist/$tar"
# >= 0.5.x
local minor=$(echo $version | cut -d '.' -f 2)
[[ "$minor" -ge "5" ]] && url="http://nodejs.org/dist/v$version/$tar"
# Download and unpack version in it's version directory
echo "Downloading Node.js $version..."
cd "$VERSIONS_DIR/$version" && $GET $url | tar xz --strip-components=1 > $LOGPATH 2>&1
# Give error if an error happens during download
if [[ "$?" != "0" ]]; then
rm -rf "$VERSIONS_DIR/$version" >> $LOGPATH 2>&1
# Remove version from list of versions
sed -i "s/$version//g" "$VERSIONS_DIR/versions"
sed -i '/^ *$/d' "$VERSIONS_DIR/versions" # Fix empty lines
echo -e "\033[31mError: installation failed\033[0m"
echo " node version $version does not exist,"
echo " nvm failed to fetch the tarball,"
echo " or tar failed. Try a different"
echo " version or view $LOGPATH to view"
echo " error details."
exit 1
fi
#build "$version" # Build the Node version
echo "Node $version has been installed! Install directory: $VERSIONS_DIR/$version"
else
abort "Node $version is already installed"
fi
done
}
# Remove a Node version or if multiple versions are given remove them all
remove() {
for version in $@; do
if [[ "$version" == 'system' ]] || [[ "$version" == 's' ]]; then
# Remove the Node version being used
local old_version=`cat "$CURRENT_NVM/version"`
# Uninstall old version
if [[ -d "$CURRENT_NVM/$old_version" ]]; then
cd "$CURRENT_NVM/$old_version" \
&& make uninstall >> $LOGPATH 2>&1 | echo "Uninstalling the current Node version in use..."
fi
# Delete files that exist
rm -rf "$CURRENT_NVM/*"
else
# Remove "v" if used
version=${version#v}
# Only remove if it exists
if [[ -d "$VERSIONS_DIR/$version" ]]; then
# Remove version from list of versions
sed -i "s/$version//g" "$VERSIONS_DIR/versions"
sed -i '/^ *$/d' "$VERSIONS_DIR/versions" # Fix empty lines
# Remove the version directory
rm -rf "$VERSIONS_DIR/$version"
if [[ -d "$VERSIONS_DIR/$version" ]]; then
abort "There was an error deleting version $version"
else
echo "Version $version has been removed..."
fi
fi
fi
done
}
# List the versions of Node available
list_versions() {
if [[ "$@" == "a" ]] || [[ "$@" == "all" ]]; then
echo -e "All Node Versions:\n"
local versions=`$GET 2> /dev/null http://nodejs.org/dist/ \
| egrep -o '[0-9]+\.[0-9]+\.[0-9]+' \
| sort -u -k 1,1n -k 2,2n -k 3,3n -t . | organize_version_list`
echo "$versions"
elif [[ "$@" == "i" ]] || [[ "$@" == "installed" ]]; then
echo -e "Installed Node Versions:\n"
# List versions
if [[ `cat "$VERSIONS_DIR/versions"` != "" ]]; then
cat "$VERSIONS_DIR/versions" | organize_version_list 'installed'
echo -e " *: Node version currently in use"
else
echo "No Node versions are installed"
fi
else
list_versions "installed"
echo -e "\n-----------------------------------------------------------------------\n"
list_versions "all"
fi
}
# Organize remote version list into a compact readable format
organize_version_list () {
local i=0
local v
# TODO: Make faster
while read v; do
if [[ "$i" == "8" ]]; then
i=0
echo "$v"
else
let 'i = i + 1'
if [[ "$@" == "installed" ]] && [[ -f `which node` ]]; then
local version=`node -v`
version=${version#v}
[[ "$v" == "$version" ]] && echo -ne "*$v\t" || echo -ne "$v\t"
else
echo -ne "$v\t"
fi
fi
done
echo ""
[[ "$i" != "0" ]] && echo ""
return 0
}
init() {
if [[ "$@" == "" ]]; then
help
else
setup
while [[ "$#" != 0 ]]; do
case "$1" in
--help|-h|help)
help
exit 0 ;;
latest)
install_latest
exit 0 ;;
stable)
install_stable
exit 0 ;;
install)
install "${@:2}"
exit 0 ;;
use)
use_version "$2"
exit 0 ;;
remove|uninstall|delete)
remove "${@:2}"
exit 0 ;;
ls|list)
list_versions "$2"
exit 0 ;;
esac
shift
done
fi
}; init "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment