Files
citation-evidence/scripts/check-install.sh
tegwick 85a562b2a1 Add make check-install for umbrella layout consistency
Verify sibling citation-engine checkout, link dependency resolution,
toolchain, and absence of stale in-repo engine copies. Prints actionable
fix hints when the installation layout is wrong.
2026-06-22 20:10:38 +02:00

162 lines
5.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Verify that citation-evidence is installed consistently with its ecosystem
# layout. citation-evidence is the umbrella repo; @citation-evidence/engine
# must resolve from a sibling citation-engine checkout (see CE-WP-0009).
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
ENGINE_SIBLING="$ROOT/../citation-engine"
ENGINE_DEP="link:../citation-engine"
ENGINE_PKG="@citation-evidence/engine"
errors=0
warnings=0
ok() { printf ' \033[32m✓\033[0m %s\n' "$1"; }
fail() { printf ' \033[31m✗\033[0m %s\n' "$1"; errors=$((errors + 1)); }
warn() { printf ' \033[33m!\033[0m %s\n' "$1"; warnings=$((warnings + 1)); }
hint() { printf ' → %s\n' "$1"; }
section() {
printf '\n%s\n' "$1"
}
fix_clone_engine() {
hint "Clone citation-engine as a sibling of this repo:"
hint " cd $(dirname "$ROOT")"
hint " git clone <citation-engine-remote-url> citation-engine"
hint "Expected layout:"
hint " $(dirname "$ROOT")/citation-evidence/ (this repo)"
hint " $(dirname "$ROOT")/citation-engine/ (required sibling)"
}
printf 'citation-evidence install consistency check\n'
printf 'Umbrella root: %s\n' "$ROOT"
section "Required sibling: citation-engine"
if [[ -d "$ENGINE_SIBLING" ]]; then
ok "citation-engine directory exists at ../citation-engine"
else
fail "citation-engine not found at ../citation-engine"
fix_clone_engine
fi
if [[ -f "$ENGINE_SIBLING/package.json" ]]; then
ok "citation-engine/package.json present"
engine_name="$(node -e "
const p = require('$ENGINE_SIBLING/package.json');
process.stdout.write(p.name ?? '');
" 2>/dev/null || true)"
if [[ "$engine_name" == "$ENGINE_PKG" ]]; then
ok "citation-engine package name is $ENGINE_PKG"
else
fail "citation-engine package name is '${engine_name:-<missing>}' (expected $ENGINE_PKG)"
hint "Check that ../citation-engine is the correct repository."
fi
elif [[ -d "$ENGINE_SIBLING" ]]; then
fail "citation-engine/package.json missing"
hint "../citation-engine does not look like a valid checkout."
fi
for path in src/shared/index.ts src/engine/index.ts; do
if [[ -f "$ENGINE_SIBLING/$path" ]]; then
ok "citation-engine/$path present"
elif [[ -d "$ENGINE_SIBLING" ]]; then
fail "citation-engine/$path missing"
hint "Run 'git pull' in ../citation-engine or check out a complete tree."
fi
done
section "package.json link dependency"
declared="$(node -e "
const p = require('$ROOT/package.json');
const v = p.dependencies?.['$ENGINE_PKG'];
process.stdout.write(v ?? '');
" 2>/dev/null || true)"
if [[ "$declared" == "$ENGINE_DEP" ]]; then
ok "package.json declares \"$ENGINE_PKG\": \"$ENGINE_DEP\""
else
fail "package.json should declare \"$ENGINE_PKG\": \"$ENGINE_DEP\" (found: ${declared:-<missing>})"
fi
section "node_modules resolution"
linked="$ROOT/node_modules/@citation-evidence/engine"
if [[ -e "$linked" ]]; then
ok "node_modules/@citation-evidence/engine exists"
real="$(cd "$linked" && pwd -P 2>/dev/null || true)"
expected="$(cd "$ENGINE_SIBLING" 2>/dev/null && pwd -P || true)"
if [[ -n "$real" && -n "$expected" && "$real" == "$expected" ]]; then
ok "link resolves to ../citation-engine"
elif [[ -n "$real" && -n "$expected" ]]; then
fail "node_modules link points to $real (expected $expected)"
hint "Run 'pnpm install' from citation-evidence after fixing the sibling checkout."
fi
else
fail "node_modules/@citation-evidence/engine not found"
hint "Run 'pnpm install' from the citation-evidence root."
if [[ ! -d "$ENGINE_SIBLING" ]]; then
fix_clone_engine
fi
fi
section "Toolchain"
if command -v node >/dev/null 2>&1; then
node_ver="$(node -v | sed 's/^v//')"
ok "node $node_ver available"
if [[ -f "$ROOT/.nvmrc" ]]; then
want="$(tr -d '[:space:]' < "$ROOT/.nvmrc")"
node_major_minor="$(printf '%s' "$node_ver" | cut -d. -f1-2)"
want_major_minor="$(printf '%s' "$want" | cut -d. -f1-2)"
if [[ "$node_major_minor" == "$want_major_minor" ]]; then
ok "node version matches .nvmrc ($want)"
else
warn "node $node_ver does not match .nvmrc ($want) — use nvm/fnm to switch"
hint " nvm use # or: fnm use"
fi
fi
else
fail "node not found on PATH"
hint "Install Node 20 LTS (see .nvmrc)."
fi
if command -v pnpm >/dev/null 2>&1; then
ok "pnpm $(pnpm -v) available"
else
fail "pnpm not found on PATH"
hint "Enable corepack: corepack enable && corepack prepare pnpm@9.15.0 --activate"
fi
section "Optional sister repos (INTENT-only during MVP)"
parent="$(dirname "$ROOT")"
for repo in evidence-anchor evidence-source evidence-binder citation-work; do
if [[ -f "$parent/$repo/INTENT.md" ]]; then
ok "$repo checked out (optional)"
else
warn "$repo not present at ../$repo (optional — not required to run the umbrella)"
fi
done
section "Stale in-repo engine copies"
if [[ -d "$ROOT/src/shared" || -d "$ROOT/src/engine" ]]; then
fail "src/shared/ or src/engine/ still present in citation-evidence (removed in CE-WP-0009)"
hint "Delete local copies; engine code must come from ../citation-engine only."
else
ok "no duplicate src/shared or src/engine in umbrella"
fi
printf '\n'
if [[ "$errors" -gt 0 ]]; then
printf '\033[31mInstall check failed (%d error(s), %d warning(s)).\033[0m\n' "$errors" "$warnings"
printf 'Fix the items above, then run: pnpm install && make check-install\n'
exit 1
fi
if [[ "$warnings" -gt 0 ]]; then
printf '\033[33mInstall check passed with %d warning(s).\033[0m\n' "$warnings"
else
printf '\033[32mInstall check passed.\033[0m\n'
fi
exit 0