From 25f836f81bdaace50ee9a185131843e9cf080020 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sat, 14 Mar 2026 14:44:24 -0700 Subject: [PATCH] [Fix] `install.sh`: check `mkdir` return codes If directory creation fails (e.g., permissions), the script would continue and fail with confusing errors later. Fail early with a clear error message instead. Bugs introduced in https://github.com/nvm-sh/nvm/commit/68bf93514bdf5d2852ce74819350bed99eb472a6, https://github.com/nvm-sh/nvm/commit/6cee20a0717298658dd222efbc94616d96d5224c, and https://github.com/nvm-sh/nvm/commit/703babe60a9fa09d55fbc67107a07beba09ef090. --- install.sh | 15 ++++-- test/install_script/nvm_mkdir_error_handling | 49 ++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100755 test/install_script/nvm_mkdir_error_handling diff --git a/install.sh b/install.sh index 4aea547..29f6192 100755 --- a/install.sh +++ b/install.sh @@ -149,7 +149,10 @@ install_nvm_from_git() { 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}" + 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}" || { @@ -234,7 +237,10 @@ install_nvm_as_script() { NVM_BASH_COMPLETION_SOURCE="$(nvm_source script-nvm-bash-completion)" # Downloading to $INSTALL_DIR - mkdir -p "$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 @@ -374,7 +380,10 @@ nvm_do_install() { fi if [ "${NVM_DIR}" = "$(nvm_default_install_dir)" ]; then - mkdir "${NVM_DIR}" + 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 diff --git a/test/install_script/nvm_mkdir_error_handling b/test/install_script/nvm_mkdir_error_handling new file mode 100755 index 0000000..d92476a --- /dev/null +++ b/test/install_script/nvm_mkdir_error_handling @@ -0,0 +1,49 @@ +#!/bin/sh + +cleanup () { + if [ -n "${SAVE_NVM_DIR-}" ]; then + NVM_DIR="$SAVE_NVM_DIR" + fi + unset -f die cleanup + unset SAVE_NVM_DIR +} +die () { echo "$@" ; cleanup ; exit 1; } + +SAVE_NVM_DIR="$NVM_DIR" + +NVM_ENV=testing \. ../../install.sh + +# install_nvm_from_git is available +type install_nvm_from_git > /dev/null 2>&1 || die 'install_nvm_from_git is not available' + +# install_nvm_as_script is available +type install_nvm_as_script > /dev/null 2>&1 || die 'install_nvm_as_script is not available' + +# nvm_do_install is available +type nvm_do_install > /dev/null 2>&1 || die 'nvm_do_install is not available' + +IMPOSSIBLE_DIR="/dev/null/impossible_path" + +## install_nvm_from_git: mkdir failure should exit with code 2 and print error +OUTPUT="$(NVM_DIR="${IMPOSSIBLE_DIR}" install_nvm_from_git 2>&1)" +EXIT_CODE=$? +[ "${EXIT_CODE}" = '2' ] || die "install_nvm_from_git should exit 2 on mkdir failure, got ${EXIT_CODE}" +echo "${OUTPUT}" | grep -q "Failed to create directory" || die "install_nvm_from_git should print mkdir error message, got: ${OUTPUT}" + +## install_nvm_as_script: mkdir failure should return 1 and print error +OUTPUT="$(NVM_DIR="${IMPOSSIBLE_DIR}" install_nvm_as_script 2>&1)" +EXIT_CODE=$? +[ "${EXIT_CODE}" = '1' ] || die "install_nvm_as_script should return 1 on mkdir failure, got ${EXIT_CODE}" +echo "${OUTPUT}" | grep -q "Failed to create directory" || die "install_nvm_as_script should print mkdir error message, got: ${OUTPUT}" + +## nvm_do_install: mkdir failure for default dir should exit with code 2 and print error +# Override nvm_default_install_dir to return the impossible path so the mkdir branch is taken +nvm_default_install_dir() { + printf %s "${IMPOSSIBLE_DIR}" +} +OUTPUT="$(NVM_DIR="${IMPOSSIBLE_DIR}" nvm_do_install 2>&1)" +EXIT_CODE=$? +[ "${EXIT_CODE}" = '2' ] || die "nvm_do_install should exit 2 on mkdir failure, got ${EXIT_CODE}" +echo "${OUTPUT}" | grep -q "Failed to create directory" || die "nvm_do_install should print mkdir error message, got: ${OUTPUT}" + +cleanup