1#!/usr/bin/env node
2
16import { copyFileSync, existsSync, readFileSync } from "node:fs";
17import { dirname, join, relative } from "node:path";
18import { fileURLToPath } from "node:url";
19
20const here = dirname(fileURLToPath(import.meta.url));
21const kdir = join(here, "..");
22const sdir = join(here, "..", "..", "..", "observability");
23
24const PAIRS = [
25 ["prometheus/scrape.yaml", "prometheus/scrape.yaml"],
26 ["prometheus/recording-rules.yaml", "prometheus/recording-rules.yaml"],
27 ["prometheus/alerts.yaml", "prometheus/alerts.yaml"],
28 ["alertmanager/alertmanager.yaml", "alertmanager/alertmanager.yaml"],
29 ["grafana/provisioning/datasources/datasource.yaml", "grafana/provisioning/datasources/datasource.yaml"],
30 ["grafana/provisioning/dashboards/dashboards.yaml", "grafana/provisioning/dashboards/dashboards.yaml"],
31 ["grafana/dashboards/api-overview.json", "grafana/dashboards/api-overview.json"],
32 ["grafana/dashboards/realtime.json", "grafana/dashboards/realtime.json"],
33 ["grafana/dashboards/workers-queues.json", "grafana/dashboards/workers-queues.json"],
34 ["grafana/dashboards/search.json", "grafana/dashboards/search.json"],
35 ["grafana/dashboards/ai.json", "grafana/dashboards/ai.json"],
36 ["grafana/dashboards/infra.json", "grafana/dashboards/infra.json"]
37];
38
39const write = process.argv.includes("--write");
40let bad = 0;
41
42for (const [srcRel, mirrorRel] of PAIRS) {
43 const src = join(sdir, srcRel);
44 const mirror = join(kdir, mirrorRel);
45 if (!existsSync(src)) {
46 console.error(`MISSING SOURCE: ${srcRel}`);
47 bad++;
48 continue;
49 }
50 if (!existsSync(mirror) || readFileSync(src, "utf8") !== readFileSync(mirror, "utf8")) {
51 if (write) {
52 copyFileSync(src, mirror);
53 console.log(`re-mirrored ${mirrorRel}`);
54 } else {
55 console.error(`DRIFT: ${mirrorRel} != ${srcRel}`);
56 bad++;
57 }
58 }
59}
60
61if (write && bad === 0) {
62 console.log("OK: mirror is in sync (write mode)");
63} else if (bad === 0) {
64 console.log(`OK: ${PAIRS.length} mirror files are in sync with infrastructure/observability/`);
65} else {
66 console.error(`${bad} file(s) out of sync — run: node ${relative(process.cwd(), join(here, "sync-sources.mjs"))} --write`);
67 process.exit(1);
68}
69