64 lines
3.6 KiB
Bash
Executable File
64 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd -P)
|
|
FAILURES=0
|
|
|
|
fail() { printf 'FAIL: %s\n' "$1" >&2; FAILURES=$((FAILURES + 1)); }
|
|
have() {
|
|
local name=$1 link=$2
|
|
if ! command -v "$name" >/dev/null 2>&1; then
|
|
fail "$name is missing — install from $link"
|
|
return 1
|
|
fi
|
|
}
|
|
exact_version() {
|
|
local name=$1 expected=$2 actual=$3 link=$4
|
|
if [[ "$actual" == "$expected" ]]; then printf 'ok: %s %s\n' "$name" "$actual"
|
|
else fail "$name must be $expected (found $actual) — install from $link"; fi
|
|
}
|
|
port_free() {
|
|
local port=$1
|
|
if (exec 9<>"/dev/tcp/127.0.0.1/$port") 2>/dev/null; then
|
|
fail "127.0.0.1:$port is occupied; stop that external service before starting the demo"
|
|
else
|
|
printf 'ok: 127.0.0.1:%s is available\n' "$port"
|
|
fi
|
|
}
|
|
|
|
printf '%s\n' 'Checking the pinned V1 demo environment (read-only).'
|
|
if have git https://git-scm.com/downloads; then printf 'ok: %s\n' "$(git --version)"; fi
|
|
if have forge https://getfoundry.sh; then exact_version forge 1.7.1 "$(forge --version | sed -nE 's/^forge Version: ([^ ]+).*/\1/p')" https://getfoundry.sh; fi
|
|
if have anvil https://getfoundry.sh; then exact_version anvil 1.7.1 "$(anvil --version | sed -nE 's/^anvil Version: ([^ ]+).*/\1/p')" https://getfoundry.sh; fi
|
|
if have cast https://getfoundry.sh; then exact_version cast 1.7.1 "$(cast --version | sed -nE 's/^cast Version: ([^ ]+).*/\1/p')" https://getfoundry.sh; fi
|
|
if have node https://nodejs.org/en/download; then exact_version Node 24.18.0 "$(node --version | sed 's/^v//')" https://nodejs.org/en/download; fi
|
|
if have npm https://docs.npmjs.com/downloading-and-installing-node-js-and-npm; then exact_version npm 11.17.0 "$(npm --version)" https://docs.npmjs.com/downloading-and-installing-node-js-and-npm; fi
|
|
if have bash https://www.gnu.org/software/bash/; then printf 'ok: %s\n' "$(bash --version | sed -n '1p')"; fi
|
|
if have make https://www.gnu.org/software/make/; then printf 'ok: %s\n' "$(make --version | sed -n '1p')"; fi
|
|
if have curl https://curl.se/download.html; then printf 'ok: %s\n' "$(curl --version | sed -n '1p')"; fi
|
|
|
|
if git -C "$ROOT" submodule status --recursive | while IFS= read -r line; do [[ "$line" == ' '* ]] || exit 1; done; then
|
|
printf '%s\n' 'ok: recursive Git submodules are initialized at recorded commits'
|
|
else
|
|
fail 'recursive Git submodules are missing or differ from recorded commits — run make setup'
|
|
fi
|
|
if [[ -d "$ROOT/node_modules" ]]; then printf '%s\n' 'ok: root node_modules is installed'; else fail 'root node_modules is missing — run make setup'; fi
|
|
if [[ -d "$ROOT/web/node_modules" ]]; then printf '%s\n' 'ok: web node_modules is installed'; else fail 'web node_modules is missing — run make setup'; fi
|
|
if command -v node >/dev/null 2>&1 && [[ -d "$ROOT/node_modules" ]]; then
|
|
node "$ROOT/tools/check-upgrades-cli.mjs" || fail 'the pinned offline OpenZeppelin upgrades CLI is unavailable — run make setup'
|
|
fi
|
|
|
|
for path in "$ROOT" "$ROOT/deployments" "$ROOT/web/public" "$ROOT/web/src/generated"; do
|
|
if [[ -d "$path" && -w "$path" ]]; then printf 'ok: writable runtime directory %s\n' "${path#"$ROOT/"}"; else fail "runtime directory is not writable: $path"; fi
|
|
done
|
|
if [[ -d "$ROOT/.demo" ]]; then [[ -w "$ROOT/.demo" ]] || fail "$ROOT/.demo is not writable"; fi
|
|
port_free 8545
|
|
port_free 5173
|
|
|
|
for variable in BASE_SEPOLIA_RPC_URL BASE_SEPOLIA_ACCOUNT; do
|
|
if [[ -n ${!variable:-} ]]; then printf 'optional: %s is configured\n' "$variable"; else printf 'optional: %s is not configured (local demo unaffected)\n' "$variable"; fi
|
|
done
|
|
|
|
if ((FAILURES)); then printf 'Doctor found %d problem(s).\n' "$FAILURES" >&2; exit 1; fi
|
|
printf '%s\n' 'Doctor passed.'
|