Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 1 | # Node Version Manager |
| 2 | # Implemented as a bash function |
| 3 | # To use source this file from your bash profile |
| 4 | # |
| 5 | # Implemented by Tim Caswell <tim@creationix.com> |
| 6 | # with much bash help from Matthew Ranney |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 7 | |
| 8 | export NVM_DIR=$HOME/.nvm |
| 9 | |
| 10 | if [ ! -d "$NVM_DIR" ]; then |
| 11 | mkdir $NVM_DIR |
| 12 | fi |
| 13 | |
| 14 | # Auto detect the NVM_DIR |
| 15 | if [ ! -d "$NVM_DIR" ]; then |
| 16 | export NVM_DIR=$(cd $(dirname ${BASH_SOURCE[0]:-$0}); pwd) |
| 17 | fi |
| 18 | |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 19 | # Expand a version using the version cache |
| 20 | nvm_version() |
| 21 | { |
| 22 | PATTERN=$1 |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 23 | # The default version is the current one |
| 24 | if [ ! "$PATTERN" ]; then |
| 25 | PATTERN='current' |
| 26 | fi |
| 27 | |
| 28 | VERSION=`nvm_ls $PATTERN | tail -n1` |
| 29 | echo "$VERSION" |
| 30 | |
| 31 | if [ "$VERSION" = 'N/A' ]; then |
| 32 | return 13 |
| 33 | fi |
| 34 | } |
| 35 | |
| 36 | nvm_ls() |
| 37 | { |
| 38 | PATTERN=$1 |
| 39 | VERSIONS='' |
| 40 | if [ "$PATTERN" = 'current' ]; then |
| 41 | echo `node -v 2>/dev/null` |
| 42 | return |
| 43 | fi |
| 44 | |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 45 | if [ -f "$NVM_DIR/alias/$PATTERN" ]; then |
| 46 | nvm_version `cat $NVM_DIR/alias/$PATTERN` |
| 47 | return |
| 48 | fi |
| 49 | # If it looks like an explicit version, don't do anything funny |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 50 | if [[ "$PATTERN" == v?*.?*.?* ]]; then |
| 51 | VERSIONS="$PATTERN" |
| 52 | else |
| 53 | VERSIONS=`(cd $NVM_DIR; \ls -d v${PATTERN}* 2>/dev/null) | sort -t. -k 1.2,1n -k 2,2n -k 3,3n` |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 54 | fi |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 55 | if [ ! "$VERSIONS" ]; then |
| 56 | echo "N/A" |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 57 | return |
| 58 | fi |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 59 | echo "$VERSIONS" |
| 60 | return |
| 61 | } |
| 62 | |
| 63 | print_versions() |
| 64 | { |
| 65 | OUTPUT='' |
| 66 | for VERSION in $1; do |
| 67 | PADDED_VERSION=`printf '%10s' $VERSION` |
| 68 | if [[ -d "$NVM_DIR/$VERSION" ]]; then |
| 69 | PADDED_VERSION="\033[0;34m$PADDED_VERSION\033[0m" |
| 70 | fi |
| 71 | OUTPUT="$OUTPUT\n$PADDED_VERSION" |
| 72 | done |
| 73 | echo -e "$OUTPUT" | column |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | nvm() |
| 77 | { |
| 78 | if [ $# -lt 1 ]; then |
| 79 | nvm help |
| 80 | return |
| 81 | fi |
| 82 | case $1 in |
| 83 | "help" ) |
| 84 | echo |
| 85 | echo "Node Version Manager" |
| 86 | echo |
| 87 | echo "Usage:" |
| 88 | echo " nvm help Show this message" |
| 89 | echo " nvm install <version> Download and install a <version>" |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 90 | echo " nvm uninstall <version> Uninstall a version" |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 91 | echo " nvm use <version> Modify PATH to use <version>" |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 92 | echo " nvm run <version> [<args>] Run <version> with <args> as arguments" |
| 93 | echo " nvm ls List installed versions" |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 94 | echo " nvm ls <version> List versions matching a given description" |
| 95 | echo " nvm deactivate Undo effects of NVM on current shell" |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 96 | echo " nvm alias [<pattern>] Show all aliases beginning with <pattern>" |
| 97 | echo " nvm alias <name> <version> Set an alias named <name> pointing to <version>" |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 98 | echo " nvm unalias <name> Deletes the alias named <name>" |
| 99 | echo " nvm copy-packages <version> Install global NPM packages contained in <version> to current version" |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 100 | echo |
| 101 | echo "Example:" |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 102 | echo " nvm install v0.4.12 Install a specific version number" |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 103 | echo " nvm use 0.2 Use the latest available 0.2.x release" |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 104 | echo " nvm run 0.4.12 myApp.js Run myApp.js using node v0.4.12" |
| 105 | echo " nvm alias default 0.4 Auto use the latest installed v0.4.x version" |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 106 | echo |
| 107 | ;; |
| 108 | "install" ) |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 109 | if [ ! `which curl` ]; then |
| 110 | echo 'NVM Needs curl to proceed.' >&2; |
| 111 | fi |
| 112 | |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 113 | if [ $# -ne 2 ]; then |
| 114 | nvm help |
| 115 | return |
| 116 | fi |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 117 | VERSION=`nvm_version $2` |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 118 | |
| 119 | [ -d "$NVM_DIR/$VERSION" ] && echo "$VERSION is already installed." && return |
| 120 | |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 121 | tarball='' |
| 122 | if [ "`curl -Is "http://nodejs.org/dist/$VERSION/node-$VERSION.tar.gz" | grep '200 OK'`" != '' ]; then |
| 123 | tarball="http://nodejs.org/dist/$VERSION/node-$VERSION.tar.gz" |
| 124 | elif [ "`curl -Is "http://nodejs.org/dist/node-$VERSION.tar.gz" | grep '200 OK'`" != '' ]; then |
| 125 | tarball="http://nodejs.org/dist/node-$VERSION.tar.gz" |
| 126 | fi |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 127 | if ( |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 128 | [ ! -z $tarball ] && \ |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 129 | mkdir -p "$NVM_DIR/src" && \ |
| 130 | cd "$NVM_DIR/src" && \ |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 131 | curl -C - --progress-bar $tarball -o "node-$VERSION.tar.gz" && \ |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 132 | tar -xzf "node-$VERSION.tar.gz" && \ |
| 133 | cd "node-$VERSION" && \ |
| 134 | ./configure --prefix="$NVM_DIR/$VERSION" && \ |
| 135 | make && \ |
| 136 | rm -f "$NVM_DIR/$VERSION" 2>/dev/null && \ |
| 137 | make install |
| 138 | ) |
| 139 | then |
| 140 | nvm use $VERSION |
| 141 | if ! which npm ; then |
| 142 | echo "Installing npm..." |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 143 | if [[ "`expr match $VERSION '\(^v0\.1\.\)'`" != '' ]]; then |
| 144 | echo "npm requires node v0.2.3 or higher" |
| 145 | elif [[ "`expr match $VERSION '\(^v0\.2\.\)'`" != '' ]]; then |
| 146 | if [[ "`expr match $VERSION '\(^v0\.2\.[0-2]$\)'`" != '' ]]; then |
| 147 | echo "npm requires node v0.2.3 or higher" |
| 148 | else |
| 149 | curl http://npmjs.org/install.sh | clean=yes npm_install=0.2.19 sh |
| 150 | fi |
| 151 | else |
| 152 | curl http://npmjs.org/install.sh | clean=yes sh |
| 153 | fi |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 154 | fi |
| 155 | else |
| 156 | echo "nvm: install $VERSION failed!" |
| 157 | fi |
| 158 | ;; |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 159 | "uninstall" ) |
| 160 | [ $# -ne 2 ] && nvm help && return |
| 161 | if [[ $2 == `nvm_version` ]]; then |
| 162 | echo "nvm: Cannot uninstall currently-active node version, $2." |
| 163 | return |
| 164 | fi |
| 165 | VERSION=`nvm_version $2` |
| 166 | if [ ! -d $NVM_DIR/$VERSION ]; then |
| 167 | echo "$VERSION version is not installed yet" |
| 168 | return; |
| 169 | fi |
| 170 | |
| 171 | # Delete all files related to target version. |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 172 | (mkdir -p "$NVM_DIR/src" && \ |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 173 | cd "$NVM_DIR/src" && \ |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 174 | rm -rf "node-$VERSION" 2>/dev/null && \ |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 175 | rm -f "node-$VERSION.tar.gz" 2>/dev/null && \ |
| 176 | rm -rf "$NVM_DIR/$VERSION" 2>/dev/null) |
| 177 | echo "Uninstalled node $VERSION" |
| 178 | |
| 179 | # Rm any aliases that point to uninstalled version. |
| 180 | for A in `grep -l $VERSION $NVM_DIR/alias/*` |
| 181 | do |
| 182 | nvm unalias `basename $A` |
| 183 | done |
| 184 | |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 185 | ;; |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 186 | "deactivate" ) |
| 187 | if [[ $PATH == *$NVM_DIR/*/bin* ]]; then |
| 188 | export PATH=${PATH%$NVM_DIR/*/bin*}${PATH#*$NVM_DIR/*/bin:} |
| 189 | hash -r |
| 190 | echo "$NVM_DIR/*/bin removed from \$PATH" |
| 191 | else |
| 192 | echo "Could not find $NVM_DIR/*/bin in \$PATH" |
| 193 | fi |
| 194 | if [[ $MANPATH == *$NVM_DIR/*/share/man* ]]; then |
| 195 | export MANPATH=${MANPATH%$NVM_DIR/*/share/man*}${MANPATH#*$NVM_DIR/*/share/man:} |
| 196 | echo "$NVM_DIR/*/share/man removed from \$MANPATH" |
| 197 | else |
| 198 | echo "Could not find $NVM_DIR/*/share/man in \$MANPATH" |
| 199 | fi |
| 200 | ;; |
| 201 | "use" ) |
| 202 | if [ $# -ne 2 ]; then |
| 203 | nvm help |
| 204 | return |
| 205 | fi |
| 206 | VERSION=`nvm_version $2` |
| 207 | if [ ! -d $NVM_DIR/$VERSION ]; then |
| 208 | echo "$VERSION version is not installed yet" |
| 209 | return; |
| 210 | fi |
| 211 | if [[ $PATH == *$NVM_DIR/*/bin* ]]; then |
| 212 | PATH=${PATH%$NVM_DIR/*/bin*}$NVM_DIR/$VERSION/bin${PATH#*$NVM_DIR/*/bin} |
| 213 | else |
| 214 | PATH="$NVM_DIR/$VERSION/bin:$PATH" |
| 215 | fi |
| 216 | if [[ $MANPATH == *$NVM_DIR/*/share/man* ]]; then |
| 217 | MANPATH=${MANPATH%$NVM_DIR/*/share/man*}$NVM_DIR/$VERSION/share/man${MANPATH#*$NVM_DIR/*/share/man} |
| 218 | else |
| 219 | MANPATH="$NVM_DIR/$VERSION/share/man:$MANPATH" |
| 220 | fi |
| 221 | export PATH |
| 222 | hash -r |
| 223 | export MANPATH |
| 224 | export NVM_PATH="$NVM_DIR/$VERSION/lib/node" |
| 225 | export NVM_BIN="$NVM_DIR/$VERSION/bin" |
| 226 | echo "Now using node $VERSION" |
| 227 | ;; |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 228 | "run" ) |
| 229 | # run given version of node |
| 230 | if [ $# -lt 2 ]; then |
| 231 | nvm help |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 232 | return |
| 233 | fi |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 234 | VERSION=`nvm_version $2` |
| 235 | if [ ! -d $NVM_DIR/$VERSION ]; then |
| 236 | echo "$VERSION version is not installed yet" |
| 237 | return; |
| 238 | fi |
| 239 | echo "Running node $VERSION" |
| 240 | $NVM_DIR/$VERSION/bin/node "${@:3}" |
| 241 | ;; |
| 242 | "ls" | "list" ) |
| 243 | print_versions "`nvm_ls $2`" |
| 244 | if [ $# -eq 1 ]; then |
| 245 | echo -ne "current: \t"; nvm_version current |
| 246 | nvm alias |
| 247 | fi |
| 248 | return |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 249 | ;; |
| 250 | "alias" ) |
| 251 | mkdir -p $NVM_DIR/alias |
| 252 | if [ $# -le 2 ]; then |
| 253 | (cd $NVM_DIR/alias && for ALIAS in `\ls $2* 2>/dev/null`; do |
| 254 | DEST=`cat $ALIAS` |
| 255 | VERSION=`nvm_version $DEST` |
| 256 | if [ "$DEST" = "$VERSION" ]; then |
| 257 | echo "$ALIAS -> $DEST" |
| 258 | else |
| 259 | echo "$ALIAS -> $DEST (-> $VERSION)" |
| 260 | fi |
| 261 | done) |
| 262 | return |
| 263 | fi |
| 264 | if [ ! "$3" ]; then |
| 265 | rm -f $NVM_DIR/alias/$2 |
| 266 | echo "$2 -> *poof*" |
| 267 | return |
| 268 | fi |
| 269 | mkdir -p $NVM_DIR/alias |
| 270 | VERSION=`nvm_version $3` |
| 271 | if [ $? -ne 0 ]; then |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 272 | echo "! WARNING: Version '$3' does not exist." >&2 |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 273 | fi |
| 274 | echo $3 > "$NVM_DIR/alias/$2" |
| 275 | if [ ! "$3" = "$VERSION" ]; then |
| 276 | echo "$2 -> $3 (-> $VERSION)" |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 277 | else |
| 278 | echo "$2 -> $3" |
| 279 | fi |
| 280 | ;; |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 281 | "unalias" ) |
| 282 | mkdir -p $NVM_DIR/alias |
| 283 | [ $# -ne 2 ] && nvm help && return |
| 284 | [ ! -f $NVM_DIR/alias/$2 ] && echo "Alias $2 doesn't exist!" && return |
| 285 | rm -f $NVM_DIR/alias/$2 |
| 286 | echo "Deleted alias $2" |
| 287 | ;; |
Antono Vasiljev | 18bccea | 2011-08-25 16:45:51 +0300 | [diff] [blame] | 288 | "copy-packages" ) |
| 289 | if [ $# -ne 2 ]; then |
| 290 | nvm help |
| 291 | return |
| 292 | fi |
| 293 | VERSION=`nvm_version $2` |
| 294 | ROOT=`nvm use $VERSION && npm -g root` |
| 295 | INSTALLS=`nvm use $VERSION > /dev/null && npm -g -p ll | grep "$ROOT\/[^/]\+$" | cut -d '/' -f 8 | cut -d ":" -f 2 | grep -v npm | tr "\n" " "` |
| 296 | npm install -g $INSTALLS |
| 297 | ;; |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 298 | "clear-cache" ) |
| 299 | rm -f $NVM_DIR/v* 2>/dev/null |
| 300 | echo "Cache cleared." |
| 301 | ;; |
| 302 | "version" ) |
Antono Vasiljev | 1527630 | 2012-03-05 02:13:53 +0300 | [diff] [blame] | 303 | print_versions "`nvm_version $2`" |
Antono Vasiljev | 8c7b8f2 | 2011-07-17 06:52:27 +0300 | [diff] [blame] | 304 | ;; |
| 305 | * ) |
| 306 | nvm help |
| 307 | ;; |
| 308 | esac |
| 309 | } |
| 310 | |
| 311 | nvm ls default >/dev/null 2>&1 && nvm use default >/dev/null |