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.
162 lines
No EOL
5.5 KiB
Bash
Executable file
162 lines
No EOL
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 |