@cplieger/deadset-ts 7.2.0-dev.4 → 8.0.0-dev.10
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/README.md +1 -1
- package/dist/bin/mapper-connection.js +2 -1
- package/dist/bin/node-host.js +24 -5
- package/dist/src/analysis.js +245 -309
- package/dist/src/augmentations.js +124 -18
- package/dist/src/automatic-types.js +170 -0
- package/dist/src/build-scripts.js +425 -0
- package/dist/src/component-layer.js +4 -2
- package/dist/src/components.js +9 -9
- package/dist/src/config.js +6 -81
- package/dist/src/configuration-files.js +78 -188
- package/dist/src/configured-declarations.js +15 -20
- package/dist/src/conformance-record.js +2 -2
- package/dist/src/consumers.js +3 -30
- package/dist/src/contextual-uses.js +56 -9
- package/dist/src/contract/config.generated.js +558 -0
- package/dist/src/contract/contract.generated.js +1244 -0
- package/dist/src/contract/report.generated.js +862 -0
- package/dist/src/convention-rows.js +146 -1
- package/dist/src/conventions.js +136 -70
- package/dist/src/decorator.js +21 -18
- package/dist/src/dependencies.js +280 -62
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +4 -6
- package/dist/src/entry-point-gaps.js +9 -18
- package/dist/src/entry-points.js +106 -21
- package/dist/src/enum-group.js +3 -10
- package/dist/src/erased-stores.js +4 -6
- package/dist/src/exempt-classes.js +1 -63
- package/dist/src/exempt.js +21 -40
- package/dist/src/failure.js +36 -0
- package/dist/src/file-facts.js +2 -25
- package/dist/src/findings/completion.js +225 -63
- package/dist/src/findings/dependencies-and-module-machinery.js +72 -27
- package/dist/src/findings/emitters.js +6 -6
- package/dist/src/findings/interfaces.js +4 -5
- package/dist/src/findings/intra-function.js +53 -19
- package/dist/src/findings/non-code-artifacts.js +71 -39
- package/dist/src/findings/reads-and-writes.js +16 -13
- package/dist/src/findings/self-check.js +10 -12
- package/dist/src/findings/unused-declarations.js +57 -28
- package/dist/src/findings/visibility-narrowing.js +40 -18
- package/dist/src/findings-pass.js +8 -15
- package/dist/src/framework-lifecycle.js +7 -7
- package/dist/src/fs/document.js +52 -0
- package/dist/src/fs/manifest.js +72 -0
- package/dist/src/fs/tree.js +88 -0
- package/dist/src/generated-file.js +18 -4
- package/dist/src/git-ignore.js +99 -0
- package/dist/src/graph.js +9 -4
- package/dist/src/html-entries.js +6 -33
- package/dist/src/import-bindings.js +97 -0
- package/dist/src/in-operands.js +2 -1
- package/dist/src/index.js +1 -1
- package/dist/src/indexed-access.js +130 -28
- package/dist/src/injection-container.js +1 -1
- package/dist/src/interface-satisfaction.js +30 -12
- package/dist/src/intra-function-parts.js +341 -69
- package/dist/src/inventory.js +54 -29
- package/dist/src/javascript-file.js +33 -0
- package/dist/src/json-document.js +198 -67
- package/dist/src/keyof-comparisons.js +4 -6
- package/dist/src/kinds.js +3 -366
- package/dist/src/load/classify.js +270 -0
- package/dist/src/load/diagnostics.js +80 -0
- package/dist/src/load/discover.js +277 -0
- package/dist/src/{emit-map.js → load/emit-map.js} +1 -1
- package/dist/src/load/expected-module.js +136 -0
- package/dist/src/load/load.js +27 -0
- package/dist/src/load/module-lookup.js +37 -0
- package/dist/src/load/plan.js +313 -0
- package/dist/src/load/specifiers.js +115 -0
- package/dist/src/load/synthesize.js +140 -0
- package/dist/src/load/test-globals.js +207 -0
- package/dist/src/load/test-joins.js +82 -0
- package/dist/src/{workspace-manifests.js → load/workspace-manifests.js} +4 -4
- package/dist/src/{workspace-programs.js → load/workspace-programs.js} +88 -61
- package/dist/src/{workspace-resolution.js → load/workspace-resolution.js} +60 -59
- package/dist/src/{workspace-run.js → load/workspace-run.js} +7 -7
- package/dist/src/{workspace.js → load/workspace.js} +62 -124
- package/dist/src/manifest.js +49 -54
- package/dist/src/matrix.js +94 -13
- package/dist/src/mdx-entries.js +174 -0
- package/dist/src/module-declarations.js +9 -13
- package/dist/src/outside-tests.js +1 -1
- package/dist/src/overrides.js +41 -10
- package/dist/src/partial.js +2 -1
- package/dist/src/paths.js +26 -15
- package/dist/src/position.js +2 -1
- package/dist/src/print.js +11 -78
- package/dist/src/product.js +13 -0
- package/dist/src/query.js +1 -0
- package/dist/src/ref.js +11 -0
- package/dist/src/references.js +52 -31
- package/dist/src/report-schema.js +51 -0
- package/dist/src/report.js +59 -41
- package/dist/src/reporters/annotations.js +15 -8
- package/dist/src/reporters/sarif.js +16 -10
- package/dist/src/reporters/template.js +4 -19
- package/dist/src/resolve.js +245 -727
- package/dist/src/roots.js +374 -116
- package/dist/src/run.js +66 -77
- package/dist/src/schema.js +320 -342
- package/dist/src/scope.js +38 -115
- package/dist/src/serialization-contract.js +649 -29
- package/dist/src/session.js +41 -29
- package/dist/src/source-files.js +40 -15
- package/dist/src/suppress-file.js +34 -29
- package/dist/src/suppress-inline.js +21 -4
- package/dist/src/suppress.js +40 -56
- package/dist/src/sweep.js +32 -17
- package/dist/src/symbol-keys.js +105 -6
- package/dist/src/template-field.js +9 -19
- package/dist/src/test-support.js +119 -18
- package/dist/src/text/compare.js +26 -0
- package/dist/src/text/glob.js +194 -0
- package/dist/src/text/named-files.js +54 -0
- package/dist/src/text/shell.js +159 -0
- package/dist/src/text/yaml.js +393 -0
- package/dist/src/type-errors.js +27 -221
- package/dist/src/type-parameter-reads.js +172 -0
- package/dist/src/unseen-loads.js +100 -0
- package/dist/src/unwrap.js +23 -0
- package/dist/src/usage.js +10 -0
- package/dist/src/verbs/analyze.js +181 -125
- package/dist/src/verbs/describe.js +9 -16
- package/dist/src/verbs/explain.js +14 -9
- package/dist/src/verbs/print-config.js +2 -1
- package/dist/src/verbs/print-projects.js +6 -4
- package/dist/src/verbs/print-retained.js +4 -2
- package/dist/src/verbs/print-roots.js +4 -2
- package/dist/src/verbs/verb.js +1 -5
- package/dist/src/verbs/version.js +14 -3
- package/dist/src/workflow-steps.js +128 -33
- package/jsr.json +1 -1
- package/package.json +5 -4
- package/src/analysis.ts +333 -457
- package/src/augmentations.ts +152 -23
- package/src/automatic-types.ts +228 -0
- package/src/build-scripts.ts +543 -0
- package/src/component-layer.ts +4 -2
- package/src/components.ts +9 -10
- package/src/config.ts +31 -299
- package/src/configuration-files.ts +100 -191
- package/src/configured-declarations.ts +18 -23
- package/src/conformance-record.ts +2 -2
- package/src/consumers.ts +6 -57
- package/src/contextual-uses.ts +64 -12
- package/src/contract/config.generated.ts +818 -0
- package/src/contract/contract.generated.ts +1308 -0
- package/src/contract/report.generated.ts +1237 -0
- package/src/convention-rows.ts +186 -1
- package/src/conventions.ts +166 -90
- package/src/decorator.ts +28 -18
- package/src/dependencies.ts +356 -78
- package/src/edges.ts +41 -140
- package/src/element-access.ts +4 -7
- package/src/entry-point-gaps.ts +11 -20
- package/src/entry-points.ts +124 -28
- package/src/enum-group.ts +2 -11
- package/src/erased-stores.ts +3 -7
- package/src/exempt-classes.ts +1 -75
- package/src/exempt.ts +36 -50
- package/src/failure.ts +63 -0
- package/src/file-facts.ts +9 -24
- package/src/finding.ts +24 -9
- package/src/findings/boundary.ts +2 -0
- package/src/findings/completion.ts +297 -77
- package/src/findings/dependencies-and-module-machinery.ts +90 -31
- package/src/findings/emitter.ts +8 -9
- package/src/findings/emitters.ts +8 -8
- package/src/findings/interfaces.ts +4 -6
- package/src/findings/intra-function.ts +64 -20
- package/src/findings/non-code-artifacts.ts +88 -50
- package/src/findings/reads-and-writes.ts +20 -16
- package/src/findings/self-check.ts +11 -17
- package/src/findings/unused-declarations.ts +65 -28
- package/src/findings/visibility-narrowing.ts +51 -19
- package/src/findings-pass.ts +10 -19
- package/src/framework-lifecycle.ts +7 -7
- package/src/fs/document.ts +70 -0
- package/src/fs/manifest.ts +92 -0
- package/src/fs/tree.ts +110 -0
- package/src/generated-file.ts +23 -4
- package/src/git-ignore.ts +122 -0
- package/src/graph.ts +11 -3
- package/src/host.ts +17 -14
- package/src/html-entries.ts +6 -33
- package/src/import-bindings.ts +128 -0
- package/src/in-operands.ts +2 -1
- package/src/index.ts +1 -1
- package/src/indexed-access.ts +152 -30
- package/src/injection-container.ts +1 -1
- package/src/interface-satisfaction.ts +33 -13
- package/src/intra-function-parts.ts +449 -85
- package/src/inventory.ts +73 -27
- package/src/javascript-file.ts +37 -0
- package/src/json-document.ts +241 -76
- package/src/keyof-comparisons.ts +3 -7
- package/src/kinds.ts +5 -413
- package/src/load/classify.ts +397 -0
- package/src/load/diagnostics.ts +144 -0
- package/src/load/discover.ts +455 -0
- package/src/{emit-map.ts → load/emit-map.ts} +1 -1
- package/src/load/expected-module.ts +188 -0
- package/src/load/load.ts +73 -0
- package/src/load/module-lookup.ts +50 -0
- package/src/load/plan.ts +504 -0
- package/src/load/specifiers.ts +168 -0
- package/src/load/synthesize.ts +211 -0
- package/src/load/test-globals.ts +251 -0
- package/src/load/test-joins.ts +98 -0
- package/src/{workspace-manifests.ts → load/workspace-manifests.ts} +5 -5
- package/src/{workspace-programs.ts → load/workspace-programs.ts} +127 -80
- package/src/{workspace-resolution.ts → load/workspace-resolution.ts} +73 -64
- package/src/{workspace-run.ts → load/workspace-run.ts} +18 -16
- package/src/{workspace.ts → load/workspace.ts} +90 -134
- package/src/manifest.ts +81 -75
- package/src/matrix.ts +154 -18
- package/src/mdx-entries.ts +218 -0
- package/src/module-declarations.ts +11 -13
- package/src/outside-tests.ts +1 -1
- package/src/overrides.ts +51 -12
- package/src/partial.ts +3 -2
- package/src/paths.ts +27 -15
- package/src/position.ts +2 -1
- package/src/print.ts +12 -91
- package/src/product.ts +18 -0
- package/src/query.ts +11 -0
- package/src/ref.ts +13 -0
- package/src/references.ts +62 -32
- package/src/report-schema.ts +68 -0
- package/src/report.ts +105 -215
- package/src/reporters/annotations.ts +22 -11
- package/src/reporters/json.ts +1 -1
- package/src/reporters/reporter.ts +2 -4
- package/src/reporters/reporters.ts +1 -1
- package/src/reporters/sarif.ts +29 -16
- package/src/reporters/template.ts +4 -20
- package/src/reporters/text.ts +3 -3
- package/src/resolve.ts +283 -1111
- package/src/roots.ts +490 -137
- package/src/run.ts +75 -91
- package/src/schema.ts +391 -387
- package/src/scope.ts +46 -138
- package/src/serialization-contract.ts +818 -26
- package/src/session.ts +77 -54
- package/src/source-files.ts +67 -17
- package/src/suppress-file.ts +36 -34
- package/src/suppress-inline.ts +20 -3
- package/src/suppress.ts +52 -63
- package/src/sweep.ts +53 -18
- package/src/symbol-keys.ts +131 -7
- package/src/template-field.ts +15 -25
- package/src/test-support.ts +155 -18
- package/src/text/compare.ts +27 -0
- package/src/text/glob.ts +210 -0
- package/src/text/named-files.inputs.json +1522 -0
- package/src/text/named-files.ts +68 -0
- package/src/text/shell.ts +161 -0
- package/src/text/yaml.ts +423 -0
- package/src/type-errors.ts +35 -273
- package/src/type-parameter-reads.ts +227 -0
- package/src/unseen-loads.ts +134 -0
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/verbs/analyze.ts +245 -161
- package/src/verbs/describe.ts +14 -15
- package/src/verbs/explain.ts +15 -13
- package/src/verbs/print-config.ts +2 -1
- package/src/verbs/print-projects.ts +6 -4
- package/src/verbs/print-retained.ts +4 -2
- package/src/verbs/print-roots.ts +4 -2
- package/src/verbs/verb.ts +2 -8
- package/src/verbs/version.ts +15 -3
- package/src/workflow-steps.ts +149 -34
- package/dist/src/discover.js +0 -347
- package/dist/src/glob.js +0 -65
- package/dist/src/pnpm-workspace.js +0 -120
- package/dist/src/setup-failure.js +0 -23
- package/dist/src/test-joins.js +0 -101
- package/dist/src/version.js +0 -7
- package/src/discover.ts +0 -510
- package/src/glob.ts +0 -67
- package/src/pnpm-workspace.ts +0 -135
- package/src/setup-failure.ts +0 -39
- package/src/test-joins.ts +0 -120
- package/src/version.ts +0 -7
|
@@ -1,18 +1,24 @@
|
|
|
1
|
+
import { CONTRACT_VERSION, EXIT_CLEAN } from "../contract/contract.generated.js";
|
|
1
2
|
import { runAnalysis, runBaselineWrite, unansweredCounts, } from "../analysis.js";
|
|
2
|
-
import {
|
|
3
|
+
import { kindOf } from "../config.js";
|
|
3
4
|
import { CONFORMANCE, DECLARED_GAPS } from "../conformance.js";
|
|
4
|
-
import { moduleIdentity } from "../consumers.js";
|
|
5
5
|
import { analyzerProvenance, verdictOf } from "../findings-pass.js";
|
|
6
|
-
import { joinPath, normalizePath, relativePath, resolvePath } from "../paths.js";
|
|
6
|
+
import { dirnamePath, joinPath, normalizePath, relativePath, resolvePath } from "../paths.js";
|
|
7
|
+
import { moduleIdentity } from "../load/discover.js";
|
|
7
8
|
import { partialNotes } from "../partial.js";
|
|
8
|
-
import { buildReport,
|
|
9
|
+
import { buildReport, capFindings, sortFindings, } from "../report.js";
|
|
10
|
+
import { reportRefusals } from "../report-schema.js";
|
|
9
11
|
import { json } from "../reporters/json.js";
|
|
10
12
|
import { RENDERINGS } from "../reporters/reporters.js";
|
|
11
13
|
import { parseTemplate, TemplateError } from "../reporters/template.js";
|
|
12
14
|
import { resolve } from "../resolve.js";
|
|
13
15
|
import { otherSchemeRows, rowReason, writeBaseline } from "../suppress-file.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
+
import {} from "./verb.js";
|
|
17
|
+
import { UsageError } from "../usage.js";
|
|
18
|
+
import { bytewise } from "../text/compare.js";
|
|
19
|
+
import { productFault, failureExit } from "../failure.js";
|
|
20
|
+
import { diagnose, message } from "../product.js";
|
|
21
|
+
import { ownVersion } from "./version.js";
|
|
16
22
|
/** The options `analyze` takes beside the ones every verb takes. */
|
|
17
23
|
export const ANALYZE_OPTIONS = {
|
|
18
24
|
plain: ["report", "baseline-write", "exit-code", "template"],
|
|
@@ -21,16 +27,9 @@ export const ANALYZE_OPTIONS = {
|
|
|
21
27
|
/** The two values `--exit-code` takes; on, the default, puts the run's verdict in the exit code. */
|
|
22
28
|
const EXIT_CODE_ON = "on";
|
|
23
29
|
const EXIT_CODE_OFF = "off";
|
|
24
|
-
/** A path of the run no report can name, which ends the run with the failure code. */
|
|
25
|
-
class ReportPathError extends Error {
|
|
26
|
-
constructor(message) {
|
|
27
|
-
super(message);
|
|
28
|
-
this.name = "ReportPathError";
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
30
|
/** The formats this analyzer renders, for a message that names them. */
|
|
32
31
|
function formatNames() {
|
|
33
|
-
return [...RENDERINGS.keys()].sort().join(", ");
|
|
32
|
+
return [...RENDERINGS.keys()].sort(bytewise).join(", ");
|
|
34
33
|
}
|
|
35
34
|
/** The renderings one invocation writes: the ones it named, else the configuration's. */
|
|
36
35
|
function formatsOf(named, configured) {
|
|
@@ -38,10 +37,10 @@ function formatsOf(named, configured) {
|
|
|
38
37
|
const seen = new Set();
|
|
39
38
|
for (const format of formats) {
|
|
40
39
|
if (!RENDERINGS.has(format)) {
|
|
41
|
-
throw new
|
|
40
|
+
throw new UsageError(`${JSON.stringify(format)} is not a format this analyzer renders: the formats are ${formatNames()}`);
|
|
42
41
|
}
|
|
43
42
|
if (seen.has(format)) {
|
|
44
|
-
throw new
|
|
43
|
+
throw new UsageError(`the format ${JSON.stringify(format)} is named twice`);
|
|
45
44
|
}
|
|
46
45
|
seen.add(format);
|
|
47
46
|
}
|
|
@@ -58,16 +57,80 @@ function runRelative(invoked, path) {
|
|
|
58
57
|
}
|
|
59
58
|
const below = relativePath(invoked, path);
|
|
60
59
|
if (below === undefined) {
|
|
61
|
-
throw
|
|
60
|
+
throw failureExit("unreportable-path", `a report names its target relative to the directory the run was invoked from, and ${invoked} does not contain ${path}: run from a directory that does`);
|
|
62
61
|
}
|
|
63
62
|
return below;
|
|
64
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* One note per manifest entry the run reads back to no source file: what the entry names
|
|
66
|
+
* reaches nothing, so the findings its file would have rooted are reported.
|
|
67
|
+
*/
|
|
68
|
+
function unmappedNotes(entries, targetRoot) {
|
|
69
|
+
return entries.map((entry) => {
|
|
70
|
+
const named = relativePath(targetRoot, entry.path) ?? entry.path;
|
|
71
|
+
return {
|
|
72
|
+
kind: "unmapped-entry",
|
|
73
|
+
path: relativePath(targetRoot, entry.dir) ?? ".",
|
|
74
|
+
key: "ts.entry_files",
|
|
75
|
+
message: `the manifest's ${entry.member} names ${named}, which reads back to no source file of the target: name the file it is built from in ts.entry_files`,
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* One note per load of a production file the run cannot resolve, each site once: a file
|
|
81
|
+
* it loads is a root the run does not see, so `ts.roots_complete` lifts no cap there.
|
|
82
|
+
*/
|
|
83
|
+
function unseenLoadNotes(loads) {
|
|
84
|
+
return [
|
|
85
|
+
...new Map(loads.map((load) => {
|
|
86
|
+
const { path, line, column } = load.position;
|
|
87
|
+
const site = `${path}:${String(line)}:${String(column)}`;
|
|
88
|
+
const note = {
|
|
89
|
+
kind: "computed-load",
|
|
90
|
+
path: dirnamePath(path),
|
|
91
|
+
message: `${site} loads a module by a computed path the analysis cannot resolve, so the configurations compiling it report what no root reaches at probable at most, whatever ts.roots_complete says`,
|
|
92
|
+
};
|
|
93
|
+
return [site, note];
|
|
94
|
+
})).values(),
|
|
95
|
+
];
|
|
96
|
+
}
|
|
97
|
+
/** One note per package whose command strings name files a configuration holds, naming every such file. */
|
|
98
|
+
function heldScriptNotes(held, targetRoot) {
|
|
99
|
+
const files = new Map();
|
|
100
|
+
for (const one of held) {
|
|
101
|
+
files.set(one.dir, new Set([...(files.get(one.dir) ?? []), ...one.files]));
|
|
102
|
+
}
|
|
103
|
+
return [...files].map(([dir, paths]) => ({
|
|
104
|
+
kind: "unread-command",
|
|
105
|
+
path: relativePath(targetRoot, dir) ?? ".",
|
|
106
|
+
message: `commands the analysis does not read name ${[...paths].sort(bytewise).join(", ")}, so no finding is reported about ${paths.size === 1 ? "that file itself or the names it exports" : "those files themselves or the names they export"}`,
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
function unresolvedNotes(specifiers) {
|
|
110
|
+
return specifiers.map(({ specifier, position }) => ({
|
|
111
|
+
kind: "unresolved-specifier",
|
|
112
|
+
path: dirnamePath(position.path),
|
|
113
|
+
message: `${position.path}:${String(position.line)}:${String(position.column)} loads ${JSON.stringify(specifier)}, which resolves to no file, so it references nothing`,
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
function unreadLine(input, targetRoot) {
|
|
117
|
+
switch (input.kind) {
|
|
118
|
+
case "manifest": {
|
|
119
|
+
const path = relativePath(targetRoot, input.manifest) ?? input.manifest;
|
|
120
|
+
return input.reason === undefined
|
|
121
|
+
? `${path} does not parse, so the manifest facts of the program formed for its package are unanswered: correct the manifest`
|
|
122
|
+
: `${path} cannot be read, so the manifest facts of the program formed for its package are unanswered: give the run read access to it: ${input.reason}`;
|
|
123
|
+
}
|
|
124
|
+
case "ignore-file":
|
|
125
|
+
return `${relativePath(targetRoot, input.path) ?? input.path} cannot be read, so the JavaScript files it would ignore are analyzed: ${input.reason}`;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
65
128
|
/** Each project the run dropped as a report names it, by its configuration file below the target. */
|
|
66
129
|
function notBuiltOf(dropped, targetRoot) {
|
|
67
130
|
return dropped.map((one) => {
|
|
68
131
|
const project = relativePath(targetRoot, one.configFile);
|
|
69
132
|
if (project === undefined) {
|
|
70
|
-
throw
|
|
133
|
+
throw failureExit("unreportable-path", `the project ${one.id} would be opened from ${one.configFile}, which is not below the target ${targetRoot}, so no report can name it: analyze a target that holds it`);
|
|
71
134
|
}
|
|
72
135
|
return { id: one.id, project, error: one.error };
|
|
73
136
|
});
|
|
@@ -77,11 +140,24 @@ function configurationsOf(projects, targetRoot) {
|
|
|
77
140
|
return projects.map((one) => {
|
|
78
141
|
const project = relativePath(targetRoot, one.configFile);
|
|
79
142
|
if (project === undefined) {
|
|
80
|
-
throw
|
|
143
|
+
throw failureExit("unreportable-path", `the project ${one.id} is opened from ${one.configFile}, which is not below the target ${targetRoot}, so no report can name it: analyze a target that holds it`);
|
|
81
144
|
}
|
|
82
145
|
return { id: one.id, project };
|
|
83
146
|
});
|
|
84
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Writes one document the run was asked for. A document that cannot be produced or written
|
|
150
|
+
* ends the run with the run failure that names it and `fix`, the documents written before it
|
|
151
|
+
* kept.
|
|
152
|
+
*/
|
|
153
|
+
function writeDocument(host, path, fix, produce) {
|
|
154
|
+
try {
|
|
155
|
+
host.writeDocument(path, produce());
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
throw failureExit("unwritten-output", `${path}: ${message(error)}: ${fix}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
85
161
|
/** A count with its noun, so a message reads for one record as well as for several. */
|
|
86
162
|
function counted(n, noun) {
|
|
87
163
|
return `${String(n)} ${noun}${n === 1 ? "" : "s"}`;
|
|
@@ -94,7 +170,7 @@ function counted(n, noun) {
|
|
|
94
170
|
function templateOf(host, invoked, named, formats) {
|
|
95
171
|
if (named === undefined || named === "") {
|
|
96
172
|
if (formats.includes("template")) {
|
|
97
|
-
throw new
|
|
173
|
+
throw new UsageError("the template format renders the template --template names, and none was named");
|
|
98
174
|
}
|
|
99
175
|
return undefined;
|
|
100
176
|
}
|
|
@@ -103,7 +179,7 @@ function templateOf(host, invoked, named, formats) {
|
|
|
103
179
|
source = host.readFile(resolvePath(invoked, named));
|
|
104
180
|
}
|
|
105
181
|
catch (error) {
|
|
106
|
-
throw new
|
|
182
|
+
throw new UsageError(`--template=${named}: ${message(error)}`);
|
|
107
183
|
}
|
|
108
184
|
try {
|
|
109
185
|
return parseTemplate(source);
|
|
@@ -112,7 +188,7 @@ function templateOf(host, invoked, named, formats) {
|
|
|
112
188
|
if (!(error instanceof TemplateError)) {
|
|
113
189
|
throw error;
|
|
114
190
|
}
|
|
115
|
-
throw new
|
|
191
|
+
throw new UsageError(`--template=${named}: ${error.message}`);
|
|
116
192
|
}
|
|
117
193
|
}
|
|
118
194
|
/**
|
|
@@ -126,17 +202,13 @@ function templateOf(host, invoked, named, formats) {
|
|
|
126
202
|
export const analyzeVerb = ({ err, host, inputs, scope, openClient, option, repeated }) => {
|
|
127
203
|
const reportPath = option("report");
|
|
128
204
|
if (reportPath === undefined || reportPath === "") {
|
|
129
|
-
throw new
|
|
205
|
+
throw new UsageError("analyze writes its report to the path --report names, and no path was named");
|
|
130
206
|
}
|
|
131
207
|
const exitCode = option("exit-code") ?? EXIT_CODE_ON;
|
|
132
208
|
if (exitCode !== EXIT_CODE_ON && exitCode !== EXIT_CODE_OFF) {
|
|
133
|
-
throw new
|
|
209
|
+
throw new UsageError(`--exit-code=${JSON.stringify(exitCode)}: the values are ${EXIT_CODE_ON} and ${EXIT_CODE_OFF}`);
|
|
134
210
|
}
|
|
135
211
|
const { config, provenance } = resolve(inputs());
|
|
136
|
-
const kind = config.targetKind;
|
|
137
|
-
if (kind === "") {
|
|
138
|
-
throw new ConfigError("missing-target-kind", "target.kind", "target.kind is not set");
|
|
139
|
-
}
|
|
140
212
|
const invoked = host.workingDirectory();
|
|
141
213
|
const baseline = option("baseline-write");
|
|
142
214
|
const documents = {
|
|
@@ -147,122 +219,106 @@ export const analyzeVerb = ({ err, host, inputs, scope, openClient, option, repe
|
|
|
147
219
|
const template = templateOf(host, invoked, option("template"), documents.formats);
|
|
148
220
|
const scoped = scope();
|
|
149
221
|
const targetRoot = scoped.target.path;
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
version = host.analyzerVersion();
|
|
153
|
-
}
|
|
154
|
-
catch (error) {
|
|
155
|
-
err.write(`deadset-ts: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
156
|
-
return EXIT_FAILURE;
|
|
157
|
-
}
|
|
158
|
-
let report;
|
|
222
|
+
const version = ownVersion(host);
|
|
159
223
|
let recorded;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
let
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const root = runRelative(invoked, targetRoot);
|
|
167
|
-
const mode = { production: true };
|
|
168
|
-
let analysis;
|
|
169
|
-
if (documents.baseline === undefined) {
|
|
170
|
-
analysis = runAnalysis(openClient(config), host, scoped, config, provenance, mode);
|
|
171
|
-
recorded = [];
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
const reason = rowReason(analyzerProvenance(version));
|
|
175
|
-
const write = runBaselineWrite(openClient(config), host, scoped, config, provenance, mode, reason);
|
|
176
|
-
analysis = write.first;
|
|
177
|
-
recorded = write.rows;
|
|
178
|
-
}
|
|
179
|
-
const { result, run } = analysis;
|
|
180
|
-
warnings = run.componentWarnings;
|
|
181
|
-
unread = run.componentsUnread.map(({ configFile, reason }) => `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: its component files are not read: ${reason}`);
|
|
182
|
-
unfound = run.librariesUnfound.map(({ configFile, error }) => `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: ${error}: the configuration is analyzed without that library`);
|
|
183
|
-
partial = partialNotes({
|
|
184
|
-
notBuilt: run.notBuilt,
|
|
185
|
-
unanswered: run.unanswered,
|
|
186
|
-
targetRoot: resolvePath(invoked, targetRoot),
|
|
187
|
-
});
|
|
188
|
-
const built = buildReport({
|
|
189
|
-
contractVersion: CONTRACT_VERSION,
|
|
190
|
-
version,
|
|
191
|
-
conformance: CONFORMANCE,
|
|
192
|
-
declaredGaps: DECLARED_GAPS,
|
|
193
|
-
target: {
|
|
194
|
-
kind: kindOf(kind, LANGUAGE),
|
|
195
|
-
root,
|
|
196
|
-
identity: moduleIdentity(host, scoped.target),
|
|
197
|
-
},
|
|
198
|
-
configurations: configurationsOf(run.projects, targetRoot),
|
|
199
|
-
notBuilt: notBuiltOf(run.notBuilt, targetRoot),
|
|
200
|
-
loaded: run.consumers.map((consumer) => ({
|
|
201
|
-
id: consumer.id,
|
|
202
|
-
path: runRelative(invoked, consumer.path),
|
|
203
|
-
})),
|
|
204
|
-
unavailable: [],
|
|
205
|
-
result,
|
|
206
|
-
testFileRules: run.testFileRules,
|
|
207
|
-
typeErrorSkips: run.typeErrorSkips,
|
|
208
|
-
unanswered: unansweredCounts(analysis),
|
|
209
|
-
conventionsApplied: run.conventionsApplied,
|
|
210
|
-
});
|
|
211
|
-
report = capFindings(sortFindings(built, config.reporters.sort), config.reporters.maxFindings);
|
|
212
|
-
verdict = verdictOf(result, config);
|
|
224
|
+
const root = runRelative(invoked, targetRoot);
|
|
225
|
+
const mode = { production: true };
|
|
226
|
+
let analysis;
|
|
227
|
+
if (documents.baseline === undefined) {
|
|
228
|
+
analysis = runAnalysis(openClient(config), host, scoped, config, provenance, mode);
|
|
229
|
+
recorded = [];
|
|
213
230
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
return EXIT_FAILURE;
|
|
231
|
+
else {
|
|
232
|
+
const reason = rowReason(analyzerProvenance(version));
|
|
233
|
+
const write = runBaselineWrite(openClient(config), host, scoped, config, provenance, mode, reason);
|
|
234
|
+
analysis = write.first;
|
|
235
|
+
recorded = write.rows;
|
|
220
236
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
237
|
+
const { result, run } = analysis;
|
|
238
|
+
const warnings = run.componentWarnings;
|
|
239
|
+
const unread = run.componentsUnread.map(({ configFile, reason }) => `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: its component files are not read: ${reason}`);
|
|
240
|
+
const unfound = run.librariesUnfound.map(({ configFile, error }) => `${relativePath(resolvePath(invoked, targetRoot), configFile) ?? configFile}: ${error}: the configuration is analyzed without that library`);
|
|
241
|
+
const unreadInputs = run.unread.map((one) => unreadLine(one, resolvePath(invoked, targetRoot)));
|
|
242
|
+
const partial = partialNotes({
|
|
243
|
+
notBuilt: run.notBuilt,
|
|
244
|
+
unanswered: run.unanswered,
|
|
245
|
+
targetRoot: resolvePath(invoked, targetRoot),
|
|
246
|
+
});
|
|
247
|
+
const built = buildReport({
|
|
248
|
+
contractVersion: CONTRACT_VERSION,
|
|
249
|
+
version,
|
|
250
|
+
conformance: CONFORMANCE,
|
|
251
|
+
declaredGaps: DECLARED_GAPS,
|
|
252
|
+
target: {
|
|
253
|
+
kind: kindOf(config.target.kind),
|
|
254
|
+
root,
|
|
255
|
+
identity: moduleIdentity(host, scoped.target),
|
|
256
|
+
},
|
|
257
|
+
configurations: configurationsOf(run.projects, targetRoot),
|
|
258
|
+
notBuilt: notBuiltOf(run.notBuilt, targetRoot),
|
|
259
|
+
loaded: run.consumers.map((consumer) => ({
|
|
260
|
+
id: consumer.id,
|
|
261
|
+
path: runRelative(invoked, consumer.path),
|
|
262
|
+
})),
|
|
263
|
+
unavailable: [],
|
|
264
|
+
result,
|
|
265
|
+
testFileRules: run.testFileRules,
|
|
266
|
+
typeErrorSkips: run.typeErrorSkips,
|
|
267
|
+
unanswered: unansweredCounts(analysis),
|
|
268
|
+
conventionsApplied: run.conventionsApplied,
|
|
269
|
+
listsComponents: config.reporters.cascade === "full",
|
|
270
|
+
notes: [
|
|
271
|
+
...unmappedNotes(run.unmappedEntries, resolvePath(invoked, targetRoot)),
|
|
272
|
+
...unseenLoadNotes(run.unseenLoads),
|
|
273
|
+
...unresolvedNotes(run.unresolvedSpecifiers),
|
|
274
|
+
...heldScriptNotes(run.heldScripts, resolvePath(invoked, targetRoot)),
|
|
275
|
+
],
|
|
276
|
+
});
|
|
277
|
+
const report = capFindings(sortFindings(built, config.reporters.sort), config.reporters.max_findings);
|
|
278
|
+
const verdict = verdictOf(result, config);
|
|
279
|
+
const [refused] = reportRefusals(report);
|
|
280
|
+
if (refused !== undefined) {
|
|
281
|
+
throw productFault(`built a report that breaks the report schema at ${refused.pointer || "the document"}: ${refused.keyword}: ${refused.reason}`);
|
|
282
|
+
}
|
|
283
|
+
writeDocument(host, documents.report, "name a path the run can write", () => json(report));
|
|
284
|
+
const options = {
|
|
285
|
+
readSource: (path) => host.readFile(joinPath(targetRoot, path)),
|
|
286
|
+
template,
|
|
287
|
+
};
|
|
288
|
+
for (const format of documents.formats) {
|
|
289
|
+
const rendering = RENDERINGS.get(format);
|
|
290
|
+
if (rendering !== undefined) {
|
|
291
|
+
writeDocument(host, documents.report + rendering.suffix, "name a path the run can write, or correct the template that renders it", () => rendering.render(report, options));
|
|
239
292
|
}
|
|
240
293
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
294
|
+
const baselinePath = documents.baseline;
|
|
295
|
+
if (baselinePath !== undefined) {
|
|
296
|
+
writeDocument(host, baselinePath, "name a path the run can write, or repair the rows of the baseline the run would keep", () => {
|
|
297
|
+
const kept = host.kindOf(baselinePath) === "file" ? otherSchemeRows(host.readFile(baselinePath)) : [];
|
|
298
|
+
return writeBaseline(recorded, analyzerProvenance(version), kept);
|
|
299
|
+
});
|
|
244
300
|
}
|
|
245
301
|
for (const note of partial) {
|
|
246
|
-
err
|
|
302
|
+
diagnose(err, note);
|
|
247
303
|
}
|
|
248
|
-
for (const line of [...unread, ...unfound]) {
|
|
249
|
-
err
|
|
304
|
+
for (const line of [...unread, ...unfound, ...unreadInputs]) {
|
|
305
|
+
diagnose(err, line);
|
|
250
306
|
}
|
|
251
307
|
for (const warning of warnings) {
|
|
252
|
-
err
|
|
308
|
+
diagnose(err, `${warning.path}:${String(warning.line)}: a <script> start tag that begins a line is not read as a block: ${warning.reason}`);
|
|
253
309
|
}
|
|
254
310
|
for (const skip of report.type_error_skips) {
|
|
255
|
-
err
|
|
311
|
+
diagnose(err, `${skip.path}:${String(skip.line)}: ${skip.message}: the function or statement holding this type error is not evaluated`);
|
|
256
312
|
}
|
|
257
313
|
if (report.totals.pending > 0) {
|
|
258
|
-
err
|
|
314
|
+
diagnose(err, `${counted(report.totals.pending, "pending finding")}: the report names a declared cross-language edge, and no merge has resolved it`);
|
|
259
315
|
}
|
|
260
316
|
if (report.totals.stale_suppressions > 0) {
|
|
261
|
-
err
|
|
317
|
+
diagnose(err, counted(report.totals.stale_suppressions, "stale suppression"));
|
|
262
318
|
}
|
|
263
319
|
if (exitCode === EXIT_CODE_OFF) {
|
|
264
320
|
if (verdict !== EXIT_CLEAN) {
|
|
265
|
-
err
|
|
321
|
+
diagnose(err, `the exit code is configured off: the verdict of this run is ${String(verdict)}`);
|
|
266
322
|
}
|
|
267
323
|
return EXIT_CLEAN;
|
|
268
324
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { CONTRACT_VERSION, EXIT_CLEAN, EXIT_USAGE, SCHEMA_VERSIONS, } from "../contract/contract.generated.js";
|
|
1
2
|
import { CONFORMANCE } from "../conformance.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import {} from "./verb.js";
|
|
4
|
+
import { diagnose, LANGUAGE, PRODUCT } from "../product.js";
|
|
5
|
+
import { ownVersion } from "./version.js";
|
|
5
6
|
/**
|
|
6
7
|
* The document `describe` writes: the analyzer, the Contract version it implements, the
|
|
7
8
|
* report schema versions it reads, the languages it claims, and its recorded result over
|
|
@@ -9,10 +10,10 @@ import { EXIT_CLEAN, EXIT_FAILURE, EXIT_USAGE } from "./verb.js";
|
|
|
9
10
|
*/
|
|
10
11
|
export function describeDocument(version, recorded) {
|
|
11
12
|
const document = {
|
|
12
|
-
name:
|
|
13
|
+
name: PRODUCT,
|
|
13
14
|
version,
|
|
14
15
|
contract_version: CONTRACT_VERSION,
|
|
15
|
-
schema_versions_accepted:
|
|
16
|
+
schema_versions_accepted: SCHEMA_VERSIONS,
|
|
16
17
|
languages: [LANGUAGE],
|
|
17
18
|
...(recorded === undefined
|
|
18
19
|
? {}
|
|
@@ -26,20 +27,12 @@ export function describeDocument(version, recorded) {
|
|
|
26
27
|
};
|
|
27
28
|
return `${JSON.stringify(document, null, 2)}\n`;
|
|
28
29
|
}
|
|
29
|
-
/** Writes this analyzer's description to the output stream
|
|
30
|
+
/** Writes this analyzer's description to the output stream. */
|
|
30
31
|
export const describeVerb = ({ out, err, host, args }) => {
|
|
31
32
|
if (args.length > 0) {
|
|
32
|
-
err
|
|
33
|
+
diagnose(err, `describe takes no argument, got ${JSON.stringify(args[0])}`);
|
|
33
34
|
return EXIT_USAGE;
|
|
34
35
|
}
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
version = host.analyzerVersion();
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
err.write(`deadset-ts: describe: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
41
|
-
return EXIT_FAILURE;
|
|
42
|
-
}
|
|
43
|
-
out.write(describeDocument(version, CONFORMANCE));
|
|
36
|
+
out.write(describeDocument(ownVersion(host), CONFORMANCE));
|
|
44
37
|
return EXIT_CLEAN;
|
|
45
38
|
};
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import { EXIT_CLEAN, EXIT_USAGE } from "../contract/contract.generated.js";
|
|
1
2
|
import { runAnalysis } from "../analysis.js";
|
|
2
3
|
import { listing } from "../components.js";
|
|
3
|
-
import { ConfigError } from "../config.js";
|
|
4
4
|
import { OUTSIDE, swept as judged } from "../graph.js";
|
|
5
5
|
import { referenceKey } from "../matrix.js";
|
|
6
6
|
import { partialNotes } from "../partial.js";
|
|
7
7
|
import { resolvePath } from "../paths.js";
|
|
8
8
|
import { positionKey } from "../position.js";
|
|
9
9
|
import { resolve } from "../resolve.js";
|
|
10
|
-
import {
|
|
10
|
+
import {} from "./verb.js";
|
|
11
|
+
import { UsageError } from "../usage.js";
|
|
12
|
+
import { bytewise } from "../text/compare.js";
|
|
13
|
+
import { diagnose } from "../product.js";
|
|
11
14
|
/**
|
|
12
15
|
* The three spellings of an explanation request, each naming the symbol to explain. They are
|
|
13
16
|
* one request, because exactly one state holds for a symbol and the answer is that state.
|
|
@@ -33,10 +36,10 @@ function namedSymbol(option) {
|
|
|
33
36
|
});
|
|
34
37
|
const [only, ...more] = named;
|
|
35
38
|
if (only === undefined) {
|
|
36
|
-
throw new
|
|
39
|
+
throw new UsageError("explain explains the symbol --why, --why-live or --why-not names, and none was named");
|
|
37
40
|
}
|
|
38
41
|
if (more.length > 0) {
|
|
39
|
-
throw new
|
|
42
|
+
throw new UsageError(`explain explains one symbol, and ${named.map((one) => `--${one.name}`).join(", ")} each name one`);
|
|
40
43
|
}
|
|
41
44
|
return only.value;
|
|
42
45
|
}
|
|
@@ -73,7 +76,7 @@ function subjectOf(symbols, named) {
|
|
|
73
76
|
const partial = symbols
|
|
74
77
|
.filter((symbol) => symbol.ref.toLowerCase().includes(folded) || symbol.name.toLowerCase().includes(folded))
|
|
75
78
|
.map(described)
|
|
76
|
-
.sort(
|
|
79
|
+
.sort(bytewise);
|
|
77
80
|
return { candidates: partial.slice(0, MAX_PARTIAL_MATCHES) };
|
|
78
81
|
}
|
|
79
82
|
/** Every reference of the run once, a reference several configurations make counted once. */
|
|
@@ -257,11 +260,13 @@ function reported(found) {
|
|
|
257
260
|
/**
|
|
258
261
|
* Every finding of the run that names the declaration by its reference and reports at
|
|
259
262
|
* another position: a part of it, or a suppression record naming it. Each is published under
|
|
260
|
-
* the reference asked about,
|
|
263
|
+
* the reference asked about, or a parameter's under one it starts, so an explanation leaving
|
|
264
|
+
* it out would disagree with the report.
|
|
261
265
|
*/
|
|
262
266
|
function namedElsewhere(findings, subject) {
|
|
263
267
|
return findings
|
|
264
|
-
.filter((found) => found.symbol.ref === subject.ref &&
|
|
268
|
+
.filter((found) => (found.symbol.holder ?? found.symbol.ref) === subject.ref &&
|
|
269
|
+
positionKey(found.position) !== subject.id)
|
|
265
270
|
.map((found) => `also reported: ${found.code} ${found.kind}\t${positionKey(found.position)}\t${found.symbol.kind} ${found.symbol.name}\n`)
|
|
266
271
|
.join("");
|
|
267
272
|
}
|
|
@@ -315,7 +320,7 @@ export const explainVerb = ({ out, err, host, inputs, scope, openClient, option
|
|
|
315
320
|
targetRoot: resolvePath(host.workingDirectory(), scoped.target.path),
|
|
316
321
|
});
|
|
317
322
|
if (subject === undefined) {
|
|
318
|
-
err
|
|
323
|
+
diagnose(err, `${JSON.stringify(named)} names no one symbol of the target`);
|
|
319
324
|
for (const candidate of candidates) {
|
|
320
325
|
err.write(` ${candidate}\n`);
|
|
321
326
|
}
|
|
@@ -327,7 +332,7 @@ export const explainVerb = ({ out, err, host, inputs, scope, openClient, option
|
|
|
327
332
|
out.write(explanation(analysis, subject, config.reporters.cascade));
|
|
328
333
|
}
|
|
329
334
|
for (const note of notes) {
|
|
330
|
-
err
|
|
335
|
+
diagnose(err, note);
|
|
331
336
|
}
|
|
332
337
|
return subject === undefined ? EXIT_USAGE : EXIT_CLEAN;
|
|
333
338
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { EXIT_CLEAN } from "../contract/contract.generated.js";
|
|
1
2
|
import { printConfig } from "../print.js";
|
|
2
3
|
import { resolve } from "../resolve.js";
|
|
3
|
-
import {
|
|
4
|
+
import {} from "./verb.js";
|
|
4
5
|
/** Writes the resolved configuration with the source of every setting. */
|
|
5
6
|
export const printConfigVerb = ({ out, inputs }) => {
|
|
6
7
|
const { config, provenance } = resolve(inputs());
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { EXIT_CLEAN } from "../contract/contract.generated.js";
|
|
1
2
|
import { runProjects } from "../analysis.js";
|
|
2
3
|
import { partialNotes } from "../partial.js";
|
|
3
4
|
import { resolvePath } from "../paths.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
5
|
+
import { resolvePartial } from "../resolve.js";
|
|
6
|
+
import {} from "./verb.js";
|
|
7
|
+
import { diagnose } from "../product.js";
|
|
6
8
|
/**
|
|
7
9
|
* Writes the name of every project one run analyzes, one per line: the identifier the
|
|
8
10
|
* build matrix declares for it, or, where discovery derived the project, its
|
|
@@ -11,7 +13,7 @@ import { EXIT_CLEAN } from "./verb.js";
|
|
|
11
13
|
* instead, and one that fails the analysis fails this command the same way.
|
|
12
14
|
*/
|
|
13
15
|
export const printProjectsVerb = ({ out, err, host, inputs, scope, openClient }) => {
|
|
14
|
-
const config =
|
|
16
|
+
const config = resolvePartial(inputs());
|
|
15
17
|
const scoped = scope();
|
|
16
18
|
const answer = runProjects(openClient(config), host, scoped, config);
|
|
17
19
|
for (const id of answer.configurations) {
|
|
@@ -22,7 +24,7 @@ export const printProjectsVerb = ({ out, err, host, inputs, scope, openClient })
|
|
|
22
24
|
unanswered: answer.unanswered,
|
|
23
25
|
targetRoot: resolvePath(host.workingDirectory(), scoped.target.path),
|
|
24
26
|
})) {
|
|
25
|
-
err
|
|
27
|
+
diagnose(err, note);
|
|
26
28
|
}
|
|
27
29
|
return EXIT_CLEAN;
|
|
28
30
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { EXIT_CLEAN } from "../contract/contract.generated.js";
|
|
1
2
|
import { runSweep } from "../analysis.js";
|
|
2
3
|
import { retainedLines } from "../exempt.js";
|
|
3
4
|
import { partialNotes } from "../partial.js";
|
|
4
5
|
import { resolvePath } from "../paths.js";
|
|
5
6
|
import { resolve } from "../resolve.js";
|
|
6
|
-
import {
|
|
7
|
+
import {} from "./verb.js";
|
|
8
|
+
import { diagnose } from "../product.js";
|
|
7
9
|
/**
|
|
8
10
|
* Writes every declaration an exemption held back in the production sweep a report is
|
|
9
11
|
* built from, one per line, and nothing where no exemption held one back. One fact
|
|
@@ -26,7 +28,7 @@ export const printRetainedVerb = ({ out, err, host, inputs, scope, openClient })
|
|
|
26
28
|
unanswered: swept.unanswered,
|
|
27
29
|
targetRoot: resolvePath(host.workingDirectory(), scoped.target.path),
|
|
28
30
|
})) {
|
|
29
|
-
err
|
|
31
|
+
diagnose(err, note);
|
|
30
32
|
}
|
|
31
33
|
return EXIT_CLEAN;
|
|
32
34
|
};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { EXIT_CLEAN, EXIT_FINDINGS } from "../contract/contract.generated.js";
|
|
1
2
|
import { runRoots } from "../analysis.js";
|
|
2
3
|
import { partialNotes } from "../partial.js";
|
|
3
4
|
import { resolvePath } from "../paths.js";
|
|
4
5
|
import { resolve } from "../resolve.js";
|
|
5
|
-
import {
|
|
6
|
+
import {} from "./verb.js";
|
|
7
|
+
import { diagnose } from "../product.js";
|
|
6
8
|
/**
|
|
7
9
|
* One root as a line: the declaration's reference, why it is a root, and the string
|
|
8
10
|
* that named it, separated by tabs. A run of several configurations adds the ones
|
|
@@ -39,7 +41,7 @@ export const printRootsVerb = ({ out, err, host, inputs, scope, openClient }) =>
|
|
|
39
41
|
unanswered: answer.unanswered,
|
|
40
42
|
targetRoot: resolvePath(host.workingDirectory(), scoped.target.path),
|
|
41
43
|
})) {
|
|
42
|
-
err
|
|
44
|
+
diagnose(err, note);
|
|
43
45
|
}
|
|
44
46
|
return answer.findings.length > 0 ? EXIT_FINDINGS : EXIT_CLEAN;
|
|
45
47
|
};
|
package/dist/src/verbs/verb.js
CHANGED