#!/usr/bin/env bash set -euo pipefail repo_dir="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd -P)" # shellcheck disable=SC1091 . "$repo_dir/config/node-runtime.env" runtime_root="$repo_dir/.runtime" mkdir -p "$runtime_root/downloads" os_name="$(uname -s)" cpu_name="$(uname -m)" case "$os_name:$cpu_name" in Linux:x86_64|Linux:amd64) platform=linux; arch=x64; archive_ext=tar.xz; checksum="$NODE_LINUX_X64_SHA256" ;; Linux:aarch64|Linux:arm64) platform=linux; arch=arm64; archive_ext=tar.xz; checksum="$NODE_LINUX_ARM64_SHA256" ;; Darwin:x86_64|Darwin:amd64) platform=darwin; arch=x64; archive_ext=tar.gz; checksum="$NODE_DARWIN_X64_SHA256" ;; Darwin:arm64|Darwin:aarch64) platform=darwin; arch=arm64; archive_ext=tar.gz; checksum="$NODE_DARWIN_ARM64_SHA256" ;; *) echo "Unsupported project runtime platform: $os_name/$cpu_name (use Node $NODE_VERSION manually on this host)." >&2 exit 2 ;; esac archive_name="node-v${NODE_VERSION}-${platform}-${arch}.${archive_ext}" archive_path="$runtime_root/downloads/$archive_name" runtime_dir="$runtime_root/node-v${NODE_VERSION}-${platform}-${arch}" if [ -x "$runtime_dir/bin/node" ] && [ "$($runtime_dir/bin/node --version)" = "v$NODE_VERSION" ]; then printf '%s\n' "$runtime_dir" exit 0 fi if [ -e "$archive_path" ]; then if command -v sha256sum >/dev/null 2>&1; then actual_checksum="$(sha256sum "$archive_path" | awk '{print $1}')" else actual_checksum="$(shasum -a 256 "$archive_path" | awk '{print $1}')" fi if [ "$actual_checksum" != "$checksum" ]; then rm -f "$archive_path" fi fi if [ ! -e "$archive_path" ]; then temp_archive="$archive_path.part" rm -f "$temp_archive" if ! command -v curl >/dev/null 2>&1; then echo "curl is required to bootstrap the project-local Node runtime." >&2 exit 2 fi curl --fail --location --retry 3 --output "$temp_archive" "$NODE_DIST_BASE/$archive_name" if command -v sha256sum >/dev/null 2>&1; then actual_checksum="$(sha256sum "$temp_archive" | awk '{print $1}')" else actual_checksum="$(shasum -a 256 "$temp_archive" | awk '{print $1}')" fi if [ "$actual_checksum" != "$checksum" ]; then rm -f "$temp_archive" echo "SHA-256 verification failed for $archive_name." >&2 exit 3 fi mv "$temp_archive" "$archive_path" fi if command -v sha256sum >/dev/null 2>&1; then actual_checksum="$(sha256sum "$archive_path" | awk '{print $1}')" else actual_checksum="$(shasum -a 256 "$archive_path" | awk '{print $1}')" fi if [ "$actual_checksum" != "$checksum" ]; then echo "Cached Node archive checksum does not match the pinned value." >&2 exit 3 fi extract_dir="$(mktemp -d "$runtime_root/extract.XXXXXX")" cleanup() { rm -rf "$extract_dir"; } trap cleanup EXIT tar -xf "$archive_path" -C "$extract_dir" extracted_dir="$extract_dir/node-v${NODE_VERSION}-${platform}-${arch}" if [ ! -x "$extracted_dir/bin/node" ]; then echo "Node archive did not contain the expected executable." >&2 exit 4 fi rm -rf "$runtime_dir" mv "$extracted_dir" "$runtime_dir" if [ "$($runtime_dir/bin/node --version)" != "v$NODE_VERSION" ]; then echo "Bootstrapped Node version is not v$NODE_VERSION." >&2 exit 4 fi printf '%s\n' "$runtime_dir"