[Fix] install.sh: only write $HOME when $NVM_DIR is inside it
The profile line was built by replacing a leading `$HOME` with `sed`, without a path boundary, and with `$HOME` treated as a regex. With `HOME=/home/me` and `NVM_DIR=/home/me2/nvm`, or with `HOME=/` and `NVM_DIR=/usr/local/nvm`, the profile got `export NVM_DIR="$HOME2/nvm"` or `export NVM_DIR="$HOMEusr/local/nvm"`, which expand to the wrong directory, so nvm does not load in new shells. A `.` in `$HOME` matched any character, a `:` in it broke the `sed` expression, and a trailing slash on it left `$HOME.nvm`. Match `$HOME` literally, as a whole path component, and leave the path absolute when `$HOME` is empty.
This commit is contained in:
1 parent
93da6595ce
commit
c7a1b344da
2 files changed
+72
-1
No files matched your search
+7
-1
@@ -495,7 +495,13 @@ nvm_do_install() {
|
||||
local NVM_PROFILE
|
||||
NVM_PROFILE="$(nvm_detect_profile)"
|
||||
local PROFILE_INSTALL_DIR
|
||||
PROFILE_INSTALL_DIR="$(nvm_install_dir | command sed "s:^$HOME:\$HOME:")"
|
||||
PROFILE_INSTALL_DIR="$(nvm_install_dir)"
|
||||
# an empty `$HOME` would make every absolute path look like it is inside it
|
||||
if [ -n "${HOME-}" ]; then
|
||||
case "${PROFILE_INSTALL_DIR}/" in
|
||||
"${HOME}"/*) PROFILE_INSTALL_DIR="\$HOME${PROFILE_INSTALL_DIR#"${HOME}"}" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
SOURCE_STR="\\nexport NVM_DIR=\"${PROFILE_INSTALL_DIR}\"\\n[ -s \"\$NVM_DIR/nvm.sh\" ] && \\. \"\$NVM_DIR/nvm.sh\" # This loads nvm\\n"
|
||||
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
#!/bin/sh
|
||||
|
||||
die () { echo "$@" ; cleanup ; exit 1; }
|
||||
|
||||
cleanup() {
|
||||
unset -f install_nvm_from_git install_nvm_as_script nvm_detect_profile nvm_has
|
||||
unset -f nvm_check_global_modules nvm_install_node
|
||||
unset -f setup cleanup die assert_nvm_dir_line
|
||||
unset NVM_ENV METHOD PROFILE
|
||||
rm -rf "${TMPDIR_FOR_TEST-}" 2>/dev/null
|
||||
}
|
||||
|
||||
setup() {
|
||||
NVM_ENV=testing \. ../../install.sh
|
||||
|
||||
# Mock installation functions to do nothing
|
||||
install_nvm_from_git() { :; }
|
||||
install_nvm_as_script() { :; }
|
||||
nvm_check_global_modules() { :; }
|
||||
nvm_install_node() { :; }
|
||||
|
||||
# Mock nvm_has to return true for git
|
||||
nvm_has() {
|
||||
case "$1" in
|
||||
git) return 0 ;;
|
||||
xcode-select) return 1 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# no profile found, so the lines to add are printed
|
||||
nvm_detect_profile() {
|
||||
echo ""
|
||||
}
|
||||
}
|
||||
|
||||
TMPDIR_FOR_TEST="$(mktemp -d)"
|
||||
TEST_HOME="${TMPDIR_FOR_TEST}/home"
|
||||
mkdir -p "${TEST_HOME}/.nvm" "${TEST_HOME}2/nvm" "${TMPDIR_FOR_TEST}/a.b/.nvm" "${TMPDIR_FOR_TEST}/axb/.nvm" "${TMPDIR_FOR_TEST}/c:d/.nvm"
|
||||
|
||||
# `nvm_do_install` unsets every `nvm_` function when it finishes, so each run sources the installer and mocks afresh.
|
||||
assert_nvm_dir_line() {
|
||||
setup
|
||||
OUTPUT="$(HOME="$1" PROFILE='' METHOD='' NVM_DIR="$2" nvm_do_install 2>/dev/null)"
|
||||
EXPECTED="export NVM_DIR=\"$3\""
|
||||
echo "${OUTPUT}" | command grep -qxF "${EXPECTED}" || die "HOME=$1 NVM_DIR=$2: expected line >${EXPECTED}<; got >${OUTPUT}<"
|
||||
}
|
||||
|
||||
# inside $HOME: written relative to $HOME
|
||||
assert_nvm_dir_line "${TEST_HOME}" "${TEST_HOME}/.nvm" '$HOME/.nvm'
|
||||
|
||||
# a sibling directory whose name starts with $HOME is not inside $HOME
|
||||
assert_nvm_dir_line "${TEST_HOME}" "${TEST_HOME}2/nvm" "${TEST_HOME}2/nvm"
|
||||
|
||||
# with HOME=/, every absolute path starts with $HOME
|
||||
assert_nvm_dir_line '/' "${TEST_HOME}2/nvm" "${TEST_HOME}2/nvm"
|
||||
|
||||
# $HOME is matched literally, not as a regex
|
||||
assert_nvm_dir_line "${TMPDIR_FOR_TEST}/a.b" "${TMPDIR_FOR_TEST}/axb/.nvm" "${TMPDIR_FOR_TEST}/axb/.nvm"
|
||||
assert_nvm_dir_line "${TMPDIR_FOR_TEST}/c:d" "${TMPDIR_FOR_TEST}/c:d/.nvm" '$HOME/.nvm'
|
||||
|
||||
# with an empty HOME, no path is inside it
|
||||
assert_nvm_dir_line '' "${TEST_HOME}/.nvm" "${TEST_HOME}/.nvm"
|
||||
|
||||
cleanup
|
||||
Reference in new issue
Block a user