mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
Reorganizes the 29 active scripts under scripts/ into purpose-driven subfolders: - scripts/build/ (11) — Build, install, publish, runtime env - scripts/dev/ (13) — Dev servers, test runners, healthchecks - scripts/check/ (10) — Lint/validation/coverage checks - scripts/docs/ (2) — Docs index and provider reference generation - scripts/i18n/ (+3) — Adds Python translation utilities (check/validate/autotranslate) - scripts/ad-hoc/ (4) — One-shot maintenance utilities Updates all references in package.json, electron/package.json, .husky/pre-commit, .github/workflows/ci.yml, Dockerfile, src/, tests/, scripts/ internal cross-imports, playwright.config.ts, and English docs (CODEBASE_DOCUMENTATION, ENVIRONMENT, FEATURES, RELEASE_CHECKLIST, COVERAGE_PLAN, ELECTRON_GUIDE, I18N, GEMINI). Also patches scripts/build/pack-artifact-policy.ts so the npm pack allowlist mirrors the new layout. Validates with: - npm run lint (exit 0 — pre-existing minified-bundle errors only) - npm run typecheck:core (exit 0) - npm run check:docs-all (exit 0) - unit tests for moved scripts (57 tests pass) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
132 lines
4.1 KiB
JavaScript
132 lines
4.1 KiB
JavaScript
#!/usr/bin/env node
|
|
// Validates that env vars referenced in code appear in .env.example AND in docs/ENVIRONMENT.md.
|
|
// Exits 0 on success, 1 on missing entries. Designed for use in pre-commit / CI.
|
|
//
|
|
// Run: node scripts/check/check-env-doc-sync.mjs
|
|
// Strict mode: node scripts/check/check-env-doc-sync.mjs --strict
|
|
// In strict mode, missing entries cause failure. In default mode, only summary is printed.
|
|
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { execSync } from "node:child_process";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const ROOT = path.resolve(__dirname, "..", "..");
|
|
const ENV_EXAMPLE = path.join(ROOT, ".env.example");
|
|
const ENV_DOC = path.join(ROOT, "docs", "ENVIRONMENT.md");
|
|
|
|
const STRICT = process.argv.includes("--strict");
|
|
|
|
// Vars that are intentionally not documented or detected in code via dynamic patterns.
|
|
const IGNORE = new Set([
|
|
"NODE_ENV",
|
|
"PATH",
|
|
"HOME",
|
|
"USER",
|
|
"PWD",
|
|
"SHELL",
|
|
"TERM",
|
|
"TZ",
|
|
"LANG",
|
|
"LC_ALL",
|
|
"CI",
|
|
"GITHUB_ACTIONS",
|
|
"RUNNER_OS",
|
|
// Add false positives here as discovered.
|
|
]);
|
|
|
|
function readEnvExampleVars() {
|
|
if (!fs.existsSync(ENV_EXAMPLE)) {
|
|
console.error(`✗ ${ENV_EXAMPLE} not found`);
|
|
process.exit(2);
|
|
}
|
|
const txt = fs.readFileSync(ENV_EXAMPLE, "utf8");
|
|
const vars = new Set();
|
|
for (const line of txt.split("\n")) {
|
|
// Match both "VAR=value" and "# VAR=value" (commented-out examples are still documented)
|
|
const m = line.match(/^#?\s*([A-Z][A-Z0-9_]+)\s*=/);
|
|
if (m) vars.add(m[1]);
|
|
}
|
|
return vars;
|
|
}
|
|
|
|
function readEnvDocVars() {
|
|
if (!fs.existsSync(ENV_DOC)) {
|
|
console.error(`✗ ${ENV_DOC} not found`);
|
|
process.exit(2);
|
|
}
|
|
const txt = fs.readFileSync(ENV_DOC, "utf8");
|
|
const vars = new Set();
|
|
// Match `VAR_NAME` in inline code or table cells.
|
|
for (const m of txt.matchAll(/`([A-Z][A-Z0-9_]{2,})`/g)) {
|
|
vars.add(m[1]);
|
|
}
|
|
return vars;
|
|
}
|
|
|
|
function readCodeVars() {
|
|
const vars = new Set();
|
|
let stdout;
|
|
try {
|
|
stdout = execSync(
|
|
"grep -rhoE 'process\\.env\\.[A-Z][A-Z0-9_]+' src/ open-sse/ bin/ scripts/ 2>/dev/null || true",
|
|
{ cwd: ROOT, encoding: "utf8", maxBuffer: 20 * 1024 * 1024 }
|
|
);
|
|
} catch (e) {
|
|
console.error(`✗ grep failed: ${e.message}`);
|
|
process.exit(2);
|
|
}
|
|
for (const line of stdout.split("\n")) {
|
|
const m = line.match(/^process\.env\.([A-Z][A-Z0-9_]+)$/);
|
|
if (m && !IGNORE.has(m[1])) vars.add(m[1]);
|
|
}
|
|
return vars;
|
|
}
|
|
|
|
function diff(set, against) {
|
|
return [...set].filter((v) => !against.has(v)).sort();
|
|
}
|
|
|
|
function main() {
|
|
const codeVars = readCodeVars();
|
|
const exampleVars = readEnvExampleVars();
|
|
const docVars = readEnvDocVars();
|
|
|
|
const inCodeMissingExample = diff(codeVars, exampleVars);
|
|
const inCodeMissingDoc = diff(codeVars, docVars);
|
|
const inExampleMissingDoc = diff(exampleVars, docVars);
|
|
const inExampleMissingCode = diff(exampleVars, codeVars);
|
|
|
|
console.log("Env var sync report");
|
|
console.log("===================");
|
|
console.log(`Code references: ${codeVars.size} unique vars`);
|
|
console.log(`In .env.example: ${exampleVars.size} unique vars`);
|
|
console.log(`In docs/ENVIRONMENT.md: ${docVars.size} unique vars (heuristic)`);
|
|
console.log();
|
|
|
|
function printList(label, list) {
|
|
if (list.length === 0) {
|
|
console.log(` ✓ ${label}: none`);
|
|
} else {
|
|
console.log(` ⚠ ${label}: ${list.length}`);
|
|
for (const v of list.slice(0, 30)) console.log(` - ${v}`);
|
|
if (list.length > 30) console.log(` ... and ${list.length - 30} more`);
|
|
}
|
|
}
|
|
|
|
printList("In code but missing from .env.example", inCodeMissingExample);
|
|
printList("In code but missing from ENVIRONMENT.md", inCodeMissingDoc);
|
|
printList("In .env.example but missing from ENVIRONMENT.md", inExampleMissingDoc);
|
|
printList("In .env.example but not referenced in code (dead?)", inExampleMissingCode);
|
|
|
|
const errors = inCodeMissingExample.length + inExampleMissingDoc.length;
|
|
if (STRICT && errors > 0) {
|
|
console.error(`\n✗ ${errors} drift(s) detected (strict mode)`);
|
|
process.exit(1);
|
|
}
|
|
console.log(`\n${errors === 0 ? "✓" : "⚠"} Done.`);
|
|
}
|
|
|
|
main();
|