@hublo/sentinel 1.5.0-alpha.27 → 1.5.0-alpha.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/sentinel.js
CHANGED
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
palette,
|
|
16
16
|
registerAdapters,
|
|
17
17
|
resolve
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-BYV4XD5W.js";
|
|
19
19
|
import {
|
|
20
20
|
resolveContext
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-OS5TMEKH.js";
|
|
22
22
|
import {
|
|
23
23
|
ensureWorkspacePrep,
|
|
24
24
|
findWorkspaceRoot,
|
|
@@ -148,7 +148,7 @@ async function runValidate(ctx) {
|
|
|
148
148
|
);
|
|
149
149
|
}
|
|
150
150
|
if (!ctx.targets.includes("test")) return 1;
|
|
151
|
-
const { validateModuleTests } = await import("../validate-
|
|
151
|
+
const { validateModuleTests } = await import("../validate-3KEHAU66.js");
|
|
152
152
|
const outcomes = modules.flatMap(
|
|
153
153
|
(module) => validateModuleTests(module.name, module.root)
|
|
154
154
|
);
|
|
@@ -52,8 +52,9 @@ import {
|
|
|
52
52
|
rewriteToolchainImports,
|
|
53
53
|
selfCommand,
|
|
54
54
|
splitToolArgs,
|
|
55
|
-
walk
|
|
56
|
-
|
|
55
|
+
walk,
|
|
56
|
+
writtenFileFormatter
|
|
57
|
+
} from "./chunk-OS5TMEKH.js";
|
|
57
58
|
import {
|
|
58
59
|
DEFAULT_MAX_DIAGNOSTICS,
|
|
59
60
|
WORKSPACE_ROOT_MARKER,
|
|
@@ -7284,6 +7285,59 @@ var JscpdAdapter = class extends BaseAdapter {
|
|
|
7284
7285
|
if (emitting) await emit(report, shape, ctx.cwd, graph, coverage);
|
|
7285
7286
|
return { ok: true, code: 0, metrics: metricsOf(report) };
|
|
7286
7287
|
}
|
|
7288
|
+
/**
|
|
7289
|
+
* Format what `--init` wrote, with the MODULE's own formatter.
|
|
7290
|
+
*
|
|
7291
|
+
* ⛔ Found by adopting the role on `libs/front/ui`, where the module's `lint` target is
|
|
7292
|
+
* `prettier --check . && eslint .`. Adoption turned it red on the two files adoption itself had
|
|
7293
|
+
* just written:
|
|
7294
|
+
*
|
|
7295
|
+
* [warn] package.json
|
|
7296
|
+
* [warn] static-analysis.config.mjs
|
|
7297
|
+
*
|
|
7298
|
+
* So a team adopting this role is handed a red lint on a target the adoption never touched, for
|
|
7299
|
+
* something the adoption caused. That is what the test role already refuses in its own words:
|
|
7300
|
+
* "the migration handing its own consequence to whoever adopts, which is the one thing this role
|
|
7301
|
+
* must not do". It had the mechanism and this role did not use it.
|
|
7302
|
+
*
|
|
7303
|
+
* ⚠️ The blast radius is small and measured: **2 modules of 243** run `prettier --check` in their
|
|
7304
|
+
* own lint without having adopted our format role, `apps/front/host-admin` and `libs/front/ui`.
|
|
7305
|
+
* Small is not a reason to leave it: the two are exactly the modules a team would adopt by hand.
|
|
7306
|
+
*
|
|
7307
|
+
* The formatter is borrowed from the test role rather than written again, the same way the size
|
|
7308
|
+
* gauge borrows `resolveOxlint` from the lint role: it already knows how a module declares a
|
|
7309
|
+
* style, including the case where that style IS ours.
|
|
7310
|
+
*
|
|
7311
|
+
* ⛔ Never fatal. Adoption succeeded; only the tidy-up did not. Reverting an adoption over a
|
|
7312
|
+
* formatting pass would be the wrong trade, so a failure here is reported as what it is.
|
|
7313
|
+
*
|
|
7314
|
+
* No batching, unlike the test role: `--init` writes two files, and the OOM that forced batches
|
|
7315
|
+
* there came from handing a formatter 273 at once.
|
|
7316
|
+
*/
|
|
7317
|
+
async afterInit(ctx) {
|
|
7318
|
+
const written = ctx.written ?? [];
|
|
7319
|
+
if (written.length === 0) return Promise.resolve();
|
|
7320
|
+
const formatter = writtenFileFormatter(ctx.cwd);
|
|
7321
|
+
if (formatter === void 0) {
|
|
7322
|
+
this.say(
|
|
7323
|
+
`no style is declared here, by this module or its workspace, so the ${written.length} file(s) this wrote keep the shape they were written in. Run your own formatter over them before committing.`
|
|
7324
|
+
);
|
|
7325
|
+
return Promise.resolve();
|
|
7326
|
+
}
|
|
7327
|
+
const pass = spawnSync6(formatter.bin, [...formatter.args, ...written], {
|
|
7328
|
+
cwd: ctx.cwd,
|
|
7329
|
+
encoding: "utf8"
|
|
7330
|
+
});
|
|
7331
|
+
this.say(
|
|
7332
|
+
pass.status === 0 ? `formatted the ${written.length} file(s) this wrote with ${formatter.origin}, so a format check passes on files it did not write itself.` : `${formatter.origin} could not run over the ${written.length} file(s) this wrote. Adoption itself is applied; run your formatter before committing.`
|
|
7333
|
+
);
|
|
7334
|
+
return Promise.resolve();
|
|
7335
|
+
}
|
|
7336
|
+
/** One line, prefixed like every other message this role writes. */
|
|
7337
|
+
say(message) {
|
|
7338
|
+
process.stderr.write(`sentinel static-analysis(jscpd): ${message}
|
|
7339
|
+
`);
|
|
7340
|
+
}
|
|
7287
7341
|
/** `--run`: measure and show it. */
|
|
7288
7342
|
async run(ctx) {
|
|
7289
7343
|
return this.measure(ctx, true);
|
|
@@ -7518,7 +7572,7 @@ function safeParseDeadCode(text) {
|
|
|
7518
7572
|
return void 0;
|
|
7519
7573
|
}
|
|
7520
7574
|
}
|
|
7521
|
-
function placesToLook(product, tests, dead, complexity, graph, size) {
|
|
7575
|
+
function placesToLook(product, tests, dead, complexity, graph, size, unreadable) {
|
|
7522
7576
|
const at = (side) => `${side?.name ?? "(unknown)"}${side?.start === void 0 ? "" : `:${side.start}`}`;
|
|
7523
7577
|
const clones = (outcome, metric) => outcome.kind === "figures" ? outcome.duplicates.map((entry) => ({
|
|
7524
7578
|
metric,
|
|
@@ -7543,7 +7597,7 @@ function placesToLook(product, tests, dead, complexity, graph, size) {
|
|
|
7543
7597
|
name: fn.name,
|
|
7544
7598
|
value: fn.complexity
|
|
7545
7599
|
})),
|
|
7546
|
-
...dead.kind === "figures" ? dead.findings.map((finding) => ({
|
|
7600
|
+
...dead.kind === "figures" && !unreadable ? dead.findings.map((finding) => ({
|
|
7547
7601
|
metric: deadMetric[finding.category ?? ""] ?? "deadLinesPercent",
|
|
7548
7602
|
path: finding.path ?? "(unknown)",
|
|
7549
7603
|
...finding.name ? { name: finding.name } : {},
|
|
@@ -7555,7 +7609,7 @@ function placesToLook(product, tests, dead, complexity, graph, size) {
|
|
|
7555
7609
|
// One finding per GROUP of mutually importing files, not per cycle path: see `graph/scan.ts`.
|
|
7556
7610
|
// The first file names the finding and the rest go in `other`, which is the shape the report
|
|
7557
7611
|
// already renders for a clone's two sides.
|
|
7558
|
-
...graph.cycles.map((cycle) => ({
|
|
7612
|
+
...(unreadable ? [] : graph.cycles).map((cycle) => ({
|
|
7559
7613
|
metric: "cycles",
|
|
7560
7614
|
path: cycle.files[0] ?? "(unknown)",
|
|
7561
7615
|
other: cycle.files.slice(1).join(", "),
|
|
@@ -7593,7 +7647,7 @@ function placesToLook(product, tests, dead, complexity, graph, size) {
|
|
|
7593
7647
|
})),
|
|
7594
7648
|
// ⛔ Context, not defects. Every module has a most-imported file, and nothing here says the
|
|
7595
7649
|
// count is too high: the caveat on the metric says so in the reader's own words.
|
|
7596
|
-
...graph.mostImported.map((file) => ({
|
|
7650
|
+
...(unreadable ? [] : graph.mostImported).map((file) => ({
|
|
7597
7651
|
metric: "mostImported",
|
|
7598
7652
|
path: file.path,
|
|
7599
7653
|
value: file.importedBy,
|
|
@@ -7779,17 +7833,22 @@ function assembleReport(ctx, config, product, tests, dead, complexity, graph, co
|
|
|
7779
7833
|
* 2% of the files, so the reader looks for a big generated or seed file instead of concluding
|
|
7780
7834
|
* anything about the code they write. Nothing is computed that the pass did not hand over.
|
|
7781
7835
|
*
|
|
7782
|
-
* ⚠️ "
|
|
7836
|
+
* ⚠️ "N files UNREACHABLE IN FULL" and not "in N files", which is what this said first. The
|
|
7783
7837
|
* two numbers do NOT contain one another: dead lines also come from exports and symbols that
|
|
7784
7838
|
* are dead inside files the walk DOES reach. Measured on `apps/front/console`, 0 files are
|
|
7785
7839
|
* unreachable and 0.64% of lines are still dead, which read as a contradiction. On `agency`
|
|
7786
7840
|
* the wording looked right only by coincidence, because 13 files carried 53 233 of its
|
|
7787
7841
|
* 53 242 dead lines.
|
|
7842
|
+
*
|
|
7843
|
+
* ⛔ And a COMMA, not a semicolon. The markdown recap truncates a unit at its first `;`,
|
|
7844
|
+
* because the bundle units carry a second comparison that pushes a table row past readable
|
|
7845
|
+
* width. A semicolon here meant the recap silently dropped the very denominator this comment
|
|
7846
|
+
* exists for, which is the shape of defect the denominator was added to prevent.
|
|
7788
7847
|
*/
|
|
7789
7848
|
{
|
|
7790
7849
|
metric: "deadLinesPercent",
|
|
7791
7850
|
value: share(stats),
|
|
7792
|
-
unit: `% of lines
|
|
7851
|
+
unit: `% of lines, ${(stats.files ?? 0) - (stats.reachableFiles ?? 0)} of ${stats.files ?? 0} files unreachable in full`
|
|
7793
7852
|
},
|
|
7794
7853
|
// ⛔ Minus the files the TOOL itself labels `used-only-by-tests`. They were counted as
|
|
7795
7854
|
// unreachable while the tool knew better: measured on `libs/nest/auth`, 5 of the 20. A file a
|
|
@@ -7897,7 +7956,7 @@ function assembleReport(ctx, config, product, tests, dead, complexity, graph, co
|
|
|
7897
7956
|
rows,
|
|
7898
7957
|
notes,
|
|
7899
7958
|
settings,
|
|
7900
|
-
findings: placesToLook(product, tests, dead, complexity, graph, size),
|
|
7959
|
+
findings: placesToLook(product, tests, dead, complexity, graph, size, unreadable),
|
|
7901
7960
|
byLanguage
|
|
7902
7961
|
};
|
|
7903
7962
|
}
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
registerAdapters,
|
|
7
7
|
resolve,
|
|
8
8
|
setDefaultRunner
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BYV4XD5W.js";
|
|
10
10
|
import {
|
|
11
11
|
BaseAdapter
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-OS5TMEKH.js";
|
|
13
13
|
import "./chunk-JEYGPPSL.js";
|
|
14
14
|
import "./chunk-GCHCLR7P.js";
|
|
15
15
|
import "./chunk-O7REVMOC.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hublo/sentinel",
|
|
3
|
-
"version": "1.5.0-alpha.
|
|
3
|
+
"version": "1.5.0-alpha.28",
|
|
4
4
|
"description": "One CLI that guards code health across Hublo repos: shared lint/typescript/build/test presets, static & dynamic analysis, and architecture checks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|