1#!/bin/sh 2 3# A word about this shell script: 4# 5# It must work everywhere, including on systems that lack 6# a /bin/bash, map 'sh' to ksh, ksh97, bash, ash, or zsh, 7# and potentially have either a posix shell or bourne 8# shell living at /bin/sh. 9# 10# See this helpful document on writing portable shell scripts: 11# https://www.gnu.org/s/hello/manual/autoconf/Portable-Shell.html 12# 13# The only shell it won't ever work on is cmd.exe. 14 15if [ "x$0" = "xsh" ]; then 16 # run as curl | sh 17 # on some systems, you can just do cat>npm-install.sh 18 # which is a bit cuter. But on others, &1 is already closed, 19 # so catting to another script file won't do anything. 20 # Follow Location: headers, and fail on errors 21 curl -f -L -s https://www.npmjs.org/install.sh > npm-install-$$.sh 22 ret=$? 23 if [ $ret -eq 0 ]; then 24 (exit 0) 25 else 26 echo "Uninstalling npm-install-$$.sh" >&2 27 rm npm-install-$$.sh 28 echo "Failed to download script" >&2 29 exit $ret 30 fi 31 sh npm-install-$$.sh 32 ret=$? 33 echo "Uninstalling npm-install-$$.sh" >&2 34 rm npm-install-$$.sh 35 exit $ret 36fi 37 38# See what "npm_config_*" things there are in the env, 39# and make them permanent. 40# If this fails, it's not such a big deal. 41configures="`env | grep 'npm_config_' | sed -e 's|^npm_config_||g'`" 42 43npm_config_loglevel="error" 44if [ "x$npm_debug" = "x" ]; then 45 (exit 0) 46else 47 echo "Running in debug mode." 48 echo "Note that this requires bash or zsh." 49 set -o xtrace 50 set -o pipefail 51 npm_config_loglevel="verbose" 52fi 53export npm_config_loglevel 54 55# make sure that node exists 56node=`which node 2>&1` 57ret=$? 58# if not found, try "nodejs" as it is the case on debian 59if [ $ret -ne 0 ]; then 60 node=`which nodejs 2>&1` 61 ret=$? 62fi 63if [ $ret -eq 0 ] && [ -x "$node" ]; then 64 (exit 0) 65else 66 echo "npm cannot be installed without node.js." >&2 67 echo "Install node first, and then try again." >&2 68 echo "" >&2 69 echo "Maybe node is installed, but not in the PATH?" >&2 70 echo "Note that running as sudo can change envs." >&2 71 echo "" 72 echo "PATH=$PATH" >&2 73 exit $ret 74fi 75 76# set the temp dir 77TMP="${TMPDIR}" 78if [ "x$TMP" = "x" ]; then 79 TMP="/tmp" 80fi 81TMP="${TMP}/npm.$$" 82rm -rf "$TMP" || true 83mkdir "$TMP" 84if [ $? -ne 0 ]; then 85 echo "failed to mkdir $TMP" >&2 86 exit 1 87fi 88 89BACK="$PWD" 90 91ret=0 92tar="${TAR}" 93if [ -z "$tar" ]; then 94 tar="${npm_config_tar}" 95fi 96if [ -z "$tar" ]; then 97 tar=`which tar 2>&1` 98 ret=$? 99fi 100 101if [ $ret -eq 0 ] && [ -x "$tar" ]; then 102 echo "tar=$tar" 103 if [ $tar --version > /dev/null 2>&1 ]; then 104 echo "version:" 105 $tar --version 106 fi 107 ret=$? 108fi 109 110if [ $ret -eq 0 ]; then 111 (exit 0) 112else 113 echo "No suitable tar program found." 114 exit 1 115fi 116 117 118 119# Try to find a suitable make 120# If the MAKE environment var is set, use that. 121# otherwise, try to find gmake, and then make. 122# If no make is found, then just execute the necessary commands. 123 124# XXX For some reason, make is building all the docs every time. This 125# is an annoying source of bugs. Figure out why this happens. 126MAKE=NOMAKE 127 128if [ "x$MAKE" = "x" ]; then 129 make=`which gmake 2>&1` 130 if [ $? -eq 0 ] && [ -x "$make" ]; then 131 (exit 0) 132 else 133 make=`which make 2>&1` 134 if [ $? -eq 0 ] && [ -x "$make" ]; then 135 (exit 0) 136 else 137 make=NOMAKE 138 fi 139 fi 140else 141 make="$MAKE" 142fi 143 144if [ -x "$make" ]; then 145 (exit 0) 146else 147 # echo "Installing without make. This may fail." >&2 148 make=NOMAKE 149fi 150 151# If there's no bash, then don't even try to clean 152if [ -x "/bin/bash" ]; then 153 (exit 0) 154else 155 clean="no" 156fi 157 158node_version=`"$node" --version 2>&1` 159ret=$? 160if [ $ret -ne 0 ]; then 161 echo "You need node to run this program." >&2 162 echo "node --version reports: $node_version" >&2 163 echo "with exit code = $ret" >&2 164 echo "Please install node before continuing." >&2 165 exit $ret 166fi 167 168t="${npm_install}" 169if [ -z "$t" ]; then 170 # switch based on node version. 171 # note that we can only use strict sh-compatible patterns here. 172 case $node_version in 173 0.[01234567].* | v0.[01234567].*) 174 echo "You are using an outdated and unsupported version of" >&2 175 echo "node ($node_version). Please update node and try again." >&2 176 exit 99 177 ;; 178 *) 179 echo "install npm@latest" 180 t="latest" 181 ;; 182 esac 183fi 184 185# need to echo "" after, because Posix sed doesn't treat EOF 186# as an implied end of line. 187url=`(curl -SsL https://registry.npmjs.org/npm/$t; echo "") \ 188 | sed -e 's/^.*tarball":"//' \ 189 | sed -e 's/".*$//'` 190 191ret=$? 192if [ "x$url" = "x" ]; then 193 ret=125 194 # try without the -e arg to sed. 195 url=`(curl -SsL https://registry.npmjs.org/npm/$t; echo "") \ 196 | sed 's/^.*tarball":"//' \ 197 | sed 's/".*$//'` 198 ret=$? 199 if [ "x$url" = "x" ]; then 200 ret=125 201 fi 202fi 203if [ $ret -ne 0 ]; then 204 echo "Failed to get tarball url for npm/$t" >&2 205 exit $ret 206fi 207 208 209echo "fetching: $url" >&2 210 211cd "$TMP" \ 212 && curl -SsL "$url" \ 213 | $tar -xzf - \ 214 && cd "$TMP"/* \ 215 && (ret=0 216 if [ $ret -ne 0 ]; then 217 echo "Aborted 0.x cleanup. Exiting." >&2 218 exit $ret 219 fi) \ 220 && (if [ "x$configures" = "x" ]; then 221 (exit 0) 222 else 223 echo "./configure $configures" 224 echo "$configures" > npmrc 225 fi) \ 226 && (if [ "$make" = "NOMAKE" ]; then 227 (exit 0) 228 elif "$make" uninstall install; then 229 (exit 0) 230 else 231 make="NOMAKE" 232 fi 233 if [ "$make" = "NOMAKE" ]; then 234 "$node" bin/npm-cli.js rm npm -gf 235 "$node" bin/npm-cli.js install -gf $("$node" bin/npm-cli.js pack | tail -1) 236 fi) \ 237 && cd "$BACK" \ 238 && rm -rf "$TMP" \ 239 && echo "It worked" 240 241ret=$? 242if [ $ret -ne 0 ]; then 243 echo "It failed" >&2 244fi 245exit $ret 246