Bootstrap keeps yarn and node only at their pinned versions (closes #154)
check / check (push) Canceled after 0s
check / check (push) Canceled after 0s
script/bootstrap kept any yarn found on PATH, so YARN_VERSION applied only where none was installed. It now keeps the yarn on PATH only when yarn --version is exactly YARN_VERSION, and otherwise prepares that version through corepack. The node on PATH is used only when it has the pinned major version and is at least NODE_MIN_VERSION, as REPO_POLICIES.md asks. After installing either, bootstrap looks the tool up through PATH again, stops naming the path if it is not the pinned one, and prints the version it uses, as it does for Go. The other host scripts that run yarn run it through the new script/yarn, which uses the same node test with ~/.local/bin first on PATH, and otherwise the pinned node in nvm. Model: opus-5-5
This commit is contained in:
+56
-14
@@ -3,11 +3,13 @@
|
||||
# this repo. Idempotent: every install is guarded by a check so already
|
||||
# installed tools are skipped. Base tooling comes from nix, apt, brew,
|
||||
# or apk (detected in that order); assumes nothing is present. Node is
|
||||
# used directly if it is at least NODE_MIN_VERSION; otherwise it is
|
||||
# installed at a pinned version via nvm (installing nvm itself first,
|
||||
# from a hash-verified release archive, never curl | sh). Go, with its
|
||||
# gofmt, is used directly only if it is exactly GO_VERSION; otherwise
|
||||
# that release is installed from its hash-verified archive.
|
||||
# used directly only if it has the major version of NODE_VERSION and is
|
||||
# at least NODE_MIN_VERSION; otherwise NODE_VERSION is installed via nvm
|
||||
# (installing nvm itself first, from a hash-verified release archive,
|
||||
# never curl | sh). Yarn is used directly only if it is exactly
|
||||
# YARN_VERSION; otherwise that version is prepared through corepack.
|
||||
# Go, with its gofmt, is used directly only if it is exactly GO_VERSION;
|
||||
# otherwise that release is installed from its hash-verified archive.
|
||||
#
|
||||
# What this script installs outside the system package manager lives
|
||||
# under $HOME and is linked into ~/.local/bin, where make and the git
|
||||
@@ -142,32 +144,65 @@ ensure_nvm() {
|
||||
rm -rf "$tmp"
|
||||
}
|
||||
|
||||
# node_ok: the node on PATH is at least NODE_MIN_VERSION. node itself
|
||||
# compares the two: major, then minor, then patch.
|
||||
# node_ok: the node on PATH has the major version of NODE_VERSION and is
|
||||
# at least NODE_MIN_VERSION. Only the major is compared with the pin:
|
||||
# the Dockerfile's node stages start from a node 22 alpine image whose
|
||||
# exact version is not the pin, and nvm cannot install a prebuilt node
|
||||
# on alpine. node itself compares the versions: major, then minor, then
|
||||
# patch. A node that fails does not pass. script/bootstrap and
|
||||
# script/yarn carry this function unchanged.
|
||||
node_ok() {
|
||||
if missing node; then return 1; fi
|
||||
if ! command -v node >/dev/null 2>&1; then return 1; fi
|
||||
node -e '
|
||||
const have = process.versions.node.split(".").map(Number);
|
||||
const want = process.argv[1].split(".").map(Number);
|
||||
const pinned = process.argv[2].split(".").map(Number);
|
||||
if (have[0] !== pinned[0]) process.exit(1);
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (have[i] !== want[i]) process.exit(have[i] > want[i] ? 0 : 1);
|
||||
}
|
||||
' "$NODE_MIN_VERSION"
|
||||
' "$NODE_MIN_VERSION" "$NODE_VERSION"
|
||||
}
|
||||
|
||||
# ensure_node: unless node_ok, install NODE_VERSION and link its node.
|
||||
# Afterwards node is looked up through PATH again and must pass node_ok.
|
||||
ensure_node() {
|
||||
if node_ok; then return 0; fi
|
||||
if node_ok; then
|
||||
echo "bootstrap: using node $(node --version)"
|
||||
return 0
|
||||
fi
|
||||
ensure_nvm
|
||||
nvm_sh "nvm install $NODE_VERSION"
|
||||
link_bin "$HOME/.nvm/versions/node/v$NODE_VERSION/bin/node" node
|
||||
hash -r
|
||||
if ! node_ok; then
|
||||
echo "bootstrap: after installing node $NODE_VERSION through nvm," >&2
|
||||
echo " the node on PATH, $(command -v node), is not it" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "bootstrap: installed node $(node --version)"
|
||||
}
|
||||
|
||||
# ensure_yarn: corepack writes its shims (pnpm and yarnpkg as well as
|
||||
# yarn) into $TOOLCHAIN rather than next to itself, and the npm fallback
|
||||
# installs there too; only yarn is linked.
|
||||
# yarn_ok: yarn --version on PATH prints exactly YARN_VERSION, compared
|
||||
# over the whole version. A yarn that fails or prints anything else does
|
||||
# not pass.
|
||||
yarn_ok() {
|
||||
if missing yarn; then return 1; fi
|
||||
version="$(yarn --version 2>/dev/null)" || return 1
|
||||
[ "$version" = "$YARN_VERSION" ]
|
||||
}
|
||||
|
||||
# ensure_yarn: unless yarn_ok, prepare YARN_VERSION and link its yarn.
|
||||
# corepack writes its shims (pnpm and yarnpkg as well as yarn) into
|
||||
# $TOOLCHAIN rather than next to itself, and the npm fallback installs
|
||||
# there too; only yarn is linked. Afterwards yarn is looked up through
|
||||
# PATH again and must pass yarn_ok, so another yarn that hides the link
|
||||
# stops bootstrap.
|
||||
ensure_yarn() {
|
||||
if ! missing yarn; then return 0; fi
|
||||
if yarn_ok; then
|
||||
echo "bootstrap: using yarn $(yarn --version)"
|
||||
return 0
|
||||
fi
|
||||
shims="$TOOLCHAIN/corepack-shims"
|
||||
mkdir -p "$shims"
|
||||
if ! missing corepack; then
|
||||
@@ -182,6 +217,13 @@ ensure_yarn() {
|
||||
shims="$TOOLCHAIN/npm-global/bin"
|
||||
fi
|
||||
link_bin "$shims/yarn" yarn
|
||||
hash -r
|
||||
if ! yarn_ok; then
|
||||
echo "bootstrap: after installing yarn $YARN_VERSION in $shims," >&2
|
||||
echo " the yarn on PATH, $(command -v yarn), does not report it" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "bootstrap: installed yarn $(yarn --version)"
|
||||
}
|
||||
|
||||
# go_ok: the go on PATH has its gofmt beside it (a Go release ships the
|
||||
|
||||
Reference in New Issue
Block a user