Created
December 10, 2012 18:29
-
-
Save eldargab/4252327 to your computer and use it in GitHub Desktop.
n
This file contains hidden or 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
#!/usr/bin/env sh | |
# Library version | |
VERSION="0.7.3" | |
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 $N_PREFIX/bin \ | |
&& ln -fs $dir/bin/* .\ | |
&& mkdir -p $N_PREFIX/lib/node \ | |
&& cp -fr $dir/include/node $N_PREFIX/include \ | |
&& 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 "$version 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 to 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment