[Refactor] install.sh: check profile lines through one comment-aware helper

`nvm_do_install` checked for its `nvm.sh` and `bash_completion` source lines
with two separate regexes that each had to skip commented-out lines.
Move that into `nvm_profile_has_line`,
which strips whole-line comments before matching,
and test the `bash_completion` line and an already set up profile too.
This commit is contained in:
NUAAwqy authored and Jordan Harband committed 2026-10-29 17:46:35 +00:00
1 parent db03e5e1c3
commit edde7ce995
2 files changed
+101 -3

No files matched your search

+8 -3
View File
@@ -48,6 +48,11 @@ nvm_latest_version() {
nvm_echo "v0.40.8"
}
nvm_profile_has_line() {
# a commented-out line sources nothing, so it must not count as already present
command sed 's/^[[:space:]]*#.*//' "$1" | nvm_grep -q "$2"
}
nvm_profile_is_bash_or_zsh() {
local TEST_PROFILE
TEST_PROFILE="${1-}"
@@ -527,14 +532,14 @@ nvm_do_install() {
if nvm_profile_is_bash_or_zsh "${NVM_PROFILE-}"; then
BASH_OR_ZSH=true
fi
if ! command grep -qc '^[[:space:]]*[^#[:space:]].*/nvm\.sh' "$NVM_PROFILE"; then
if ! nvm_profile_has_line "${NVM_PROFILE}" '/nvm.sh'; 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 '^[[:space:]]*[^#[:space:]].*\$NVM_DIR/bash_completion' "$NVM_PROFILE"; then
if ${BASH_OR_ZSH} && ! nvm_profile_has_line "${NVM_PROFILE}" '$NVM_DIR/bash_completion'; then
nvm_echo "=> Appending bash_completion source string to $NVM_PROFILE"
if [ -n "$(command tail -c 1 "$NVM_PROFILE")" ]; then
nvm_echo >> "$NVM_PROFILE"
@@ -574,7 +579,7 @@ 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_is_wsl nvm_check_global_modules \
nvm_do_install nvm_reset nvm_default_install_dir nvm_grep
nvm_do_install nvm_reset nvm_default_install_dir nvm_grep nvm_profile_has_line
}
[ "_$NVM_ENV" = "_testing" ] || nvm_do_install
+93
View File
@@ -0,0 +1,93 @@
#!/bin/sh
NVM_TEST_DIR=''
NVM_PROFILE_PATH=''
die () { echo "$@" ; cleanup ; exit 1; }
cleanup() {
if [ -n "${NVM_TEST_DIR}" ] && [ -d "${NVM_TEST_DIR}" ]; then
rm -rf "${NVM_TEST_DIR}"
fi
unset -f install_nvm_from_git install_nvm_as_script nvm_detect_profile nvm_has
unset -f setup cleanup die make_profile run_install
unset NVM_ENV METHOD PROFILE NVM_DIR NVM_TEST_DIR NVM_PROFILE_PATH
}
setup() {
NVM_ENV=testing \. ../../install.sh
# Mock installation functions to do nothing
install_nvm_from_git() { :; }
install_nvm_as_script() { :; }
# Mock nvm_has to return true for git (to take the git path)
nvm_has() {
case "$1" in
git) return 0 ;;
*) return 1 ;;
esac
}
# Mock nvm_detect_profile to point at the profile under test
nvm_detect_profile() {
nvm_echo "${NVM_PROFILE_PATH}"
}
}
make_profile() {
printf '%s\n' "$@" > "${NVM_PROFILE_PATH}"
}
run_install() {
PROFILE='' METHOD='' NVM_DIR="${NVM_TEST_DIR}/nvm" nvm_do_install 2>&1
}
setup
NVM_TEST_DIR="$(mktemp -d)" || die 'unable to make the test dir'
mkdir -p "${NVM_TEST_DIR}/nvm" || die 'unable to make the install dir'
touch "${NVM_TEST_DIR}/nvm/nvm.sh" || die 'unable to make an empty nvm.sh'
NVM_PROFILE_PATH="${NVM_TEST_DIR}/.bashrc"
#
# Test: a commented-out nvm.sh line does not load nvm, so the source string is still appended
#
make_profile 'export NVM_DIR="$HOME/.nvm"' '# [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm' ' # [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"'
OUTPUT="$(run_install)"
case "${OUTPUT}" in
*"Appending nvm source string"*) ;;
*) die "a commented-out nvm.sh line should not count as the source string; got: ${OUTPUT}" ;;
esac
grep -q '^\[ -s "$NVM_DIR/nvm.sh"' "${NVM_PROFILE_PATH}" || die "the source string was not appended to the profile: $(cat "${NVM_PROFILE_PATH}")"
#
# Test: the same for a commented-out bash_completion line in a bash profile
#
make_profile '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm' '# [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion'
OUTPUT="$(run_install)"
case "${OUTPUT}" in
*"nvm source string already in"*) ;;
*) die "an active nvm.sh line should still count as the source string; got: ${OUTPUT}" ;;
esac
case "${OUTPUT}" in
*"Appending bash_completion source string"*) ;;
*) die "a commented-out bash_completion line should not count; got: ${OUTPUT}" ;;
esac
#
# Test: with both lines active, the profile is left alone
#
make_profile 'export NVM_DIR="$HOME/.nvm"' '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm' '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion'
BEFORE="$(cat "${NVM_PROFILE_PATH}")"
OUTPUT="$(run_install)"
case "${OUTPUT}" in
*"nvm source string already in"*"bash_completion source string already in"*) ;;
*) die "an active profile should not be touched; got: ${OUTPUT}" ;;
esac
[ "_$(cat "${NVM_PROFILE_PATH}")" = "_${BEFORE}" ] || die "the profile was changed: $(cat "${NVM_PROFILE_PATH}")"
cleanup