@cplieger/deadset-ts 8.0.0-dev.6 → 8.0.0-dev.8
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/mapper-connection.js +2 -1
- package/dist/bin/node-host.js +24 -5
- package/dist/src/analysis.js +37 -56
- package/dist/src/automatic-types.js +10 -29
- package/dist/src/build-scripts.js +17 -29
- package/dist/src/component-layer.js +4 -2
- package/dist/src/components.js +2 -3
- package/dist/src/config.js +6 -82
- package/dist/src/configuration-files.js +27 -168
- package/dist/src/configured-declarations.js +15 -20
- package/dist/src/consumers.js +2 -2
- package/dist/src/contract/config.generated.js +544 -0
- package/dist/src/contract/contract.generated.js +13 -0
- package/dist/src/contract/report.generated.js +3 -2
- package/dist/src/conventions.js +20 -60
- package/dist/src/dependencies.js +25 -43
- package/dist/src/discover.js +14 -40
- package/dist/src/edges.js +38 -122
- package/dist/src/element-access.js +4 -6
- package/dist/src/entry-point-gaps.js +2 -8
- package/dist/src/entry-points.js +3 -10
- package/dist/src/enum-group.js +3 -10
- package/dist/src/erased-stores.js +4 -6
- package/dist/src/exempt-classes.js +0 -4
- package/dist/src/exempt.js +6 -22
- package/dist/src/file-facts.js +2 -25
- package/dist/src/findings/completion.js +5 -4
- package/dist/src/findings/emitters.js +1 -1
- package/dist/src/findings/intra-function.js +1 -1
- package/dist/src/findings/non-code-artifacts.js +2 -2
- package/dist/src/findings/reads-and-writes.js +2 -1
- package/dist/src/findings/self-check.js +3 -2
- package/dist/src/findings/unused-declarations.js +1 -1
- package/dist/src/findings/visibility-narrowing.js +2 -2
- package/dist/src/findings-pass.js +7 -12
- package/dist/src/framework-lifecycle.js +7 -7
- package/dist/src/fs/document.js +59 -0
- package/dist/src/fs/manifest.js +43 -0
- package/dist/src/fs/tree.js +88 -0
- package/dist/src/git-ignore.js +34 -25
- package/dist/src/html-entries.js +6 -33
- package/dist/src/in-operands.js +2 -1
- package/dist/src/injection-container.js +1 -1
- package/dist/src/intra-function-parts.js +10 -13
- package/dist/src/inventory.js +2 -21
- package/dist/src/json-document.js +198 -67
- package/dist/src/keyof-comparisons.js +4 -6
- package/dist/src/kinds.js +0 -7
- package/dist/src/manifest.js +5 -43
- package/dist/src/mdx-entries.js +3 -26
- 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 -79
- package/dist/src/product.js +13 -0
- package/dist/src/references.js +14 -27
- package/dist/src/report-schema.js +3 -225
- package/dist/src/report.js +22 -31
- package/dist/src/reporters/sarif.js +4 -2
- package/dist/src/reporters/template.js +4 -19
- package/dist/src/resolve.js +245 -724
- package/dist/src/roots.js +7 -17
- package/dist/src/run.js +55 -61
- package/dist/src/schema.js +320 -343
- package/dist/src/scope.js +34 -103
- package/dist/src/serialization-contract.js +5 -9
- package/dist/src/session.js +2 -1
- package/dist/src/suppress-file.js +21 -25
- package/dist/src/suppress.js +3 -3
- package/dist/src/symbol-keys.js +3 -5
- package/dist/src/template-field.js +9 -19
- package/dist/src/test-globals.js +6 -28
- package/dist/src/test-joins.js +6 -6
- package/dist/src/text/compare.js +26 -0
- package/dist/src/text/glob.js +194 -0
- package/dist/src/text/shell.js +159 -0
- package/dist/src/{yaml-document.js → text/yaml.js} +38 -0
- package/dist/src/type-errors.js +14 -38
- package/dist/src/unseen-loads.js +2 -9
- package/dist/src/unwrap.js +23 -0
- package/dist/src/usage.js +10 -0
- package/dist/src/verbs/analyze.js +25 -26
- package/dist/src/verbs/describe.js +4 -4
- package/dist/src/verbs/explain.js +8 -6
- package/dist/src/verbs/print-projects.js +4 -3
- package/dist/src/verbs/print-retained.js +2 -1
- package/dist/src/verbs/print-roots.js +2 -1
- package/dist/src/verbs/version.js +2 -1
- package/dist/src/workflow-steps.js +9 -46
- package/dist/src/workspace-manifests.js +2 -2
- package/dist/src/workspace-programs.js +5 -3
- package/dist/src/workspace-resolution.js +13 -17
- package/dist/src/workspace.js +28 -116
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/analysis.ts +55 -76
- package/src/automatic-types.ts +11 -29
- package/src/build-scripts.ts +17 -38
- package/src/component-layer.ts +4 -2
- package/src/components.ts +2 -4
- package/src/config.ts +31 -296
- package/src/configuration-files.ts +27 -170
- package/src/configured-declarations.ts +18 -23
- package/src/consumers.ts +4 -4
- package/src/contract/config.generated.ts +798 -0
- package/src/contract/contract.generated.ts +25 -0
- package/src/contract/report.generated.ts +3 -2
- package/src/conventions.ts +26 -74
- package/src/dependencies.ts +32 -50
- package/src/discover.ts +15 -40
- package/src/edges.ts +41 -140
- package/src/element-access.ts +4 -7
- package/src/entry-point-gaps.ts +3 -9
- package/src/entry-points.ts +2 -13
- package/src/enum-group.ts +2 -11
- package/src/erased-stores.ts +3 -7
- package/src/exempt-classes.ts +0 -5
- package/src/exempt.ts +8 -30
- package/src/file-facts.ts +6 -24
- package/src/findings/completion.ts +5 -6
- package/src/findings/emitter.ts +2 -2
- package/src/findings/emitters.ts +1 -1
- package/src/findings/intra-function.ts +1 -1
- package/src/findings/non-code-artifacts.ts +4 -4
- package/src/findings/reads-and-writes.ts +2 -1
- package/src/findings/self-check.ts +3 -2
- package/src/findings/unused-declarations.ts +1 -1
- package/src/findings/visibility-narrowing.ts +2 -2
- package/src/findings-pass.ts +9 -15
- package/src/framework-lifecycle.ts +7 -7
- package/src/fs/document.ts +74 -0
- package/src/fs/manifest.ts +52 -0
- package/src/fs/tree.ts +110 -0
- package/src/git-ignore.ts +38 -25
- package/src/host.ts +12 -5
- package/src/html-entries.ts +6 -33
- package/src/in-operands.ts +2 -1
- package/src/injection-container.ts +1 -1
- package/src/intra-function-parts.ts +10 -14
- package/src/inventory.ts +2 -20
- package/src/json-document.ts +241 -76
- package/src/keyof-comparisons.ts +3 -7
- package/src/kinds.ts +0 -8
- package/src/manifest.ts +5 -46
- package/src/mdx-entries.ts +3 -26
- package/src/partial.ts +2 -1
- package/src/paths.ts +27 -15
- package/src/position.ts +2 -1
- package/src/print.ts +12 -92
- package/src/product.ts +18 -0
- package/src/references.ts +14 -29
- package/src/report-schema.ts +3 -301
- package/src/report.ts +24 -34
- package/src/reporters/sarif.ts +4 -4
- package/src/reporters/template.ts +4 -20
- package/src/resolve.ts +283 -1114
- package/src/roots.ts +7 -20
- package/src/run.ts +57 -75
- package/src/schema.ts +391 -388
- package/src/scope.ts +40 -126
- package/src/serialization-contract.ts +5 -10
- package/src/session.ts +2 -1
- package/src/suppress-file.ts +21 -29
- package/src/suppress.ts +3 -3
- package/src/symbol-keys.ts +2 -5
- package/src/template-field.ts +15 -25
- package/src/test-globals.ts +9 -27
- package/src/test-joins.ts +6 -8
- package/src/text/compare.ts +27 -0
- package/src/text/glob.ts +210 -0
- package/src/text/shell.ts +161 -0
- package/src/{yaml-document.ts → text/yaml.ts} +46 -0
- package/src/type-errors.ts +25 -36
- package/src/unseen-loads.ts +1 -12
- package/src/unwrap.ts +34 -0
- package/src/usage.ts +10 -0
- package/src/verbs/analyze.ts +32 -42
- package/src/verbs/describe.ts +4 -4
- package/src/verbs/explain.ts +8 -10
- package/src/verbs/print-projects.ts +4 -3
- package/src/verbs/print-retained.ts +2 -1
- package/src/verbs/print-roots.ts +2 -1
- package/src/verbs/verb.ts +2 -2
- package/src/verbs/version.ts +2 -1
- package/src/workflow-steps.ts +9 -44
- package/src/workspace-manifests.ts +2 -2
- package/src/workspace-programs.ts +5 -3
- package/src/workspace-resolution.ts +21 -17
- package/src/workspace.ts +35 -121
- package/dist/src/glob.js +0 -65
- package/dist/src/pnpm-workspace.js +0 -120
- package/src/glob.ts +0 -67
- package/src/pnpm-workspace.ts +0 -135
package/src/roots.ts
CHANGED
|
@@ -43,17 +43,19 @@ import {
|
|
|
43
43
|
} from "./configuration-files.ts";
|
|
44
44
|
import { conventionEntries, type Conventions } from "./conventions.ts";
|
|
45
45
|
import { entryPoints, type EntryRule } from "./entry-points.ts";
|
|
46
|
-
import { globExpression } from "./glob.ts";
|
|
47
46
|
import type { Host } from "./host.ts";
|
|
48
47
|
import { nodeKey, type Inventory, type InventorySymbol } from "./inventory.ts";
|
|
49
48
|
import type { Manifest, ManifestEntry } from "./manifest.ts";
|
|
50
|
-
import {
|
|
49
|
+
import { ancestors, dirnamePath, relativePath, resolvePath } from "./paths.ts";
|
|
51
50
|
import { byPosition } from "./position.ts";
|
|
52
51
|
import { UNANSWERED } from "./query.ts";
|
|
53
52
|
import type { ProjectView } from "./session.ts";
|
|
54
53
|
import type { Symbol as TSSymbol, Type } from "@typescript/native/sync";
|
|
55
54
|
import { sourceFilesOf, type SourceFiles } from "./source-files.ts";
|
|
56
55
|
import { typeQueryAliases } from "./type-query-alias.ts";
|
|
56
|
+
import { bytewise } from "./text/compare.ts";
|
|
57
|
+
import { holdsManifest } from "./fs/manifest.ts";
|
|
58
|
+
import { globExpression } from "./text/glob.ts";
|
|
57
59
|
|
|
58
60
|
/** Why one declaration is a root. */
|
|
59
61
|
export type RootKind =
|
|
@@ -197,15 +199,8 @@ const SOURCE_EXTENSION = /\.(?:d\.)?[cm]?[jt]sx?$/u;
|
|
|
197
199
|
|
|
198
200
|
/** Whether no `package.json` sits between one file and the manifest's directory, which holds it. */
|
|
199
201
|
function ofPackage(host: Host, dir: string, file: string): boolean {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
relativePath(dir, at) === undefined ||
|
|
203
|
-
host.kindOf(joinPath(at, "package.json")) === "file"
|
|
204
|
-
) {
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return true;
|
|
202
|
+
const between = ancestors(dirnamePath(file), dir);
|
|
203
|
+
return between.length > 0 && !between.slice(0, -1).some((at) => holdsManifest(host, at));
|
|
209
204
|
}
|
|
210
205
|
|
|
211
206
|
/**
|
|
@@ -331,14 +326,6 @@ export function matchRef(pattern: string, ref: string): boolean {
|
|
|
331
326
|
return matchGlob(Array.from(pattern), Array.from(ref));
|
|
332
327
|
}
|
|
333
328
|
|
|
334
|
-
/** Two strings ordered bytewise, which is the order every set of a run is read in. */
|
|
335
|
-
function compare(a: string, b: string): number {
|
|
336
|
-
if (a === b) {
|
|
337
|
-
return 0;
|
|
338
|
-
}
|
|
339
|
-
return a < b ? -1 : 1;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
329
|
/** The members of one declaration, indexed by the container that holds them. */
|
|
343
330
|
function childrenOf(held: Inventory): ReadonlyMap<string, readonly InventorySymbol[]> {
|
|
344
331
|
const byParent = new Map<string, InventorySymbol[]>();
|
|
@@ -561,7 +548,7 @@ export function roots<Brand>(
|
|
|
561
548
|
const left = sites.get(a.id);
|
|
562
549
|
const right = sites.get(b.id);
|
|
563
550
|
const site = left === undefined || right === undefined ? 0 : byPosition(left, right);
|
|
564
|
-
return site ||
|
|
551
|
+
return site || bytewise(a.kind, b.kind) || bytewise(a.source, b.source);
|
|
565
552
|
});
|
|
566
553
|
|
|
567
554
|
return {
|
package/src/run.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
import { CONFIG_MAX_BYTES, SETTINGS } from "./contract/config.generated.ts";
|
|
1
2
|
import { EXIT_FAILURE, EXIT_USAGE } from "./contract/contract.generated.ts";
|
|
2
|
-
import {
|
|
3
|
+
import { REPOSITORY_DOCUMENT, type Document, type Inputs } from "./config.ts";
|
|
3
4
|
import { DiscoveryError, renderDiagnostic } from "./discover.ts";
|
|
5
|
+
import { readTargetDocument, TargetDocumentError } from "./fs/document.ts";
|
|
4
6
|
import type { Host } from "./host.ts";
|
|
5
7
|
import { joinPath, resolvePath } from "./paths.ts";
|
|
6
8
|
import { readScope, ScopeError, scopeForDir, type Scope } from "./scope.ts";
|
|
7
9
|
import { SetupError, setupLine } from "./setup-failure.ts";
|
|
10
|
+
import { UsageError } from "./usage.ts";
|
|
8
11
|
import { openEngine, type Engine, type EngineOptions } from "./session.ts";
|
|
9
12
|
import { printConfigVerb } from "./verbs/print-config.ts";
|
|
10
13
|
import { printProjectsVerb } from "./verbs/print-projects.ts";
|
|
@@ -15,6 +18,7 @@ import { describeVerb } from "./verbs/describe.ts";
|
|
|
15
18
|
import { EXPLAIN_OPTIONS, explainVerb } from "./verbs/explain.ts";
|
|
16
19
|
import { type Verb, type VerbOptions } from "./verbs/verb.ts";
|
|
17
20
|
import { versionVerb } from "./verbs/version.ts";
|
|
21
|
+
import { diagnose, message, PRODUCT } from "./product.ts";
|
|
18
22
|
|
|
19
23
|
/** One output stream of the command line. `process.stdout` and `process.stderr` satisfy it. */
|
|
20
24
|
export interface Writer {
|
|
@@ -37,7 +41,7 @@ const VERBS: readonly {
|
|
|
37
41
|
{ name: "version", run: versionVerb },
|
|
38
42
|
];
|
|
39
43
|
|
|
40
|
-
const USAGE = `usage:
|
|
44
|
+
const USAGE = `usage: ${PRODUCT} <verb> [options]\nverbs: ${VERBS.map((verb) => verb.name).join(", ")}\n`;
|
|
41
45
|
|
|
42
46
|
/**
|
|
43
47
|
* The tokens whose presence in an option's name makes that option a request to
|
|
@@ -47,33 +51,16 @@ const USAGE = `usage: deadset-ts <verb> [options]\nverbs: ${VERBS.map((verb) =>
|
|
|
47
51
|
const SOURCE_EDIT_TOKENS = ["fix", "edit", "delete", "rewrite"] as const;
|
|
48
52
|
|
|
49
53
|
/**
|
|
50
|
-
* Maps an option name to the setting of the Contract's configuration schema it supplies
|
|
51
|
-
*
|
|
52
|
-
* the spelling the setting's provenance names. The name is this command's vocabulary and
|
|
53
|
-
* is never derived from the path: a setting reaches the command line only by an entry,
|
|
54
|
-
* and a path names a key the schema declares.
|
|
54
|
+
* Maps an option name to the setting of the Contract's configuration schema it supplies:
|
|
55
|
+
* the options contract/settings.json names for a setting this analyzer reads.
|
|
55
56
|
*/
|
|
56
|
-
export const SETTING_OPTIONS: ReadonlyMap<string, string> = new Map(
|
|
57
|
-
[
|
|
58
|
-
|
|
59
|
-
["cascade", "reporters.cascade"],
|
|
60
|
-
["max-findings", "reporters.max_findings"],
|
|
61
|
-
["fail-on", "reporters.fail_on"],
|
|
62
|
-
]);
|
|
57
|
+
export const SETTING_OPTIONS: ReadonlyMap<string, string> = new Map(
|
|
58
|
+
SETTINGS.flatMap((row) => (row.option === undefined ? [] : [[row.option, row.key] as const])),
|
|
59
|
+
);
|
|
63
60
|
|
|
64
61
|
/** The options that take a value and are not settings. */
|
|
65
62
|
const PLAIN_OPTIONS: ReadonlySet<string> = new Set(["target", "config", "central", "scope"]);
|
|
66
63
|
|
|
67
|
-
/**
|
|
68
|
-
* The setting options whose value is an integer rather than a string. A value
|
|
69
|
-
* written other than as digits is passed on as the string it is, so resolution
|
|
70
|
-
* refuses it by its type rather than reading `1e2` as 100.
|
|
71
|
-
*/
|
|
72
|
-
const INTEGER_OPTIONS: ReadonlySet<string> = new Set(["max-findings"]);
|
|
73
|
-
|
|
74
|
-
/** An integer as an option writes it: an optional minus sign and digits alone. */
|
|
75
|
-
const INTEGER_TEXT = /^-?[0-9]+$/u;
|
|
76
|
-
|
|
77
64
|
/** One invocation's options, by name: the last value of each, and every value of a repeatable one. */
|
|
78
65
|
interface Options {
|
|
79
66
|
readonly named: ReadonlyMap<string, string>;
|
|
@@ -108,7 +95,7 @@ function readOptions(args: readonly string[], own: VerbOptions): Options {
|
|
|
108
95
|
const repeated = new Map<string, string[]>();
|
|
109
96
|
for (const arg of args) {
|
|
110
97
|
if (!arg.startsWith("-")) {
|
|
111
|
-
throw new
|
|
98
|
+
throw new UsageError(`unexpected argument ${JSON.stringify(arg)}`);
|
|
112
99
|
}
|
|
113
100
|
const [spelled, ...rest] = arg.split("=");
|
|
114
101
|
const name = (spelled ?? "").replace(/^-+/u, "");
|
|
@@ -118,14 +105,10 @@ function readOptions(args: readonly string[], own: VerbOptions): Options {
|
|
|
118
105
|
!own.plain.includes(name) &&
|
|
119
106
|
!own.repeatable.includes(name)
|
|
120
107
|
) {
|
|
121
|
-
throw new
|
|
108
|
+
throw new UsageError(`unknown option ${JSON.stringify(spelled ?? arg)}`);
|
|
122
109
|
}
|
|
123
110
|
if (rest.length === 0) {
|
|
124
|
-
throw new
|
|
125
|
-
"malformed",
|
|
126
|
-
"",
|
|
127
|
-
`option ${JSON.stringify(spelled ?? arg)} takes a value`,
|
|
128
|
-
);
|
|
111
|
+
throw new UsageError(`option ${JSON.stringify(spelled ?? arg)} takes a value`);
|
|
129
112
|
}
|
|
130
113
|
const value = rest.join("=");
|
|
131
114
|
named.set(name, value);
|
|
@@ -134,51 +117,54 @@ function readOptions(args: readonly string[], own: VerbOptions): Options {
|
|
|
134
117
|
return { named, repeated };
|
|
135
118
|
}
|
|
136
119
|
|
|
137
|
-
|
|
120
|
+
/** The document an option names. */
|
|
121
|
+
function documentAt(host: Host, label: string): Document {
|
|
138
122
|
try {
|
|
139
|
-
|
|
123
|
+
const path = resolvePath(host.workingDirectory(), label);
|
|
124
|
+
// A file past the bound reads as one byte more than it, which resolution refuses.
|
|
125
|
+
return { text: host.readFile(path, CONFIG_MAX_BYTES + 1), label };
|
|
140
126
|
} catch (error: unknown) {
|
|
141
|
-
|
|
142
|
-
return undefined;
|
|
143
|
-
}
|
|
144
|
-
throw new ConfigError(
|
|
145
|
-
"malformed",
|
|
146
|
-
"",
|
|
147
|
-
`${path}: ${error instanceof Error ? error.message : String(error)}`,
|
|
148
|
-
);
|
|
127
|
+
throw new UsageError(`${label}: ${message(error)}`);
|
|
149
128
|
}
|
|
150
129
|
}
|
|
151
130
|
|
|
152
131
|
/**
|
|
153
|
-
* The configuration
|
|
154
|
-
*
|
|
155
|
-
|
|
132
|
+
* The repository configuration at the target root, none where it is absent. One that
|
|
133
|
+
* cannot be read is a configuration document that cannot be, refused with the usage code.
|
|
134
|
+
*/
|
|
135
|
+
function repositoryAt(host: Host, target: string): Document | undefined {
|
|
136
|
+
const label = joinPath(target, REPOSITORY_DOCUMENT);
|
|
137
|
+
const root = resolvePath(host.workingDirectory(), target);
|
|
138
|
+
try {
|
|
139
|
+
const text = readTargetDocument(host, root, REPOSITORY_DOCUMENT, label);
|
|
140
|
+
return text === undefined ? undefined : { text, label };
|
|
141
|
+
} catch (error: unknown) {
|
|
142
|
+
throw error instanceof TargetDocumentError ? new UsageError(error.message) : error;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* The configuration sources one invocation carries: the repository configuration at
|
|
148
|
+
* the target root or the path an option named, the central configuration, and the
|
|
149
|
+
* text each setting option was given.
|
|
156
150
|
*/
|
|
157
151
|
function inputsOf(host: Host, options: Options): Inputs {
|
|
158
|
-
const target = options.named.get("target") ?? ".";
|
|
159
152
|
const named = options.named.get("config");
|
|
160
|
-
const
|
|
161
|
-
const repository =
|
|
153
|
+
const target = options.named.get("target") ?? ".";
|
|
154
|
+
const repository = named === undefined ? repositoryAt(host, target) : documentAt(host, named);
|
|
162
155
|
const centralLabel = options.named.get("central");
|
|
163
|
-
const central = centralLabel === undefined ? undefined :
|
|
164
|
-
|
|
165
|
-
const
|
|
166
|
-
const flagLabels = new Map<string, string>();
|
|
167
|
-
for (const [name, path] of SETTING_OPTIONS) {
|
|
156
|
+
const central = centralLabel === undefined ? undefined : documentAt(host, centralLabel);
|
|
157
|
+
const flags = new Map<string, string>();
|
|
158
|
+
for (const [name, key] of SETTING_OPTIONS) {
|
|
168
159
|
const value = options.named.get(name);
|
|
169
|
-
if (value
|
|
170
|
-
|
|
160
|
+
if (value !== undefined) {
|
|
161
|
+
flags.set(key, value);
|
|
171
162
|
}
|
|
172
|
-
flat[path] = INTEGER_OPTIONS.has(name) && INTEGER_TEXT.test(value) ? Number(value) : value;
|
|
173
|
-
flagLabels.set(path, `--${name}`);
|
|
174
163
|
}
|
|
175
|
-
const flags = Object.keys(flat).length === 0 ? undefined : JSON.stringify(flat);
|
|
176
|
-
|
|
177
164
|
return {
|
|
178
|
-
|
|
179
|
-
...(repository === undefined ? {} : { repository
|
|
180
|
-
...(central === undefined
|
|
181
|
-
flagLabels,
|
|
165
|
+
flags,
|
|
166
|
+
...(repository === undefined ? {} : { repository }),
|
|
167
|
+
...(central === undefined ? {} : { central }),
|
|
182
168
|
};
|
|
183
169
|
}
|
|
184
170
|
|
|
@@ -196,9 +182,7 @@ function scopeOf(host: Host, options: Options): Scope {
|
|
|
196
182
|
* the exit code: 0 for a completed verb, 1 for a finding that fails the run, 2 for a
|
|
197
183
|
* usage error, a requested source edit or a refused configuration, 3 for a failure that
|
|
198
184
|
* produced no answer. It writes nothing outside `out` and `err` and never exits the
|
|
199
|
-
* process.
|
|
200
|
-
* `openClient` opens the compiler client; a caller that watches what a run reads
|
|
201
|
-
* supplies its own of either.
|
|
185
|
+
* process. A caller that watches what a run reads supplies its own `host` or `openClient`.
|
|
202
186
|
*/
|
|
203
187
|
export function run(
|
|
204
188
|
args: readonly string[],
|
|
@@ -209,9 +193,7 @@ export function run(
|
|
|
209
193
|
): number {
|
|
210
194
|
const editing = sourceEditOption(args);
|
|
211
195
|
if (editing !== undefined) {
|
|
212
|
-
err
|
|
213
|
-
`deadset-ts: ${editing} is not supported: deadset-ts reports and never edits a source file\n`,
|
|
214
|
-
);
|
|
196
|
+
diagnose(err, `${editing} is not supported: ${PRODUCT} reports and never edits a source file`);
|
|
215
197
|
err.write(USAGE);
|
|
216
198
|
return EXIT_USAGE;
|
|
217
199
|
}
|
|
@@ -228,7 +210,7 @@ export function run(
|
|
|
228
210
|
);
|
|
229
211
|
}
|
|
230
212
|
if (name !== undefined) {
|
|
231
|
-
err
|
|
213
|
+
diagnose(err, `unknown verb ${JSON.stringify(name)}`);
|
|
232
214
|
}
|
|
233
215
|
err.write(USAGE);
|
|
234
216
|
return EXIT_USAGE;
|
|
@@ -260,7 +242,7 @@ function invoke(
|
|
|
260
242
|
openClient: (config) => {
|
|
261
243
|
opened = openClient({
|
|
262
244
|
collectTiming: false,
|
|
263
|
-
components: { extensions: config.ts.
|
|
245
|
+
components: { extensions: config.ts.component_extensions, host: streams.host },
|
|
264
246
|
});
|
|
265
247
|
return opened;
|
|
266
248
|
},
|
|
@@ -273,8 +255,8 @@ function invoke(
|
|
|
273
255
|
|
|
274
256
|
/** Turns one refusal into the exit code the Contract's table gives it. */
|
|
275
257
|
function refuse(error: unknown, err: Writer): number {
|
|
276
|
-
if (error instanceof
|
|
277
|
-
err
|
|
258
|
+
if (error instanceof UsageError) {
|
|
259
|
+
diagnose(err, error.message);
|
|
278
260
|
err.write(USAGE);
|
|
279
261
|
return EXIT_USAGE;
|
|
280
262
|
}
|
|
@@ -282,7 +264,7 @@ function refuse(error: unknown, err: Writer): number {
|
|
|
282
264
|
for (const diagnostic of error.diagnostics) {
|
|
283
265
|
err.write(`${renderDiagnostic(diagnostic)}\n`);
|
|
284
266
|
}
|
|
285
|
-
err
|
|
267
|
+
diagnose(err, error.message);
|
|
286
268
|
return EXIT_FAILURE;
|
|
287
269
|
}
|
|
288
270
|
if (error instanceof SetupError) {
|
|
@@ -291,8 +273,8 @@ function refuse(error: unknown, err: Writer): number {
|
|
|
291
273
|
}
|
|
292
274
|
return EXIT_FAILURE;
|
|
293
275
|
}
|
|
294
|
-
if (error instanceof ScopeError) {
|
|
295
|
-
err
|
|
276
|
+
if (error instanceof ScopeError || error instanceof TargetDocumentError) {
|
|
277
|
+
diagnose(err, error.message);
|
|
296
278
|
return EXIT_FAILURE;
|
|
297
279
|
}
|
|
298
280
|
throw error;
|