mirror of
https://github.com/nvm-sh/nvm.git
synced 2026-09-01 00:00:07 +08:00
Two `nvm install <same version>` runs could race on the version directory - one removing or replacing it while the other reads or writes it. Take a per-version advisory lock (an atomically-created directory under $NVM_DIR/.cache locks) around the binary/source install, so a second run of the same version waits for the first; installs of different versions never contend. NVM_INSTALL_LOCK_TIMEOUT (seconds, default 600) bounds the wait, after which nvm reports the lock path so a lock left by a killed install can be removed. NVM_INSTALL_LOCK_STALE (minutes, default 0 / off) opts into automatically stealing a lock older than that, for unattended or CI use.
36 lines
1.2 KiB
Bash
Executable File
36 lines
1.2 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
cleanup() {
|
|
[ -n "${NVM_DIR}" ] && [ -d "${NVM_DIR}" ] && rm -rf "${NVM_DIR}"
|
|
unset -f die cleanup
|
|
unset NVM_DIR NVM_INSTALL_LOCK version lock
|
|
}
|
|
|
|
die() { echo "$@" ; cleanup ; exit 1; }
|
|
|
|
: nvm.sh
|
|
\. ../../../nvm.sh
|
|
|
|
type nvm_release_install_lock > /dev/null 2>&1 || die 'nvm_release_install_lock is not available'
|
|
|
|
NVM_DIR="$(mktemp -d)"
|
|
[ -n "${NVM_DIR}" ] || die 'unable to create temp NVM_DIR'
|
|
version='v20.0.0'
|
|
lock="$(nvm_cache_dir)/locks/$(nvm_install_lock_name "${version}")"
|
|
|
|
# Releasing when nothing is held is a no-op that succeeds.
|
|
unset NVM_INSTALL_LOCK
|
|
nvm_release_install_lock || die 'releasing with no lock held should succeed'
|
|
|
|
# After acquiring, releasing removes the lock directory and clears the marker.
|
|
nvm_acquire_install_lock "${version}" || die 'setup: acquire failed'
|
|
[ -d "${lock}" ] || die 'setup: lock dir should exist after acquire'
|
|
nvm_release_install_lock || die 'release should succeed'
|
|
[ ! -d "${lock}" ] || die 'release should remove the lock directory'
|
|
[ -z "${NVM_INSTALL_LOCK-}" ] || die 'release should clear NVM_INSTALL_LOCK'
|
|
|
|
# Releasing again is a harmless no-op.
|
|
nvm_release_install_lock || die 'a second release should be a no-op'
|
|
|
|
cleanup
|