@descent-vtt/spec-guard 0.7.0 → 0.9.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/CHANGELOG.md +147 -0
- package/README.md +224 -27
- package/dist/cli.d.ts +37 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +275 -59
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +66 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +165 -0
- package/dist/config.js.map +1 -0
- package/dist/engine.d.ts +22 -8
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +118 -67
- package/dist/engine.js.map +1 -1
- package/dist/facts.d.ts +106 -0
- package/dist/facts.d.ts.map +1 -0
- package/dist/facts.js +188 -0
- package/dist/facts.js.map +1 -0
- package/dist/glob.d.ts +17 -21
- package/dist/glob.d.ts.map +1 -1
- package/dist/glob.js +13 -24
- package/dist/glob.js.map +1 -1
- package/dist/imports.d.ts +6 -1
- package/dist/imports.d.ts.map +1 -1
- package/dist/imports.js +9 -5
- package/dist/imports.js.map +1 -1
- package/dist/index.d.ts +20 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -5
- package/dist/index.js.map +1 -1
- package/dist/io.d.ts +51 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +44 -0
- package/dist/io.js.map +1 -0
- package/dist/mcp.d.ts +11 -0
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +23 -18
- package/dist/mcp.js.map +1 -1
- package/dist/memo.d.ts +53 -0
- package/dist/memo.d.ts.map +1 -0
- package/dist/memo.js +67 -0
- package/dist/memo.js.map +1 -0
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +17 -0
- package/dist/parser.js.map +1 -1
- package/dist/query.d.ts +5 -2
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +12 -3
- package/dist/query.js.map +1 -1
- package/dist/reporter.d.ts +10 -0
- package/dist/reporter.d.ts.map +1 -1
- package/dist/reporter.js +33 -4
- package/dist/reporter.js.map +1 -1
- package/dist/rules.d.ts +12 -1
- package/dist/rules.d.ts.map +1 -1
- package/dist/rules.js +45 -1
- package/dist/rules.js.map +1 -1
- package/dist/runner.d.ts +42 -2
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +261 -76
- package/dist/runner.js.map +1 -1
- package/dist/specs.d.ts +3 -1
- package/dist/specs.d.ts.map +1 -1
- package/dist/specs.js +6 -5
- package/dist/specs.js.map +1 -1
- package/dist/structure.d.ts +104 -0
- package/dist/structure.d.ts.map +1 -0
- package/dist/structure.js +254 -0
- package/dist/structure.js.map +1 -0
- package/dist/types.d.ts +50 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/watch.d.ts +125 -0
- package/dist/watch.d.ts.map +1 -0
- package/dist/watch.js +321 -0
- package/dist/watch.js.map +1 -0
- package/package.json +8 -2
package/dist/watch.js
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `spec-guard --watch`: the same report, again, whenever the tree changes.
|
|
3
|
+
* ADR-0014.
|
|
4
|
+
*
|
|
5
|
+
* Two parts. A session answers "what does a run say now" and re-executes a
|
|
6
|
+
* rule only when its resolved form or something it read has changed; what may
|
|
7
|
+
* be reused, and why, is in facts.ts and memo.ts. The scheduler around it turns
|
|
8
|
+
* a watcher's events into batches, never runs two at once, redraws the terminal,
|
|
9
|
+
* and stops on Ctrl+C.
|
|
10
|
+
*
|
|
11
|
+
* The session is held to a fresh run of the same tree by
|
|
12
|
+
* tests/watch-equivalence.test.ts, and nothing here is trusted beyond that.
|
|
13
|
+
*/
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
import { createCachedEngine, createJavaScriptEngine } from './engine.js';
|
|
16
|
+
import { createFactCache } from './facts.js';
|
|
17
|
+
import { createImportIndex } from './imports.js';
|
|
18
|
+
import { nodeIo } from './io.js';
|
|
19
|
+
import { createMemo } from './memo.js';
|
|
20
|
+
import { formatReport } from './reporter.js';
|
|
21
|
+
import { createScopeProbe, DEFAULT_CONCURRENCY, DEFAULT_MAX_SNIPPETS, executeAssertion, planRun, reportRun, } from './runner.js';
|
|
22
|
+
import { readSpecs } from './specs.js';
|
|
23
|
+
import { createTreeIndex } from './structure.js';
|
|
24
|
+
/**
|
|
25
|
+
* A rule's own caches, over its own door.
|
|
26
|
+
*
|
|
27
|
+
* Never shared between rules. Each is keyed by path, which makes it a fact
|
|
28
|
+
* under another name: a second rule served from the first one's walk would skip
|
|
29
|
+
* the reads, and with them the record of what it depends on.
|
|
30
|
+
*/
|
|
31
|
+
export function ruleCaches(root, door, memo) {
|
|
32
|
+
const scanner = createJavaScriptEngine(door, memo);
|
|
33
|
+
return {
|
|
34
|
+
engine: createCachedEngine(scanner, scanner),
|
|
35
|
+
imports: createImportIndex(door, memo),
|
|
36
|
+
hasFiles: createScopeProbe(door),
|
|
37
|
+
tree: createTreeIndex(root, door),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* What decides a rule's result besides the tree: its resolved form, and the run
|
|
42
|
+
* options its execution reads. Two rules with equal identities executed over the
|
|
43
|
+
* same facts give the same result, which is the whole of what reuse relies on.
|
|
44
|
+
*
|
|
45
|
+
* Only the options execution reads. The ones resolution reads - which specs are
|
|
46
|
+
* excluded, which directories skipped - are already in the resolved form, as the
|
|
47
|
+
* spec files it leaves out and the scope it walks, and are held there, where a
|
|
48
|
+
* rule is changed by them, rather than beside it.
|
|
49
|
+
*/
|
|
50
|
+
export function identity(assertion, run) {
|
|
51
|
+
const { allowMissingTargets, strictTargets, allowEmptyScope, maxSnippets } = run;
|
|
52
|
+
return JSON.stringify([assertion, allowMissingTargets, strictTargets, allowEmptyScope, maxSnippets], (_key, value) => value instanceof Set ? [...value] : value instanceof Map ? [...value] : value);
|
|
53
|
+
}
|
|
54
|
+
export function createSession(options) {
|
|
55
|
+
const root = path.resolve(options.root);
|
|
56
|
+
const facts = createFactCache(root, options.io ?? nodeIo, options.policy);
|
|
57
|
+
const memo = options.memo ?? createMemo();
|
|
58
|
+
const identify = options.identify ?? identity;
|
|
59
|
+
const cachesFor = options.caches ?? ruleCaches;
|
|
60
|
+
let executed = new Map();
|
|
61
|
+
/** Facts the settings and the specs were read from. */
|
|
62
|
+
let planned = new Set();
|
|
63
|
+
/** Facts whose value changed since the last run. */
|
|
64
|
+
let changed = new Set();
|
|
65
|
+
const used = (key) => planned.has(key) || [...executed.values()].some((entry) => entry.reads.has(key));
|
|
66
|
+
async function execute(assertion, run) {
|
|
67
|
+
const reads = new Set();
|
|
68
|
+
const door = facts.view(reads);
|
|
69
|
+
const result = await executeAssertion(assertion, {
|
|
70
|
+
...cachesFor(root, door, memo),
|
|
71
|
+
root,
|
|
72
|
+
io: door,
|
|
73
|
+
allowMissingTargets: run.allowMissingTargets ?? false,
|
|
74
|
+
strictTargets: run.strictTargets ?? false,
|
|
75
|
+
allowEmptyScope: run.allowEmptyScope ?? false,
|
|
76
|
+
maxSnippets: run.maxSnippets ?? DEFAULT_MAX_SNIPPETS,
|
|
77
|
+
});
|
|
78
|
+
return { result, reads };
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
get facts() {
|
|
82
|
+
return facts.size;
|
|
83
|
+
},
|
|
84
|
+
async run() {
|
|
85
|
+
const startedAt = performance.now();
|
|
86
|
+
const reads = new Set();
|
|
87
|
+
const door = facts.view(reads);
|
|
88
|
+
const settings = await options.settings(door);
|
|
89
|
+
const plan = planRun(await readSpecs(settings.patterns, root, door, memo), root, settings.run);
|
|
90
|
+
planned = reads;
|
|
91
|
+
const before = executed;
|
|
92
|
+
const dirty = changed;
|
|
93
|
+
changed = new Set();
|
|
94
|
+
const next = new Map();
|
|
95
|
+
const results = [];
|
|
96
|
+
let count = 0;
|
|
97
|
+
const identities = plan.assertions.map((assertion) => identify(assertion, settings.run));
|
|
98
|
+
let cursor = 0;
|
|
99
|
+
const worker = async () => {
|
|
100
|
+
while (cursor < plan.assertions.length) {
|
|
101
|
+
const index = cursor++;
|
|
102
|
+
const key = identities[index];
|
|
103
|
+
const last = before.get(key);
|
|
104
|
+
let entry;
|
|
105
|
+
if (last !== undefined && ![...last.reads].some((read) => dirty.has(read))) {
|
|
106
|
+
entry = last;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
entry = await execute(plan.assertions[index], settings.run);
|
|
110
|
+
count += 1;
|
|
111
|
+
}
|
|
112
|
+
next.set(key, entry);
|
|
113
|
+
results[index] = entry.result;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const workers = Math.max(1, Math.min(settings.run.concurrency ?? DEFAULT_CONCURRENCY, plan.assertions.length));
|
|
117
|
+
await Promise.all(Array.from({ length: workers }, worker));
|
|
118
|
+
executed = next;
|
|
119
|
+
memo.sweep();
|
|
120
|
+
const report = reportRun(plan, results, { name: 'javascript', fallbacks: [] }, startedAt);
|
|
121
|
+
return {
|
|
122
|
+
report: { ...report, config: settings.config },
|
|
123
|
+
maxSnippets: settings.run.maxSnippets ?? DEFAULT_MAX_SNIPPETS,
|
|
124
|
+
executed: count,
|
|
125
|
+
};
|
|
126
|
+
},
|
|
127
|
+
async observe(events) {
|
|
128
|
+
const found = await facts.refresh(facts.evict(events), used);
|
|
129
|
+
for (const key of found)
|
|
130
|
+
changed.add(key);
|
|
131
|
+
return found.size;
|
|
132
|
+
},
|
|
133
|
+
forget() {
|
|
134
|
+
facts.evictAll();
|
|
135
|
+
executed = new Map();
|
|
136
|
+
changed = new Set();
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/* ---------------------------------------------------------------- scheduler */
|
|
141
|
+
/** How long a batch waits for quiet after its last event. */
|
|
142
|
+
export const QUIET_MS = 50;
|
|
143
|
+
/** How long a batch waits after its first event, however noisy the tree stays. */
|
|
144
|
+
export const MAX_WAIT_MS = 500;
|
|
145
|
+
/** The exit code of an interrupted command, as a shell reports one: 128 + SIGINT. */
|
|
146
|
+
export const EXIT_INTERRUPTED = 130;
|
|
147
|
+
export const systemClock = {
|
|
148
|
+
now: () => Date.now(),
|
|
149
|
+
setTimeout: (callback, ms) => setTimeout(callback, ms),
|
|
150
|
+
clearTimeout: (handle) => clearTimeout(handle),
|
|
151
|
+
};
|
|
152
|
+
const CLEAR_SCREEN = '\x1b[2J\x1b[3J\x1b[H';
|
|
153
|
+
/** Up one line, and clear it: the status line a quiet batch rewrites. */
|
|
154
|
+
const REWRITE_LINE = '\x1b[1A\x1b[2K';
|
|
155
|
+
function plural(count, one, many) {
|
|
156
|
+
return `${count} ${count === 1 ? one : many}`;
|
|
157
|
+
}
|
|
158
|
+
/** A report stripped of how long things took, to tell a new report from the last. */
|
|
159
|
+
function signature(report) {
|
|
160
|
+
return JSON.stringify(report, (key, value) => (key === 'durationMs' ? undefined : value));
|
|
161
|
+
}
|
|
162
|
+
/** Why a first run cannot become a session, or null when it can. */
|
|
163
|
+
function outsideRoot(report) {
|
|
164
|
+
const outside = report.specFiles.filter((file) => path.isAbsolute(file) || file === '..' || file.startsWith('../'));
|
|
165
|
+
return outside.length === 0
|
|
166
|
+
? null
|
|
167
|
+
: `--watch watches ${report.root}, and ${outside.length === 1 ? 'this spec is' : 'these specs are'} outside it: ${outside.join(', ')}`;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Runs a session until it is interrupted, and resolves to the exit code.
|
|
171
|
+
*
|
|
172
|
+
* 130 when stopped, since a session is neither a pass nor a failure. 2 when it
|
|
173
|
+
* cannot start or its watcher fails, including when the root disappears.
|
|
174
|
+
*/
|
|
175
|
+
export async function runWatch(options) {
|
|
176
|
+
const clock = options.clock ?? systemClock;
|
|
177
|
+
const { session, write } = options;
|
|
178
|
+
let finish = () => { };
|
|
179
|
+
const finished = new Promise((resolve) => {
|
|
180
|
+
finish = resolve;
|
|
181
|
+
});
|
|
182
|
+
let stopped = false;
|
|
183
|
+
// From the start: the first run begins before anything can be queued, and a
|
|
184
|
+
// batch must not begin beside it.
|
|
185
|
+
let running = true;
|
|
186
|
+
let everything = false;
|
|
187
|
+
const pending = [];
|
|
188
|
+
let firstQueuedAt = 0;
|
|
189
|
+
let timer;
|
|
190
|
+
let lastSignature = null;
|
|
191
|
+
const status = (run, changes, startedAt) => [
|
|
192
|
+
`watching ${plural(run.report.summary.specs, 'spec', 'specs')}`,
|
|
193
|
+
changes,
|
|
194
|
+
`${run.executed} of ${plural(run.report.summary.total, 'rule', 'rules')} ${changes === 'first run' ? 'executed' : 're-executed'}`,
|
|
195
|
+
`${Math.round(clock.now() - startedAt)} ms`,
|
|
196
|
+
'Enter re-runs everything, Ctrl+C stops',
|
|
197
|
+
].join(' · ');
|
|
198
|
+
const heading = () => (options.isTTY ? CLEAR_SCREEN : `--- ${new Date(clock.now()).toTimeString().slice(0, 8)} ---\n`);
|
|
199
|
+
const render = (run, line) => {
|
|
200
|
+
const current = signature(run.report);
|
|
201
|
+
if (current === lastSignature) {
|
|
202
|
+
write(`${options.isTTY ? REWRITE_LINE : ''}${line}\n`);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
lastSignature = current;
|
|
206
|
+
const body = run.report.summary.specs === 0
|
|
207
|
+
? 'spec-guard: no spec files matched, watching for one to appear'
|
|
208
|
+
: formatReport(run.report, options.reporter, run.maxSnippets);
|
|
209
|
+
write(`${heading()}${body}\n\n${line}\n`);
|
|
210
|
+
};
|
|
211
|
+
const stop = (code) => {
|
|
212
|
+
if (stopped)
|
|
213
|
+
return;
|
|
214
|
+
stopped = true;
|
|
215
|
+
clock.clearTimeout(timer);
|
|
216
|
+
watcher?.close();
|
|
217
|
+
unregisterInterrupt();
|
|
218
|
+
unregisterLine?.();
|
|
219
|
+
finish(code);
|
|
220
|
+
};
|
|
221
|
+
// Reached only from the timer `schedule` sets, which it sets only while nothing
|
|
222
|
+
// runs and the session has not stopped, and which stopping clears.
|
|
223
|
+
const batch = async () => {
|
|
224
|
+
running = true;
|
|
225
|
+
const events = pending.splice(0);
|
|
226
|
+
const rerunAll = everything;
|
|
227
|
+
everything = false;
|
|
228
|
+
const startedAt = clock.now();
|
|
229
|
+
try {
|
|
230
|
+
if (rerunAll)
|
|
231
|
+
session.forget();
|
|
232
|
+
else
|
|
233
|
+
await session.observe(events);
|
|
234
|
+
const run = await session.run();
|
|
235
|
+
if (stopped)
|
|
236
|
+
return;
|
|
237
|
+
// A configuration edited to name specs outside the root is refused the
|
|
238
|
+
// way a first run refuses it, without ending a session someone is using.
|
|
239
|
+
const outside = outsideRoot(run.report);
|
|
240
|
+
if (outside !== null)
|
|
241
|
+
throw new Error(outside);
|
|
242
|
+
const changes = rerunAll ? 'every rule, on request' : plural(new Set(events.map((event) => event.filename)).size, 'change', 'changes');
|
|
243
|
+
render(run, status(run, changes, startedAt));
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
if (stopped)
|
|
247
|
+
return;
|
|
248
|
+
lastSignature = null;
|
|
249
|
+
write(`${heading()}spec-guard: ${error instanceof Error ? error.message : String(error)}\n\nwatching · waiting for a change · Ctrl+C stops\n`);
|
|
250
|
+
}
|
|
251
|
+
finally {
|
|
252
|
+
running = false;
|
|
253
|
+
}
|
|
254
|
+
schedule();
|
|
255
|
+
};
|
|
256
|
+
/** Sets the timer for the next batch, if there is anything for one to do and it may start. */
|
|
257
|
+
const schedule = () => {
|
|
258
|
+
if (stopped || running || (pending.length === 0 && !everything))
|
|
259
|
+
return;
|
|
260
|
+
clock.clearTimeout(timer);
|
|
261
|
+
const waited = clock.now() - firstQueuedAt;
|
|
262
|
+
timer = clock.setTimeout(() => void batch(), everything ? 0 : Math.max(0, Math.min(QUIET_MS, MAX_WAIT_MS - waited)));
|
|
263
|
+
};
|
|
264
|
+
const queue = (event) => {
|
|
265
|
+
if (pending.length === 0)
|
|
266
|
+
firstQueuedAt = clock.now();
|
|
267
|
+
pending.push(event);
|
|
268
|
+
schedule();
|
|
269
|
+
};
|
|
270
|
+
let watcher;
|
|
271
|
+
const unregisterInterrupt = options.onInterrupt(() => stop(EXIT_INTERRUPTED));
|
|
272
|
+
const unregisterLine = options.onLine?.(() => {
|
|
273
|
+
everything = true;
|
|
274
|
+
schedule();
|
|
275
|
+
});
|
|
276
|
+
const cannot = (message) => {
|
|
277
|
+
write(`spec-guard: ${message}\n`);
|
|
278
|
+
stop(2);
|
|
279
|
+
return 2;
|
|
280
|
+
};
|
|
281
|
+
// The watcher first, so nothing that changes during the first run is missed.
|
|
282
|
+
try {
|
|
283
|
+
watcher = options.watch(queue, (error) => {
|
|
284
|
+
if (stopped)
|
|
285
|
+
return;
|
|
286
|
+
write(`spec-guard: the watch on ${options.root} failed: ${describeWatchError(error)}\n`);
|
|
287
|
+
stop(2);
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
return cannot(`cannot watch ${options.root}: ${describeWatchError(error)}`);
|
|
292
|
+
}
|
|
293
|
+
const startedAt = clock.now();
|
|
294
|
+
try {
|
|
295
|
+
const first = await session.run();
|
|
296
|
+
if (stopped)
|
|
297
|
+
return finished;
|
|
298
|
+
const outside = outsideRoot(first.report);
|
|
299
|
+
if (outside !== null)
|
|
300
|
+
return cannot(outside);
|
|
301
|
+
render(first, status(first, 'first run', startedAt));
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
if (stopped)
|
|
305
|
+
return finished;
|
|
306
|
+
return cannot(error instanceof Error ? error.message : String(error));
|
|
307
|
+
}
|
|
308
|
+
finally {
|
|
309
|
+
running = false;
|
|
310
|
+
}
|
|
311
|
+
schedule();
|
|
312
|
+
return finished;
|
|
313
|
+
}
|
|
314
|
+
/** A watcher's error, with what to do about the one a person can fix. */
|
|
315
|
+
export function describeWatchError(error) {
|
|
316
|
+
const code = error.code;
|
|
317
|
+
return code === 'ENOSPC'
|
|
318
|
+
? `${error.message} (the system's limit on watched directories was reached; raise fs.inotify.max_user_watches)`
|
|
319
|
+
: error.message;
|
|
320
|
+
}
|
|
321
|
+
//# sourceMappingURL=watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@descent-vtt/spec-guard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Executable architecture assertions for Markdown specs & ADRs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"adr",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"test:watch": "vitest",
|
|
48
48
|
"test:coverage": "vitest run --coverage",
|
|
49
49
|
"test:mutation": "stryker run",
|
|
50
|
-
"selfcheck": "node ./bin/spec-guard.js
|
|
50
|
+
"selfcheck": "node ./bin/spec-guard.js --verbose",
|
|
51
51
|
"prepublishOnly": "npm run clean && npm run build"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
@@ -67,6 +67,12 @@
|
|
|
67
67
|
"url": "https://github.com/DescentVTT/spec-guard/issues"
|
|
68
68
|
},
|
|
69
69
|
"homepage": "https://github.com/DescentVTT/spec-guard#readme",
|
|
70
|
+
"specGuard": {
|
|
71
|
+
"specs": [
|
|
72
|
+
"docs/**/*.md",
|
|
73
|
+
"README.md"
|
|
74
|
+
]
|
|
75
|
+
},
|
|
70
76
|
"overrides": {
|
|
71
77
|
"qs": "^6.16.0"
|
|
72
78
|
}
|