From eafc9e4fe34cb33b6da72a887ab35342e59ac3b7 Mon Sep 17 00:00:00 2001 From: sneak Date: Tue, 6 Oct 2026 22:05:26 +0000 Subject: [PATCH] chore: script/bootstrap fails unless node finds every dependency and devDependency in package.json (closes #263) yarn install exits 0 without touching node_modules whenever node_modules/.yarn-integrity matches yarn.lock, so a package deleted from node_modules stayed deleted while bootstrap printed "bootstrap complete". After the install, bootstrap now asks node for the package.json of every package listed in dependencies and devDependencies of package.json, and on the first it cannot find it names the package and the fix: rm -rf node_modules && make bootstrap. A package whose exports hides its package.json (ethers, libsodium-wrappers-sumo) makes node throw ERR_PACKAGE_PATH_NOT_EXPORTED, which it does only after finding the package, so that error counts as found. Model: opus-5-5 --- README.md | 4 +++- TODO.md | 9 +++++++++ script/bootstrap | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 58ba78c..20afbeb 100644 --- a/README.md +++ b/README.md @@ -218,7 +218,9 @@ development workflow, and the Makefile targets are thin shims that call them. We provide: - `script/bootstrap` — install all dependencies (pinned node via nvm if needed, - yarn via corepack, `yarn install --frozen-lockfile`) + yarn via corepack, `yarn install --frozen-lockfile`), then fail, naming the + package, if node cannot find a package listed in `dependencies` or + `devDependencies` of `package.json` - `script/setup` — make a fresh clone ready for development: bootstrap plus the git pre-commit hook - `script/projectname` — print the project name (used for the Docker image tag) diff --git a/TODO.md b/TODO.md index 225c833..a3db404 100644 --- a/TODO.md +++ b/TODO.md @@ -45,6 +45,15 @@ but the review is broader than any of them. # Completed Steps +- 2026-10-06: `script/bootstrap` no longer reports success while node cannot + find a package listed in `dependencies` or `devDependencies` of `package.json` + ([#263](https://git.eeqj.de/sneak/AutistMask/issues/263)). After the install + it asks node for each one's `package.json`, and fails naming the missing + package and the fix. yarn skips the install whenever + `node_modules/.yarn-integrity` matches `yarn.lock`, so a package deleted from + `node_modules` stayed deleted while bootstrap said it was complete. The + fresh-clone failure the issue reports did not reproduce. + - 2026-10-06: A token symbol or name read off a contract is no longer stored cut between the two halves of an emoji ([#458](https://git.eeqj.de/sneak/AutistMask/issues/458)). `lookupTokenInfo()` diff --git a/script/bootstrap b/script/bootstrap index 4df1d8c..a0a19ef 100755 --- a/script/bootstrap +++ b/script/bootstrap @@ -127,6 +127,40 @@ install_js_deps() { fi } +# run_node: run node from the repo root, through nvm when node is not on PATH; +# the script comes on stdin +run_node() { + if missing node && [ -s "$HOME/.nvm/nvm.sh" ]; then + nvm_sh "nvm use $NODE_VERSION >/dev/null && cd \"$ROOT\" && node" + else + node + fi +} + +# yarn install exits 0 without touching node_modules once +# node_modules/.yarn-integrity matches yarn.lock, so a package deleted from +# node_modules stays deleted. Fail unless node finds every package listed in +# dependencies and devDependencies of package.json, by its package.json. When a +# package's exports does not list that file, node throws +# ERR_PACKAGE_PATH_NOT_EXPORTED, which it can only do once it has found the +# package, so that error counts as found. +check_js_deps() { + run_node <<'EOF' +const { dependencies, devDependencies } = require("./package.json"); +for (const name of Object.keys({ ...dependencies, ...devDependencies })) { + try { + require.resolve(name + "/package.json"); + } catch (e) { + if (e.code !== "ERR_PACKAGE_PATH_NOT_EXPORTED") { + console.error(`bootstrap: node cannot find ${name} after yarn install`); + console.error(" fix: rm -rf node_modules && make bootstrap"); + process.exit(1); + } + } +} +EOF +} + main() { cd "$ROOT" @@ -136,6 +170,7 @@ main() { ensure_node ensure_yarn install_js_deps + check_js_deps echo "bootstrap complete" }