#!/usr/bin/env bash # Every path listed under "packages:" in pnpm-workspace.yaml must have a matching # importer entry in pnpm-lock.yaml. If one is missing, pnpm can fail in confusing # ways (e.g. pnpm outdated -r: Cannot read ... 'optionalDependencies'). # Usage: bash scripts/verify/check-pnpm-workspace-lockfile.sh # Exit: 0 if check passes or pnpm is not used; 1 on mismatch. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" WS="${PROJECT_ROOT}/pnpm-workspace.yaml" LOCK="${PROJECT_ROOT}/pnpm-lock.yaml" if [[ ! -f "$WS" ]] || [[ ! -f "$LOCK" ]]; then echo " (skip: pnpm-workspace.yaml or pnpm-lock.yaml not present at repo root)" exit 0 fi # Paths under the top-level `packages:` block only (stops at next top-level key) mapfile -t _paths < <(awk ' /^packages:/ { p=1; next } p && /^[a-zA-Z]/ && $0 !~ /^packages/ { exit } p && /^[[:space:]]*-[[:space:]]/ { sub(/^[[:space:]]*-[[:space:]]+/, "") sub(/[[:space:]]*#.*/, "") gsub(/[[:space:]]+$/, "") if (length) print } ' "$WS") missing=() for relp in "${_paths[@]}"; do if [[ -z "$relp" ]]; then continue fi if ! grep -qFx " ${relp}:" "$LOCK"; then missing+=("$relp") fi done if [[ ${#missing[@]} -gt 0 ]]; then echo "✗ pnpm lockfile is missing importer(s) for these workspace path(s):" printf ' %q\n' "${missing[@]}" echo " Run: pnpm install (at repo root) to refresh pnpm-lock.yaml" exit 1 fi echo " pnpm workspace / lockfile importers aligned (${#_paths[@]} path(s))." exit 0