@timiagama/ecr 0.0.1 → 0.1.0
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/LICENSE +202 -0
- package/NOTICE +16 -0
- package/README.md +411 -7
- package/dist/bin.d.ts +20 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +26 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli/corpus-loader.d.ts +198 -0
- package/dist/cli/corpus-loader.d.ts.map +1 -0
- package/dist/cli/corpus-loader.js +351 -0
- package/dist/cli/corpus-loader.js.map +1 -0
- package/dist/cli/corpus-statistics.d.ts +113 -0
- package/dist/cli/corpus-statistics.d.ts.map +1 -0
- package/dist/cli/corpus-statistics.js +119 -0
- package/dist/cli/corpus-statistics.js.map +1 -0
- package/dist/cli/diagnostic-reporter.d.ts +103 -0
- package/dist/cli/diagnostic-reporter.d.ts.map +1 -0
- package/dist/cli/diagnostic-reporter.js +254 -0
- package/dist/cli/diagnostic-reporter.js.map +1 -0
- package/dist/cli/project-ignore.d.ts +113 -0
- package/dist/cli/project-ignore.d.ts.map +1 -0
- package/dist/cli/project-ignore.js +199 -0
- package/dist/cli/project-ignore.js.map +1 -0
- package/dist/cli/safe-text.d.ts +25 -0
- package/dist/cli/safe-text.d.ts.map +1 -0
- package/dist/cli/safe-text.js +34 -0
- package/dist/cli/safe-text.js.map +1 -0
- package/dist/cli/supervisor.d.ts +108 -0
- package/dist/cli/supervisor.d.ts.map +1 -0
- package/dist/cli/supervisor.js +139 -0
- package/dist/cli/supervisor.js.map +1 -0
- package/dist/cli.d.ts +247 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +591 -0
- package/dist/cli.js.map +1 -0
- package/dist/corpus-validator.d.ts +183 -0
- package/dist/corpus-validator.d.ts.map +1 -0
- package/dist/corpus-validator.js +479 -0
- package/dist/corpus-validator.js.map +1 -0
- package/dist/document-identity-rule.d.ts +198 -0
- package/dist/document-identity-rule.d.ts.map +1 -0
- package/dist/document-identity-rule.js +244 -0
- package/dist/document-identity-rule.js.map +1 -0
- package/dist/ecr.d.ts +103 -0
- package/dist/ecr.d.ts.map +1 -0
- package/dist/ecr.js +216 -0
- package/dist/ecr.js.map +1 -0
- package/dist/glob-pattern.d.ts +94 -0
- package/dist/glob-pattern.d.ts.map +1 -0
- package/dist/glob-pattern.js +188 -0
- package/dist/glob-pattern.js.map +1 -0
- package/dist/heading-source-form.d.ts +77 -0
- package/dist/heading-source-form.d.ts.map +1 -0
- package/dist/heading-source-form.js +129 -0
- package/dist/heading-source-form.js.map +1 -0
- package/dist/identifier-grammar.d.ts +212 -0
- package/dist/identifier-grammar.d.ts.map +1 -0
- package/dist/identifier-grammar.js +273 -0
- package/dist/identifier-grammar.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/inline-reference-rule.d.ts +557 -0
- package/dist/inline-reference-rule.d.ts.map +1 -0
- package/dist/inline-reference-rule.js +802 -0
- package/dist/inline-reference-rule.js.map +1 -0
- package/dist/meta-documents.d.ts +91 -0
- package/dist/meta-documents.d.ts.map +1 -0
- package/dist/meta-documents.js +133 -0
- package/dist/meta-documents.js.map +1 -0
- package/dist/per-document-visitor.d.ts +510 -0
- package/dist/per-document-visitor.d.ts.map +1 -0
- package/dist/per-document-visitor.js +1032 -0
- package/dist/per-document-visitor.js.map +1 -0
- package/dist/references-section-rule.d.ts +482 -0
- package/dist/references-section-rule.d.ts.map +1 -0
- package/dist/references-section-rule.js +777 -0
- package/dist/references-section-rule.js.map +1 -0
- package/dist/section-hierarchy-rule.d.ts +299 -0
- package/dist/section-hierarchy-rule.d.ts.map +1 -0
- package/dist/section-hierarchy-rule.js +482 -0
- package/dist/section-hierarchy-rule.js.map +1 -0
- package/dist/source-alignment.d.ts +41 -0
- package/dist/source-alignment.d.ts.map +1 -0
- package/dist/source-alignment.js +166 -0
- package/dist/source-alignment.js.map +1 -0
- package/dist/source-lines.d.ts +69 -0
- package/dist/source-lines.d.ts.map +1 -0
- package/dist/source-lines.js +104 -0
- package/dist/source-lines.js.map +1 -0
- package/dist/spec-version.d.ts +19 -0
- package/dist/spec-version.d.ts.map +1 -0
- package/dist/spec-version.js +19 -0
- package/dist/spec-version.js.map +1 -0
- package/dist/types.d.ts +219 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/examples/docs/0. Orientation/0.0 - System Overview.md +34 -0
- package/examples/docs/0. Orientation/0.0.1 - Glossary.md +21 -0
- package/examples/docs/0. Orientation/0.0.2 - Quality Gates.md +22 -0
- package/examples/docs/3. Ingestion/3.1 - Ingestion - Validation Rules.md +33 -0
- package/examples/docs/4. Payments/4.10 - Settlement.md +22 -0
- package/examples/docs/4. Payments/4.2 - Payment Processing Contract.md +33 -0
- package/examples/docs/8. Orchestration/8.1 - Workflow Orchestration Contract.md +38 -0
- package/examples/docs/8. Orchestration/8.1.3 - Retry Policy.md +17 -0
- package/examples/docs/8. Orchestration/8.10 - Dead Letter Queue.md +20 -0
- package/examples/docs/README.md +7 -0
- package/package.json +65 -7
- package/protocol/navigation-protocol.md +223 -0
- package/spec/v2/1 - ECR - Structural Specification.md +1467 -0
- package/spec/v2/2 - ECR - User Guide.md +845 -0
- package/spec/v2/3 - Design Rationale - The Section Separator.md +243 -0
- package/src/bin.ts +30 -0
- package/src/cli/corpus-loader.ts +482 -0
- package/src/cli/corpus-statistics.ts +196 -0
- package/src/cli/diagnostic-reporter.ts +344 -0
- package/src/cli/project-ignore.ts +238 -0
- package/src/cli/safe-text.ts +39 -0
- package/src/cli/supervisor.ts +204 -0
- package/src/cli.ts +836 -0
- package/src/corpus-validator.ts +642 -0
- package/src/document-identity-rule.ts +422 -0
- package/src/ecr.ts +298 -0
- package/src/glob-pattern.ts +242 -0
- package/src/heading-source-form.ts +173 -0
- package/src/identifier-grammar.ts +380 -0
- package/src/index.ts +78 -0
- package/src/inline-reference-rule.ts +1235 -0
- package/src/meta-documents.ts +159 -0
- package/src/per-document-visitor.ts +1528 -0
- package/src/references-section-rule.ts +1182 -0
- package/src/section-hierarchy-rule.ts +705 -0
- package/src/source-alignment.ts +209 -0
- package/src/source-lines.ts +123 -0
- package/src/spec-version.ts +19 -0
- package/src/types.ts +267 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ECR Command Line
|
|
3
|
+
*
|
|
4
|
+
* The executable entry point is `bin.ts`; this module only defines the
|
|
5
|
+
* commands, so that tests can drive them without spawning a process.
|
|
6
|
+
*
|
|
7
|
+
* Three commands, and deliberately no more:
|
|
8
|
+
*
|
|
9
|
+
* - `lint` validates a corpus against the ECR structural rules
|
|
10
|
+
* - `stats` measures the explicit structure a corpus already carries
|
|
11
|
+
* - `init` installs the ECR documentation, including the agent navigation
|
|
12
|
+
* protocol, beside a corpus
|
|
13
|
+
*
|
|
14
|
+
* There is no `backlinks` command, and there should never be one. ECR's claim
|
|
15
|
+
* is that a corpus is navigable with `grep` alone; a navigation command here
|
|
16
|
+
* would quietly make the tool a dependency of the thing it exists to prove
|
|
17
|
+
* unnecessary. Navigation belongs in the protocol `init` installs, not in this
|
|
18
|
+
* binary.
|
|
19
|
+
*/
|
|
20
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync } from 'node:fs';
|
|
21
|
+
import { dirname, join, resolve } from 'node:path';
|
|
22
|
+
import { fileURLToPath } from 'node:url';
|
|
23
|
+
import { Ecr } from './ecr.js';
|
|
24
|
+
import { ECR_SPEC_VERSION } from './spec-version.js';
|
|
25
|
+
import { CorpusLoader } from './cli/corpus-loader.js';
|
|
26
|
+
import { PROJECT_IGNORE_FILENAME, ProjectIgnoreFile } from './cli/project-ignore.js';
|
|
27
|
+
import { CorpusStatistics } from './cli/corpus-statistics.js';
|
|
28
|
+
import { DiagnosticReporter } from './cli/diagnostic-reporter.js';
|
|
29
|
+
import { showControlCharacters } from './cli/safe-text.js';
|
|
30
|
+
import { DEFAULT_SUPERVISION_LIMITS, SUPERVISED_VARIABLE, Supervisor } from './cli/supervisor.js';
|
|
31
|
+
/** Process exit code signalling success. */
|
|
32
|
+
const EXIT_SUCCESS = 0;
|
|
33
|
+
/** Process exit code signalling that the corpus contains errors. */
|
|
34
|
+
const EXIT_VALIDATION_FAILED = 1;
|
|
35
|
+
/**
|
|
36
|
+
* Process exit code signalling that the command could not run: arguments it
|
|
37
|
+
* could not understand, or a corpus it could not find or fully read.
|
|
38
|
+
*/
|
|
39
|
+
const EXIT_USAGE_ERROR = 2;
|
|
40
|
+
/**
|
|
41
|
+
* What `init` installs, from the package root, keeping each path as it is in
|
|
42
|
+
* the repository so the README's relative links work in the installed copy.
|
|
43
|
+
*/
|
|
44
|
+
const INSTALLED_DOCUMENTATION = [
|
|
45
|
+
'README.md',
|
|
46
|
+
'LICENSE',
|
|
47
|
+
'NOTICE',
|
|
48
|
+
'protocol',
|
|
49
|
+
'spec',
|
|
50
|
+
'examples',
|
|
51
|
+
];
|
|
52
|
+
/** Every exit code this command itself produces. */
|
|
53
|
+
const EXIT_CODES = [EXIT_SUCCESS, EXIT_VALIDATION_FAILED, EXIT_USAGE_ERROR];
|
|
54
|
+
/**
|
|
55
|
+
* How V8 says it has run out of heap. It says so differently depending on
|
|
56
|
+
* when it happens: "Reached heap limit" once running, "JavaScript heap out of
|
|
57
|
+
* memory" on an allocation, and "Fatal JavaScript out of memory" while it is
|
|
58
|
+
* still starting, which is what a limit of a megabyte or two produces.
|
|
59
|
+
*/
|
|
60
|
+
const HEAP_EXHAUSTED = /Reached heap limit|out of memory/i;
|
|
61
|
+
/**
|
|
62
|
+
* The longest time limit that can be applied: `spawnSync` takes milliseconds
|
|
63
|
+
* as a 32-bit count, which is about twenty-five days.
|
|
64
|
+
*/
|
|
65
|
+
const MAXIMUM_TIMEOUT_SECONDS = 2_147_483;
|
|
66
|
+
/** The largest heap limit that can be applied, in mebibytes: a tebibyte. */
|
|
67
|
+
const MAXIMUM_MEMORY_MIB = 1_048_576;
|
|
68
|
+
/** Where `lint` and `stats` look when no directory is given. */
|
|
69
|
+
const DEFAULT_CORPUS_DIRECTORY = 'docs';
|
|
70
|
+
/**
|
|
71
|
+
* Where `init` installs when no directory is given: beside the corpus, never
|
|
72
|
+
* in it, because the specification's own DocIDs would collide with the
|
|
73
|
+
* user's.
|
|
74
|
+
*/
|
|
75
|
+
const DEFAULT_INSTALL_DIRECTORY = 'ecr';
|
|
76
|
+
/** Usage text shown for `--help` and on a usage error. */
|
|
77
|
+
const USAGE_TEXT = `
|
|
78
|
+
ecr - Explicit Constraint Referencing
|
|
79
|
+
|
|
80
|
+
Usage
|
|
81
|
+
ecr lint [directory] [options] validate a corpus
|
|
82
|
+
ecr stats [directory] [options] measure a corpus
|
|
83
|
+
ecr init [directory] install the ECR documentation
|
|
84
|
+
|
|
85
|
+
Options
|
|
86
|
+
--format <pretty|json> output format (default: pretty)
|
|
87
|
+
--ignore <glob> exclude paths; repeatable
|
|
88
|
+
--example lint or measure the example corpus bundled
|
|
89
|
+
with this package, instead of a directory
|
|
90
|
+
--timeout <seconds> stop lint or stats if it takes longer
|
|
91
|
+
(default: 120; 0 for no limit)
|
|
92
|
+
--max-memory <MiB> cap the heap lint or stats may use
|
|
93
|
+
(default: 2048; 0 for node's own default)
|
|
94
|
+
--version show the linter and spec versions
|
|
95
|
+
--help show this message
|
|
96
|
+
|
|
97
|
+
The directory defaults to ./docs, or to ./ecr for init.
|
|
98
|
+
|
|
99
|
+
lint and stats parse your documents in a separate process, so that a
|
|
100
|
+
document which takes unreasonably long to parse stops rather than hanging
|
|
101
|
+
the command. A run that has to be stopped prints nothing and exits 2,
|
|
102
|
+
because a report of a corpus that was never finished is not a report.
|
|
103
|
+
|
|
104
|
+
Patterns in .ecrignore, in the directory the command runs from, are
|
|
105
|
+
excluded too. They are relative to that directory; --ignore patterns are
|
|
106
|
+
relative to the directory being linted.
|
|
107
|
+
|
|
108
|
+
Exit codes
|
|
109
|
+
0 no errors
|
|
110
|
+
1 the corpus contains errors
|
|
111
|
+
2 the command could not run
|
|
112
|
+
`;
|
|
113
|
+
/**
|
|
114
|
+
* Parses command-line arguments.
|
|
115
|
+
*
|
|
116
|
+
* Throws on anything it cannot understand rather than guessing, because a
|
|
117
|
+
* silently misread `--ignore` would quietly exclude documents from validation.
|
|
118
|
+
*/
|
|
119
|
+
export class ArgumentParser {
|
|
120
|
+
/**
|
|
121
|
+
* Parses an argument list.
|
|
122
|
+
*
|
|
123
|
+
* @param argv - Arguments, excluding the node executable and script path
|
|
124
|
+
* @returns The parsed command line
|
|
125
|
+
* @throws Error when the arguments cannot be understood
|
|
126
|
+
*/
|
|
127
|
+
parse(argv) {
|
|
128
|
+
const [commandCandidate, ...rest] = argv;
|
|
129
|
+
if (commandCandidate === undefined) {
|
|
130
|
+
throw new Error('No command given.');
|
|
131
|
+
}
|
|
132
|
+
if (!this.isCommandName(commandCandidate)) {
|
|
133
|
+
throw new Error(`Unknown command "${commandCandidate}".`);
|
|
134
|
+
}
|
|
135
|
+
let corpusRoot = undefined;
|
|
136
|
+
let useExample = false;
|
|
137
|
+
let format = 'pretty';
|
|
138
|
+
let timeoutSeconds = undefined;
|
|
139
|
+
let maxMemoryMib = undefined;
|
|
140
|
+
const ignorePatterns = [];
|
|
141
|
+
for (let index = 0; index < rest.length; index += 1) {
|
|
142
|
+
const argument = rest[index] ?? '';
|
|
143
|
+
if (argument === '--example') {
|
|
144
|
+
useExample = true;
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
if (argument === '--format') {
|
|
148
|
+
const value = rest[index + 1];
|
|
149
|
+
if (value !== 'pretty' && value !== 'json') {
|
|
150
|
+
throw new Error('--format expects "pretty" or "json".');
|
|
151
|
+
}
|
|
152
|
+
format = value;
|
|
153
|
+
index += 1;
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (argument === '--ignore') {
|
|
157
|
+
const value = rest[index + 1];
|
|
158
|
+
if (value === undefined || value.startsWith('--')) {
|
|
159
|
+
throw new Error('--ignore expects a glob pattern.');
|
|
160
|
+
}
|
|
161
|
+
ignorePatterns.push(value);
|
|
162
|
+
index += 1;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (argument === '--timeout') {
|
|
166
|
+
timeoutSeconds = ArgumentParser.readWholeNumber(rest[index + 1], '--timeout', 'seconds', MAXIMUM_TIMEOUT_SECONDS);
|
|
167
|
+
index += 1;
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (argument === '--max-memory') {
|
|
171
|
+
maxMemoryMib = ArgumentParser.readWholeNumber(rest[index + 1], '--max-memory', 'mebibytes', MAXIMUM_MEMORY_MIB);
|
|
172
|
+
index += 1;
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (argument.startsWith('--')) {
|
|
176
|
+
throw new Error(`Unknown option "${argument}".`);
|
|
177
|
+
}
|
|
178
|
+
if (corpusRoot !== undefined) {
|
|
179
|
+
throw new Error('More than one directory given.');
|
|
180
|
+
}
|
|
181
|
+
corpusRoot = argument;
|
|
182
|
+
}
|
|
183
|
+
if (useExample && commandCandidate === 'init') {
|
|
184
|
+
throw new Error('--example works with lint and stats; init installs into your own project.');
|
|
185
|
+
}
|
|
186
|
+
if (useExample && corpusRoot !== undefined) {
|
|
187
|
+
throw new Error('Give a directory or --example, not both.');
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
command: commandCandidate,
|
|
191
|
+
corpusRoot: corpusRoot ?? (commandCandidate === 'init' ? DEFAULT_INSTALL_DIRECTORY : DEFAULT_CORPUS_DIRECTORY),
|
|
192
|
+
useExample,
|
|
193
|
+
format,
|
|
194
|
+
ignorePatterns,
|
|
195
|
+
...(timeoutSeconds !== undefined ? { timeoutSeconds } : {}),
|
|
196
|
+
...(maxMemoryMib !== undefined ? { maxMemoryMib } : {}),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Reads an option's value as a whole number of some unit, where zero means
|
|
201
|
+
* no limit.
|
|
202
|
+
*
|
|
203
|
+
* @param value - The argument following the option
|
|
204
|
+
* @param option - The option's name, for the message
|
|
205
|
+
* @param unit - What the number counts, for the message
|
|
206
|
+
* @param maximum - The largest value the limit can be applied as
|
|
207
|
+
* @returns The number
|
|
208
|
+
* @throws When the value is missing, is not a whole number, or is beyond what can be applied
|
|
209
|
+
*/
|
|
210
|
+
static readWholeNumber(value, option, unit, maximum) {
|
|
211
|
+
const parsed = value === undefined ? Number.NaN : Number(value);
|
|
212
|
+
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
213
|
+
throw new Error(`${option} expects a whole number of ${unit}, or 0 for no limit.`);
|
|
214
|
+
}
|
|
215
|
+
// A limit too large to apply is not the same as no limit: passed on, it
|
|
216
|
+
// would fail inside the machinery that imposes it rather than here.
|
|
217
|
+
if (parsed > maximum) {
|
|
218
|
+
throw new Error(`${option} expects at most ${String(maximum)} ${unit}, or 0 for no limit.`);
|
|
219
|
+
}
|
|
220
|
+
return parsed;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Determines whether a string names a supported command.
|
|
224
|
+
*
|
|
225
|
+
* @param candidate - The string to test
|
|
226
|
+
* @returns `true` when the string is a command name
|
|
227
|
+
*/
|
|
228
|
+
isCommandName(candidate) {
|
|
229
|
+
return candidate === 'lint' || candidate === 'stats' || candidate === 'init';
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Runs the CLI commands.
|
|
234
|
+
*
|
|
235
|
+
* Output is returned rather than printed so that the commands can be exercised
|
|
236
|
+
* directly by tests without capturing a stream.
|
|
237
|
+
*/
|
|
238
|
+
export class EcrCommandLine {
|
|
239
|
+
/** Parses the command line. */
|
|
240
|
+
argumentParser;
|
|
241
|
+
/**
|
|
242
|
+
* The directory the command runs from: relative directories resolve against
|
|
243
|
+
* it, and it is the project root whose `.ecrignore` applies.
|
|
244
|
+
*/
|
|
245
|
+
workingDirectory;
|
|
246
|
+
/** The package's own root, holding `package.json` and what `init` installs. */
|
|
247
|
+
packageRoot;
|
|
248
|
+
/** How to run the parsing commands in a child process, when asked to. */
|
|
249
|
+
supervision;
|
|
250
|
+
/**
|
|
251
|
+
* Creates a command-line runner.
|
|
252
|
+
*
|
|
253
|
+
* @param options - Where the command runs from and where the package lives; both default to the real ones
|
|
254
|
+
*/
|
|
255
|
+
constructor(options = {}) {
|
|
256
|
+
this.argumentParser = new ArgumentParser();
|
|
257
|
+
this.workingDirectory = options.workingDirectory ?? process.cwd();
|
|
258
|
+
// Resolved relative to this module, so it is correct whether the CLI runs
|
|
259
|
+
// from source, from `dist/`, or from an installed package.
|
|
260
|
+
this.packageRoot = options.packageRoot ?? resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
261
|
+
this.supervision = options.supervision;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Runs one invocation.
|
|
265
|
+
*
|
|
266
|
+
* @param argv - Arguments, excluding the node executable and script path
|
|
267
|
+
* @returns The text to print and the process exit code
|
|
268
|
+
*/
|
|
269
|
+
run(argv) {
|
|
270
|
+
if (argv.length === 0) {
|
|
271
|
+
return this.fail(USAGE_TEXT);
|
|
272
|
+
}
|
|
273
|
+
if (argv.includes('--help')) {
|
|
274
|
+
return this.succeed(USAGE_TEXT);
|
|
275
|
+
}
|
|
276
|
+
if (argv.includes('--version')) {
|
|
277
|
+
return this.succeed(`ecr ${this.showPackageVersion()} (ECR spec ${ECR_SPEC_VERSION})\n`);
|
|
278
|
+
}
|
|
279
|
+
let parsed;
|
|
280
|
+
try {
|
|
281
|
+
parsed = this.argumentParser.parse(argv);
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
285
|
+
return this.fail(` ${message}\n${USAGE_TEXT}`);
|
|
286
|
+
}
|
|
287
|
+
const corpusRoot = resolve(this.workingDirectory, parsed.corpusRoot);
|
|
288
|
+
// `init` installs the documentation, so it may create the directory; the
|
|
289
|
+
// other commands read a corpus that must already exist.
|
|
290
|
+
if (parsed.command === 'init') {
|
|
291
|
+
return this.runInit(corpusRoot, parsed.corpusRoot);
|
|
292
|
+
}
|
|
293
|
+
// Everything past this point parses documents, which is the work that
|
|
294
|
+
// cannot be bounded from the inside.
|
|
295
|
+
const supervision = this.readSupervision();
|
|
296
|
+
if (supervision !== undefined) {
|
|
297
|
+
return this.runSupervised(supervision, argv, parsed);
|
|
298
|
+
}
|
|
299
|
+
// The bundled example belongs to the package, not the project, so the
|
|
300
|
+
// project's .ecrignore does not apply to it; --ignore still does.
|
|
301
|
+
if (parsed.useExample) {
|
|
302
|
+
return this.runValidation(parsed, join(this.packageRoot, 'examples', 'docs'), 'the bundled example corpus', false);
|
|
303
|
+
}
|
|
304
|
+
return this.runValidation(parsed, corpusRoot, parsed.corpusRoot, true);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Runs `lint` or `stats` against a corpus.
|
|
308
|
+
*
|
|
309
|
+
* @param parsed - The parsed command line
|
|
310
|
+
* @param corpusRoot - Resolved corpus directory
|
|
311
|
+
* @param displayedRoot - How to name the corpus in messages
|
|
312
|
+
* @param applyProjectIgnore - Whether the project's `.ecrignore` applies
|
|
313
|
+
* @returns The text to print and the process exit code
|
|
314
|
+
*/
|
|
315
|
+
runValidation(parsed, corpusRoot, displayedRoot, applyProjectIgnore) {
|
|
316
|
+
if (!existsSync(corpusRoot) || !statSync(corpusRoot).isDirectory()) {
|
|
317
|
+
return this.fail(` Directory not found: ${displayedRoot}\n`);
|
|
318
|
+
}
|
|
319
|
+
let projectIgnore = undefined;
|
|
320
|
+
if (applyProjectIgnore) {
|
|
321
|
+
const read = new ProjectIgnoreFile(this.workingDirectory).read();
|
|
322
|
+
if (read.kind === 'unreadable') {
|
|
323
|
+
return this.fail(` Could not read ${PROJECT_IGNORE_FILENAME} (${read.reason}).\n`);
|
|
324
|
+
}
|
|
325
|
+
if (read.kind === 'patterns') {
|
|
326
|
+
projectIgnore = { workingDirectory: this.workingDirectory, patterns: read.patterns };
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
const loader = new CorpusLoader(corpusRoot, parsed.ignorePatterns, projectIgnore);
|
|
330
|
+
const loaded = loader.load();
|
|
331
|
+
if (loaded.rootExcluded) {
|
|
332
|
+
return this.fail(` ${displayedRoot} is excluded by ${PROJECT_IGNORE_FILENAME}, so there is nothing to check.\n`);
|
|
333
|
+
}
|
|
334
|
+
// A corpus that was not fully read cannot pass or be summarised, so the
|
|
335
|
+
// command cannot run; the walk still finished, so every such path is named.
|
|
336
|
+
if (loaded.unreadablePaths.length > 0) {
|
|
337
|
+
return this.fail(' Could not read:\n' +
|
|
338
|
+
loaded.unreadablePaths.map((unreadable) => ` ${unreadable.path} (${unreadable.reason})\n`).join('') +
|
|
339
|
+
' Fix these paths, or exclude them with --ignore.\n');
|
|
340
|
+
}
|
|
341
|
+
if (loaded.documents.length === 0) {
|
|
342
|
+
// Links are the likeliest reason a directory of documents yields none.
|
|
343
|
+
const links = DiagnosticReporter.listNotFollowed(loaded.notFollowedPaths);
|
|
344
|
+
return this.fail(` No Markdown documents found in ${displayedRoot}\n` +
|
|
345
|
+
links.map((line) => `${line}\n`).join('') +
|
|
346
|
+
(links.length > 0 ? ' Links are not followed, because `rg` and `grep -r` do not follow them either.\n' : ''));
|
|
347
|
+
}
|
|
348
|
+
const corpusResult = new Ecr().validateCorpus(loaded.documents);
|
|
349
|
+
const reporter = new DiagnosticReporter(parsed.format);
|
|
350
|
+
if (parsed.command === 'stats') {
|
|
351
|
+
const statistics = new CorpusStatistics(corpusResult);
|
|
352
|
+
return this.succeed(reporter.reportStatistics(statistics.summarise(), loaded.notFollowedPaths));
|
|
353
|
+
}
|
|
354
|
+
const output = reporter.reportValidation(corpusResult, loaded.excludedPaths, loaded.notFollowedPaths);
|
|
355
|
+
const hasErrors = this.tellCorpusHasErrors(corpusResult);
|
|
356
|
+
// A report of a failing corpus is still the command's result, so it goes
|
|
357
|
+
// to stdout; only the exit code signals the failure.
|
|
358
|
+
return {
|
|
359
|
+
output,
|
|
360
|
+
stream: 'stdout',
|
|
361
|
+
exitCode: hasErrors ? EXIT_VALIDATION_FAILED : EXIT_SUCCESS,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Installs the ECR documentation into a new or empty directory, keeping the
|
|
366
|
+
* repository's layout, and adds that directory to the project's
|
|
367
|
+
* `.ecrignore` so that linting the project does not validate it.
|
|
368
|
+
*
|
|
369
|
+
* Everything that could stop the installation is checked before anything is
|
|
370
|
+
* written, and a failure part-way removes what was copied.
|
|
371
|
+
*
|
|
372
|
+
* @param destination - Resolved installation directory
|
|
373
|
+
* @param displayedDestination - The directory as the user typed it, for messages
|
|
374
|
+
* @returns The text to print and the process exit code
|
|
375
|
+
*/
|
|
376
|
+
runInit(destination, displayedDestination) {
|
|
377
|
+
const packageRoot = this.packageRoot;
|
|
378
|
+
const missing = INSTALLED_DOCUMENTATION.filter((path) => !existsSync(join(packageRoot, path)));
|
|
379
|
+
if (missing.length > 0) {
|
|
380
|
+
return this.fail(` The packaged documentation is incomplete; missing: ${missing.join(', ')}\n`);
|
|
381
|
+
}
|
|
382
|
+
const existed = existsSync(destination);
|
|
383
|
+
let isDirectory = false;
|
|
384
|
+
let isEmpty = true;
|
|
385
|
+
try {
|
|
386
|
+
isDirectory = existed && statSync(destination).isDirectory();
|
|
387
|
+
isEmpty = !isDirectory || readdirSync(destination).length === 0;
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
return this.fail(` Could not examine ${displayedDestination} (${ProjectIgnoreFile.showReason(error)}), so nothing was installed.\n`);
|
|
391
|
+
}
|
|
392
|
+
if (existed && !isDirectory) {
|
|
393
|
+
return this.fail(` ${displayedDestination} exists but is not a directory.\n`);
|
|
394
|
+
}
|
|
395
|
+
// It may hold the user's own documents, so the advice is to choose
|
|
396
|
+
// another directory; deleting is only right for an earlier installation.
|
|
397
|
+
if (!isEmpty) {
|
|
398
|
+
return this.fail(` ${displayedDestination} already exists and is not empty.\n` +
|
|
399
|
+
' init installs into a new or empty directory, so choose another one.\n' +
|
|
400
|
+
' If this is an earlier ECR installation, delete it and run init again\n' +
|
|
401
|
+
' to install this version.\n');
|
|
402
|
+
}
|
|
403
|
+
const exclusion = ProjectIgnoreFile.readInstallExclusion(this.workingDirectory, destination);
|
|
404
|
+
if (exclusion.kind === 'invalid') {
|
|
405
|
+
return this.fail(` Cannot install into ${displayedDestination}: ${exclusion.reason}.\n`);
|
|
406
|
+
}
|
|
407
|
+
const ignoreFile = new ProjectIgnoreFile(this.workingDirectory);
|
|
408
|
+
const currentIgnore = ignoreFile.read();
|
|
409
|
+
if (exclusion.kind === 'pattern' && currentIgnore.kind === 'unreadable') {
|
|
410
|
+
return this.fail(` Could not read ${PROJECT_IGNORE_FILENAME} (${currentIgnore.reason}), so nothing was installed.\n`);
|
|
411
|
+
}
|
|
412
|
+
try {
|
|
413
|
+
mkdirSync(destination, { recursive: true });
|
|
414
|
+
for (const path of INSTALLED_DOCUMENTATION) {
|
|
415
|
+
cpSync(join(packageRoot, path), join(destination, path), { recursive: true, errorOnExist: true, force: false });
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
catch (error) {
|
|
419
|
+
const reason = ProjectIgnoreFile.showReason(error);
|
|
420
|
+
const cleanupFailure = this.removePartialInstallation(destination, existed);
|
|
421
|
+
if (cleanupFailure !== undefined) {
|
|
422
|
+
return this.fail(` Could not install the documentation (${reason}), and could not remove\n` +
|
|
423
|
+
` what was copied (${cleanupFailure}). Delete ${displayedDestination} before running init again.\n`);
|
|
424
|
+
}
|
|
425
|
+
return this.fail(` Could not install the documentation (${reason}), so nothing was installed.\n`);
|
|
426
|
+
}
|
|
427
|
+
let ignoreNote = ` ${displayedDestination} is outside this directory, so ${PROJECT_IGNORE_FILENAME} was not changed.\n`;
|
|
428
|
+
if (exclusion.kind === 'pattern') {
|
|
429
|
+
try {
|
|
430
|
+
ignoreNote = ignoreFile.addPattern(exclusion.pattern) === 'added'
|
|
431
|
+
? ` Added ${exclusion.pattern} to ${PROJECT_IGNORE_FILENAME}, so linting this project skips it.\n`
|
|
432
|
+
: ` ${PROJECT_IGNORE_FILENAME} already excludes it (${exclusion.pattern}).\n`;
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
return this.fail(` Installed the documentation in ${displayedDestination}, but could not update ` +
|
|
436
|
+
`${PROJECT_IGNORE_FILENAME} (${ProjectIgnoreFile.showReason(error)}).\n` +
|
|
437
|
+
` Add this line to ${PROJECT_IGNORE_FILENAME} yourself: ${exclusion.pattern}\n`);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
// Success says where the documentation went, in a name the user gave,
|
|
441
|
+
// so it is made safe to print for the same reason a failure is.
|
|
442
|
+
return this.succeed(showControlCharacters(`\n Installed the ECR documentation in ${displayedDestination}\n\n` +
|
|
443
|
+
` Start with ${join(displayedDestination, 'README.md')}\n` +
|
|
444
|
+
` Point your coding agent at ${join(displayedDestination, 'protocol', 'navigation-protocol.md')}\n` +
|
|
445
|
+
' It is the half that does the navigating; the linter only checks structure.\n\n' +
|
|
446
|
+
`${ignoreNote}\n`));
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Removes what a failed installation copied. The destination was new or
|
|
450
|
+
* empty, so nothing of the user's is inside it.
|
|
451
|
+
*
|
|
452
|
+
* @param destination - The installation directory
|
|
453
|
+
* @param existed - Whether it existed, empty, before installation began
|
|
454
|
+
* @returns Why removal failed, or `undefined` when everything copied was removed
|
|
455
|
+
*/
|
|
456
|
+
removePartialInstallation(destination, existed) {
|
|
457
|
+
try {
|
|
458
|
+
if (!existed) {
|
|
459
|
+
rmSync(destination, { recursive: true, force: true });
|
|
460
|
+
return undefined;
|
|
461
|
+
}
|
|
462
|
+
for (const path of INSTALLED_DOCUMENTATION) {
|
|
463
|
+
rmSync(join(destination, path), { recursive: true, force: true });
|
|
464
|
+
}
|
|
465
|
+
return undefined;
|
|
466
|
+
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
return ProjectIgnoreFile.showReason(error);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Reads how this invocation should bound its parsing, if at all.
|
|
473
|
+
*
|
|
474
|
+
* @returns The supervision settings, or `undefined` when this invocation does the work itself
|
|
475
|
+
*/
|
|
476
|
+
readSupervision() {
|
|
477
|
+
// The child is this same executable, and must do the work rather than
|
|
478
|
+
// start a child of its own.
|
|
479
|
+
return process.env[SUPERVISED_VARIABLE] === '1' ? undefined : this.supervision;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Runs `lint` or `stats` in a child process with a time limit and a heap
|
|
483
|
+
* limit, and passes on what it produced.
|
|
484
|
+
*
|
|
485
|
+
* A child that had to be stopped produced no usable report, however much of
|
|
486
|
+
* one reached this process, so none of it is passed on: the invocation
|
|
487
|
+
* failed, and says why.
|
|
488
|
+
*
|
|
489
|
+
* @param settings - Where the child's script is, and any limits overriding the defaults
|
|
490
|
+
* @param argv - The arguments to pass on, exactly as they were given
|
|
491
|
+
* @param parsed - The same arguments, for the limits they carry
|
|
492
|
+
* @returns The child's output and exit code, or the reason it was stopped
|
|
493
|
+
*/
|
|
494
|
+
runSupervised(settings, argv, parsed) {
|
|
495
|
+
// What the command line asked for wins; what the run was configured with
|
|
496
|
+
// stands where the command line said nothing; the defaults are the rest.
|
|
497
|
+
const limits = {
|
|
498
|
+
...DEFAULT_SUPERVISION_LIMITS,
|
|
499
|
+
...settings.limits,
|
|
500
|
+
...(parsed.timeoutSeconds !== undefined ? { timeoutMs: parsed.timeoutSeconds * 1000 } : {}),
|
|
501
|
+
...(parsed.maxMemoryMib !== undefined ? { memoryMib: parsed.maxMemoryMib } : {}),
|
|
502
|
+
};
|
|
503
|
+
const outcome = new Supervisor(settings.entryPoint, limits, this.workingDirectory).run(argv);
|
|
504
|
+
if (outcome.kind === 'stopped') {
|
|
505
|
+
return this.fail(` ecr did not finish: ${outcome.reason}.\n`);
|
|
506
|
+
}
|
|
507
|
+
// Every code this command exits with means something. A child that ended
|
|
508
|
+
// with any other did not end as this command ends: it ran out of heap, or
|
|
509
|
+
// the runtime beneath it stopped. Passing such a code on would offer it
|
|
510
|
+
// as a verdict on the corpus, and on Windows as a number no caller could
|
|
511
|
+
// read.
|
|
512
|
+
if (!EXIT_CODES.includes(outcome.exitCode)) {
|
|
513
|
+
return this.fail(` ecr did not finish: ${this.showAbnormalExit(outcome, limits)}.\n`);
|
|
514
|
+
}
|
|
515
|
+
// A verdict on a corpus comes with the report it is a verdict on. A child
|
|
516
|
+
// that exited 1 having printed nothing never got as far as validating,
|
|
517
|
+
// and passing that code on would read as a corpus full of errors.
|
|
518
|
+
if (outcome.stdout === '' && outcome.exitCode === EXIT_VALIDATION_FAILED) {
|
|
519
|
+
return this.fail(` ecr did not finish: the run failed without producing a report.\n${outcome.stderr}`);
|
|
520
|
+
}
|
|
521
|
+
// A command writes to one stream per invocation, so whichever the child
|
|
522
|
+
// used is the one this process writes to.
|
|
523
|
+
return outcome.stdout === ''
|
|
524
|
+
? { output: outcome.stderr, stream: 'stderr', exitCode: outcome.exitCode }
|
|
525
|
+
: { output: outcome.stdout, stream: 'stdout', exitCode: outcome.exitCode };
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Describes a child that ended in a way this command never ends.
|
|
529
|
+
*
|
|
530
|
+
* Running out of heap is worth naming, because it is the one such ending a
|
|
531
|
+
* user can do anything about, and the limit that caused it is one they set.
|
|
532
|
+
*
|
|
533
|
+
* @param outcome - What the child produced before it ended
|
|
534
|
+
* @param limits - The limits it was given
|
|
535
|
+
* @returns The reason, as a phrase completing "ecr did not finish..."
|
|
536
|
+
*/
|
|
537
|
+
showAbnormalExit(outcome, limits) {
|
|
538
|
+
if (HEAP_EXHAUSTED.test(outcome.stderr)) {
|
|
539
|
+
return (`it ran out of heap, limited to ${String(limits.memoryMib)} MiB. ` +
|
|
540
|
+
`Raise the limit with --max-memory <MiB>, or 0 for node's own default`);
|
|
541
|
+
}
|
|
542
|
+
return `the run ended unexpectedly (exit ${String(outcome.exitCode)})`;
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Builds a successful outcome, written to stdout.
|
|
546
|
+
*
|
|
547
|
+
* @param output - The text to print
|
|
548
|
+
* @returns The outcome
|
|
549
|
+
*/
|
|
550
|
+
succeed(output) {
|
|
551
|
+
return { output, stream: 'stdout', exitCode: EXIT_SUCCESS };
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Builds the outcome of an invocation that could not run, written to stderr.
|
|
555
|
+
*
|
|
556
|
+
* @param output - The message to print
|
|
557
|
+
* @returns The outcome
|
|
558
|
+
*/
|
|
559
|
+
fail(output) {
|
|
560
|
+
// A message names paths that came from the disk, so it is made safe to
|
|
561
|
+
// print for the same reason a report of a document's text is.
|
|
562
|
+
return { output: showControlCharacters(output), stream: 'stderr', exitCode: EXIT_USAGE_ERROR };
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* Reads the published package version from `package.json`.
|
|
566
|
+
*
|
|
567
|
+
* @returns The package version
|
|
568
|
+
*/
|
|
569
|
+
showPackageVersion() {
|
|
570
|
+
const manifestText = readFileSync(join(this.packageRoot, 'package.json'), 'utf8');
|
|
571
|
+
const manifest = JSON.parse(manifestText);
|
|
572
|
+
return manifest.version;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Determines whether a corpus result contains any error-severity diagnostic.
|
|
576
|
+
*
|
|
577
|
+
* @param corpusResult - The result to inspect
|
|
578
|
+
* @returns `true` when at least one error was reported
|
|
579
|
+
*/
|
|
580
|
+
tellCorpusHasErrors(corpusResult) {
|
|
581
|
+
for (const entry of corpusResult.documents) {
|
|
582
|
+
for (const diagnostic of entry.result.diagnostics) {
|
|
583
|
+
if (diagnostic.severity === 'error') {
|
|
584
|
+
return true;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
return corpusResult.diagnostics.some((diagnostic) => diagnostic.severity === 'error');
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|