@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
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@assert-structure`: what files are called, what directories hold, and which
|
|
3
|
+
* files come in pairs. ADR-0013.
|
|
4
|
+
*
|
|
5
|
+
* Names only. Nothing here reads a file's contents, and nothing asks the
|
|
6
|
+
* filesystem whether a path exists: a path exists when its name is in its
|
|
7
|
+
* parent's listing, compared exactly. A lookup of `README.md` finds `Readme.md`
|
|
8
|
+
* on Windows and macOS and does not on Linux, and a rule about names that
|
|
9
|
+
* answers one way on a laptop and the other in CI is not a rule about names.
|
|
10
|
+
*/
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { comparePaths } from './engine.js';
|
|
13
|
+
import { createExcludeMatcher, createGlobMatcher, globToRegExp, isGlob, toPosix, walkPaths, } from './glob.js';
|
|
14
|
+
import { nodeIo } from './io.js';
|
|
15
|
+
import { LedgerBuilder, UNCERTAIN_REASONS } from './scope.js';
|
|
16
|
+
export function createTreeIndex(root, io = nodeIo) {
|
|
17
|
+
// Each directory's read, by its path from the root, kept twice over: as the
|
|
18
|
+
// reader returned it, for the walk - which needs a failed read to fail, and
|
|
19
|
+
// sorts in place a list that is then already sorted - and as a lookup by
|
|
20
|
+
// name, built once. Keyed by the relative path rather than the absolute one
|
|
21
|
+
// because a lookup names every directory on its way, and joining an absolute
|
|
22
|
+
// path per segment was most of what a partner rule cost over ten thousand
|
|
23
|
+
// files.
|
|
24
|
+
const reads = new Map();
|
|
25
|
+
const walks = new Map();
|
|
26
|
+
const read = (relativeDirectory) => {
|
|
27
|
+
let cached = reads.get(relativeDirectory);
|
|
28
|
+
if (!cached) {
|
|
29
|
+
const entries = io.readDirectory(path.join(root, relativeDirectory));
|
|
30
|
+
const listing = entries.then((found) => new Map(found.map((entry) => [entry.name, entry])), () => null);
|
|
31
|
+
cached = { entries, listing };
|
|
32
|
+
reads.set(relativeDirectory, cached);
|
|
33
|
+
}
|
|
34
|
+
return cached;
|
|
35
|
+
};
|
|
36
|
+
const listing = async (relativeDirectory) => {
|
|
37
|
+
let current = await read('.').listing;
|
|
38
|
+
if (relativeDirectory === '.')
|
|
39
|
+
return current;
|
|
40
|
+
const names = relativeDirectory.split('/');
|
|
41
|
+
for (const [depth, name] of names.entries()) {
|
|
42
|
+
if (current?.get(name)?.isDirectory() !== true)
|
|
43
|
+
return null;
|
|
44
|
+
current = await read(names.slice(0, depth + 1).join('/')).listing;
|
|
45
|
+
}
|
|
46
|
+
return current;
|
|
47
|
+
};
|
|
48
|
+
const walk = (target, scope) => {
|
|
49
|
+
const key = JSON.stringify([target, [...scope.skippedDirectories.keys()]]);
|
|
50
|
+
let pending = walks.get(key);
|
|
51
|
+
if (!pending) {
|
|
52
|
+
pending = (async () => {
|
|
53
|
+
const tree = { files: [], directories: [], gaps: [] };
|
|
54
|
+
const fromRoot = (relativePath) => path.posix.join(target, relativePath);
|
|
55
|
+
const walked = walkPaths(path.join(root, target), {
|
|
56
|
+
scope,
|
|
57
|
+
io: { ...io, readDirectory: (directory) => read(toPosix(path.relative(root, directory)) || '.').entries },
|
|
58
|
+
onDirectory: (relativePath) => tree.directories.push(fromRoot(relativePath)),
|
|
59
|
+
// Only the gaps. `.git` and `node_modules` are the run's policy, and
|
|
60
|
+
// are no more news here than they are to a search.
|
|
61
|
+
onSkip: (relativePath, reason) => {
|
|
62
|
+
if (UNCERTAIN_REASONS.has(reason))
|
|
63
|
+
tree.gaps.push(fromRoot(relativePath));
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
for await (const file of walked)
|
|
67
|
+
tree.files.push(fromRoot(file.relativePath));
|
|
68
|
+
return tree;
|
|
69
|
+
})();
|
|
70
|
+
walks.set(key, pending);
|
|
71
|
+
}
|
|
72
|
+
return pending;
|
|
73
|
+
};
|
|
74
|
+
return { listing, walk };
|
|
75
|
+
}
|
|
76
|
+
/** What a root-relative path is, by name - or null, which a link is too. */
|
|
77
|
+
async function kindOf(index, relativePath) {
|
|
78
|
+
if (relativePath === '.')
|
|
79
|
+
return 'directory';
|
|
80
|
+
const entry = (await index.listing(path.posix.dirname(relativePath)))?.get(path.posix.basename(relativePath));
|
|
81
|
+
return entry?.isDirectory() ? 'directory' : entry?.isFile() ? 'file' : null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Whether a directory holds a required entry: a file, or a directory when it
|
|
85
|
+
* ends in `/` - which `basename` and `dirname` both already ignore.
|
|
86
|
+
*/
|
|
87
|
+
async function holds(index, directory, entry) {
|
|
88
|
+
const wantsDirectory = entry.endsWith('/');
|
|
89
|
+
const named = globToRegExp(path.posix.basename(entry));
|
|
90
|
+
const listing = await index.listing(path.posix.join(directory, path.posix.dirname(entry)));
|
|
91
|
+
return [...(listing?.values() ?? [])].some((item) => named.test(item.name) && (wantsDirectory ? item.isDirectory() : item.isFile()));
|
|
92
|
+
}
|
|
93
|
+
/* -------------------------------------------------------------- the grammar */
|
|
94
|
+
const PLACEHOLDER = /\[(name|ext|dir)\]/g;
|
|
95
|
+
/**
|
|
96
|
+
* The path a partner template names for a file.
|
|
97
|
+
*
|
|
98
|
+
* `[name]` is the base name up to its last dot and `[ext]` is what follows it;
|
|
99
|
+
* a name whose only dot leads it, like `.env`, is all name. `[dir]` is the
|
|
100
|
+
* file's directory below the target it was found from - empty for a file at the
|
|
101
|
+
* top, or for a target that is the file itself - and a segment left empty leaves
|
|
102
|
+
* no separator behind. A template without a `/` names a sibling; a template
|
|
103
|
+
* with one names a path from the root.
|
|
104
|
+
*
|
|
105
|
+
* That is the whole grammar, and it is small on purpose: a reader can expand a
|
|
106
|
+
* template by eye, which is the property a substitution engine gives up.
|
|
107
|
+
*/
|
|
108
|
+
export function expandPartner(template, file, target) {
|
|
109
|
+
const directory = path.posix.dirname(file);
|
|
110
|
+
const base = path.posix.basename(file);
|
|
111
|
+
const dot = base.lastIndexOf('.');
|
|
112
|
+
const values = {
|
|
113
|
+
name: dot > 0 ? base.slice(0, dot) : base,
|
|
114
|
+
ext: dot > 0 ? base.slice(dot + 1) : '',
|
|
115
|
+
dir: path.posix.relative(file === target ? directory : target, directory),
|
|
116
|
+
};
|
|
117
|
+
const filled = template
|
|
118
|
+
.split('/')
|
|
119
|
+
.map((segment) => segment.replace(PLACEHOLDER, (_, key) => values[key]))
|
|
120
|
+
.filter((segment) => segment.length > 0)
|
|
121
|
+
.join('/');
|
|
122
|
+
return template.includes('/') ? filled : path.posix.join(directory, filled);
|
|
123
|
+
}
|
|
124
|
+
/** Why a partner template cannot be used, or null when it can. */
|
|
125
|
+
export function partnerTemplateIssue(template) {
|
|
126
|
+
const literal = template.replace(PLACEHOLDER, '');
|
|
127
|
+
const unknown = /\[[^\]]*\]/.exec(literal);
|
|
128
|
+
if (unknown) {
|
|
129
|
+
return `Partner template "${template}" uses ${unknown[0]}; the placeholders are [name], [ext] and [dir].`;
|
|
130
|
+
}
|
|
131
|
+
if (isGlob(literal)) {
|
|
132
|
+
return `Partner template "${template}" is a name, not a glob, so it cannot hold *, ?, [, ], { or }.`;
|
|
133
|
+
}
|
|
134
|
+
if (template.split('/').some((segment) => segment === '' || segment === '.' || segment === '..')) {
|
|
135
|
+
return `Partner template "${template}" must be a path inside the root, with no empty, "." or ".." segment.`;
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
/** Why a required entry cannot be used, or null when it can. */
|
|
140
|
+
export function requiredEntryIssue(entry) {
|
|
141
|
+
const segments = entry.replace(/\/$/, '').split('/');
|
|
142
|
+
if (segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
|
|
143
|
+
return `Required entry "${entry}" must be a path inside the directory, with no empty, "." or ".." segment.`;
|
|
144
|
+
}
|
|
145
|
+
if (segments.slice(0, -1).some(isGlob)) {
|
|
146
|
+
return `Required entry "${entry}" can use a glob only in its last segment.`;
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Holds every file or directory in scope to the claim.
|
|
152
|
+
*
|
|
153
|
+
* A subject is counted once, with the first target that reaches it - which is
|
|
154
|
+
* the target `[dir]` is measured from when two targets overlap.
|
|
155
|
+
*/
|
|
156
|
+
export async function checkStructure(query, request, index) {
|
|
157
|
+
const excluded = createExcludeMatcher(request.excludeGlobs);
|
|
158
|
+
const included = createGlobMatcher(request.globs);
|
|
159
|
+
const required = query.claim === 'required';
|
|
160
|
+
const selects = query.dirs === undefined ? null : globToRegExp(query.dirs);
|
|
161
|
+
const missing = [];
|
|
162
|
+
const notDirectories = [];
|
|
163
|
+
const gaps = new Set();
|
|
164
|
+
const subjects = new Map();
|
|
165
|
+
const add = (subject, target) => {
|
|
166
|
+
if (!subjects.has(subject))
|
|
167
|
+
subjects.set(subject, target);
|
|
168
|
+
};
|
|
169
|
+
for (const target of request.targets) {
|
|
170
|
+
const kind = await kindOf(index, target);
|
|
171
|
+
if (kind === 'file') {
|
|
172
|
+
if (required)
|
|
173
|
+
notDirectories.push(target);
|
|
174
|
+
else if (included(target) && !excluded(target))
|
|
175
|
+
add(target, target);
|
|
176
|
+
}
|
|
177
|
+
else if (kind !== 'directory') {
|
|
178
|
+
missing.push(target);
|
|
179
|
+
}
|
|
180
|
+
else if (required && selects === null) {
|
|
181
|
+
if (!excluded(target))
|
|
182
|
+
add(target, target);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
const tree = await index.walk(target, request.scope);
|
|
186
|
+
for (const gap of tree.gaps)
|
|
187
|
+
gaps.add(gap);
|
|
188
|
+
if (selects !== null) {
|
|
189
|
+
for (const directory of tree.directories) {
|
|
190
|
+
if (!excluded(directory) && selects.test(path.posix.relative(target, directory)))
|
|
191
|
+
add(directory, target);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
for (const file of tree.files)
|
|
196
|
+
if (included(file) && !excluded(file))
|
|
197
|
+
add(file, target);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const ledger = new LedgerBuilder();
|
|
202
|
+
for (const gap of gaps)
|
|
203
|
+
ledger.add(gap, 'unreadable');
|
|
204
|
+
const ordered = [...subjects].sort(([a], [b]) => comparePaths(a, b));
|
|
205
|
+
const check = {
|
|
206
|
+
missing,
|
|
207
|
+
notDirectories,
|
|
208
|
+
inspected: ordered.length,
|
|
209
|
+
violations: [],
|
|
210
|
+
scope: ledger.build(),
|
|
211
|
+
};
|
|
212
|
+
if (query.claim === 'pattern') {
|
|
213
|
+
const named = createGlobMatcher(query.values);
|
|
214
|
+
for (const [file] of ordered) {
|
|
215
|
+
if (!named(file))
|
|
216
|
+
check.violations.push({ path: file, text: `matches none of ${query.values.join(', ')}` });
|
|
217
|
+
}
|
|
218
|
+
return check;
|
|
219
|
+
}
|
|
220
|
+
if (required) {
|
|
221
|
+
const found = await Promise.all(ordered.map(([directory]) => Promise.all(query.values.map((entry) => holds(index, directory, entry)))));
|
|
222
|
+
ordered.forEach(([directory], at) => {
|
|
223
|
+
const lacking = query.values.filter((_, position) => !found[at][position]);
|
|
224
|
+
if (lacking.length > 0)
|
|
225
|
+
check.violations.push({ path: directory, text: `missing ${lacking.join(', ')}` });
|
|
226
|
+
});
|
|
227
|
+
return check;
|
|
228
|
+
}
|
|
229
|
+
// Partners. Expanded before anything is looked up, so a template naming the
|
|
230
|
+
// file itself is refused rather than satisfied by every file.
|
|
231
|
+
const partners = ordered.map(([file, target]) => query.values.map((template) => expandPartner(template, file, target)));
|
|
232
|
+
const expectedBy = new Map();
|
|
233
|
+
for (const [at, [file]] of ordered.entries()) {
|
|
234
|
+
const names = partners[at];
|
|
235
|
+
const own = names.indexOf(file);
|
|
236
|
+
if (own !== -1)
|
|
237
|
+
return { ...check, selfPartner: { file, template: query.values[own] } };
|
|
238
|
+
for (const name of names)
|
|
239
|
+
if (!expectedBy.has(name))
|
|
240
|
+
expectedBy.set(name, file);
|
|
241
|
+
}
|
|
242
|
+
const found = await Promise.all(partners.map((names) => Promise.all(names.map(async (name) => (await index.listing(path.posix.dirname(name)))?.get(path.posix.basename(name))?.isFile() === true))));
|
|
243
|
+
ordered.forEach(([file], at) => {
|
|
244
|
+
if (found[at].includes(true))
|
|
245
|
+
return;
|
|
246
|
+
// The likeliest reason a file has no partner is that it is one, and the
|
|
247
|
+
// directive forgot to exclude the partners.
|
|
248
|
+
const owner = expectedBy.get(file);
|
|
249
|
+
const hint = owner === undefined ? '' : ` (it is the partner of ${owner} - exclude it?)`;
|
|
250
|
+
check.violations.push({ path: file, text: `has no partner ${partners[at].join(' or ')}${hint}` });
|
|
251
|
+
});
|
|
252
|
+
return check;
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=structure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structure.js","sourceRoot":"","sources":["../src/structure.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -6,7 +6,24 @@ import type { ScopeLedger, ScopePolicy } from './scope.js';
|
|
|
6
6
|
* parser -> Directive[] -> runner (+ engine) -> AssertionResult[] -> reporter
|
|
7
7
|
*/
|
|
8
8
|
/** Every assertion kind the parser understands. */
|
|
9
|
-
export type DirectiveKind = 'assert-absence' | 'assert-count' | 'assert-present' | 'assert-import-absence' | 'assert-import-count' | 'assert-import-cycle' | 'assert-layers';
|
|
9
|
+
export type DirectiveKind = 'assert-absence' | 'assert-count' | 'assert-present' | 'assert-import-absence' | 'assert-import-count' | 'assert-import-cycle' | 'assert-layers' | 'assert-structure';
|
|
10
|
+
/** What an `@assert-structure` directive claims. Exactly one per directive; see ADR-0013. */
|
|
11
|
+
export type StructureClaim = 'pattern' | 'required' | 'partner';
|
|
12
|
+
/** The claim of an `@assert-structure` directive, resolved. */
|
|
13
|
+
export interface StructureQuery {
|
|
14
|
+
claim: StructureClaim;
|
|
15
|
+
/**
|
|
16
|
+
* The claim's list, as written: the name patterns every file must match, the
|
|
17
|
+
* entries every directory must hold, or the partner templates of which one
|
|
18
|
+
* must exist.
|
|
19
|
+
*/
|
|
20
|
+
values: string[];
|
|
21
|
+
/**
|
|
22
|
+
* For `required`, the glob choosing directories below each target. Absent
|
|
23
|
+
* when the rule is about the targets themselves.
|
|
24
|
+
*/
|
|
25
|
+
dirs?: string;
|
|
26
|
+
}
|
|
10
27
|
/** Extra scope carried by the import assertions. */
|
|
11
28
|
export interface ImportQuery {
|
|
12
29
|
/** Module patterns, matched with gitignore-style rules. */
|
|
@@ -145,9 +162,12 @@ export interface Bounds {
|
|
|
145
162
|
export interface MatchLocation {
|
|
146
163
|
/** Path relative to root, forward slashes. */
|
|
147
164
|
file: string;
|
|
148
|
-
/**
|
|
165
|
+
/**
|
|
166
|
+
* 1-based line number, or 0 when the match is the path as a whole - a file
|
|
167
|
+
* with the wrong name, or a directory missing an entry, has no line.
|
|
168
|
+
*/
|
|
149
169
|
line: number;
|
|
150
|
-
/** 1-based column of the first match on that line. */
|
|
170
|
+
/** 1-based column of the first match on that line; 0 alongside a line of 0. */
|
|
151
171
|
column: number;
|
|
152
172
|
/** Trimmed line content, truncated for display. */
|
|
153
173
|
text: string;
|
|
@@ -200,6 +220,8 @@ export interface Assertion {
|
|
|
200
220
|
* on to the layer that may depend on everything. See ADR-0011.
|
|
201
221
|
*/
|
|
202
222
|
layers?: string[];
|
|
223
|
+
/** Present on `@assert-structure`. */
|
|
224
|
+
structure?: StructureQuery;
|
|
203
225
|
/**
|
|
204
226
|
* Known violations that do not count. Empty when the directive declared none.
|
|
205
227
|
*
|
|
@@ -211,8 +233,6 @@ export interface Assertion {
|
|
|
211
233
|
baseline: readonly BaselineEntry[];
|
|
212
234
|
/** Whether a baseline entry that no longer matches fails the run. */
|
|
213
235
|
ratchet: RatchetMode;
|
|
214
|
-
/** Targets that do not exist on disk. */
|
|
215
|
-
missingTargets: string[];
|
|
216
236
|
/**
|
|
217
237
|
* Tolerate a scope containing no files.
|
|
218
238
|
*
|
|
@@ -234,6 +254,14 @@ export interface AssertionResult {
|
|
|
234
254
|
targets: string[];
|
|
235
255
|
files: string[];
|
|
236
256
|
bounds: Bounds;
|
|
257
|
+
/**
|
|
258
|
+
* The claim of an `@assert-structure` result.
|
|
259
|
+
*
|
|
260
|
+
* Carried because it decides what a match is: a file for `pattern` and
|
|
261
|
+
* `partner`, a directory for `required` - and a directory is not something a
|
|
262
|
+
* code-scanning annotation can be placed on.
|
|
263
|
+
*/
|
|
264
|
+
claim?: StructureClaim;
|
|
237
265
|
/** Observed count: matches for searches, existing files for `assert-present`. */
|
|
238
266
|
actual: number;
|
|
239
267
|
/** Short "expected X, found Y" style explanation. */
|
|
@@ -290,6 +318,21 @@ export interface RunSummary {
|
|
|
290
318
|
*/
|
|
291
319
|
inactive: number;
|
|
292
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* What a command took from a project's configuration, by key. ADR-0014.
|
|
323
|
+
*
|
|
324
|
+
* Carried on a report because an option in a file nobody is looking at is an
|
|
325
|
+
* option nobody knows is in force - and `allowEmptyScope` there weakens every
|
|
326
|
+
* rule in the project.
|
|
327
|
+
*/
|
|
328
|
+
export interface ConfigUse {
|
|
329
|
+
/** The file the options came from, relative to the root. */
|
|
330
|
+
file: string;
|
|
331
|
+
/** Keys whose values were used. */
|
|
332
|
+
applied: string[];
|
|
333
|
+
/** Keys the command line set too, and won. */
|
|
334
|
+
overridden: string[];
|
|
335
|
+
}
|
|
293
336
|
export interface RunReport {
|
|
294
337
|
ok: boolean;
|
|
295
338
|
root: string;
|
|
@@ -310,5 +353,7 @@ export interface RunReport {
|
|
|
310
353
|
* tool exists to prevent.
|
|
311
354
|
*/
|
|
312
355
|
inactiveSpecs: InactiveSpec[];
|
|
356
|
+
/** What the command line took from the project's configuration, when it took anything. */
|
|
357
|
+
config?: ConfigUse;
|
|
313
358
|
}
|
|
314
359
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D;;;;;GAKG;AAEH,mDAAmD;AACnD,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,uBAAuB,GACvB,qBAAqB,GACrB,qBAAqB,GACrB,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/watch.d.ts
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
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 { type FactPolicy, type WatchEvent } from './facts.js';
|
|
15
|
+
import { type Io, type TreeWatcher } from './io.js';
|
|
16
|
+
import { type Memo, type SessionMemo } from './memo.js';
|
|
17
|
+
import { type ReporterOptions } from './reporter.js';
|
|
18
|
+
import { type ExecuteOptions, type RunOptions, type RunResult } from './runner.js';
|
|
19
|
+
import type { Assertion, ConfigUse } from './types.js';
|
|
20
|
+
/** The options a session's run takes: a run's, less the engine it never uses. */
|
|
21
|
+
export type SessionRunOptions = Pick<RunOptions, 'allowMissingTargets' | 'strictTargets' | 'allowEmptyScope' | 'maxSnippets' | 'includeSpecs' | 'defaultSkips' | 'ignoreStatus' | 'concurrency'>;
|
|
22
|
+
/** What one run of a session is asked to do. */
|
|
23
|
+
export interface SessionSettings {
|
|
24
|
+
patterns: readonly string[];
|
|
25
|
+
run: SessionRunOptions;
|
|
26
|
+
/** What those settings took from the project's configuration, for the report. */
|
|
27
|
+
config?: ConfigUse;
|
|
28
|
+
}
|
|
29
|
+
export interface SessionOptions {
|
|
30
|
+
root: string;
|
|
31
|
+
/** The filesystem underneath the session's cache. */
|
|
32
|
+
io?: Io;
|
|
33
|
+
/**
|
|
34
|
+
* Decides a run's settings, reading whatever it needs through the door it is
|
|
35
|
+
* handed - so an edit to `package.json` reaches the session as a changed fact
|
|
36
|
+
* like any other. Throws to fail the run with its message.
|
|
37
|
+
*/
|
|
38
|
+
settings: (io: Io) => Promise<SessionSettings>;
|
|
39
|
+
/** What an event evicts and what counts as a change. */
|
|
40
|
+
policy?: FactPolicy;
|
|
41
|
+
/** Where pure work is remembered. */
|
|
42
|
+
memo?: SessionMemo;
|
|
43
|
+
/** What decides whether a rule's last result can be reused. */
|
|
44
|
+
identify?: (assertion: Assertion, run: SessionRunOptions) => string;
|
|
45
|
+
/** The per-run caches a rule executes with. */
|
|
46
|
+
caches?: (root: string, door: Io, memo: Memo) => RuleCaches;
|
|
47
|
+
}
|
|
48
|
+
/** The caches one execution of one rule reads through. */
|
|
49
|
+
export type RuleCaches = Pick<ExecuteOptions, 'engine' | 'imports' | 'hasFiles' | 'tree'>;
|
|
50
|
+
/**
|
|
51
|
+
* A rule's own caches, over its own door.
|
|
52
|
+
*
|
|
53
|
+
* Never shared between rules. Each is keyed by path, which makes it a fact
|
|
54
|
+
* under another name: a second rule served from the first one's walk would skip
|
|
55
|
+
* the reads, and with them the record of what it depends on.
|
|
56
|
+
*/
|
|
57
|
+
export declare function ruleCaches(root: string, door: Io, memo: Memo): RuleCaches;
|
|
58
|
+
export interface SessionRun {
|
|
59
|
+
report: RunResult;
|
|
60
|
+
/** How many snippets a failure shows, as the run was configured. */
|
|
61
|
+
maxSnippets: number;
|
|
62
|
+
/** Rules executed by this run rather than carried over from the last. */
|
|
63
|
+
executed: number;
|
|
64
|
+
}
|
|
65
|
+
export interface Session {
|
|
66
|
+
/** What a run says now. */
|
|
67
|
+
run(): Promise<SessionRun>;
|
|
68
|
+
/** Evicts what the events may have changed, and reads it again. Returns how many facts changed. */
|
|
69
|
+
observe(events: readonly WatchEvent[]): Promise<number>;
|
|
70
|
+
/** Forgets every fact, so the next run executes every rule. */
|
|
71
|
+
forget(): void;
|
|
72
|
+
/** Facts held, for the numbers ADR-0014 reports. */
|
|
73
|
+
readonly facts: number;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* What decides a rule's result besides the tree: its resolved form, and the run
|
|
77
|
+
* options its execution reads. Two rules with equal identities executed over the
|
|
78
|
+
* same facts give the same result, which is the whole of what reuse relies on.
|
|
79
|
+
*
|
|
80
|
+
* Only the options execution reads. The ones resolution reads - which specs are
|
|
81
|
+
* excluded, which directories skipped - are already in the resolved form, as the
|
|
82
|
+
* spec files it leaves out and the scope it walks, and are held there, where a
|
|
83
|
+
* rule is changed by them, rather than beside it.
|
|
84
|
+
*/
|
|
85
|
+
export declare function identity(assertion: Assertion, run: SessionRunOptions): string;
|
|
86
|
+
export declare function createSession(options: SessionOptions): Session;
|
|
87
|
+
/** How long a batch waits for quiet after its last event. */
|
|
88
|
+
export declare const QUIET_MS = 50;
|
|
89
|
+
/** How long a batch waits after its first event, however noisy the tree stays. */
|
|
90
|
+
export declare const MAX_WAIT_MS = 500;
|
|
91
|
+
/** The exit code of an interrupted command, as a shell reports one: 128 + SIGINT. */
|
|
92
|
+
export declare const EXIT_INTERRUPTED = 130;
|
|
93
|
+
/** Timers, injectable so a test can run the scheduler without waiting. */
|
|
94
|
+
export interface Clock {
|
|
95
|
+
now(): number;
|
|
96
|
+
setTimeout(callback: () => void, ms: number): unknown;
|
|
97
|
+
clearTimeout(handle: unknown): void;
|
|
98
|
+
}
|
|
99
|
+
export declare const systemClock: Clock;
|
|
100
|
+
export interface WatchOptions {
|
|
101
|
+
root: string;
|
|
102
|
+
session: Session;
|
|
103
|
+
/** Starts watching the root; may throw. */
|
|
104
|
+
watch: (listener: (event: WatchEvent) => void, onError: (error: Error) => void) => TreeWatcher;
|
|
105
|
+
/** Writes text as it is, with no newline added. */
|
|
106
|
+
write: (text: string) => void;
|
|
107
|
+
/** Clear the screen and redraw, rather than append. */
|
|
108
|
+
isTTY: boolean;
|
|
109
|
+
reporter: ReporterOptions;
|
|
110
|
+
/** Registers the handler for Ctrl+C and SIGTERM, and returns how to unregister it. */
|
|
111
|
+
onInterrupt: (handler: () => void) => () => void;
|
|
112
|
+
/** Registers the handler for a line on stdin, and returns how to unregister it. */
|
|
113
|
+
onLine?: (handler: () => void) => () => void;
|
|
114
|
+
clock?: Clock;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Runs a session until it is interrupted, and resolves to the exit code.
|
|
118
|
+
*
|
|
119
|
+
* 130 when stopped, since a session is neither a pass nor a failure. 2 when it
|
|
120
|
+
* cannot start or its watcher fails, including when the root disappears.
|
|
121
|
+
*/
|
|
122
|
+
export declare function runWatch(options: WatchOptions): Promise<number>;
|
|
123
|
+
/** A watcher's error, with what to do about the one a person can fix. */
|
|
124
|
+
export declare function describeWatchError(error: Error): string;
|
|
125
|
+
//# sourceMappingURL=watch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"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"}
|