diff --git a/.github/workflows/windows-npm.yml b/.github/workflows/windows-npm.yml new file mode 100755 index 0000000..2515a23 --- /dev/null +++ b/.github/workflows/windows-npm.yml @@ -0,0 +1,106 @@ +name: 'Tests on Windows: `nvm install`' + +on: [pull_request, push] + +env: + NVM_INSTALL_GITHUB_REPO: ${{ github.repository }} + NVM_INSTALL_VERSION: ${{ github.sha }} + +jobs: + node_fail_install: + # Default installation does not work due to npm_config_prefix set to C:\npm\prefix + name: 'MSYS fail prefix nvm install' + runs-on: windows-latest + steps: + - name: Retrieve nvm + shell: bash + run: | + curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | METHOD=script bash + . "$HOME/.nvm/nvm.sh" + ! nvm install --lts + nodes: + name: 'MSYS nvm install' + runs-on: windows-latest + strategy: + matrix: + npm-node-version: + - '--lts' + - '--default 12' + - '--no-progress 10' + steps: + - name: Retrieve nvm + shell: bash + run: | + unset npm_config_prefix + if [ "${{ matrix.npm-node-version }}" = "--lts" ]; then + curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | bash + else + curl -fsSLo- "https://raw.githubusercontent.com/${NVM_INSTALL_GITHUB_REPO}/${NVM_INSTALL_VERSION}/install.sh" | METHOD=script bash + fi + . "$HOME/.nvm/nvm.sh" + nvm install ${{ matrix.npm-node-version }} + node_cygwin: + name: 'Cygwin nvm install' + runs-on: windows-latest + steps: + - name: Install Cygwin + shell: bash + run: | + export SITE='https://mirror.clarkson.edu/cygwin/' + export LOCALDIR="$(pwd)" + export ROOTDIR="$USERPROFILE\\cygwin" + export PACKAGES='bash,git,curl' + + curl -fsSLo setup-x86_64.exe 'https://cygwin.com/setup-x86_64.exe' + ./setup-x86_64.exe --disable-buggy-antivirus -q -s "$SITE" -l "$LOCALDIR" -R "$ROOTDIR" -P "$PACKAGES" + + cat >~/setup.sh </dev/null)"/bin/node ] + if [ -z "${1-}" ]; then + return 1 + fi + local NVM_NODE_BINARY + NVM_NODE_BINARY='node' + if [ "_$(nvm_get_os)" = '_win' ]; then + NVM_NODE_BINARY='node.exe' + fi + if [ -x "$(nvm_version_path "$1" 2>/dev/null)/bin/${NVM_NODE_BINARY}" ]; then + return 0 + fi + return 1 } nvm_print_npm_version() { @@ -326,10 +337,14 @@ nvm_tree_contains_path() { return 2 fi + local previous_pathdir + previous_pathdir="${node_path}" local pathdir - pathdir=$(dirname "${node_path}") - while [ "${pathdir}" != "" ] && [ "${pathdir}" != "." ] && [ "${pathdir}" != "/" ] && [ "${pathdir}" != "${tree}" ]; do - pathdir=$(dirname "${pathdir}") + pathdir=$(dirname "${previous_pathdir}") + while [ "${pathdir}" != '' ] && [ "${pathdir}" != '.' ] && [ "${pathdir}" != '/' ] && + [ "${pathdir}" != "${tree}" ] && [ "${pathdir}" != "${previous_pathdir}" ]; do + previous_pathdir="${pathdir}" + pathdir=$(dirname "${previous_pathdir}") done [ "${pathdir}" = "${tree}" ] } @@ -1763,6 +1778,7 @@ nvm_get_os() { FreeBSD\ *) NVM_OS=freebsd ;; OpenBSD\ *) NVM_OS=openbsd ;; AIX\ *) NVM_OS=aix ;; + CYGWIN* | MSYS* | MINGW*) NVM_OS=win ;; esac nvm_echo "${NVM_OS-}" } @@ -1892,23 +1908,37 @@ nvm_install_binary_extract() { command mkdir -p "${TMPDIR}" && \ VERSION_PATH="$(nvm_version_path "${PREFIXED_VERSION}")" || return 1 - local tar_compression_flag - tar_compression_flag='z' - if nvm_supports_xz "${VERSION}"; then - tar_compression_flag='J' - fi - - local tar - if [ "${NVM_OS}" = 'aix' ]; then - tar='gtar' + # For Windows system (GitBash with MSYS, Cygwin) + if [ "${NVM_OS}" = 'win' ]; then + VERSION_PATH="${VERSION_PATH}/bin" + command unzip -q "${TARBALL}" -d "${TMPDIR}" || return 1 + # For non Windows system (including WSL running on Windows) else - tar='tar' + local tar_compression_flag + tar_compression_flag='z' + if nvm_supports_xz "${VERSION}"; then + tar_compression_flag='J' + fi + + local tar + if [ "${NVM_OS}" = 'aix' ]; then + tar='gtar' + else + tar='tar' + fi + command "${tar}" -x${tar_compression_flag}f "${TARBALL}" -C "${TMPDIR}" --strip-components 1 || return 1 fi - command "${tar}" -x${tar_compression_flag}f "${TARBALL}" -C "${TMPDIR}" --strip-components 1 || return 1 command mkdir -p "${VERSION_PATH}" || return 1 - command mv "${TMPDIR}/"* "${VERSION_PATH}" || return 1 + if [ "${NVM_OS}" = 'win' ]; then + command mv "${TMPDIR}/"*/* "${VERSION_PATH}" || return 1 + command chmod +x "${VERSION_PATH}"/node.exe || return 1 + command chmod +x "${VERSION_PATH}"/npm || return 1 + command chmod +x "${VERSION_PATH}"/npx 2>/dev/null + else + command mv "${TMPDIR}/"* "${VERSION_PATH}" || return 1 + fi command rm -rf "${TMPDIR}" @@ -2042,7 +2072,9 @@ nvm_get_artifact_compression() { local COMPRESSION COMPRESSION='tar.gz' - if nvm_supports_xz "${VERSION}"; then + if [ "_${NVM_OS}" = '_win' ]; then + COMPRESSION='zip' + elif nvm_supports_xz "${VERSION}"; then COMPRESSION='tar.xz' fi @@ -2409,6 +2441,9 @@ nvm_die_on_prefix() { return 3 fi + local NVM_OS + NVM_OS="$(nvm_get_os)" + # npm normalizes NPM_CONFIG_-prefixed env vars # https://github.com/npm/npmconf/blob/22827e4038d6eebaafeb5c13ed2b92cf97b8fb82/npmconf.js#L331-L348 # https://github.com/npm/npm/blob/5e426a78ca02d0044f8dd26e0c5f881217081cbd/lib/config/core.js#L343-L359 @@ -2420,6 +2455,9 @@ nvm_die_on_prefix() { if [ -n "${NVM_NPM_CONFIG_PREFIX_ENV-}" ]; then local NVM_CONFIG_VALUE eval "NVM_CONFIG_VALUE=\"\$${NVM_NPM_CONFIG_PREFIX_ENV}\"" + if [ -n "${NVM_CONFIG_VALUE-}" ] && [ "_${NVM_OS}" = "_win" ]; then + NVM_CONFIG_VALUE="$(cd "$NVM_CONFIG_VALUE" 2>/dev/null && pwd)" + fi if [ -n "${NVM_CONFIG_VALUE-}" ] && ! nvm_tree_contains_path "${NVM_DIR}" "${NVM_CONFIG_VALUE}"; then nvm deactivate >/dev/null 2>&1 nvm_err "nvm is not compatible with the \"${NVM_NPM_CONFIG_PREFIX_ENV}\" environment variable: currently set to \"${NVM_CONFIG_VALUE}\"" @@ -3209,8 +3247,13 @@ nvm() { nvm_get_make_jobs fi - NVM_NO_PROGRESS="${NVM_NO_PROGRESS:-${noprogress}}" nvm_install_source "${FLAVOR}" std "${VERSION}" "${NVM_MAKE_JOBS}" "${ADDITIONAL_PARAMETERS}" - EXIT_CODE=$? + if [ "_${NVM_OS}" = "_win" ]; then + nvm_err 'Installing from source on non-WSL Windows is not supported' + EXIT_CODE=87 + else + NVM_NO_PROGRESS="${NVM_NO_PROGRESS:-${noprogress}}" nvm_install_source "${FLAVOR}" std "${VERSION}" "${NVM_MAKE_JOBS}" "${ADDITIONAL_PARAMETERS}" + EXIT_CODE=$? + fi fi fi diff --git a/test/fast/Unit tests/nvm_get_artifact_compression b/test/fast/Unit tests/nvm_get_artifact_compression index ed7a180..3fc5fcf 100755 --- a/test/fast/Unit tests/nvm_get_artifact_compression +++ b/test/fast/Unit tests/nvm_get_artifact_compression @@ -13,4 +13,10 @@ die () { echo "$@" ; cleanup ; exit 1; } # nvm_get_artifact_compression with xz [ "$(nvm_get_artifact_compression "14.0.0")" = 'tar.xz' ] || die 'nvm_get_artifact_compression should return "tar.xz" for this version' +# nvm_get_artifact_compression with zip on Windows +nvm_get_os() { + nvm_echo 'win' +} +[ "$(nvm_get_artifact_compression)" = 'zip' ] || die 'nvm_get_artifact_compression should return "zip" for Windows' + cleanup diff --git a/test/fast/Unit tests/nvm_install_binary_extract b/test/fast/Unit tests/nvm_install_binary_extract index a0fc58a..8b8782a 100644 --- a/test/fast/Unit tests/nvm_install_binary_extract +++ b/test/fast/Unit tests/nvm_install_binary_extract @@ -43,6 +43,9 @@ if [ -z "$NVM_DIR" ] || [ -z "$tmp_dir" ]; then die 'Unable to create temporary folder' fi +# Test windows zip +test_archi 'win' 'v15.6.0' 'x64' 'node' 'zip' 'zip' '-qr' + # Test linux tar.xz test_archi 'linux' 'v14.15.4' 'x64' 'bin/node' 'tar.xz' 'tar' '-cJf' diff --git a/test/fast/Unit tests/nvm_is_version_installed b/test/fast/Unit tests/nvm_is_version_installed index d530658..45971f0 100644 --- a/test/fast/Unit tests/nvm_is_version_installed +++ b/test/fast/Unit tests/nvm_is_version_installed @@ -2,7 +2,7 @@ cleanup () { rm -rf "$NVM_DIR" - unset -f die cleanup check_version + unset -f die cleanup nvm_get_os check_version unset NVM_DIR NODE_PATH } die () { echo "$@" ; cleanup ; exit 1; } @@ -44,4 +44,11 @@ type nvm_is_version_installed > /dev/null 2>&1 || die 'nvm_is_version_installed check_version '12.0.0' 'node' +# Checking for Windows +nvm_get_os() { + echo "win" +} +check_version '13.0.0' 'node.exe' + + cleanup