@codometer/configuration 0.0.1
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 +21 -0
- package/README.md +900 -0
- package/dist/src/index.d.ts +1204 -0
- package/dist/src/index.js +450 -0
- package/package.json +64 -0
|
@@ -0,0 +1,1204 @@
|
|
|
1
|
+
import { CodeStatisticsResult } from '@codometer/core';
|
|
2
|
+
import { CodometerSeverity } from '@codometer/core';
|
|
3
|
+
import { CodometerStatisticGroup } from '@codometer/core';
|
|
4
|
+
import { CodometerSymbolKind } from '@codometer/core';
|
|
5
|
+
import { CodometerSymbolModifier } from '@codometer/core';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
|
|
8
|
+
/** What `--check limits` asks the run to fail on: a breached failing limit. */
|
|
9
|
+
export declare const CHECK_LIMITS = "limits";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Everything `--check` accepts, in the order an error message lists them.
|
|
13
|
+
*
|
|
14
|
+
* Named here rather than spelled into each message, so the list a mistake is
|
|
15
|
+
* measured against and the list it is told about can never drift apart.
|
|
16
|
+
*/
|
|
17
|
+
export declare const CHECK_NAMES: string[];
|
|
18
|
+
|
|
19
|
+
/** What `--check reports` asks the run to fail on: a stale written report. */
|
|
20
|
+
export declare const CHECK_REPORTS = "reports";
|
|
21
|
+
|
|
22
|
+
/** How a `--check` value is written: one comma-separated set, no spaces needed. */
|
|
23
|
+
export declare const CHECK_SEPARATOR = ",";
|
|
24
|
+
|
|
25
|
+
/** Analyses an input may ask to have run over it. */
|
|
26
|
+
export declare const CODOMETER_ANALYSES: readonly ["language", "size"];
|
|
27
|
+
|
|
28
|
+
/** Languages a `comment` selector may narrow itself to. */
|
|
29
|
+
export declare const CODOMETER_COMMENT_LANGUAGES: readonly ["css", "hcl", "python", "shell", "sql", "toml", "typescript", "yaml"];
|
|
30
|
+
|
|
31
|
+
/** Compressions an input may ask its size to be measured under. */
|
|
32
|
+
export declare const CODOMETER_COMPRESSIONS: readonly ["brotli", "gzip", "none"];
|
|
33
|
+
|
|
34
|
+
/** Units a documentation limit may measure a comment's length in. */
|
|
35
|
+
export declare const CODOMETER_DOCUMENTATION_UNITS: readonly ["characters", "lines", "words"];
|
|
36
|
+
|
|
37
|
+
/** Report shapes a run may produce. */
|
|
38
|
+
export declare const CODOMETER_FORMATS: readonly ["json", "markdown"];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* An analysis codometer can run over an input.
|
|
42
|
+
*
|
|
43
|
+
* `language` parses the matched files and counts what they declare; `size`
|
|
44
|
+
* compresses them and counts bytes. Which of them an input runs is the only
|
|
45
|
+
* thing separating a source tree from build output.
|
|
46
|
+
*/
|
|
47
|
+
export declare type CodometerAnalysis = "language" | "size";
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A language a `comment` custom-statistic selector may narrow itself to.
|
|
51
|
+
*
|
|
52
|
+
* The same eight languages that used to carry their own `comments` override:
|
|
53
|
+
* every language this tool reads comments from except the JSDoc-style
|
|
54
|
+
* documentation a `kind` narrows to, which is not tied to one language.
|
|
55
|
+
*/
|
|
56
|
+
export declare type CodometerCommentLanguage = "css" | "hcl" | "python" | "shell" | "sql" | "toml" | "typescript" | "yaml";
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* One comment measured against the limit its kind carries.
|
|
60
|
+
*
|
|
61
|
+
* Shared by every analyzer that measures comment length, so a JSDoc block and
|
|
62
|
+
* a YAML comment block reach the report through one channel and render with
|
|
63
|
+
* one line of markdown. `kind` is a plain string for that reason: a symbol
|
|
64
|
+
* kind and a comment kind are both written into it, and narrowing it here
|
|
65
|
+
* would make the union the property of whichever analyzer was added first.
|
|
66
|
+
*/
|
|
67
|
+
export declare interface CodometerCommentMeasurement {
|
|
68
|
+
breached: boolean;
|
|
69
|
+
/** What the comment documents: a declaration's name, or the comment itself. */
|
|
70
|
+
declaration: string;
|
|
71
|
+
file: string;
|
|
72
|
+
kind: string;
|
|
73
|
+
limit: number;
|
|
74
|
+
/** 1-indexed line the measured thing starts on. */
|
|
75
|
+
line: number;
|
|
76
|
+
measured: number;
|
|
77
|
+
severity: CodometerSeverity;
|
|
78
|
+
unit: CodometerDocumentationUnit;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Selects a comment budget for a `CodometerCustomStatistic` to measure.
|
|
83
|
+
*
|
|
84
|
+
* A matching custom statistic's `value` counts the blocks that broke this
|
|
85
|
+
* selector's own maxima, and its `instances` names each one's file and line.
|
|
86
|
+
* No selector inherits from another: a general budget and a narrower
|
|
87
|
+
* exception are both written out in full, rather than one merging over the
|
|
88
|
+
* other.
|
|
89
|
+
*
|
|
90
|
+
* Omitting `language` applies the budget to every language that has comments.
|
|
91
|
+
* Naming `kind` narrows the budget to a documented declaration's JSDoc-style
|
|
92
|
+
* comment for that kind, rather than a plain comment block.
|
|
93
|
+
*/
|
|
94
|
+
export declare interface CodometerCommentSelector {
|
|
95
|
+
kind?: CodometerSymbolKind | undefined;
|
|
96
|
+
language?: CodometerCommentLanguage | undefined;
|
|
97
|
+
/** How many characters a block may hold, markers and newlines and all. */
|
|
98
|
+
maximumCharacters?: number | undefined;
|
|
99
|
+
/** How many lines a block may span. */
|
|
100
|
+
maximumLines?: number | undefined;
|
|
101
|
+
/** How many words of prose a block may hold, once markers are stripped. */
|
|
102
|
+
maximumWords?: number | undefined;
|
|
103
|
+
/** How loudly a breach is reported. Defaults to `fail`, as limits do. */
|
|
104
|
+
severity?: CodometerSeverity | undefined;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* How a target's files are compressed before size analysis counts them.
|
|
109
|
+
*
|
|
110
|
+
* `none` reports the bytes on disk. Named explicitly rather than inferred from
|
|
111
|
+
* which options are absent, because a compression nobody chose is a byte count
|
|
112
|
+
* nobody can explain.
|
|
113
|
+
*/
|
|
114
|
+
export declare type CodometerCompression = "brotli" | "gzip" | "none";
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Configuration authored in a `codometer.config.ts` file.
|
|
118
|
+
*
|
|
119
|
+
* Every field but `format` is optional, so a repository can leave its
|
|
120
|
+
* exclusions and output destinations unwritten until it has decided what they
|
|
121
|
+
* should be. `format` is the one thing every run must be told, and there is no
|
|
122
|
+
* built-in fallback for it — so a directory with no configuration file
|
|
123
|
+
* anywhere above it does not measure at all: it fails on the missing `format`
|
|
124
|
+
* exactly as a file that forgot to write one does. A shared default object,
|
|
125
|
+
* spread by each project's own file, is how a workspace states it once.
|
|
126
|
+
*/
|
|
127
|
+
export declare interface CodometerConfiguration {
|
|
128
|
+
/**
|
|
129
|
+
* Every counter this configuration measures, regardless of where — or
|
|
130
|
+
* whether — any of them is rendered.
|
|
131
|
+
*
|
|
132
|
+
* Declaring a counter here is what measures it; an `outputs[].custom` entry
|
|
133
|
+
* then only *selects* which of these labels that destination renders. A
|
|
134
|
+
* label an output selects that is not declared here is refused: selection
|
|
135
|
+
* cannot conjure a counter that was never measured.
|
|
136
|
+
*/
|
|
137
|
+
custom?: CodometerCustomStatistic[] | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Input an unqualified limit's metric path belongs to.
|
|
140
|
+
*
|
|
141
|
+
* A limit addresses its metric by input name followed by metric path.
|
|
142
|
+
* Naming a default lets the input that dominates a repository's limits go
|
|
143
|
+
* unwritten, leaving `typescript.interfaces` where every line would
|
|
144
|
+
* otherwise repeat the same input name. A path that could be read either
|
|
145
|
+
* way is rejected rather than resolved, so the shorthand can never bind
|
|
146
|
+
* somewhere unintended.
|
|
147
|
+
*/
|
|
148
|
+
defaultInput?: string | undefined;
|
|
149
|
+
exclude?: string[] | undefined;
|
|
150
|
+
/**
|
|
151
|
+
* Ignore files, in gitignore syntax, whose patterns also exclude files.
|
|
152
|
+
*
|
|
153
|
+
* For the committed-but-generated files no glob list should have to restate —
|
|
154
|
+
* lockfiles, vendored bundles, anything a repository already tells its other
|
|
155
|
+
* tools to skip. Files the repository's own `.gitignore` claims need no
|
|
156
|
+
* mention at all: discovery reads those files itself.
|
|
157
|
+
*/
|
|
158
|
+
excludeFrom?: string[] | undefined;
|
|
159
|
+
/**
|
|
160
|
+
* Which report shape a run produces.
|
|
161
|
+
*
|
|
162
|
+
* Required, with no code-level fallback: a shared default object — spread
|
|
163
|
+
* by every project's own `codometer.config.ts` — is what sets it once for a
|
|
164
|
+
* workspace, and a configuration reaching neither it nor its own value
|
|
165
|
+
* fails to resolve rather than silently picking one.
|
|
166
|
+
*/
|
|
167
|
+
format: CodometerFormat;
|
|
168
|
+
/**
|
|
169
|
+
* Named sets of files measured alongside — or instead of — the codebase.
|
|
170
|
+
*
|
|
171
|
+
* A built-in entry named `codebase` — the whole-tree scan, running the
|
|
172
|
+
* `language` analysis — is always present unless this array declares an
|
|
173
|
+
* entry of its own by that name, which replaces it outright. A
|
|
174
|
+
* configuration declaring no `inputs` at all gets exactly that built-in
|
|
175
|
+
* entry and nothing else, which is today's implicit whole-tree behavior.
|
|
176
|
+
*/
|
|
177
|
+
inputs?: CodometerInput[] | undefined;
|
|
178
|
+
/**
|
|
179
|
+
* How high each measured metric may go.
|
|
180
|
+
*
|
|
181
|
+
* A metric nothing here names is measured and reported like every other one,
|
|
182
|
+
* and gated by nothing.
|
|
183
|
+
*/
|
|
184
|
+
limits?: CodometerLimit[] | undefined;
|
|
185
|
+
/**
|
|
186
|
+
* Destinations the measured statistics are written to.
|
|
187
|
+
*
|
|
188
|
+
* An array of typed entries rather than a fixed-key object, so each entry
|
|
189
|
+
* carries its own `custom` counters independently of every other one.
|
|
190
|
+
*
|
|
191
|
+
* At most one entry per `type`: a second entry of a kind is refused rather
|
|
192
|
+
* than silently ignored, because `--output-json [path]` and
|
|
193
|
+
* `--output-markdown [path]` each name one path, so nothing on the command
|
|
194
|
+
* line could ever address a second destination of the same kind.
|
|
195
|
+
*/
|
|
196
|
+
outputs?: CodometerOutput[] | undefined;
|
|
197
|
+
python?: CodometerPythonConfiguration | undefined;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Validates a configuration file's contents.
|
|
202
|
+
*
|
|
203
|
+
* Zod strips unknown keys rather than rejecting them, so a configuration
|
|
204
|
+
* written for a newer codometer still loads under an older one instead of
|
|
205
|
+
* failing on a field it has no opinion about. That is also what makes a
|
|
206
|
+
* removed field — `comments`, `documentation`, a per-language override —
|
|
207
|
+
* silently absent from the resolved configuration rather than a validation
|
|
208
|
+
* error.
|
|
209
|
+
*/
|
|
210
|
+
export declare const codometerConfigurationSchema: z.ZodObject<{
|
|
211
|
+
custom: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
212
|
+
color: z.ZodOptional<z.ZodString>;
|
|
213
|
+
comment: z.ZodOptional<z.ZodObject<{
|
|
214
|
+
kind: z.ZodOptional<z.ZodEnum<{
|
|
215
|
+
function: "function";
|
|
216
|
+
class: "class";
|
|
217
|
+
enum: "enum";
|
|
218
|
+
getter: "getter";
|
|
219
|
+
interface: "interface";
|
|
220
|
+
method: "method";
|
|
221
|
+
property: "property";
|
|
222
|
+
setter: "setter";
|
|
223
|
+
}>>;
|
|
224
|
+
language: z.ZodOptional<z.ZodEnum<{
|
|
225
|
+
css: "css";
|
|
226
|
+
hcl: "hcl";
|
|
227
|
+
python: "python";
|
|
228
|
+
shell: "shell";
|
|
229
|
+
sql: "sql";
|
|
230
|
+
toml: "toml";
|
|
231
|
+
typescript: "typescript";
|
|
232
|
+
yaml: "yaml";
|
|
233
|
+
}>>;
|
|
234
|
+
maximumCharacters: z.ZodOptional<z.ZodNumber>;
|
|
235
|
+
maximumLines: z.ZodOptional<z.ZodNumber>;
|
|
236
|
+
maximumWords: z.ZodOptional<z.ZodNumber>;
|
|
237
|
+
severity: z.ZodOptional<z.ZodEnum<{
|
|
238
|
+
fail: "fail";
|
|
239
|
+
warn: "warn";
|
|
240
|
+
}>>;
|
|
241
|
+
}, z.core.$strip>>;
|
|
242
|
+
group: z.ZodOptional<z.ZodEnum<{
|
|
243
|
+
json: "json";
|
|
244
|
+
markdown: "markdown";
|
|
245
|
+
conventions: "conventions";
|
|
246
|
+
css: "css";
|
|
247
|
+
hcl: "hcl";
|
|
248
|
+
jupyter: "jupyter";
|
|
249
|
+
python: "python";
|
|
250
|
+
repository: "repository";
|
|
251
|
+
shell: "shell";
|
|
252
|
+
sql: "sql";
|
|
253
|
+
toml: "toml";
|
|
254
|
+
typescript: "typescript";
|
|
255
|
+
yaml: "yaml";
|
|
256
|
+
}>>;
|
|
257
|
+
label: z.ZodString;
|
|
258
|
+
patterns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
259
|
+
symbols: z.ZodOptional<z.ZodObject<{
|
|
260
|
+
kinds: z.ZodArray<z.ZodEnum<{
|
|
261
|
+
function: "function";
|
|
262
|
+
class: "class";
|
|
263
|
+
enum: "enum";
|
|
264
|
+
getter: "getter";
|
|
265
|
+
interface: "interface";
|
|
266
|
+
method: "method";
|
|
267
|
+
property: "property";
|
|
268
|
+
setter: "setter";
|
|
269
|
+
}>>;
|
|
270
|
+
modifiers: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
271
|
+
abstract: "abstract";
|
|
272
|
+
async: "async";
|
|
273
|
+
export: "export";
|
|
274
|
+
override: "override";
|
|
275
|
+
private: "private";
|
|
276
|
+
protected: "protected";
|
|
277
|
+
public: "public";
|
|
278
|
+
readonly: "readonly";
|
|
279
|
+
static: "static";
|
|
280
|
+
}>>>;
|
|
281
|
+
}, z.core.$strip>>;
|
|
282
|
+
}, z.core.$strip>>>;
|
|
283
|
+
defaultInput: z.ZodOptional<z.ZodString>;
|
|
284
|
+
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
285
|
+
excludeFrom: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
286
|
+
format: z.ZodEnum<{
|
|
287
|
+
json: "json";
|
|
288
|
+
markdown: "markdown";
|
|
289
|
+
}>;
|
|
290
|
+
inputs: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
291
|
+
analyses: z.ZodArray<z.ZodEnum<{
|
|
292
|
+
language: "language";
|
|
293
|
+
size: "size";
|
|
294
|
+
}>>;
|
|
295
|
+
compression: z.ZodOptional<z.ZodEnum<{
|
|
296
|
+
brotli: "brotli";
|
|
297
|
+
gzip: "gzip";
|
|
298
|
+
none: "none";
|
|
299
|
+
}>>;
|
|
300
|
+
directory: z.ZodOptional<z.ZodString>;
|
|
301
|
+
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
302
|
+
include: z.ZodArray<z.ZodString>;
|
|
303
|
+
name: z.ZodString;
|
|
304
|
+
}, z.core.$strip>>>;
|
|
305
|
+
limits: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
306
|
+
label: z.ZodOptional<z.ZodString>;
|
|
307
|
+
metric: z.ZodString;
|
|
308
|
+
severity: z.ZodOptional<z.ZodEnum<{
|
|
309
|
+
fail: "fail";
|
|
310
|
+
warn: "warn";
|
|
311
|
+
}>>;
|
|
312
|
+
value: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
|
|
313
|
+
}, z.core.$strip>>>;
|
|
314
|
+
outputs: z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
315
|
+
custom: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
316
|
+
indentation: z.ZodOptional<z.ZodNumber>;
|
|
317
|
+
path: z.ZodString;
|
|
318
|
+
type: z.ZodLiteral<"json">;
|
|
319
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
320
|
+
custom: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
321
|
+
description: z.ZodOptional<z.ZodString>;
|
|
322
|
+
endMarker: z.ZodOptional<z.ZodString>;
|
|
323
|
+
path: z.ZodOptional<z.ZodString>;
|
|
324
|
+
startMarker: z.ZodOptional<z.ZodString>;
|
|
325
|
+
type: z.ZodLiteral<"markdown">;
|
|
326
|
+
write: z.ZodOptional<z.ZodType<WriteMarkdownOutput, unknown, z.core.$ZodTypeInternals<WriteMarkdownOutput, unknown>>>;
|
|
327
|
+
}, z.core.$strip>]>>>;
|
|
328
|
+
python: z.ZodOptional<z.ZodObject<{
|
|
329
|
+
command: z.ZodOptional<z.ZodString>;
|
|
330
|
+
}, z.core.$strip>>;
|
|
331
|
+
}, z.core.$strip>;
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* One configured counter.
|
|
335
|
+
*
|
|
336
|
+
* A counter measures one of three things. With `patterns` alone it counts
|
|
337
|
+
* *files* whose repository-relative path matches at least one glob. With
|
|
338
|
+
* `symbols` it counts *declarations* in TypeScript and JavaScript sources
|
|
339
|
+
* matching the AST criteria, and `patterns` then narrows which files are
|
|
340
|
+
* searched rather than being what is counted. With `comment` it counts
|
|
341
|
+
* *comment blocks* that broke the selector's own budget, instead of files or
|
|
342
|
+
* declarations.
|
|
343
|
+
*
|
|
344
|
+
* Either way a match is counted once, however many patterns claim it.
|
|
345
|
+
*/
|
|
346
|
+
export declare interface CodometerCustomStatistic {
|
|
347
|
+
/** Badge color, as a shields.io hexadecimal triplet. */
|
|
348
|
+
color?: string | undefined;
|
|
349
|
+
comment?: CodometerCommentSelector | undefined;
|
|
350
|
+
/**
|
|
351
|
+
* Which badge group the counter is rendered into.
|
|
352
|
+
*
|
|
353
|
+
* Defaults to `conventions`, the group that exists for these counters and
|
|
354
|
+
* is omitted entirely when none are configured. Naming a language group
|
|
355
|
+
* instead puts the badge beside the built-in counters it belongs with.
|
|
356
|
+
*/
|
|
357
|
+
group?: CodometerStatisticGroup | undefined;
|
|
358
|
+
label: string;
|
|
359
|
+
patterns?: string[] | undefined;
|
|
360
|
+
symbols?: CodometerSymbolMatcher | undefined;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/** Unit a documentation length is measured in. */
|
|
364
|
+
export declare type CodometerDocumentationUnit = "characters" | "lines" | "words";
|
|
365
|
+
|
|
366
|
+
/** Which report shape a run produces. */
|
|
367
|
+
export declare type CodometerFormat = "json" | "markdown";
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* A named set of files, declared by include and exclude globs.
|
|
371
|
+
*
|
|
372
|
+
* Globs are relative to `directory`, which itself is relative to the
|
|
373
|
+
* process's working directory — not to the configuration file's own
|
|
374
|
+
* directory — and a leading `!` on an include glob excludes instead of
|
|
375
|
+
* including. Negations are collected rather than applied in order, so moving
|
|
376
|
+
* one within the array cannot change which files the input holds.
|
|
377
|
+
*
|
|
378
|
+
* Ignore files are not consulted, except for the entry named `codebase`,
|
|
379
|
+
* whose files are every one the repository's ignore files leave behind
|
|
380
|
+
* rather than a glob match. An entry declared under that name replaces the
|
|
381
|
+
* built-in one, which is what lets a repository measure the whole tree under
|
|
382
|
+
* a compression or a different set of analyses — but only its `compression`
|
|
383
|
+
* and `analyses` are read. Its `include` and `exclude` globs are not
|
|
384
|
+
* consulted at all, because the whole-tree scan is discovered by ignore-file
|
|
385
|
+
* walking rather than by matching globs; to measure a subset of the tree,
|
|
386
|
+
* declare an input under some other name.
|
|
387
|
+
*/
|
|
388
|
+
export declare interface CodometerInput {
|
|
389
|
+
/** Which analyses run over the matched files. At least one. */
|
|
390
|
+
analyses: CodometerAnalysis[];
|
|
391
|
+
compression?: CodometerCompression | undefined;
|
|
392
|
+
/**
|
|
393
|
+
* Where the input's globs start, relative to the process's working
|
|
394
|
+
* directory.
|
|
395
|
+
*
|
|
396
|
+
* Defaults to the working directory itself. A repository that builds into
|
|
397
|
+
* one tree while measuring a project in another names the way out here —
|
|
398
|
+
* `"../.."` for a project two levels down from a workspace-level `dist` —
|
|
399
|
+
* so that codometer never has to know a build output convention to find the
|
|
400
|
+
* files an input claims.
|
|
401
|
+
*/
|
|
402
|
+
directory?: string | undefined;
|
|
403
|
+
exclude?: string[] | undefined;
|
|
404
|
+
include: string[];
|
|
405
|
+
name: string;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Where and how the JSON statistics report is written.
|
|
410
|
+
*
|
|
411
|
+
* `custom` selects, by label, which of the top-level `custom` counters this
|
|
412
|
+
* destination renders — independently of any other output's own selection.
|
|
413
|
+
* Selecting a label the top level never declared is refused.
|
|
414
|
+
*/
|
|
415
|
+
export declare interface CodometerJsonOutput {
|
|
416
|
+
custom?: string[] | undefined;
|
|
417
|
+
indentation?: number | undefined;
|
|
418
|
+
path: string;
|
|
419
|
+
type: "json";
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* How high one measured metric may go.
|
|
424
|
+
*
|
|
425
|
+
* Limits are absolute: the metric is compared against `value` and nothing
|
|
426
|
+
* else, with no baseline and no floor. A metric that stays under its limit is
|
|
427
|
+
* reported the same way it would be without one.
|
|
428
|
+
*/
|
|
429
|
+
export declare interface CodometerLimit {
|
|
430
|
+
/** What to call the limit in a report, when the path itself reads poorly. */
|
|
431
|
+
label?: string | undefined;
|
|
432
|
+
/**
|
|
433
|
+
* The metric this limits, as a dotted path.
|
|
434
|
+
*
|
|
435
|
+
* Written as the input's name followed by the metric's path within it —
|
|
436
|
+
* `codebase.typescript.interfaces`, `codebase.markdown.files`, or
|
|
437
|
+
* `Compiled JavaScript.size`. With a `defaultInput` configured, a path
|
|
438
|
+
* naming no input is read as that input's. A path that resolves to more
|
|
439
|
+
* than one metric, or to none, fails the run rather than binding to
|
|
440
|
+
* whichever came first.
|
|
441
|
+
*/
|
|
442
|
+
metric: string;
|
|
443
|
+
/**
|
|
444
|
+
* How loudly a breach is reported. Defaults to `fail`.
|
|
445
|
+
*
|
|
446
|
+
* Defaulted to the strict one on purpose: a limit exists to gate, and one
|
|
447
|
+
* that quietly warned because nobody said otherwise would be a gate in name
|
|
448
|
+
* only.
|
|
449
|
+
*/
|
|
450
|
+
severity?: CodometerSeverity | undefined;
|
|
451
|
+
/**
|
|
452
|
+
* How high the metric may go, as a number or a string carrying a unit.
|
|
453
|
+
*
|
|
454
|
+
* Units are decimal and their trailing `b` is required: `"8 KB"` is 8000 and
|
|
455
|
+
* `"1 MB"` is 1000000, while `"8 K"` is not a size and is rejected. A value
|
|
456
|
+
* nothing can read fails the run rather than being taken as zero, which
|
|
457
|
+
* would gate every metric at nothing.
|
|
458
|
+
*/
|
|
459
|
+
value: number | string;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Where and how the markdown report is written.
|
|
464
|
+
*
|
|
465
|
+
* `write` is the whole of the customizable behavior: it turns the measured
|
|
466
|
+
* statistics into markdown and decides which file that markdown lands in and
|
|
467
|
+
* how, replacing what used to be two separate callbacks. Leaving it unset
|
|
468
|
+
* keeps the built-in rendering and writing.
|
|
469
|
+
*
|
|
470
|
+
* `path` is optional because a `write` function may choose the file itself —
|
|
471
|
+
* but one of the two must be present, or there is no markdown output at all.
|
|
472
|
+
* `custom` selects, by label, which of the top-level `custom` counters this
|
|
473
|
+
* destination renders — independently of any other output's own selection.
|
|
474
|
+
* Selecting a label the top level never declared is refused.
|
|
475
|
+
*/
|
|
476
|
+
export declare interface CodometerMarkdownOutput {
|
|
477
|
+
custom?: string[] | undefined;
|
|
478
|
+
description?: string | undefined;
|
|
479
|
+
endMarker?: string | undefined;
|
|
480
|
+
path?: string | undefined;
|
|
481
|
+
startMarker?: string | undefined;
|
|
482
|
+
type: "markdown";
|
|
483
|
+
write?: undefined | WriteMarkdownOutput;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/** Destination the measured statistics are written to, one report shape each. */
|
|
487
|
+
export declare type CodometerOutput = CodometerJsonOutput | CodometerMarkdownOutput;
|
|
488
|
+
|
|
489
|
+
/** How Python sources are analyzed. */
|
|
490
|
+
export declare interface CodometerPythonConfiguration {
|
|
491
|
+
command?: string | undefined;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Which TypeScript and JavaScript declarations a counter claims.
|
|
496
|
+
*
|
|
497
|
+
* A declaration counts when its kind is one of `kinds` and it carries every
|
|
498
|
+
* modifier in `modifiers`. An empty or absent `modifiers` asks for the kind
|
|
499
|
+
* alone.
|
|
500
|
+
*/
|
|
501
|
+
export declare interface CodometerSymbolMatcher {
|
|
502
|
+
kinds: CodometerSymbolKind[];
|
|
503
|
+
modifiers?: CodometerSymbolModifier[] | undefined;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* File names searched for when no configuration path is given.
|
|
508
|
+
*
|
|
509
|
+
* Searched in order, so a repository carrying both a TypeScript and a JSON
|
|
510
|
+
* configuration file gets the TypeScript one — the richer format, and the one
|
|
511
|
+
* a type-checked configuration was written in.
|
|
512
|
+
*/
|
|
513
|
+
export declare const CONFIGURATION_FILE_NAMES: readonly ["codometer.config.ts", "codometer.config.mts", "codometer.config.cts", "codometer.config.js", "codometer.config.mjs", "codometer.config.cjs", "codometer.config.json", "codometer.config.jsonc"];
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Reads the command line `ConfigurationService` answers a run from.
|
|
517
|
+
*
|
|
518
|
+
* Not exported. The configuration layer has one public entry point, and this
|
|
519
|
+
* is the half of it that reads flags rather than files.
|
|
520
|
+
*
|
|
521
|
+
* `codometer`, `changes` and `configuration` share the rules for the flags
|
|
522
|
+
* they hold in common, and those rules are subtle enough to be worth stating
|
|
523
|
+
* once: commander hands a valueless flag through as `true` without ever
|
|
524
|
+
* calling its parser, so a command that narrows text and one that does not
|
|
525
|
+
* disagree about what `--flag "$UNSET"` meant. A flag only one command takes
|
|
526
|
+
* keeps its own parser.
|
|
527
|
+
*/
|
|
528
|
+
declare class ConfigurationFlagsService {
|
|
529
|
+
constructor();
|
|
530
|
+
/** States what `--check` accepts, in front of whatever went wrong. */
|
|
531
|
+
private describeAcceptedCheckNames;
|
|
532
|
+
/**
|
|
533
|
+
* Reads the `--check` value into the set of things the run fails on.
|
|
534
|
+
*
|
|
535
|
+
* A flag passed without a value arrives as `true` and is a mistake rather
|
|
536
|
+
* than a shorthand: it used to mean "check everything", and a set with
|
|
537
|
+
* nothing in it looks exactly like the flag having been left off.
|
|
538
|
+
*/
|
|
539
|
+
private readCheckNames;
|
|
540
|
+
/** Keeps the names `--check` knows and complains about the rest. */
|
|
541
|
+
private validateCheckNames;
|
|
542
|
+
/**
|
|
543
|
+
* Reads an option that carries a default when it was left off.
|
|
544
|
+
*
|
|
545
|
+
* The fallback belongs to the command rather than here: two commands that
|
|
546
|
+
* share the parsing rule for `--format` need not share what they render
|
|
547
|
+
* when nobody said.
|
|
548
|
+
*/
|
|
549
|
+
parseDefaultedOption(value: unknown, fallback: string): string;
|
|
550
|
+
/**
|
|
551
|
+
* Reads a directory option, falling back to the working directory.
|
|
552
|
+
*
|
|
553
|
+
* The fallback is the process's working directory as it stands when the
|
|
554
|
+
* option is read, which is what every command means by "here" — no command
|
|
555
|
+
* changes it mid-run, and one that did would want the new one.
|
|
556
|
+
*/
|
|
557
|
+
parseDirectoryOption(value: unknown): string;
|
|
558
|
+
/**
|
|
559
|
+
* Reads an option that carries text, or nothing at all.
|
|
560
|
+
*
|
|
561
|
+
* A flag written `--baseline-url "$EMPTY"` can reach commander with no
|
|
562
|
+
* value at all, which it reports as `true` without calling the option's
|
|
563
|
+
* parser. So anything but a non-empty string counts as absent — passing
|
|
564
|
+
* that boolean through renders a link to the word `true`.
|
|
565
|
+
*
|
|
566
|
+
* Deliberately does not trim, unlike `callidescope`'s same-named method: a
|
|
567
|
+
* codometer option is a path, and a path whose surrounding spaces were
|
|
568
|
+
* silently dropped is a different path from the one that was asked for.
|
|
569
|
+
*/
|
|
570
|
+
parseOptionalOption(value: unknown): string | undefined;
|
|
571
|
+
/**
|
|
572
|
+
* Reads `--format` into what the run prints, falling back to the resolved
|
|
573
|
+
* configuration's own `format` when the flag was left off.
|
|
574
|
+
*
|
|
575
|
+
* The fallback never infers from which other flags are present — omitting
|
|
576
|
+
* `--format` always reads the same value the configuration declares,
|
|
577
|
+
* whether or not this run also writes a file.
|
|
578
|
+
*/
|
|
579
|
+
resolveFormat(value: string | undefined, configuredFormat: CodometerFormat, errors: string[]): MeasureFormat | undefined;
|
|
580
|
+
/**
|
|
581
|
+
* Reads the flags into what the run writes and what it fails on.
|
|
582
|
+
*
|
|
583
|
+
* Writing is answered per output, by whether that output's own
|
|
584
|
+
* `--output-*` flag was passed at all. `--output-json`/`--output-markdown`
|
|
585
|
+
* together with `--check reports` is refused rather than obeyed: nothing
|
|
586
|
+
* can be stale immediately after being written, so a run asking for both on
|
|
587
|
+
* the same output has misunderstood one of them and would silently compare
|
|
588
|
+
* instead of writing.
|
|
589
|
+
*/
|
|
590
|
+
selectMode(options: MeasureCommandOptions): ModeSelection;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Finds and reads a codometer configuration file.
|
|
595
|
+
*
|
|
596
|
+
* Owns locating the file and turning whatever it exports into a plain,
|
|
597
|
+
* unvalidated configuration object — parsing JSON/JSONC by hand, everything
|
|
598
|
+
* else through `jiti`. What the object means is `ConfigurationService`'s to
|
|
599
|
+
* validate and resolve, kept apart so a file finding no configuration reads
|
|
600
|
+
* exactly like one that found an empty object.
|
|
601
|
+
*/
|
|
602
|
+
declare class ConfigurationLoaderService {
|
|
603
|
+
constructor();
|
|
604
|
+
/**
|
|
605
|
+
* Walks upward from a directory looking for a configuration file.
|
|
606
|
+
*
|
|
607
|
+
* Returns `undefined` when the search reaches the filesystem root without
|
|
608
|
+
* finding one: a repository that never wrote a configuration file is
|
|
609
|
+
* measured with the defaults rather than told to write one.
|
|
610
|
+
*/
|
|
611
|
+
private findConfigurationFile;
|
|
612
|
+
/**
|
|
613
|
+
* Walks upward from the process cwd looking for the repository root.
|
|
614
|
+
*
|
|
615
|
+
* Used to resolve a configuration path given relative to that root even when
|
|
616
|
+
* the command was invoked from a nested directory, which is what a task
|
|
617
|
+
* runner does whenever it sets the cwd to the project rather than the
|
|
618
|
+
* workspace.
|
|
619
|
+
*/
|
|
620
|
+
private findRepositoryRoot;
|
|
621
|
+
/** Loads a configuration module, choosing the reader by extension. */
|
|
622
|
+
private loadConfigurationModule;
|
|
623
|
+
/** Reads a JSON or JSONC configuration file. */
|
|
624
|
+
private loadJsonConfiguration;
|
|
625
|
+
/**
|
|
626
|
+
* Reads what a configuration module exported, through either interop shape.
|
|
627
|
+
*
|
|
628
|
+
* Anything that is not a plain object — including a function, since a
|
|
629
|
+
* configuration file authored as one is no longer supported — falls back to
|
|
630
|
+
* an empty object, the same way a configuration file exporting `42` does:
|
|
631
|
+
* the schema then applies to that empty object exactly as it would to a
|
|
632
|
+
* genuinely empty configuration file.
|
|
633
|
+
*/
|
|
634
|
+
private readDefaultExport;
|
|
635
|
+
/**
|
|
636
|
+
* Resolves a configuration path against the cwd, then the repository root.
|
|
637
|
+
*/
|
|
638
|
+
private resolveConfigurationPath;
|
|
639
|
+
/**
|
|
640
|
+
* Loads a configuration file's raw export, or `undefined` when none exists.
|
|
641
|
+
*
|
|
642
|
+
* Unvalidated on purpose: the caller runs the result through the schema
|
|
643
|
+
* before trusting any of it, so this service never has to know the shape a
|
|
644
|
+
* configuration is supposed to have.
|
|
645
|
+
*/
|
|
646
|
+
load(args?: LoadConfigurationArguments): Promise<LoadedConfigurationModule | undefined>;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Provides the configuration layer's one public service.
|
|
651
|
+
*
|
|
652
|
+
* `ConfigurationLoaderService`, `ConfigurationResolverService` and
|
|
653
|
+
* `ConfigurationFlagsService` are providers rather than exports: they are how
|
|
654
|
+
* `ConfigurationService` finds a file, fills it in, and reads the command line
|
|
655
|
+
* beside it, and nothing outside this package injects any of them.
|
|
656
|
+
*/
|
|
657
|
+
export declare class ConfigurationModule {
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Fills a validated configuration in, field by field, with what it left out.
|
|
662
|
+
*
|
|
663
|
+
* Not exported from this package. The configuration layer has exactly one
|
|
664
|
+
* public entry point, and this is the half of it that turns a file's contents
|
|
665
|
+
* into the resolved object every analyzer reads — held apart from
|
|
666
|
+
* `ConfigurationService` so that class states what the layer answers rather
|
|
667
|
+
* than how each default is arrived at.
|
|
668
|
+
*/
|
|
669
|
+
declare class ConfigurationResolverService {
|
|
670
|
+
constructor();
|
|
671
|
+
/**
|
|
672
|
+
* Validates a configuration object, refusing it in prose rather than in JSON.
|
|
673
|
+
*
|
|
674
|
+
* Every load goes through here — a file's contents and the empty object a
|
|
675
|
+
* directory with no configuration file stands in with alike — so the two
|
|
676
|
+
* fail identically and a reader gets the same sentence either way.
|
|
677
|
+
*/
|
|
678
|
+
private parseConfigurationInternal;
|
|
679
|
+
/**
|
|
680
|
+
* Reads a limit's value, in decimal units when it was written as a string.
|
|
681
|
+
*
|
|
682
|
+
* Everything unreadable is refused: a negative number, a unit missing its
|
|
683
|
+
* `b`, a word, an empty string. The tool this replaces coerced an unreadable
|
|
684
|
+
* limit to nothing and then failed every target holding a single byte.
|
|
685
|
+
*/
|
|
686
|
+
private parseLimitValue;
|
|
687
|
+
/**
|
|
688
|
+
* Reads a limit written as a string, unit and all.
|
|
689
|
+
*
|
|
690
|
+
* A unit multiplies and then rounds: `"1.5 KB"` is 1500, and the rounding is
|
|
691
|
+
* what keeps `"0.1 KB"` from arriving as the 100.00000000000001 floating
|
|
692
|
+
* point makes of it. A string carrying no unit at all is the plain number,
|
|
693
|
+
* which is what a limit on a count of interfaces or files is written as.
|
|
694
|
+
*/
|
|
695
|
+
private parseLimitValueText;
|
|
696
|
+
/**
|
|
697
|
+
* Gives every configured counter a color and a group, and its `comment`
|
|
698
|
+
* selector a severity.
|
|
699
|
+
*
|
|
700
|
+
* Colors are handed out by position within a group rather than within the
|
|
701
|
+
* whole list, so adding a counter to one group does not recolor the badges
|
|
702
|
+
* of another — which would rewrite a report that had not otherwise changed.
|
|
703
|
+
* A `comment` selector's own defaulting is inlined here rather than given
|
|
704
|
+
* its own method: this list already runs one call deep inside
|
|
705
|
+
* `resolveConfiguration`, and a further call would push the whole chain
|
|
706
|
+
* past what this package's callidescope gate allows.
|
|
707
|
+
*
|
|
708
|
+
* Runs once, over the top-level `custom` declaration — never per output.
|
|
709
|
+
* An output only selects labels back out of what this resolves, so a
|
|
710
|
+
* counter is never resolved twice just because two outputs both render it.
|
|
711
|
+
*/
|
|
712
|
+
private resolveCustomStatistics;
|
|
713
|
+
/**
|
|
714
|
+
* Fills in every input's compression and directory, and splits its globs
|
|
715
|
+
* into what they add and what they remove.
|
|
716
|
+
*
|
|
717
|
+
* A `!` prefix in `include` is what the tool this replaced used to subtract
|
|
718
|
+
* a file, and there it mattered where in the array it sat. Here the
|
|
719
|
+
* negations join the exclude globs in a single set, so an input holds the
|
|
720
|
+
* same files however its patterns are arranged.
|
|
721
|
+
*/
|
|
722
|
+
private resolveInput;
|
|
723
|
+
/**
|
|
724
|
+
* Resolves every declared input, and the built-in `codebase` one.
|
|
725
|
+
*
|
|
726
|
+
* The built-in entry is prepended unless the configuration already declares
|
|
727
|
+
* one by that name, which replaces it outright — the only way a
|
|
728
|
+
* configuration reaches the built-in whole-tree scan under a compression or
|
|
729
|
+
* a different set of analyses.
|
|
730
|
+
*/
|
|
731
|
+
private resolveInputs;
|
|
732
|
+
/** Applies defaults to one JSON output destination. */
|
|
733
|
+
private resolveJsonOutput;
|
|
734
|
+
/**
|
|
735
|
+
* Gives every limit its severity and a value read as a number.
|
|
736
|
+
*
|
|
737
|
+
* Which metric a limit lands on is decided where the measurement is, since
|
|
738
|
+
* nothing here knows what was measured — the only thing settled at this
|
|
739
|
+
* point is what the limit says.
|
|
740
|
+
*/
|
|
741
|
+
private resolveLimits;
|
|
742
|
+
/** Applies defaults to one markdown output destination. */
|
|
743
|
+
private resolveMarkdownOutput;
|
|
744
|
+
/** Applies defaults to every declared output destination. */
|
|
745
|
+
private resolveOutputs;
|
|
746
|
+
/**
|
|
747
|
+
* Picks out the top-level custom statistics an output's own `custom` array
|
|
748
|
+
* selected, by label.
|
|
749
|
+
*
|
|
750
|
+
* The schema already refuses a label naming no top-level declaration, so a
|
|
751
|
+
* label failing to resolve here is dropped rather than treated as another
|
|
752
|
+
* way to fail: this method's job is the lookup, not re-validating what the
|
|
753
|
+
* schema already guarantees.
|
|
754
|
+
*/
|
|
755
|
+
private selectCustomStatistics;
|
|
756
|
+
/** Validates a configuration object, refusing it in prose rather than in JSON. */
|
|
757
|
+
parseConfiguration(configuration: unknown): CodometerConfiguration;
|
|
758
|
+
/**
|
|
759
|
+
* Fills in every field a configuration file may leave out.
|
|
760
|
+
*
|
|
761
|
+
* Exposed so a host embedding codometer can hand over a configuration object
|
|
762
|
+
* it assembled itself and get the same shape a configuration file produces.
|
|
763
|
+
*/
|
|
764
|
+
resolveConfiguration(configuration: CodometerConfiguration): ResolvedCodometerConfiguration;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/**
|
|
768
|
+
* Answers what a codometer run is configured to do.
|
|
769
|
+
*
|
|
770
|
+
* The configuration layer's one public entry point. The file says what to
|
|
771
|
+
* measure, and the flags beside it say what to do about what was measured;
|
|
772
|
+
* both are answered here, so a command injects this and nothing else from
|
|
773
|
+
* this package.
|
|
774
|
+
*
|
|
775
|
+
* It composes rather than implements. Finding and reading a file is
|
|
776
|
+
* `ConfigurationLoaderService`, filling one in is
|
|
777
|
+
* `ConfigurationResolverService`, and reading a command line is
|
|
778
|
+
* `ConfigurationFlagsService` — three package-internal collaborators, none of
|
|
779
|
+
* them reachable from outside. What the configuration *means* — which files an
|
|
780
|
+
* exclusion glob removes, where a badge block is spliced in — belongs to the
|
|
781
|
+
* analyzers that read it, so that reading a configuration stays free of any
|
|
782
|
+
* knowledge of the repository being measured.
|
|
783
|
+
*/
|
|
784
|
+
export declare class ConfigurationService {
|
|
785
|
+
private readonly configurationLoaderService;
|
|
786
|
+
private readonly configurationResolverService;
|
|
787
|
+
private readonly configurationFlagsService;
|
|
788
|
+
constructor(configurationLoaderService: ConfigurationLoaderService, configurationResolverService: ConfigurationResolverService, configurationFlagsService: ConfigurationFlagsService);
|
|
789
|
+
/**
|
|
790
|
+
* Loads and validates a codometer configuration file.
|
|
791
|
+
*
|
|
792
|
+
* A path that was named explicitly must exist — a typo in a task runner's
|
|
793
|
+
* arguments should fail rather than quietly measure the repository with
|
|
794
|
+
* defaults it never asked for. A path that was not named is searched for
|
|
795
|
+
* from the measured directory upward, and its absence is legal.
|
|
796
|
+
*
|
|
797
|
+
* The nearest configuration file wins outright: nothing from a further
|
|
798
|
+
* ancestor is folded into it. Merging the two would leave a limit that never
|
|
799
|
+
* applied looking exactly like one that did, and the only way to tell them
|
|
800
|
+
* apart would be to know which of several files each field came from.
|
|
801
|
+
*/
|
|
802
|
+
loadConfiguration(args?: LoadConfigurationArguments): Promise<ResolvedCodometerConfiguration>;
|
|
803
|
+
/**
|
|
804
|
+
* Loads a configuration and says which file answered.
|
|
805
|
+
*
|
|
806
|
+
* The same work as `loadConfiguration`, keeping the path the upward walk
|
|
807
|
+
* settled on. A caller measuring one directory has no use for it — the
|
|
808
|
+
* configuration is the whole answer — but one listing what a repository
|
|
809
|
+
* configures has to attribute each answer to the file that gave it, and
|
|
810
|
+
* nothing downstream of the walk can still tell.
|
|
811
|
+
*/
|
|
812
|
+
loadConfigurationFile(args?: LoadConfigurationArguments): Promise<LoadedConfiguration>;
|
|
813
|
+
/** Validates a configuration object, refusing it in prose rather than JSON. */
|
|
814
|
+
parseConfiguration(configuration: unknown): CodometerConfiguration;
|
|
815
|
+
/** Reads an option that carries a default when it was left off. */
|
|
816
|
+
parseDefaultedOption(value: unknown, fallback: string): string;
|
|
817
|
+
/** Reads a directory option, falling back to the working directory. */
|
|
818
|
+
parseDirectoryOption(value: unknown): string;
|
|
819
|
+
/** Reads an option that carries text, or nothing at all. */
|
|
820
|
+
parseOptionalOption(value: unknown): string | undefined;
|
|
821
|
+
/** Fills in every field a configuration file may leave out. */
|
|
822
|
+
resolveConfiguration(configuration: CodometerConfiguration): ResolvedCodometerConfiguration;
|
|
823
|
+
/** Reads `--format` into what the run prints, or the configured format. */
|
|
824
|
+
resolveFormat(value: string | undefined, configuredFormat: CodometerFormat, errors: string[]): MeasureFormat | undefined;
|
|
825
|
+
/** Reads the flags into what the run writes and what it fails on. */
|
|
826
|
+
selectMode(options: MeasureCommandOptions): ModeSelection;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/**
|
|
830
|
+
* The built-in `codebase` input, present unless a configuration's `inputs`
|
|
831
|
+
* names an entry of its own by that name.
|
|
832
|
+
*/
|
|
833
|
+
export declare const DEFAULT_CODEBASE_INPUT: CodometerInput;
|
|
834
|
+
|
|
835
|
+
/**
|
|
836
|
+
* Badge colors handed to configured counters that name none, in order.
|
|
837
|
+
*
|
|
838
|
+
* Cycled rather than exhausted, so a repository can configure as many counters
|
|
839
|
+
* as it likes and each still gets a color that is stable between runs.
|
|
840
|
+
*/
|
|
841
|
+
export declare const DEFAULT_CUSTOM_STATISTIC_COLORS: readonly ["7c3aed", "0284c7", "16a34a", "ea580c", "db2777", "0ea5e9", "059669", "ca8a04"];
|
|
842
|
+
|
|
843
|
+
/** Badge group a configured counter is rendered into when it names none. */
|
|
844
|
+
export declare const DEFAULT_CUSTOM_STATISTIC_GROUP = "conventions";
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* Path globs excluded from measurement when a configuration names none.
|
|
848
|
+
*
|
|
849
|
+
* Only the directories every ecosystem generates. Everything a specific
|
|
850
|
+
* repository considers noise — ingested corpora, generated documentation,
|
|
851
|
+
* scratch notes — belongs in that repository's own configuration file.
|
|
852
|
+
*/
|
|
853
|
+
export declare const DEFAULT_EXCLUDE_GLOBS: readonly ["**/.nx/**", "**/build/**", "**/coverage/**", "**/dist/**", "**/node_modules/**"];
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* Compression applied to an input that names none.
|
|
857
|
+
*
|
|
858
|
+
* Gzip rather than the best available, because a compressed size is only worth
|
|
859
|
+
* measuring against what a server would actually send, and gzip is what every
|
|
860
|
+
* client understands. An input measuring bytes on disk asks for `none`.
|
|
861
|
+
*/
|
|
862
|
+
export declare const DEFAULT_INPUT_COMPRESSION = "gzip";
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* Where an input's globs start when it names no directory of its own.
|
|
866
|
+
*
|
|
867
|
+
* The process's working directory. An input that means to reach outside it
|
|
868
|
+
* says so, which keeps "measure what I was pointed at" the thing that needs
|
|
869
|
+
* no writing down.
|
|
870
|
+
*/
|
|
871
|
+
export declare const DEFAULT_INPUT_DIRECTORY = ".";
|
|
872
|
+
|
|
873
|
+
/**
|
|
874
|
+
* Name of the input every run measures unless a configuration replaces it:
|
|
875
|
+
* the codebase itself.
|
|
876
|
+
*
|
|
877
|
+
* Its files are every one the repository's ignore files leave behind rather
|
|
878
|
+
* than a glob match — `include` here is a placeholder a glob-based reader
|
|
879
|
+
* never consults for this one entry — which is what makes this input
|
|
880
|
+
* different from every other one a configuration declares.
|
|
881
|
+
*/
|
|
882
|
+
export declare const DEFAULT_INPUT_NAME = "codebase";
|
|
883
|
+
|
|
884
|
+
/** Spaces used to indent the JSON report when a configuration names none. */
|
|
885
|
+
export declare const DEFAULT_JSON_INDENTATION = 2;
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* Severity a limit that names none carries.
|
|
889
|
+
*
|
|
890
|
+
* The strict one. A limit is written to gate, so one that quietly warned
|
|
891
|
+
* because nobody spelled out the severity would be a gate in name only —
|
|
892
|
+
* `warn` is the deliberate choice, not the accidental one.
|
|
893
|
+
*/
|
|
894
|
+
export declare const DEFAULT_LIMIT_SEVERITY = "fail";
|
|
895
|
+
|
|
896
|
+
/** Closing marker of the generated badge block. */
|
|
897
|
+
export declare const DEFAULT_MARKDOWN_END_MARKER = "<!-- codometer:end -->";
|
|
898
|
+
|
|
899
|
+
/** Opening marker of the generated badge block. */
|
|
900
|
+
export declare const DEFAULT_MARKDOWN_START_MARKER = "<!-- codometer:start -->";
|
|
901
|
+
|
|
902
|
+
/**
|
|
903
|
+
* Interpreter used for Python analysis when a configuration names none.
|
|
904
|
+
*
|
|
905
|
+
* A repository whose Python lives in a managed environment overrides this with
|
|
906
|
+
* the command that enters it — `uv run python`, `poetry run python`, or the
|
|
907
|
+
* path to a virtual environment's interpreter.
|
|
908
|
+
*/
|
|
909
|
+
export declare const DEFAULT_PYTHON_COMMAND = "python3";
|
|
910
|
+
|
|
911
|
+
/** What `--format json` prints: the report, as a document something can parse. */
|
|
912
|
+
export declare const FORMAT_JSON = "json";
|
|
913
|
+
|
|
914
|
+
/** What `--format markdown` prints: the rendered badge document. */
|
|
915
|
+
export declare const FORMAT_MARKDOWN = "markdown";
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* Everything `--format` accepts, in the order an error message lists them.
|
|
919
|
+
*
|
|
920
|
+
* Named here rather than spelled into each message, so the list a mistake is
|
|
921
|
+
* measured against and the list it is told about can never drift apart. A
|
|
922
|
+
* format added here is accepted everywhere the moment it is rendered.
|
|
923
|
+
*/
|
|
924
|
+
export declare const FORMAT_NAMES: readonly ["json", "markdown"];
|
|
925
|
+
|
|
926
|
+
/** Arguments accepted when loading a configuration file. */
|
|
927
|
+
export declare interface LoadConfigurationArguments {
|
|
928
|
+
configurationPath?: string | undefined;
|
|
929
|
+
searchDirectory?: string | undefined;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
/**
|
|
933
|
+
* A resolved configuration and the file it was resolved from.
|
|
934
|
+
*
|
|
935
|
+
* `path` stays `undefined` when the upward walk reached the filesystem root
|
|
936
|
+
* without finding a file, which is legal and leaves every default in place.
|
|
937
|
+
*/
|
|
938
|
+
export declare interface LoadedConfiguration {
|
|
939
|
+
configuration: ResolvedCodometerConfiguration;
|
|
940
|
+
path: string | undefined;
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/** What `ConfigurationLoaderService.load` found, unvalidated. */
|
|
944
|
+
declare interface LoadedConfigurationModule {
|
|
945
|
+
configuration: unknown;
|
|
946
|
+
/**
|
|
947
|
+
* Absolute path of the file it came from.
|
|
948
|
+
*
|
|
949
|
+
* Carried because a caller listing what a repository configures has to say
|
|
950
|
+
* where each answer was written, and the upward walk is the only thing that
|
|
951
|
+
* knows: by the time a configuration is resolved, the file it came from is
|
|
952
|
+
* indistinguishable from one three directories higher.
|
|
953
|
+
*/
|
|
954
|
+
path: string;
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* The anchor mechanics a `write` function would otherwise have to reimplement.
|
|
959
|
+
*
|
|
960
|
+
* Splicing a generated block between two HTML comments is the common case, so
|
|
961
|
+
* it is one call away even for a writer that picks its own file.
|
|
962
|
+
*/
|
|
963
|
+
export declare interface MarkdownAnchorHelpers {
|
|
964
|
+
endMarker: string;
|
|
965
|
+
startMarker: string;
|
|
966
|
+
/**
|
|
967
|
+
* Splices the anchored block into a file, appending it when the markers are
|
|
968
|
+
* absent, and creating the file when it does not exist.
|
|
969
|
+
*
|
|
970
|
+
* In check mode nothing is written and the return value reports whether the
|
|
971
|
+
* file already holds the current block. Defaults to the rendered content and
|
|
972
|
+
* the configured path; pass either to override.
|
|
973
|
+
*/
|
|
974
|
+
syncAnchoredBlock: (overrides?: {
|
|
975
|
+
content?: string | undefined;
|
|
976
|
+
path?: string | undefined;
|
|
977
|
+
}) => boolean;
|
|
978
|
+
/** The content wrapped in the configured markers, ready to place anywhere. */
|
|
979
|
+
wrapInAnchors: (content?: string) => string;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
/**
|
|
983
|
+
* Options accepted by the measure command.
|
|
984
|
+
*
|
|
985
|
+
* `--output-json` and `--output-markdown` are each independent: passing one
|
|
986
|
+
* never implicitly writes the other, and neither implies `--check reports`.
|
|
987
|
+
* There is no `--write` — passing an `--output-*` flag at all is what makes
|
|
988
|
+
* this run produce that destination.
|
|
989
|
+
*/
|
|
990
|
+
export declare interface MeasureCommandOptions {
|
|
991
|
+
/** The comma-separated set of things to fail on, as it was written. */
|
|
992
|
+
check?: string | true | undefined;
|
|
993
|
+
config?: string | undefined;
|
|
994
|
+
/** What to print to standard output, as it was written. */
|
|
995
|
+
format?: string | undefined;
|
|
996
|
+
/**
|
|
997
|
+
* The glob array that replaces every configured input for this run, as
|
|
998
|
+
* written. `undefined` when the flag was never passed at all.
|
|
999
|
+
*/
|
|
1000
|
+
inputs?: string[] | undefined;
|
|
1001
|
+
/**
|
|
1002
|
+
* The report's destination, as it was written.
|
|
1003
|
+
*
|
|
1004
|
+
* `true` for a bare flag naming no path, a string for an explicit one, and
|
|
1005
|
+
* `undefined` when the flag was never passed.
|
|
1006
|
+
*/
|
|
1007
|
+
outputJson?: string | true | undefined;
|
|
1008
|
+
/**
|
|
1009
|
+
* The markdown destination, as it was written.
|
|
1010
|
+
*
|
|
1011
|
+
* `true` for a bare flag naming no path, a string for an explicit one, and
|
|
1012
|
+
* `undefined` when the flag was never passed.
|
|
1013
|
+
*/
|
|
1014
|
+
outputMarkdown?: string | true | undefined;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* What a run prints to standard output, when it prints anything.
|
|
1019
|
+
*
|
|
1020
|
+
* Derived from the list `--format` is validated against, so a format added
|
|
1021
|
+
* there is one this accepts rather than two lists to keep in step.
|
|
1022
|
+
*/
|
|
1023
|
+
export declare type MeasureFormat = (typeof FORMAT_NAMES)[number];
|
|
1024
|
+
|
|
1025
|
+
/**
|
|
1026
|
+
* What a configuration reaching no `format` is told — written out rather than
|
|
1027
|
+
* left as the schema's own "expected one of" line, because it is the first
|
|
1028
|
+
* thing a newcomer to codometer sees.
|
|
1029
|
+
*/
|
|
1030
|
+
export declare const MISSING_FORMAT_MESSAGE = "A codometer configuration must name a `format` of \"json\" or \"markdown\", and nothing supplies one for it. Set it in this file, or spread a shared default object that sets it \u2014 every run has to be told which report shape it produces, and a directory with no configuration file anywhere above it fails here rather than measuring with a format nobody chose.";
|
|
1031
|
+
|
|
1032
|
+
/**
|
|
1033
|
+
* What the command line asked the run to do, and what it could not make sense
|
|
1034
|
+
* of.
|
|
1035
|
+
*
|
|
1036
|
+
* Every complaint is collected before any of them is reported, so a command
|
|
1037
|
+
* line with two mistakes in it is two mistakes to fix rather than two runs.
|
|
1038
|
+
*/
|
|
1039
|
+
export declare interface ModeSelection {
|
|
1040
|
+
errors: string[];
|
|
1041
|
+
mode: RunMode;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* Marks the repository root during an upward search from the process cwd.
|
|
1046
|
+
*
|
|
1047
|
+
* A package manifest is deliberately not one of them: every package in a
|
|
1048
|
+
* monorepo carries one, so the search would stop at the nearest project rather
|
|
1049
|
+
* than the root a configuration path was written relative to.
|
|
1050
|
+
*/
|
|
1051
|
+
export declare const REPOSITORY_ROOT_MARKERS: readonly [".git", "pnpm-workspace.yaml"];
|
|
1052
|
+
|
|
1053
|
+
/** A `comment` selector with its severity filled in. */
|
|
1054
|
+
export declare interface ResolvedCodometerCommentSelector {
|
|
1055
|
+
kind: CodometerSymbolKind | undefined;
|
|
1056
|
+
language: CodometerCommentLanguage | undefined;
|
|
1057
|
+
maximumCharacters: number | undefined;
|
|
1058
|
+
maximumLines: number | undefined;
|
|
1059
|
+
maximumWords: number | undefined;
|
|
1060
|
+
severity: CodometerSeverity;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* Configuration with every default applied.
|
|
1065
|
+
*
|
|
1066
|
+
* Consumers read this shape rather than the authored one, so no analyzer has
|
|
1067
|
+
* to know which fields a configuration file may omit.
|
|
1068
|
+
*/
|
|
1069
|
+
export declare interface ResolvedCodometerConfiguration {
|
|
1070
|
+
/** Every counter this configuration measures, with defaults applied. */
|
|
1071
|
+
custom: ResolvedCodometerCustomStatistic[];
|
|
1072
|
+
/** Stays `undefined` when nothing named one, so every path must qualify. */
|
|
1073
|
+
defaultInput: string | undefined;
|
|
1074
|
+
exclude: string[];
|
|
1075
|
+
excludeFrom: string[];
|
|
1076
|
+
format: CodometerFormat;
|
|
1077
|
+
inputs: ResolvedCodometerInput[];
|
|
1078
|
+
limits: ResolvedCodometerLimit[];
|
|
1079
|
+
outputs: ResolvedCodometerOutput[];
|
|
1080
|
+
python: ResolvedCodometerPythonConfiguration;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
/** A configured counter with its badge color and group filled in. */
|
|
1084
|
+
export declare interface ResolvedCodometerCustomStatistic {
|
|
1085
|
+
color: string;
|
|
1086
|
+
comment: ResolvedCodometerCommentSelector | undefined;
|
|
1087
|
+
group: CodometerStatisticGroup;
|
|
1088
|
+
label: string;
|
|
1089
|
+
/** Empty for a symbol or comment counter naming none, which then searches every file. */
|
|
1090
|
+
patterns: string[];
|
|
1091
|
+
symbols?: CodometerSymbolMatcher | undefined;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
/**
|
|
1095
|
+
* A named set of files with its compression filled in and its negations
|
|
1096
|
+
* collected.
|
|
1097
|
+
*
|
|
1098
|
+
* `include` holds only patterns that add files and `exclude` only patterns
|
|
1099
|
+
* that remove them, whichever list they were authored in. Order carries no
|
|
1100
|
+
* meaning in either: a file is in the input when some include glob claims it
|
|
1101
|
+
* and no exclude glob does.
|
|
1102
|
+
*/
|
|
1103
|
+
export declare interface ResolvedCodometerInput {
|
|
1104
|
+
analyses: CodometerAnalysis[];
|
|
1105
|
+
compression: CodometerCompression;
|
|
1106
|
+
/** `"."` when the input never named one, meaning the process's working directory. */
|
|
1107
|
+
directory: string;
|
|
1108
|
+
exclude: string[];
|
|
1109
|
+
include: string[];
|
|
1110
|
+
name: string;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
/** JSON output destination with defaults applied. */
|
|
1114
|
+
export declare interface ResolvedCodometerJsonOutput {
|
|
1115
|
+
custom: ResolvedCodometerCustomStatistic[];
|
|
1116
|
+
indentation: number;
|
|
1117
|
+
path: string;
|
|
1118
|
+
type: "json";
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
/**
|
|
1122
|
+
* A limit with its severity filled in and its value read as a number.
|
|
1123
|
+
*
|
|
1124
|
+
* The unit is gone by this point: a limit written `"8 KB"` arrives here as
|
|
1125
|
+
* 8000, so nothing downstream has to know that limits can be written with
|
|
1126
|
+
* units at all.
|
|
1127
|
+
*/
|
|
1128
|
+
export declare interface ResolvedCodometerLimit {
|
|
1129
|
+
/** Stays `undefined` when none was written; a report falls back to the path. */
|
|
1130
|
+
label: string | undefined;
|
|
1131
|
+
metric: string;
|
|
1132
|
+
severity: CodometerSeverity;
|
|
1133
|
+
value: number;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
/**
|
|
1137
|
+
* Markdown output destination with defaults applied.
|
|
1138
|
+
*
|
|
1139
|
+
* `write` stays `undefined` when the configuration supplies none: the
|
|
1140
|
+
* built-in rendering and writing live in the CLI that calls it, so "unset" is
|
|
1141
|
+
* what selects it rather than a default named here.
|
|
1142
|
+
*/
|
|
1143
|
+
export declare interface ResolvedCodometerMarkdownOutput {
|
|
1144
|
+
custom: ResolvedCodometerCustomStatistic[];
|
|
1145
|
+
description: string | undefined;
|
|
1146
|
+
endMarker: string;
|
|
1147
|
+
path: string | undefined;
|
|
1148
|
+
startMarker: string;
|
|
1149
|
+
type: "markdown";
|
|
1150
|
+
write: undefined | WriteMarkdownOutput;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
/** Destination the measured statistics are written to, with defaults applied. */
|
|
1154
|
+
export declare type ResolvedCodometerOutput = ResolvedCodometerJsonOutput | ResolvedCodometerMarkdownOutput;
|
|
1155
|
+
|
|
1156
|
+
/** Python analysis settings with defaults applied. */
|
|
1157
|
+
export declare interface ResolvedCodometerPythonConfiguration {
|
|
1158
|
+
command: string;
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
/**
|
|
1162
|
+
* What the run does with what it measures.
|
|
1163
|
+
*
|
|
1164
|
+
* Checking staleness gates on `checksReports` alone and a breach on
|
|
1165
|
+
* `checksLimits` alone. Writing is answered per output: `writesJson` and
|
|
1166
|
+
* `writesMarkdown` are each true only when that output's own `--output-*`
|
|
1167
|
+
* flag was passed, so no flag ever quietly writes a destination the command
|
|
1168
|
+
* line never named.
|
|
1169
|
+
*/
|
|
1170
|
+
export declare interface RunMode {
|
|
1171
|
+
checksLimits: boolean;
|
|
1172
|
+
checksReports: boolean;
|
|
1173
|
+
writesJson: boolean;
|
|
1174
|
+
writesMarkdown: boolean;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
/**
|
|
1178
|
+
* Decides what the markdown report says, which file it lands in, and how.
|
|
1179
|
+
*
|
|
1180
|
+
* Return `false` to report the destination as stale — in check mode that is
|
|
1181
|
+
* what fails the command. Anything else counts as up to date.
|
|
1182
|
+
*/
|
|
1183
|
+
export declare type WriteMarkdownOutput = (args: WriteMarkdownOutputArguments) => boolean;
|
|
1184
|
+
|
|
1185
|
+
/** What a `write` function is handed. */
|
|
1186
|
+
export declare interface WriteMarkdownOutputArguments {
|
|
1187
|
+
anchors: MarkdownAnchorHelpers;
|
|
1188
|
+
/** True when nothing may be written and the file is only being inspected. */
|
|
1189
|
+
check: boolean;
|
|
1190
|
+
/** The configured description, for a writer that wants to place it itself. */
|
|
1191
|
+
description: string | undefined;
|
|
1192
|
+
/** The configured path, resolved against the measured directory. */
|
|
1193
|
+
path: string | undefined;
|
|
1194
|
+
/**
|
|
1195
|
+
* The built-in badge rendering of these same statistics.
|
|
1196
|
+
*
|
|
1197
|
+
* Call it to build the default report's content, or to add to it, rather
|
|
1198
|
+
* than reimplementing it.
|
|
1199
|
+
*/
|
|
1200
|
+
renderBadges: () => string;
|
|
1201
|
+
statistics: CodeStatisticsResult;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
export { }
|