mirror of
https://github.com/tj/n.git
synced 2024-12-01 13:41:07 +00:00
363 lines
7.6 KiB
Bash
Executable File
363 lines
7.6 KiB
Bash
Executable File
#!/usr/bin/env sh
|
||
|
||
# Library version
|
||
|
||
VERSION="0.6.1"
|
||
N_PREFIX=${N_PREFIX-/usr/local}
|
||
VERSIONS_DIR=$N_PREFIX/n/versions
|
||
|
||
#
|
||
# Log the given <msg ...>
|
||
#
|
||
|
||
log() {
|
||
printf "\033[90m...\033[0m $@\n"
|
||
}
|
||
|
||
#
|
||
# Exit with the given <msg ...>
|
||
#
|
||
|
||
abort() {
|
||
printf "\033[31mError: $@\033[0m\n" && exit 1
|
||
}
|
||
|
||
# setup
|
||
|
||
test -d $VERSIONS_DIR || mkdir -p $VERSIONS_DIR
|
||
|
||
if ! test -d $VERSIONS_DIR; then
|
||
abort "Failed to create versions directory ($VERSIONS_DIR), do you have permissions to do this?"
|
||
fi
|
||
|
||
# curl / wget support
|
||
|
||
GET=
|
||
|
||
# wget support (Added --no-check-certificate for Github downloads)
|
||
which wget > /dev/null && GET="wget --no-check-certificate -q -O-"
|
||
|
||
# curl support
|
||
which curl > /dev/null && GET="curl -# -L"
|
||
|
||
# Ensure we have curl or wget
|
||
|
||
test -z "$GET" && abort "curl or wget required"
|
||
|
||
#
|
||
# Output usage information.
|
||
#
|
||
|
||
display_help() {
|
||
cat <<-help
|
||
|
||
Usage: n [options] [COMMAND] [config]
|
||
|
||
Commands:
|
||
|
||
n Output versions installed
|
||
n latest [config ...] Install or activate the latest node release
|
||
n stable [config ...] Install or activate the latest stable node release
|
||
n <version> [config ...] Install and/or use node <version>
|
||
n custom <version> <tarball> [config ...] Install custom node <tarball> with [args ...]
|
||
n use <version> [args ...] Execute node <version> with [args ...]
|
||
n npm <version> [args ...] Execute npm <version> with [args ...]
|
||
n bin <version> Output bin path for <version>
|
||
n rm <version ...> Remove the given version(s)
|
||
n --latest Output the latest node version available
|
||
n --stable Output the latest stable node version available
|
||
n ls Output the versions of node available
|
||
|
||
Options:
|
||
|
||
-V, --version Output current version of n
|
||
-h, --help Display help information
|
||
|
||
Aliases:
|
||
|
||
- rm
|
||
which bin
|
||
use as
|
||
list ls
|
||
custom c
|
||
|
||
help
|
||
exit 0
|
||
}
|
||
|
||
#
|
||
# Output n version.
|
||
#
|
||
|
||
display_n_version() {
|
||
echo $VERSION && exit 0
|
||
}
|
||
|
||
#
|
||
# Check for installed version, and populate $active
|
||
#
|
||
|
||
check_current_version() {
|
||
which node &> /dev/null
|
||
if test $? -eq 0; then
|
||
active=`node --version`
|
||
active=${active#v}
|
||
fi
|
||
}
|
||
|
||
#
|
||
# Display current node --version
|
||
# and others installed.
|
||
#
|
||
|
||
display_versions() {
|
||
check_current_version
|
||
for dir in $VERSIONS_DIR/*; do
|
||
local version=${dir##*/}
|
||
local config=`test -f $dir/.config && cat $dir/.config`
|
||
if test "$version" = "$active"; then
|
||
printf " \033[32mο\033[0m $version \033[90m$config\033[0m\n"
|
||
else
|
||
printf " $version \033[90m$config\033[0m\n"
|
||
fi
|
||
done
|
||
}
|
||
|
||
#
|
||
# Install node <version> [config ...]
|
||
#
|
||
|
||
install_node() {
|
||
local version=$1; shift
|
||
local config=$@
|
||
check_current_version
|
||
|
||
# remove "v"
|
||
version=${version#v}
|
||
|
||
# activate
|
||
local dir=$VERSIONS_DIR/$version
|
||
if test -d $dir; then
|
||
# TODO: refactor, this is lame
|
||
cd $dir \
|
||
&& mkdir -p $N_PREFIX/lib/node \
|
||
&& cp -fr $dir/include/node $N_PREFIX/include \
|
||
&& cp -f $dir/bin/node $N_PREFIX/bin/node \
|
||
&& cp -f $dir/bin/node-waf $N_PREFIX/bin/node-waf \
|
||
&& cp -fr $dir/lib/node/* $N_PREFIX/lib/node/ .
|
||
# install
|
||
else
|
||
local tarball="node-v$version.tar.gz"
|
||
local url="http://nodejs.org/dist/$tarball"
|
||
|
||
# >= 0.5.x
|
||
local minor=$(echo $version | cut -d '.' -f 2)
|
||
test $minor -ge "5" && url="http://nodejs.org/dist/v$version/$tarball"
|
||
|
||
install_tarball $version $url $config
|
||
fi
|
||
}
|
||
|
||
#
|
||
# Install node <version> <tarball> [config ...]
|
||
#
|
||
|
||
install_tarball() {
|
||
local version=$1
|
||
local url=$2; shift 2
|
||
local config=$@
|
||
|
||
# remove "v"
|
||
version=${version#v}
|
||
|
||
local dir=$VERSIONS_DIR/$version
|
||
local tarball="node-v$version.tar.gz"
|
||
local logpath="/tmp/n.log"
|
||
|
||
# create build directory
|
||
mkdir -p $N_PREFIX/n/node-v$version
|
||
|
||
# fetch and unpack
|
||
cd $N_PREFIX/n/node-v$version \
|
||
&& $GET $url | tar xz --strip-components=1 > $logpath 2>&1
|
||
|
||
# see if things are alright
|
||
if test $? -gt 0; then
|
||
rm $tarball
|
||
echo "\033[31mError: installation failed\033[0m"
|
||
echo " node version $version does not exist,"
|
||
echo " n 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
|
||
|
||
cd "$N_PREFIX/n/node-v$version" \
|
||
&& ./configure --prefix $VERSIONS_DIR/$version $config\
|
||
&& JOBS=4 make install \
|
||
&& cd .. \
|
||
&& cleanup $version \
|
||
&& mkdir -p $dir \
|
||
&& echo $config > "$dir/.config" \
|
||
&& n $version \
|
||
&& ln -s "$N_PREFIX/n/versions/$version" "$N_PREFIX/n/current"
|
||
}
|
||
|
||
#
|
||
# Cleanup after the given <version>
|
||
#
|
||
|
||
cleanup() {
|
||
local version=$1
|
||
local dir="node-v$version"
|
||
|
||
if test -d $dir; then
|
||
log "removing source"
|
||
rm -fr $dir
|
||
fi
|
||
|
||
if test -f "$dir.tar.gz"; then
|
||
log "removing tarball"
|
||
rm -fr "$dir.tar.gz"
|
||
fi
|
||
}
|
||
|
||
#
|
||
# Remove <version ...>
|
||
#
|
||
|
||
remove_version() {
|
||
test -z $1 && abort "version(s) required"
|
||
local version=${1#v}
|
||
while test $# -ne 0; do
|
||
rm -rf $VERSIONS_DIR/$version
|
||
shift
|
||
done
|
||
}
|
||
|
||
#
|
||
# Output bin path for <version>
|
||
#
|
||
|
||
display_bin_path_for_version() {
|
||
test -z $1 && abort "version required"
|
||
local version=${1#v}
|
||
local bin=$VERSIONS_DIR/$version/bin/node
|
||
if test -f $bin; then
|
||
printf $bin
|
||
else
|
||
abort "$1 is not installed"
|
||
fi
|
||
}
|
||
|
||
#
|
||
# Execute the given <version> of node
|
||
# with [args ...]
|
||
#
|
||
|
||
execute_with_version() {
|
||
test -z $1 && abort "version required"
|
||
local version=${1#v}
|
||
local bin=$VERSIONS_DIR/$version/bin/node
|
||
|
||
shift # remove version
|
||
|
||
if test -f $bin; then
|
||
$bin $@
|
||
else
|
||
abort "$1 is not installed"
|
||
fi
|
||
}
|
||
|
||
#
|
||
# Execute the given <version> of npm
|
||
# with [args ...]
|
||
#
|
||
|
||
execute_with_npm_version() {
|
||
test -z $1 && abort "version required"
|
||
local version=${1#v}
|
||
local bin=$VERSIONS_DIR/$version/bin
|
||
|
||
shift # remove version
|
||
|
||
if test -f $bin/npm; then
|
||
$bin/node $bin/npm $@
|
||
else
|
||
abort "npm is not installed, node.js version must be greater than or equal 0.6.3"
|
||
fi
|
||
}
|
||
|
||
#
|
||
# Display the latest node release version.
|
||
#
|
||
|
||
display_latest_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
|
||
}
|
||
|
||
#
|
||
# Display the latest stable node release version.
|
||
#
|
||
|
||
display_latest_stable_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
|
||
}
|
||
|
||
#
|
||
# Display the versions of node available.
|
||
#
|
||
|
||
list_versions() {
|
||
check_current_version
|
||
local versions=""
|
||
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 . \
|
||
| awk '{ print " " $1 }'`
|
||
|
||
for v in $versions; do
|
||
if test "$active" = "$v"; then
|
||
printf " \033[32mο\033[0m $v \033[0m\n"
|
||
else
|
||
if test -d $VERSIONS_DIR/$v; then
|
||
printf " * $v \033[0m\n"
|
||
else
|
||
printf " $v\n"
|
||
fi
|
||
fi
|
||
done
|
||
}
|
||
|
||
# Handle arguments
|
||
|
||
if test $# -eq 0; then
|
||
display_versions
|
||
else
|
||
while test $# -ne 0; do
|
||
case $1 in
|
||
-V|--version) display_n_version ;;
|
||
-h|--help|help) display_help ;;
|
||
--latest) display_latest_version $2; exit ;;
|
||
--stable) display_latest_stable_version $2; exit ;;
|
||
bin|which) display_bin_path_for_version $2; exit ;;
|
||
as|use) shift; execute_with_version $@; exit ;;
|
||
npm) shift; execute_with_npm_version $@; exit ;;
|
||
rm|-) remove_version $2; exit ;;
|
||
latest) install_node `n --latest`; exit ;;
|
||
stable) install_node `n --stable`; exit ;;
|
||
ls|list) list_versions $2; exit ;;
|
||
c|custom) shift; install_tarball $@; exit ;;
|
||
*) install_node $@; exit ;;
|
||
esac
|
||
shift
|
||
done
|
||
fi
|