From 341db4f821aec0810bf2abbae179930c89a72f11 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Mon, 2 Feb 2026 19:39:13 -0500 Subject: [PATCH] Add dependency duplication check between app and framework Adds check-deps.ts which ensures backend/package.json doesn't duplicate any dependencies already provided by backend/diachron/package.json. Integrated into backend/check.sh. Co-Authored-By: Claude Opus 4.5 --- backend/check-deps.ts | 66 +++++++++++++++++++++++++++++++++++ backend/check.sh | 1 + backend/tsconfig.json | 2 +- diachron/common.d/check-deps | 11 ++++++ diachron/develop.d/check-deps | 1 + diachron/mgmt.d/check-deps | 1 + 6 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 backend/check-deps.ts create mode 100755 diachron/common.d/check-deps create mode 120000 diachron/develop.d/check-deps create mode 120000 diachron/mgmt.d/check-deps diff --git a/backend/check-deps.ts b/backend/check-deps.ts new file mode 100644 index 0000000..a4d7b91 --- /dev/null +++ b/backend/check-deps.ts @@ -0,0 +1,66 @@ +import { readFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +interface PackageJson { + dependencies?: Record; + devDependencies?: Record; +} + +function readPackageJson(path: string): PackageJson { + const content = readFileSync(path, "utf-8"); + return JSON.parse(content); +} + +function getAllDependencyNames(pkg: PackageJson): Set { + const names = new Set(); + for (const name of Object.keys(pkg.dependencies ?? {})) { + names.add(name); + } + for (const name of Object.keys(pkg.devDependencies ?? {})) { + names.add(name); + } + return names; +} + +const diachronPkgPath = join(__dirname, "diachron", "package.json"); +const backendPkgPath = join(__dirname, "package.json"); + +const diachronPkg = readPackageJson(diachronPkgPath); +const backendPkg = readPackageJson(backendPkgPath); + +const diachronDeps = getAllDependencyNames(diachronPkg); +const backendDeps = getAllDependencyNames(backendPkg); + +const duplicates: string[] = []; + +for (const dep of diachronDeps) { + if (backendDeps.has(dep)) { + duplicates.push(dep); + } +} + +if (duplicates.length > 0) { + console.error("Error: Duplicate dependencies found."); + console.error(""); + console.error( + "The following dependencies exist in both backend/package.json and backend/diachron/package.json:", + ); + console.error(""); + for (const dep of duplicates.sort()) { + console.error(` - ${dep}`); + } + console.error(""); + console.error( + "Dependencies in backend/diachron/package.json are provided by the framework", + ); + console.error( + "and must not be duplicated in backend/package.json. Remove them from", + ); + console.error("backend/package.json to fix this error."); + process.exit(1); +} + +console.log("No duplicate dependencies found."); diff --git a/backend/check.sh b/backend/check.sh index 15f51ca..9d9df00 100755 --- a/backend/check.sh +++ b/backend/check.sh @@ -11,4 +11,5 @@ out_dir="$check_dir/out" source "$check_dir"/../diachron/shims/common source "$check_dir"/../diachron/shims/node.common +$ROOT/cmd tsx "$check_dir/check-deps.ts" $ROOT/cmd pnpm tsc --outDir "$out_dir" diff --git a/backend/tsconfig.json b/backend/tsconfig.json index a1cccc6..12febab 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -10,5 +10,5 @@ "types": ["node"], "outDir": "out" }, - "exclude": ["**/*.spec.ts", "**/*.test.ts"] + "exclude": ["**/*.spec.ts", "**/*.test.ts", "check-deps.ts"] } diff --git a/diachron/common.d/check-deps b/diachron/common.d/check-deps new file mode 100755 index 0000000..e21c4c7 --- /dev/null +++ b/diachron/common.d/check-deps @@ -0,0 +1,11 @@ +#!/bin/bash + +set -eu + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +ROOT="$DIR/../.." + +cd "$ROOT/backend" + +"$ROOT/cmd" tsx check-deps.ts "$@" diff --git a/diachron/develop.d/check-deps b/diachron/develop.d/check-deps new file mode 120000 index 0000000..ddca9c8 --- /dev/null +++ b/diachron/develop.d/check-deps @@ -0,0 +1 @@ +../common.d/check-deps \ No newline at end of file diff --git a/diachron/mgmt.d/check-deps b/diachron/mgmt.d/check-deps new file mode 120000 index 0000000..ddca9c8 --- /dev/null +++ b/diachron/mgmt.d/check-deps @@ -0,0 +1 @@ +../common.d/check-deps \ No newline at end of file