mirror of
https://github.com/nvm-sh/nvm.git
synced 2026-07-18 12:58:21 +08:00
Code scanning - action / CodeQL-Build (push) Has been cancelled
Tests: `nvm install-latest-npm` / matrix (push) Has been cancelled
Tests: linting / eclint (push) Has been cancelled
Tests: linting / dockerfile_lint (push) Has been cancelled
Tests: linting / doctoc (push) Has been cancelled
Tests: linting / test_naming (push) Has been cancelled
Tests: linting / check_exec (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3, bash) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3, dash) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3, sh) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3, zsh) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3, bash) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3, dash) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3, sh) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3, zsh) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.15, bash) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.15, dash) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.15, sh) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.15, zsh) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.15, bash) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.15, dash) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.15, sh) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.15, zsh) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.19, bash) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.19, dash) (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.19, sh) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.19, bash) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.19, dash) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.19, sh) (push) Has been cancelled
Tests: alpine / fast x64 (alpine 3.19, zsh) (push) Has been cancelled
urchin tests / tests (bash, slow) (push) Has been cancelled
urchin tests / tests (bash, install_script) (push) Has been cancelled
urchin tests / tests (bash, installation_iojs) (push) Has been cancelled
Tests: release process / release (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (bash_completion, bash) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (install.sh, bash) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (nvm-exec, bash) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (nvm.sh, bash) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (nvm.sh, dash) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (nvm.sh, ksh) (push) Has been cancelled
Tests: shellcheck / shellcheck_matrix (nvm.sh, sh) (push) Has been cancelled
Tests: xenial / xenial (bash) (push) Has been cancelled
Tests: xenial / xenial (dash) (push) Has been cancelled
Tests: xenial / xenial (sh) (push) Has been cancelled
Tests: xenial / xenial (zsh) (push) Has been cancelled
Tests: alpine / musl-binary arm64 (alpine 3, node v24.9.0) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3, node v22.12.0) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.10, node v10.24.1) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.10, node v8.17.0) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.12, node v12.22.12) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.15, node v14.21.3) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.16, node v16.20.2) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.18, node v18.20.4) (push) Has been cancelled
Tests: alpine / musl-binary x64 (alpine 3.20, node v20.18.1) (push) Has been cancelled
Tests: fast / fast (bash, gawk) (push) Has been cancelled
Tests: fast / fast (dash, gawk) (push) Has been cancelled
Tests: installation_node / installation_node (zsh, without curl) (push) Has been cancelled
urchin tests / tests (bash, sourcing) (push) Has been cancelled
urchin tests / tests (dash, installation_iojs) (push) Has been cancelled
urchin tests / tests (dash, slow) (push) Has been cancelled
urchin tests / tests (dash, sourcing) (push) Has been cancelled
urchin tests / tests (sh, installation_iojs) (push) Has been cancelled
urchin tests / tests (sh, slow) (push) Has been cancelled
urchin tests / tests (sh, sourcing) (push) Has been cancelled
urchin tests / tests (zsh, installation_iojs) (push) Has been cancelled
urchin tests / tests (zsh, slow) (push) Has been cancelled
urchin tests / tests (zsh, sourcing) (push) Has been cancelled
update readme TOC / update readme TOC (push) Has been cancelled
Tests on Windows: `nvm install` / MSYS fail prefix nvm install (push) Has been cancelled
Tests on Windows: `nvm install` / MSYS nvm install (--default 12) (push) Has been cancelled
Tests on Windows: `nvm install` / MSYS nvm install (--lts) (push) Has been cancelled
Tests on Windows: `nvm install` / Cygwin nvm install (push) Has been cancelled
Tests: `nvm install-latest-npm` / nvm install-latest-npm (push) Has been cancelled
Tests: linting / all linting (push) Has been cancelled
Tests: xenial / all xenial tests (push) Has been cancelled
Tests on Windows: `nvm install` / tests, on windows (push) Has been cancelled
Tests: shellcheck / shellcheck (push) Has been cancelled
Tests: alpine / all alpine tests (push) Has been cancelled
Tests: fast / all fast tests (push) Has been cancelled
Tests: installation_iojs / all installation_iojs tests (push) Has been cancelled
Tests: fast / fast (zsh, gawk) (push) Has been cancelled
Tests: fast / fast (bash, mawk) (push) Has been cancelled
Tests: fast / fast (dash, mawk) (push) Has been cancelled
Tests: fast / fast (sh, mawk) (push) Has been cancelled
Tests: fast / fast (zsh, mawk) (push) Has been cancelled
Tests: installation_iojs / installation_iojs without curl (dash) (push) Has been cancelled
Tests: installation_iojs / installation_iojs without curl (sh) (push) Has been cancelled
Tests: installation_iojs / installation_iojs without curl (zsh) (push) Has been cancelled
Tests: installation_iojs / actually compile io.js from source (gcc 4.9 container) (push) Has been cancelled
Tests: installation_node / installation_node (bash) (push) Has been cancelled
Tests: installation_node / installation_node (bash, without curl) (push) Has been cancelled
Tests: installation_node / installation_node (dash) (push) Has been cancelled
Tests: installation_node / installation_node (dash, without curl) (push) Has been cancelled
Tests: installation_node / installation_node (sh) (push) Has been cancelled
Tests: installation_node / installation_node (sh, without curl) (push) Has been cancelled
Tests: installation_node / installation_node (zsh) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 10, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 10, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 12, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 12, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 14, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 14, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 16, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 18, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 18, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 21, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Debian) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Ubuntu-20.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, --lts, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 10, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 11, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 12, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 14, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 16, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 18, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 21, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, --lts, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 10, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 11, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 12, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 14, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 16, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 18, Alpine) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (script, 21, Alpine) (push) Has been cancelled
urchin tests / all test suites, all shells (push) Has been cancelled
Tests: alpine / fast arm64 (alpine 3.19, zsh) (push) Has been cancelled
Tests: alpine / musl-binary arm64 (alpine 3, node v22.21.1) (push) Has been cancelled
Tests: alpine / musl-binary arm64 (alpine 3.20, node v20.20.1) (push) Has been cancelled
Tests on Windows: `nvm install` / MSYS nvm install (--no-progress 10) (push) Has been cancelled
Tests: fast / fast (sh, gawk) (push) Has been cancelled
Tests: installation_iojs / installation_iojs without curl (bash) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 16, Ubuntu-18.04) (push) Has been cancelled
Tests on Windows: `nvm install` / WSL nvm install (, 21, Debian) (push) Has been cancelled
Tests: installation_node / all installation_node tests (push) Has been cancelled
`install.sh` has its own `nvm_download`,
which joined `"$@"` into a single string with `nvm_echo` and rewrote the curl-style flags with `sed`,
then ran the result through `eval command wget $ARGS`.
Flattening argv into a string is the root cause: every argument was re-parsed by the shell,
so any shell metacharacter in a legitimate value was interpreted rather than passed through.
An `$NVM_DIR` containing a space silently word-split and wrote to the wrong path,
an apostrophe or parentheses were a syntax error,
a glob character expanded against the cwd,
and an `$NVM_SOURCE` mirror URL with an `&` in its query string backgrounded `wget` and ran the remainder as a bogus command.
The `sed` rewrites were also unanchored substring replacements that would mangle a URL legitimately containing `-o `,
and `ARGS` was an undeclared global that `nvm_reset` never unset.
Translate the flags per-argument with a POSIX `set --` loop and invoke `command wget "$@"` instead,
so each argument stays a literal argv element.
This is the same shape `nvm.sh`'s `nvm_download` has used since 6d870d18,
and it stops the two implementations from diverging.
Unlike `nvm.sh`, no mirror-supplied data reaches this function:
its arguments come only from `$NVM_SOURCE`, `$NVM_INSTALL_GITHUB_REPO`, `$NVM_INSTALL_VERSION`, `$NVM_DIR`, `$XDG_CONFIG_HOME`, and `$HOME`, and `install.sh`'s `nvm_latest_version` is a hardcoded string rather than `nvm.sh`'s `nvm_get_latest`.
This is therefore a robustness fix and not a security one,
since the only party who can influence these arguments is the one already running the installer.
534 lines
18 KiB
Bash
Executable File
534 lines
18 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
{ # this ensures the entire script is downloaded #
|
|
|
|
nvm_has() {
|
|
type "$1" > /dev/null 2>&1
|
|
}
|
|
|
|
# resolves like `command "${1}"` does: only executables on the PATH,
|
|
# ignoring shell functions and aliases
|
|
nvm_has_executable() {
|
|
(
|
|
# `|| true` so that shells with errexit-style options (eg, zsh's ERR_RETURN)
|
|
# do not abort the subshell when the name is not an alias or a function
|
|
unalias "${1-}" 2>/dev/null || true
|
|
unset -f "${1-}" 2>/dev/null || true
|
|
command -v "${1-}" > /dev/null 2>&1
|
|
)
|
|
}
|
|
|
|
nvm_echo() {
|
|
command printf %s\\n "$*" 2>/dev/null
|
|
}
|
|
|
|
if [ -z "${BASH_VERSION}" ] || [ -n "${ZSH_VERSION}" ]; then
|
|
# shellcheck disable=SC2016
|
|
nvm_echo >&2 'Error: the install instructions explicitly say to pipe the install script to `bash`; please follow them'
|
|
exit 1
|
|
fi
|
|
|
|
nvm_grep() {
|
|
GREP_OPTIONS='' command grep "$@"
|
|
}
|
|
|
|
nvm_default_install_dir() {
|
|
[ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm"
|
|
}
|
|
|
|
nvm_install_dir() {
|
|
if [ -n "$NVM_DIR" ]; then
|
|
printf %s "${NVM_DIR}"
|
|
else
|
|
nvm_default_install_dir
|
|
fi
|
|
}
|
|
|
|
nvm_latest_version() {
|
|
nvm_echo "v0.40.6"
|
|
}
|
|
|
|
nvm_profile_is_bash_or_zsh() {
|
|
local TEST_PROFILE
|
|
TEST_PROFILE="${1-}"
|
|
case "${TEST_PROFILE-}" in
|
|
*"/.bashrc" | *"/.bash_profile" | *"/.zshrc" | *"/.zprofile")
|
|
return
|
|
;;
|
|
*)
|
|
return 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
#
|
|
# Outputs the location to NVM depending on:
|
|
# * The availability of $NVM_SOURCE
|
|
# * The presence of $NVM_INSTALL_GITHUB_REPO
|
|
# * The method used ("script" or "git" in the script, defaults to "git")
|
|
# NVM_SOURCE always takes precedence unless the method is "script-nvm-exec"
|
|
#
|
|
nvm_source() {
|
|
local NVM_GITHUB_REPO
|
|
NVM_GITHUB_REPO="${NVM_INSTALL_GITHUB_REPO:-nvm-sh/nvm}"
|
|
if [ "${NVM_GITHUB_REPO}" != 'nvm-sh/nvm' ]; then
|
|
{ nvm_echo >&2 "$(cat)" ; } << EOF
|
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
@ WARNING: REMOTE REPO IDENTIFICATION HAS CHANGED! @
|
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
|
|
|
|
The default repository for this install is \`nvm-sh/nvm\`,
|
|
but the environment variable \`\$NVM_INSTALL_GITHUB_REPO\` is
|
|
currently set to \`${NVM_GITHUB_REPO}\`.
|
|
|
|
If this is not intentional, interrupt this installation and
|
|
verify your environment variables.
|
|
EOF
|
|
fi
|
|
local NVM_VERSION
|
|
NVM_VERSION="${NVM_INSTALL_VERSION:-$(nvm_latest_version)}"
|
|
local NVM_METHOD
|
|
NVM_METHOD="$1"
|
|
local NVM_SOURCE_URL
|
|
NVM_SOURCE_URL="$NVM_SOURCE"
|
|
if [ "_$NVM_METHOD" = "_script-nvm-exec" ]; then
|
|
NVM_SOURCE_URL="https://raw.githubusercontent.com/${NVM_GITHUB_REPO}/${NVM_VERSION}/nvm-exec"
|
|
elif [ "_$NVM_METHOD" = "_script-nvm-bash-completion" ]; then
|
|
NVM_SOURCE_URL="https://raw.githubusercontent.com/${NVM_GITHUB_REPO}/${NVM_VERSION}/bash_completion"
|
|
elif [ -z "$NVM_SOURCE_URL" ]; then
|
|
if [ "_$NVM_METHOD" = "_script" ]; then
|
|
NVM_SOURCE_URL="https://raw.githubusercontent.com/${NVM_GITHUB_REPO}/${NVM_VERSION}/nvm.sh"
|
|
elif [ "_$NVM_METHOD" = "_git" ] || [ -z "$NVM_METHOD" ]; then
|
|
NVM_SOURCE_URL="https://github.com/${NVM_GITHUB_REPO}.git"
|
|
else
|
|
nvm_echo >&2 "Unexpected value \"$NVM_METHOD\" for \$NVM_METHOD"
|
|
return 1
|
|
fi
|
|
fi
|
|
nvm_echo "$NVM_SOURCE_URL"
|
|
}
|
|
|
|
#
|
|
# Node.js version to install
|
|
#
|
|
nvm_node_version() {
|
|
nvm_echo "$NODE_VERSION"
|
|
}
|
|
|
|
nvm_download() {
|
|
if nvm_has_executable "curl"; then
|
|
command curl --fail --compressed -q "$@"
|
|
elif nvm_has_executable "wget"; then
|
|
# Emulate curl with wget
|
|
local NVM_DOWNLOAD_WGET_COUNT
|
|
NVM_DOWNLOAD_WGET_COUNT=$#
|
|
local NVM_DOWNLOAD_WGET_SKIP
|
|
NVM_DOWNLOAD_WGET_SKIP=0
|
|
local NVM_DOWNLOAD_WGET_ARG
|
|
for NVM_DOWNLOAD_WGET_ARG in "$@"; do
|
|
if [ "${NVM_DOWNLOAD_WGET_SKIP}" = '1' ]; then
|
|
NVM_DOWNLOAD_WGET_SKIP=0
|
|
continue
|
|
fi
|
|
case "${NVM_DOWNLOAD_WGET_ARG}" in
|
|
'--progress-bar') set -- "$@" '--progress=bar' ;;
|
|
'--compressed') : ;;
|
|
'--fail') : ;;
|
|
'-L') : ;;
|
|
'-I') set -- "$@" '--server-response' ;;
|
|
'-s') set -- "$@" '-q' ;;
|
|
'-sS') set -- "$@" '-nv' ;;
|
|
'-o') set -- "$@" '-O' ;;
|
|
'-C') NVM_DOWNLOAD_WGET_SKIP=1; set -- "$@" '-c' ;;
|
|
*) set -- "$@" "${NVM_DOWNLOAD_WGET_ARG}" ;;
|
|
esac
|
|
done
|
|
shift "${NVM_DOWNLOAD_WGET_COUNT}"
|
|
command wget "$@"
|
|
fi
|
|
}
|
|
|
|
install_nvm_from_git() {
|
|
local INSTALL_DIR
|
|
INSTALL_DIR="$(nvm_install_dir)"
|
|
local NVM_VERSION
|
|
NVM_VERSION="${NVM_INSTALL_VERSION:-$(nvm_latest_version)}"
|
|
if [ -n "${NVM_INSTALL_VERSION:-}" ]; then
|
|
# Check if version is an existing ref
|
|
if command git ls-remote "$(nvm_source "git")" "$NVM_VERSION" | nvm_grep -q "$NVM_VERSION" ; then
|
|
:
|
|
# Check if version is an existing changeset
|
|
elif ! nvm_download -o /dev/null "$(nvm_source "script-nvm-exec")"; then
|
|
nvm_echo >&2 "Failed to find '$NVM_VERSION' version."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
local fetch_error
|
|
if [ -d "$INSTALL_DIR/.git" ]; then
|
|
# Updating repo
|
|
nvm_echo "=> nvm is already installed in $INSTALL_DIR, trying to update using git"
|
|
command printf '\r=> '
|
|
fetch_error="Failed to update nvm with $NVM_VERSION, run 'git fetch' in $INSTALL_DIR yourself."
|
|
else
|
|
fetch_error="Failed to fetch origin with $NVM_VERSION. Please report this!"
|
|
nvm_echo "=> Downloading nvm from git to '$INSTALL_DIR'"
|
|
command printf '\r=> '
|
|
mkdir -p "${INSTALL_DIR}" || {
|
|
nvm_echo >&2 "Failed to create directory '${INSTALL_DIR}'"
|
|
exit 2
|
|
}
|
|
if [ "$(ls -A "${INSTALL_DIR}")" ]; then
|
|
# Initializing repo
|
|
command git init "${INSTALL_DIR}" || {
|
|
nvm_echo >&2 'Failed to initialize nvm repo. Please report this!'
|
|
exit 2
|
|
}
|
|
command git --git-dir="${INSTALL_DIR}/.git" remote add origin "$(nvm_source)" 2> /dev/null \
|
|
|| command git --git-dir="${INSTALL_DIR}/.git" remote set-url origin "$(nvm_source)" || {
|
|
nvm_echo >&2 'Failed to add remote "origin" (or set the URL). Please report this!'
|
|
exit 2
|
|
}
|
|
else
|
|
# Cloning repo
|
|
command git clone -o origin "$(nvm_source)" --depth=1 "${INSTALL_DIR}" || {
|
|
nvm_echo >&2 'Failed to clone nvm repo. Please report this!'
|
|
exit 2
|
|
}
|
|
fi
|
|
fi
|
|
# Try to fetch tag
|
|
if command git --git-dir="$INSTALL_DIR"/.git --work-tree="$INSTALL_DIR" fetch origin tag "$NVM_VERSION" --depth=1 2>/dev/null; then
|
|
:
|
|
# Fetch given version
|
|
elif ! command git --git-dir="$INSTALL_DIR"/.git --work-tree="$INSTALL_DIR" fetch origin "$NVM_VERSION" --depth=1; then
|
|
nvm_echo >&2 "$fetch_error"
|
|
exit 1
|
|
fi
|
|
command git -c advice.detachedHead=false --git-dir="$INSTALL_DIR"/.git --work-tree="$INSTALL_DIR" checkout -f --quiet FETCH_HEAD || {
|
|
nvm_echo >&2 "Failed to checkout the given version $NVM_VERSION. Please report this!"
|
|
exit 2
|
|
}
|
|
if [ -n "$(command git --git-dir="$INSTALL_DIR"/.git --work-tree="$INSTALL_DIR" show-ref refs/heads/master)" ]; then
|
|
if command git --no-pager --git-dir="$INSTALL_DIR"/.git --work-tree="$INSTALL_DIR" branch --quiet 2>/dev/null; then
|
|
command git --no-pager --git-dir="$INSTALL_DIR"/.git --work-tree="$INSTALL_DIR" branch --quiet -D master >/dev/null 2>&1
|
|
else
|
|
nvm_echo >&2 "Your version of git is out of date. Please update it!"
|
|
command git --no-pager --git-dir="$INSTALL_DIR"/.git --work-tree="$INSTALL_DIR" branch -D master >/dev/null 2>&1
|
|
fi
|
|
fi
|
|
|
|
nvm_echo "=> Compressing and cleaning up git repository"
|
|
if ! command git --git-dir="$INSTALL_DIR"/.git --work-tree="$INSTALL_DIR" reflog expire --expire=now --all; then
|
|
nvm_echo >&2 "Your version of git is out of date. Please update it!"
|
|
fi
|
|
if ! command git --git-dir="$INSTALL_DIR"/.git --work-tree="$INSTALL_DIR" gc --auto --aggressive --prune=now ; then
|
|
nvm_echo >&2 "Your version of git is out of date. Please update it!"
|
|
fi
|
|
return
|
|
}
|
|
|
|
#
|
|
# Automatically install Node.js
|
|
#
|
|
nvm_install_node() {
|
|
local NODE_VERSION_LOCAL
|
|
NODE_VERSION_LOCAL="$(nvm_node_version)"
|
|
|
|
if [ -z "$NODE_VERSION_LOCAL" ]; then
|
|
return 0
|
|
fi
|
|
|
|
nvm_echo "=> Installing Node.js version $NODE_VERSION_LOCAL"
|
|
nvm install "$NODE_VERSION_LOCAL"
|
|
local CURRENT_NVM_NODE
|
|
|
|
CURRENT_NVM_NODE="$(nvm_version current)"
|
|
if [ "$(nvm_version "$NODE_VERSION_LOCAL")" = "$CURRENT_NVM_NODE" ]; then
|
|
nvm_echo "=> Node.js version $NODE_VERSION_LOCAL has been successfully installed"
|
|
else
|
|
nvm_echo >&2 "Failed to install Node.js $NODE_VERSION_LOCAL"
|
|
fi
|
|
}
|
|
|
|
install_nvm_as_script() {
|
|
local INSTALL_DIR
|
|
INSTALL_DIR="$(nvm_install_dir)"
|
|
local NVM_SOURCE_LOCAL
|
|
NVM_SOURCE_LOCAL="$(nvm_source script)"
|
|
local NVM_EXEC_SOURCE
|
|
NVM_EXEC_SOURCE="$(nvm_source script-nvm-exec)"
|
|
local NVM_BASH_COMPLETION_SOURCE
|
|
NVM_BASH_COMPLETION_SOURCE="$(nvm_source script-nvm-bash-completion)"
|
|
|
|
# Downloading to $INSTALL_DIR
|
|
mkdir -p "$INSTALL_DIR" || {
|
|
nvm_echo >&2 "Failed to create directory '$INSTALL_DIR'"
|
|
return 1
|
|
}
|
|
if [ -f "$INSTALL_DIR/nvm.sh" ]; then
|
|
nvm_echo "=> nvm is already installed in $INSTALL_DIR, trying to update the script"
|
|
else
|
|
nvm_echo "=> Downloading nvm as script to '$INSTALL_DIR'"
|
|
fi
|
|
nvm_download -s "$NVM_SOURCE_LOCAL" -o "$INSTALL_DIR/nvm.sh" || {
|
|
nvm_echo >&2 "Failed to download '$NVM_SOURCE_LOCAL'"
|
|
return 1
|
|
} &
|
|
nvm_download -s "$NVM_EXEC_SOURCE" -o "$INSTALL_DIR/nvm-exec" || {
|
|
nvm_echo >&2 "Failed to download '$NVM_EXEC_SOURCE'"
|
|
return 2
|
|
} &
|
|
nvm_download -s "$NVM_BASH_COMPLETION_SOURCE" -o "$INSTALL_DIR/bash_completion" || {
|
|
nvm_echo >&2 "Failed to download '$NVM_BASH_COMPLETION_SOURCE'"
|
|
return 2
|
|
} &
|
|
for job in $(jobs -p | command sort)
|
|
do
|
|
wait "$job" || return $?
|
|
done
|
|
chmod a+x "$INSTALL_DIR/nvm-exec" || {
|
|
nvm_echo >&2 "Failed to mark '$INSTALL_DIR/nvm-exec' as executable"
|
|
return 3
|
|
}
|
|
}
|
|
|
|
nvm_try_profile() {
|
|
if [ -z "${1-}" ] || [ ! -f "${1}" ]; then
|
|
return 1
|
|
fi
|
|
nvm_echo "${1}"
|
|
}
|
|
|
|
#
|
|
# Detect profile file if not specified as environment variable
|
|
# (eg: PROFILE=~/.myprofile)
|
|
# The echo'ed path is guaranteed to be an existing file
|
|
# Otherwise, an empty string is returned
|
|
#
|
|
nvm_detect_profile() {
|
|
if [ "${PROFILE-}" = '/dev/null' ]; then
|
|
# the user has specifically requested NOT to have nvm touch their profile
|
|
return
|
|
fi
|
|
|
|
if [ -n "${PROFILE}" ] && [ -f "${PROFILE}" ]; then
|
|
nvm_echo "${PROFILE}"
|
|
return
|
|
fi
|
|
|
|
local DETECTED_PROFILE
|
|
DETECTED_PROFILE=''
|
|
|
|
if [ "${SHELL#*bash}" != "$SHELL" ]; then
|
|
if [ -f "$HOME/.bashrc" ]; then
|
|
DETECTED_PROFILE="$HOME/.bashrc"
|
|
elif [ -f "$HOME/.bash_profile" ]; then
|
|
DETECTED_PROFILE="$HOME/.bash_profile"
|
|
fi
|
|
elif [ "${SHELL#*zsh}" != "$SHELL" ]; then
|
|
if [ -f "${ZDOTDIR:-${HOME}}/.zshrc" ]; then
|
|
DETECTED_PROFILE="${ZDOTDIR:-${HOME}}/.zshrc"
|
|
elif [ -f "${ZDOTDIR:-${HOME}}/.zprofile" ]; then
|
|
DETECTED_PROFILE="${ZDOTDIR:-${HOME}}/.zprofile"
|
|
fi
|
|
fi
|
|
|
|
if [ -z "$DETECTED_PROFILE" ]; then
|
|
for EACH_PROFILE in ".profile" ".bashrc" ".bash_profile" ".zprofile" ".zshrc"
|
|
do
|
|
if DETECTED_PROFILE="$(nvm_try_profile "${ZDOTDIR:-${HOME}}/${EACH_PROFILE}")"; then
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ -n "$DETECTED_PROFILE" ]; then
|
|
nvm_echo "$DETECTED_PROFILE"
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Check whether the user has any globally-installed npm modules in their system
|
|
# Node, and warn them if so.
|
|
#
|
|
nvm_check_global_modules() {
|
|
local NPM_COMMAND
|
|
NPM_COMMAND="$(command -v npm 2>/dev/null)" || return 0
|
|
[ -n "${NVM_DIR}" ] && [ -z "${NPM_COMMAND%%"$NVM_DIR"/*}" ] && return 0
|
|
|
|
local NPM_VERSION
|
|
NPM_VERSION="$(npm --version)"
|
|
NPM_VERSION="${NPM_VERSION:--1}"
|
|
[ "${NPM_VERSION%%[!-0-9]*}" -gt 0 ] || return 0
|
|
|
|
local NPM_GLOBAL_MODULES
|
|
NPM_GLOBAL_MODULES="$(
|
|
npm list -g --depth=0 |
|
|
command sed -e '/ npm@/d' -e '/ (empty)$/d'
|
|
)"
|
|
|
|
local MODULE_COUNT
|
|
MODULE_COUNT="$(
|
|
command printf %s\\n "$NPM_GLOBAL_MODULES" |
|
|
command sed -ne '1!p' | # Remove the first line
|
|
wc -l | command tr -d ' ' # Count entries
|
|
)"
|
|
|
|
if [ "${MODULE_COUNT}" != '0' ]; then
|
|
# shellcheck disable=SC2016
|
|
nvm_echo '=> You currently have modules installed globally with `npm`. These will no'
|
|
# shellcheck disable=SC2016
|
|
nvm_echo '=> longer be linked to the active version of Node when you install a new node'
|
|
# shellcheck disable=SC2016
|
|
nvm_echo '=> with `nvm`; and they may (depending on how you construct your `$PATH`)'
|
|
# shellcheck disable=SC2016
|
|
nvm_echo '=> override the binaries of modules installed with `nvm`:'
|
|
nvm_echo
|
|
|
|
command printf %s\\n "$NPM_GLOBAL_MODULES"
|
|
nvm_echo '=> If you wish to uninstall them at a later point (or re-install them under your'
|
|
# shellcheck disable=SC2016
|
|
nvm_echo '=> `nvm` node installs), you can remove them from the system Node as follows:'
|
|
nvm_echo
|
|
nvm_echo ' $ nvm use system'
|
|
nvm_echo ' $ npm uninstall -g a_module'
|
|
nvm_echo
|
|
fi
|
|
}
|
|
|
|
nvm_do_install() {
|
|
if [ -n "${NVM_DIR-}" ] && ! [ -d "${NVM_DIR}" ]; then
|
|
if [ -e "${NVM_DIR}" ]; then
|
|
nvm_echo >&2 "File \"${NVM_DIR}\" has the same name as installation directory."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${NVM_DIR}" = "$(nvm_default_install_dir)" ]; then
|
|
mkdir "${NVM_DIR}" || {
|
|
nvm_echo >&2 "Failed to create directory '${NVM_DIR}'"
|
|
exit 2
|
|
}
|
|
else
|
|
nvm_echo >&2 "You have \$NVM_DIR set to \"${NVM_DIR}\", but that directory does not exist. Check your profile files and environment."
|
|
exit 1
|
|
fi
|
|
fi
|
|
# Disable the optional which check, https://www.shellcheck.net/wiki/SC2230
|
|
# shellcheck disable=SC2230
|
|
if nvm_has xcode-select && [ "$(xcode-select -p >/dev/null 2>/dev/null ; echo $?)" = '2' ] && [ "$(which git)" = '/usr/bin/git' ] && [ "$(which curl)" = '/usr/bin/curl' ]; then
|
|
nvm_echo >&2 'You may be on a Mac, and need to install the Xcode Command Line Developer Tools.'
|
|
# shellcheck disable=SC2016
|
|
nvm_echo >&2 'If so, run `xcode-select --install` and try again. If not, please report this!'
|
|
exit 1
|
|
fi
|
|
if [ -z "${METHOD}" ]; then
|
|
# Autodetect install method
|
|
if nvm_has git; then
|
|
install_nvm_from_git
|
|
elif nvm_has_executable curl || nvm_has_executable wget; then
|
|
install_nvm_as_script
|
|
else
|
|
nvm_echo >&2 'You need git, curl, or wget to install nvm'
|
|
exit 1
|
|
fi
|
|
elif [ "${METHOD}" = 'git' ]; then
|
|
if ! nvm_has git; then
|
|
nvm_echo >&2 "You need git to install nvm"
|
|
exit 1
|
|
fi
|
|
install_nvm_from_git
|
|
elif [ "${METHOD}" = 'script' ]; then
|
|
if ! nvm_has_executable curl && ! nvm_has_executable wget; then
|
|
nvm_echo >&2 "You need curl or wget to install nvm"
|
|
exit 1
|
|
fi
|
|
install_nvm_as_script
|
|
else
|
|
nvm_echo >&2 "The environment variable \$METHOD is set to \"${METHOD}\", which is not recognized as a valid installation method."
|
|
exit 1
|
|
fi
|
|
|
|
nvm_echo
|
|
|
|
local NVM_PROFILE
|
|
NVM_PROFILE="$(nvm_detect_profile)"
|
|
local PROFILE_INSTALL_DIR
|
|
PROFILE_INSTALL_DIR="$(nvm_install_dir | command sed "s:^$HOME:\$HOME:")"
|
|
|
|
SOURCE_STR="\\nexport NVM_DIR=\"${PROFILE_INSTALL_DIR}\"\\n[ -s \"\$NVM_DIR/nvm.sh\" ] && \\. \"\$NVM_DIR/nvm.sh\" # This loads nvm\\n"
|
|
|
|
# shellcheck disable=SC2016
|
|
COMPLETION_STR='[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion\n'
|
|
BASH_OR_ZSH=false
|
|
|
|
if [ "${PROFILE-}" = '/dev/null' ] ; then
|
|
# the user has specifically requested NOT to have nvm touch their profile
|
|
echo
|
|
elif [ -z "${NVM_PROFILE-}" ] ; then
|
|
local TRIED_PROFILE
|
|
if [ -n "${PROFILE}" ]; then
|
|
TRIED_PROFILE="${PROFILE} (as defined in \$PROFILE), "
|
|
fi
|
|
nvm_echo "=> Profile not found. Tried ${TRIED_PROFILE-}~/.bashrc, ~/.bash_profile, ~/.zprofile, ~/.zshrc, and ~/.profile."
|
|
nvm_echo "=> Create one of them and run this script again"
|
|
nvm_echo " OR"
|
|
nvm_echo "=> Append the following lines to the correct file yourself:"
|
|
command printf '%b' "${SOURCE_STR}"
|
|
nvm_echo
|
|
else
|
|
if nvm_profile_is_bash_or_zsh "${NVM_PROFILE-}"; then
|
|
BASH_OR_ZSH=true
|
|
fi
|
|
if ! command grep -qc '/nvm.sh' "$NVM_PROFILE"; then
|
|
nvm_echo "=> Appending nvm source string to $NVM_PROFILE"
|
|
command printf '%b' "${SOURCE_STR}" >> "$NVM_PROFILE"
|
|
else
|
|
nvm_echo "=> nvm source string already in ${NVM_PROFILE}"
|
|
fi
|
|
# shellcheck disable=SC2016
|
|
if ${BASH_OR_ZSH} && ! command grep -qc '$NVM_DIR/bash_completion' "$NVM_PROFILE"; then
|
|
nvm_echo "=> Appending bash_completion source string to $NVM_PROFILE"
|
|
command printf '%b' "$COMPLETION_STR" >> "$NVM_PROFILE"
|
|
else
|
|
nvm_echo "=> bash_completion source string already in ${NVM_PROFILE}"
|
|
fi
|
|
fi
|
|
if ${BASH_OR_ZSH} && [ -z "${NVM_PROFILE-}" ] ; then
|
|
nvm_echo "=> Please also append the following lines to the if you are using bash/zsh shell:"
|
|
command printf "${COMPLETION_STR}"
|
|
fi
|
|
|
|
# Source nvm
|
|
# shellcheck source=/dev/null
|
|
\. "$(nvm_install_dir)/nvm.sh"
|
|
|
|
nvm_check_global_modules
|
|
|
|
nvm_install_node
|
|
|
|
nvm_reset
|
|
|
|
nvm_echo "=> Close and reopen your terminal to start using nvm or run the following to use it now:"
|
|
command printf '%b' "${SOURCE_STR}"
|
|
if ${BASH_OR_ZSH} ; then
|
|
command printf "${COMPLETION_STR}"
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Unsets the various functions defined
|
|
# during the execution of the install script
|
|
#
|
|
nvm_reset() {
|
|
unset -f nvm_has nvm_has_executable nvm_install_dir nvm_latest_version nvm_profile_is_bash_or_zsh \
|
|
nvm_source nvm_node_version nvm_download install_nvm_from_git nvm_install_node \
|
|
install_nvm_as_script nvm_try_profile nvm_detect_profile nvm_check_global_modules \
|
|
nvm_do_install nvm_reset nvm_default_install_dir nvm_grep
|
|
}
|
|
|
|
[ "_$NVM_ENV" = "_testing" ] || nvm_do_install
|
|
|
|
} # this ensures the entire script is downloaded #
|