mirror of
https://github.com/harivansh-afk/betterNAS.git
synced 2026-04-15 13:03:43 +00:00
pnpm, verify, cleanup
This commit is contained in:
parent
b68151035a
commit
28b6e9c264
45 changed files with 4276 additions and 5133 deletions
117
scripts/check-boundaries.mjs
Normal file
117
scripts/check-boundaries.mjs
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
import { readdirSync, readFileSync, statSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const repoRoot = process.cwd();
|
||||
const sourceExtensions = new Set([".js", ".mjs", ".cjs", ".ts", ".tsx"]);
|
||||
const ignoredDirectories = new Set([
|
||||
".git",
|
||||
".next",
|
||||
".turbo",
|
||||
"coverage",
|
||||
"dist",
|
||||
"node_modules",
|
||||
]);
|
||||
|
||||
const laneRoots = [];
|
||||
for (const baseDir of ["apps", "packages"]) {
|
||||
const absoluteBaseDir = path.join(repoRoot, baseDir);
|
||||
for (const entry of readdirSync(absoluteBaseDir, { withFileTypes: true })) {
|
||||
if (entry.isDirectory()) {
|
||||
laneRoots.push(path.join(absoluteBaseDir, entry.name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const disallowedWorkspacePackages = new Set([
|
||||
"@betternas/sdk-ts",
|
||||
"@betternas/web",
|
||||
"@betternas/control-plane",
|
||||
"@betternas/node-agent",
|
||||
"@betternas/nextcloud-app",
|
||||
]);
|
||||
|
||||
const importPattern =
|
||||
/\b(?:import|export)\b[\s\S]*?\bfrom\s*["']([^"']+)["']|import\s*\(\s*["']([^"']+)["']\s*\)/g;
|
||||
|
||||
const errors = [];
|
||||
|
||||
walk(path.join(repoRoot, "apps"));
|
||||
walk(path.join(repoRoot, "packages"));
|
||||
|
||||
if (errors.length > 0) {
|
||||
console.error("Boundary check failed:\n");
|
||||
for (const error of errors) {
|
||||
console.error(`- ${error}`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("Boundary check passed.");
|
||||
|
||||
function walk(currentPath) {
|
||||
const stat = statSync(currentPath);
|
||||
if (stat.isDirectory()) {
|
||||
if (ignoredDirectories.has(path.basename(currentPath))) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const entry of readdirSync(currentPath, { withFileTypes: true })) {
|
||||
walk(path.join(currentPath, entry.name));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sourceExtensions.has(path.extname(currentPath))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fileContent = readFileSync(currentPath, "utf8");
|
||||
const fileRoot = findLaneRoot(currentPath);
|
||||
if (fileRoot === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const match of fileContent.matchAll(importPattern)) {
|
||||
const specifier = match[1] ?? match[2];
|
||||
if (!specifier) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (disallowedWorkspacePackages.has(specifier)) {
|
||||
errors.push(
|
||||
`${relativeToRepo(currentPath)} imports forbidden workspace package ${specifier}`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!specifier.startsWith(".")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const resolvedImport = path.resolve(path.dirname(currentPath), specifier);
|
||||
const targetRoot = findLaneRoot(resolvedImport);
|
||||
if (targetRoot !== null && targetRoot !== fileRoot) {
|
||||
errors.push(
|
||||
`${relativeToRepo(currentPath)} crosses lane boundary with relative import ${specifier}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findLaneRoot(targetPath) {
|
||||
const normalizedTargetPath = path.normalize(targetPath);
|
||||
for (const laneRoot of laneRoots) {
|
||||
const normalizedLaneRoot = path.normalize(laneRoot);
|
||||
if (
|
||||
normalizedTargetPath === normalizedLaneRoot ||
|
||||
normalizedTargetPath.startsWith(`${normalizedLaneRoot}${path.sep}`)
|
||||
) {
|
||||
return normalizedLaneRoot;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function relativeToRepo(targetPath) {
|
||||
return path.relative(repoRoot, targetPath) || ".";
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue