@codometer/cli 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 +1477 -0
- package/dist/main.module-_z85wgY7.js +658 -0
- package/dist/src/index.d.ts +649 -0
- package/dist/src/index.js +2 -0
- package/dist/src/main.d.ts +1 -0
- package/dist/src/main.js +26 -0
- package/package.json +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,1477 @@
|
|
|
1
|
+
# ⏲️ Codometer
|
|
2
|
+
|
|
3
|
+
**Measure a repository and report what it found.**
|
|
4
|
+
|
|
5
|
+
Codometer walks a directory, parses everything it recognizes, and writes
|
|
6
|
+
what it counted as a markdown badge block, a JSON report, or both. It counts
|
|
7
|
+
languages the way you would expect — files, lines, classes, functions — and it
|
|
8
|
+
also counts the conventions a repository holds _itself_ to, which is usually
|
|
9
|
+
the more interesting number.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install --save-dev @codometer/cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
codometer
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
<!-- The badge block below this README's own Codometer section is produced by exactly this. -->
|
|
20
|
+
|
|
21
|
+
```markdown
|
|
22
|
+
### TypeScript & JavaScript
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+

|
|
26
|
+

|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Why
|
|
30
|
+
|
|
31
|
+
"1,034 source files" tells you almost nothing. "159 of them are services and
|
|
32
|
+
226 are the unit tests for them" tells you what the repository is actually made
|
|
33
|
+
of, and watching that ratio move tells you where it is going.
|
|
34
|
+
|
|
35
|
+
No language analyzer can produce the second number, because what a
|
|
36
|
+
`*.service.ts` means is a property of your repository rather than of
|
|
37
|
+
TypeScript. Codometer measures both halves: the built-in language counters, and
|
|
38
|
+
the ones you declare.
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
Measuring the repository is codometer's default command, so `codometer` on its
|
|
43
|
+
own is `codometer measure`:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
codometer --config configuration/codometer.config.ts --check limits
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
| Flag | Purpose |
|
|
50
|
+
| ---- | ------- |
|
|
51
|
+
| `--check [set]` | Fail on a comma-separated set drawn from `reports` and `limits` |
|
|
52
|
+
| `--config [path]` | Configuration file to read; searched for when omitted |
|
|
53
|
+
| `-f, --format <format>` | What to print to standard output, one of `json` and `markdown` |
|
|
54
|
+
| `--inputs [globs...]` | Glob array measured in place of every configured input, with no configured input — not even the built-in `codebase` one — active |
|
|
55
|
+
| `--output-json [path]` | Write the JSON report, at the given path or the configured one |
|
|
56
|
+
| `--output-markdown [path]` | Write the markdown badge block, at the given path or the configured one |
|
|
57
|
+
|
|
58
|
+
There is no `--directory`: a run always measures the process's working
|
|
59
|
+
directory, with no per-invocation override. `cd` into what you want measured,
|
|
60
|
+
or narrow it with `--inputs`.
|
|
61
|
+
|
|
62
|
+
**Every flag is independent.** `--output-json`/`--output-markdown` each write
|
|
63
|
+
their own destination, `--check limits` fails on a breached limit, `--check
|
|
64
|
+
reports` fails on a stale one, `--format` prints, and none of them turns
|
|
65
|
+
another on:
|
|
66
|
+
|
|
67
|
+
| Invocation | Writes | Fails on staleness | Fails on a breach |
|
|
68
|
+
| ---------- | ------ | ------------------ | ----------------- |
|
|
69
|
+
| `codometer` | no | no | no |
|
|
70
|
+
| `codometer --check limits` | no | no | yes |
|
|
71
|
+
| `codometer --check reports` | no | yes | no |
|
|
72
|
+
| `codometer --check limits,reports` | no | yes | yes |
|
|
73
|
+
| `codometer --output-json --output-markdown` | yes, both | no | no |
|
|
74
|
+
| `codometer --output-json --check limits` | yes | no | yes, after writing |
|
|
75
|
+
|
|
76
|
+
`--output-json`/`--output-markdown` passed **bare** write to whatever the
|
|
77
|
+
resolved configuration's own `json`/`markdown` output declares, and are
|
|
78
|
+
refused before anything is measured when the configuration names no such
|
|
79
|
+
output — there is then nowhere to write it. Passed **with a path**, that path
|
|
80
|
+
is used for this run alone, whether or not the configuration declares an
|
|
81
|
+
output of that kind.
|
|
82
|
+
|
|
83
|
+
A run that both writes and gates produces **every** output before it fails, so
|
|
84
|
+
the report is on disk even when the gate trips. Combining an `--output-*` flag
|
|
85
|
+
with `--check reports` is refused rather than obeyed: nothing can be stale in
|
|
86
|
+
the run that just wrote it. So is a `--check` value the tool does not know, or
|
|
87
|
+
one passed with no value at all — a valueless `--check` used to mean "check
|
|
88
|
+
everything", and a set with nothing in it looks exactly like the flag having
|
|
89
|
+
been left off. Every complaint about one command line is reported together
|
|
90
|
+
rather than one run at a time.
|
|
91
|
+
|
|
92
|
+
A **breach** and **staleness** are different findings and are never reported as
|
|
93
|
+
one. A `warn` breach is printed and leaves the exit code alone; a `fail` breach
|
|
94
|
+
exits 1, but only where `--check limits` asked for a gate.
|
|
95
|
+
|
|
96
|
+
`--check reports` compares a committed report against a fresh measurement, so it
|
|
97
|
+
is only as stable as the numbers it re-measures. Compressed sizes are
|
|
98
|
+
Node-version dependent — the bundled zlib differs between releases — so a report
|
|
99
|
+
written on one runtime and checked on another reads as stale when nothing
|
|
100
|
+
changed at all. Check on the runtime the repository pins, or expect false
|
|
101
|
+
staleness rather than a real finding.
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
- run: npx @codometer/cli --check reports,limits
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## One folder at a time
|
|
108
|
+
|
|
109
|
+
Codometer measures **one directory**, and knows nothing about workspaces, task
|
|
110
|
+
runners, or project graphs. Run it in a project and that project is what gets
|
|
111
|
+
measured — its own sources, and whatever inputs the configuration declares for
|
|
112
|
+
it:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
cd packages/logger && codometer --check limits
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
With no `--config`, the configuration is found by walking upward from that
|
|
119
|
+
folder and taking the **first** file found. The nearest one wins outright:
|
|
120
|
+
nothing from a further ancestor is folded into it, because a merged
|
|
121
|
+
configuration leaves a limit that never applied looking exactly like one that
|
|
122
|
+
did.
|
|
123
|
+
|
|
124
|
+
A configuration file is always read as a plain object — one exported as a
|
|
125
|
+
function is not recognized, and falls back to an empty configuration, the
|
|
126
|
+
same way a file exporting `42` does. So a project answering for itself writes
|
|
127
|
+
its own `codometer.config.ts`, typically by importing and spreading a shared
|
|
128
|
+
object a workspace root exports, the way this repository's own projects each
|
|
129
|
+
spread [`configuration/codometer.config.ts`](../../configuration/codometer.config.ts).
|
|
130
|
+
|
|
131
|
+
## What gets measured
|
|
132
|
+
|
|
133
|
+
Discovery walks the directory itself and reads every `.gitignore` it passes,
|
|
134
|
+
so **`.gitignore` is already in force** — a build directory or a virtual
|
|
135
|
+
environment is pruned where its ignore file names it, and no exclusion has to
|
|
136
|
+
name it again. Git is never invoked, so a directory that is not a repository
|
|
137
|
+
at all is measured the same way as one that is.
|
|
138
|
+
|
|
139
|
+
What is measured is the working tree rather than the index: a file that exists
|
|
140
|
+
and is not ignored counts, whether or not it has been committed yet.
|
|
141
|
+
|
|
142
|
+
| Group | Counts |
|
|
143
|
+
| ----- | ------ |
|
|
144
|
+
| Repository | Lines of code, repository size, folders, source files |
|
|
145
|
+
| TypeScript & JavaScript | Files, tests, classes, functions, methods, interfaces, generics, enums, constants, imports, decorators, exported symbols, doc comments, TODOs |
|
|
146
|
+
| Python | Files, lines, classes, functions, protocols, constants, imports, decorators, docstrings |
|
|
147
|
+
| Jupyter | Notebooks, cells by kind, executions, outputs, plus the code and prose inside them |
|
|
148
|
+
| JSON | Files, objects, arrays, properties, scalars by type, node count, max depth |
|
|
149
|
+
| YAML | Documents, mappings, sequences, keys, scalars, anchors, aliases, max depth |
|
|
150
|
+
| Markdown | Headings by level, paragraphs, lists, tables, links, images, code blocks, block quotes |
|
|
151
|
+
| SQL | Statements by kind — selects, inserts, updates, deletes, creates, joins, CTEs |
|
|
152
|
+
| Shell | Functions, variables, exports, conditionals, loops, pipelines, shebangs |
|
|
153
|
+
| TOML | Tables, array tables, keys, arrays |
|
|
154
|
+
| HCL | Blocks, resources, variables, outputs, attributes, interpolations |
|
|
155
|
+
| CSS | Rules, selectors, declarations, at-rules, media queries, custom properties |
|
|
156
|
+
| Conventions | Whatever you declare — see below |
|
|
157
|
+
|
|
158
|
+
Notebooks are measured by composition rather than by a fourth parser: the
|
|
159
|
+
document is handed to the JSON analyzer, its code cells to the Python analyzer,
|
|
160
|
+
and its markdown cells to the markdown analyzer, leaving only cells, outputs,
|
|
161
|
+
and executions for the notebook analyzer itself.
|
|
162
|
+
|
|
163
|
+
Python analysis runs through an interpreter, `python3` by default. Point it
|
|
164
|
+
elsewhere with `python: { command: "uv run python" }` when Python lives in a
|
|
165
|
+
virtual environment.
|
|
166
|
+
|
|
167
|
+
## Inputs
|
|
168
|
+
|
|
169
|
+
An **input** is a named set of files, declared by include and exclude globs
|
|
170
|
+
together with the analyses run over it. `inputs` is an array, and one entry is
|
|
171
|
+
always there whether or not a configuration declares any: the built-in
|
|
172
|
+
`codebase` scan, which measures everything the ignore files leave behind and
|
|
173
|
+
runs `language` analysis over it. Declaring an input named `codebase`
|
|
174
|
+
replaces that built-in entry outright rather than adding beside it.
|
|
175
|
+
|
|
176
|
+
An input names its files by glob, which is what lets one measure compiled
|
|
177
|
+
output: a directory every `.gitignore` claims, and therefore the one place
|
|
178
|
+
ignore rules must not reach — ignore files are never consulted for a declared
|
|
179
|
+
input.
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
inputs: [
|
|
183
|
+
{
|
|
184
|
+
analyses: ["size"],
|
|
185
|
+
compression: "gzip",
|
|
186
|
+
exclude: ["dist/vendor/**"],
|
|
187
|
+
include: ["dist/**/*.js", "!dist/**/*.map.js"],
|
|
188
|
+
name: "compiled",
|
|
189
|
+
},
|
|
190
|
+
],
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
| Field | Required | Default | Meaning |
|
|
194
|
+
| ----- | -------- | ------- | ------- |
|
|
195
|
+
| `name` | yes | — | What the input is called. Two inputs may not share one |
|
|
196
|
+
| `include` | yes | — | Globs that add files. At least one must add rather than remove |
|
|
197
|
+
| `exclude` | no | none | Globs that remove files |
|
|
198
|
+
| `analyses` | yes | — | `language`, `size`, or both. At least one |
|
|
199
|
+
| `compression` | no | `gzip` | `gzip`, `brotli`, or `none` for the bytes on disk |
|
|
200
|
+
| `directory` | no | `.` | Where the input's globs start, relative to the process's working directory |
|
|
201
|
+
|
|
202
|
+
`language` runs the analyzers above over the input's files. `size` compresses
|
|
203
|
+
each matched file on its own and sums the results — never all of them together
|
|
204
|
+
— at gzip level 9 or brotli quality 11, both stated rather than defaulted.
|
|
205
|
+
|
|
206
|
+
A `!` prefix in `include` removes files. Negations form one set applied to the
|
|
207
|
+
whole input rather than being read in order, so rearranging the array cannot
|
|
208
|
+
change what the input holds. Dot files are excluded unless a glob spells one
|
|
209
|
+
out, directories never match, and a file that was matched but cannot be read
|
|
210
|
+
fails the run rather than counting as zero bytes.
|
|
211
|
+
|
|
212
|
+
`--inputs [globs...]` on the command line replaces every configured input for
|
|
213
|
+
that one run, running only `language` analysis over exactly the globs given —
|
|
214
|
+
with no other input, not even the built-in `codebase` one, active.
|
|
215
|
+
|
|
216
|
+
## Limits
|
|
217
|
+
|
|
218
|
+
A **limit** is how high one measured metric may go. Any metric can carry one — a
|
|
219
|
+
compressed size, a line count, a counter for one of the conventions below — and
|
|
220
|
+
a metric nothing limits is measured and reported exactly as before, gated by
|
|
221
|
+
nothing.
|
|
222
|
+
|
|
223
|
+
```ts
|
|
224
|
+
defaultInput: "codebase",
|
|
225
|
+
limits: [
|
|
226
|
+
{ metric: "Compiled JavaScript.size", value: "8 KB" },
|
|
227
|
+
{ label: "Interfaces", metric: "typescript.interfaces", value: 500 },
|
|
228
|
+
{ metric: "linesOfCode", severity: "warn", value: 100_000 },
|
|
229
|
+
],
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
| Field | Required | Default | Meaning |
|
|
233
|
+
| ----- | -------- | ------- | ------- |
|
|
234
|
+
| `metric` | yes | — | Dotted path of the metric this limits |
|
|
235
|
+
| `value` | yes | — | How high the metric may go, as a number or a string with a unit |
|
|
236
|
+
| `severity` | no | `fail` | `fail` stops the run on a breach; `warn` reports it |
|
|
237
|
+
| `label` | no | the path | What to call the limit in a report |
|
|
238
|
+
|
|
239
|
+
A metric is addressed by the input's name followed by its path within that
|
|
240
|
+
input — `codebase.typescript.interfaces`, `codebase.markdown.files`,
|
|
241
|
+
`Compiled JavaScript.size`. Every input carries `files`, an input running size
|
|
242
|
+
analysis carries `size`, and one running language analysis carries every
|
|
243
|
+
counter the tables above list, with configured counters under `custom.<label>`.
|
|
244
|
+
Set `defaultInput` and a path naming no input is read as that input's.
|
|
245
|
+
|
|
246
|
+
Where a `defaultInput` is set, a path is read as that input's whenever no
|
|
247
|
+
input name prefixes it — so with `defaultInput: "codebase"` and an input
|
|
248
|
+
called `typescript`, `typescript.interfaces` is the codebase's, because the
|
|
249
|
+
`typescript` input has no `interfaces` metric of its own to compete with it.
|
|
250
|
+
Write the input name in full wherever an input and a metric group share one.
|
|
251
|
+
|
|
252
|
+
**Ambiguity is refused, never resolved.** A path that could name two metrics —
|
|
253
|
+
an input called `markdown` beside the codebase's own `markdown.files` — fails
|
|
254
|
+
the run naming both readings, as does a path naming none, or one naming a
|
|
255
|
+
metric from an analysis the input never ran. A limit that quietly bound to the
|
|
256
|
+
wrong metric would look exactly like one that works.
|
|
257
|
+
|
|
258
|
+
A value written as a string carries a **decimal** unit whose trailing `b` is
|
|
259
|
+
required: `"8 KB"` is 8000 bytes and `"1 MB"` is 1000000, while `"8 K"` is not
|
|
260
|
+
a size and is refused rather than read as anything. A value nothing can read
|
|
261
|
+
fails the run instead of being taken as zero.
|
|
262
|
+
|
|
263
|
+
An input that matched **no files** fails the run if and only if a limit is
|
|
264
|
+
written against it. Declaring a limit asserts the files are there, so an empty
|
|
265
|
+
match is a glob that stopped matching or a build that never ran — while an
|
|
266
|
+
input nobody limited simply measured zero, which is unremarkable.
|
|
267
|
+
|
|
268
|
+
### Reading every limit at once
|
|
269
|
+
|
|
270
|
+
A repository that declares its limits one per project has no single file left
|
|
271
|
+
to read them from. `codometer configuration` is that reading:
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
codometer configuration --limits
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
```text
|
|
278
|
+
| Directory | Metric | Label | Severity | Value | Declared in |
|
|
279
|
+
| --- | --- | --- | --- | --- | --- |
|
|
280
|
+
| packages/logger | `Compiled JavaScript.size`| — | fail | 12.00 kB | `packages/logger/codometer.config.ts`|
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
It walks for every configuration file beneath the directory it is given — in
|
|
284
|
+
any of the formats codometer accepts — and resolves each one **for its own
|
|
285
|
+
folder**, so what it reports is what a per-project run actually sees. The walk
|
|
286
|
+
honors the exclusions of whatever configuration answers for the directory being
|
|
287
|
+
listed, so a configuration inside a dependency or a generator template is never
|
|
288
|
+
listed as something the repository configures.
|
|
289
|
+
|
|
290
|
+
**Name that configuration with `--config` where the directory has none of its
|
|
291
|
+
own.** A workspace often states its shared configuration in a file every
|
|
292
|
+
project spreads rather than at its own root, and the upward search then finds
|
|
293
|
+
nothing:
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
codometer configuration --limits --config configuration/codometer.config.ts
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Drop `--limits` to list everything each configuration resolved to: its inputs,
|
|
300
|
+
outputs and their custom statistics, exclusions, and Python command. Add
|
|
301
|
+
`--format json` for a machine-readable listing.
|
|
302
|
+
|
|
303
|
+
It reports configuration and never measurement. No build is required and no
|
|
304
|
+
limit is evaluated, so it runs in milliseconds — and no single unreadable file
|
|
305
|
+
takes it down. A configuration file that cannot be loaded is listed as
|
|
306
|
+
unreadable, and a walk root nothing answers for falls back to the built-in
|
|
307
|
+
exclusions, says so at the top of the listing, and still reports every limit
|
|
308
|
+
the tree declares. That last case exits 1 rather than 0: the listing is real,
|
|
309
|
+
but the exclusions the repository declares were never consulted, and a clean
|
|
310
|
+
exit would claim otherwise.
|
|
311
|
+
|
|
312
|
+
## Custom statistics
|
|
313
|
+
|
|
314
|
+
A repository that names files by convention has a vocabulary no analyzer knows
|
|
315
|
+
about. Each output destination carries its own `custom` list to count them —
|
|
316
|
+
there is no longer one shared `statistics` array, so a JSON report and a
|
|
317
|
+
markdown report may count entirely different things:
|
|
318
|
+
|
|
319
|
+
```ts
|
|
320
|
+
outputs: [
|
|
321
|
+
{
|
|
322
|
+
custom: [
|
|
323
|
+
{ label: "Service Files", patterns: ["**/*.service.ts"] },
|
|
324
|
+
{ label: "Unit Tests", patterns: ["**/*.unit.test.ts"] },
|
|
325
|
+
{ color: "16a34a", label: "Migrations", patterns: ["**/migrations/*.sql"] },
|
|
326
|
+
],
|
|
327
|
+
path: "codometer-report.json",
|
|
328
|
+
type: "json",
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Counters can also match _declarations_ rather than files, by shape:
|
|
334
|
+
|
|
335
|
+
```ts
|
|
336
|
+
custom: [
|
|
337
|
+
{
|
|
338
|
+
group: "typescript",
|
|
339
|
+
label: "Static Methods",
|
|
340
|
+
symbols: { kinds: ["method"], modifiers: ["static"] },
|
|
341
|
+
},
|
|
342
|
+
];
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Or select a **comment budget** — how much prose one comment block may hold —
|
|
346
|
+
rather than counting files or declarations at all:
|
|
347
|
+
|
|
348
|
+
```ts
|
|
349
|
+
custom: [
|
|
350
|
+
{ comment: { language: "yaml", maximumWords: 128 }, label: "YAML Comment Budget" },
|
|
351
|
+
{ comment: { kind: "class", maximumLines: 24 }, label: "Class Comment Budget" },
|
|
352
|
+
];
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
A `comment` entry's `value` is how many blocks breached the selector's own
|
|
356
|
+
`maximumCharacters`/`maximumLines`/`maximumWords`, and its `instances` name
|
|
357
|
+
each one's file and line — the same shape any other custom counter reports, so
|
|
358
|
+
a comment-budget breach gates through an ordinary `limits[]` entry addressing
|
|
359
|
+
its `custom.<label>` metric path exactly the way a file or symbol counter's
|
|
360
|
+
limit does. There is no separate flag for it, and no inheritance between
|
|
361
|
+
`comment` selectors: a selector naming no `language` covers every language
|
|
362
|
+
codometer measures comments in, so expressing "every language at one budget,
|
|
363
|
+
except one language at another" means writing the general budget once per
|
|
364
|
+
covered language rather than once for all of them, leaving the exception for
|
|
365
|
+
its own, narrower selector. See
|
|
366
|
+
[`configuration/codometer.config.ts`](../../configuration/codometer.config.ts)
|
|
367
|
+
for how this repository derives one selector per language from its own list of
|
|
368
|
+
comment-bearing languages.
|
|
369
|
+
|
|
370
|
+
Each entry becomes one badge, in the order configured, rendered into the group
|
|
371
|
+
it names — `conventions` by default. Symbol counting happens during the walk
|
|
372
|
+
the TypeScript analyzer already makes, so any number of these costs one pass
|
|
373
|
+
over the sources.
|
|
374
|
+
|
|
375
|
+
The full reference — kinds, modifiers, colors, groups, the comment-selector
|
|
376
|
+
fields, and how `patterns` narrows a symbol counter rather than being what it
|
|
377
|
+
counts — is in
|
|
378
|
+
[**@codometer/configuration**](../codometer-configuration/README.md#custom-statistics).
|
|
379
|
+
|
|
380
|
+
## Output
|
|
381
|
+
|
|
382
|
+
What a run prints and what it writes are asked for separately, and neither
|
|
383
|
+
implies the other:
|
|
384
|
+
|
|
385
|
+
| Sink | Flag | What lands there |
|
|
386
|
+
| ---- | ---- | ---------------- |
|
|
387
|
+
| Console | `-f, --format <format>` | The report as `json`, or the rendered badges as `markdown` |
|
|
388
|
+
| Report | `--output-json [path]` | The structured report below |
|
|
389
|
+
| Markdown | `--output-markdown [path]` | The badge block, in a markdown file |
|
|
390
|
+
|
|
391
|
+
**One markdown sink, not two.** `--output-markdown` splices the badge block
|
|
392
|
+
between its markers when the file already carries them, appends it with them
|
|
393
|
+
when it does not, and creates the file when it is not there. A README somebody
|
|
394
|
+
else wrote the rest of and a file holding nothing but badges are the same case,
|
|
395
|
+
so neither needs a flag of its own.
|
|
396
|
+
|
|
397
|
+
**Each `--output-*` flag's value is optional, and the two meanings differ.**
|
|
398
|
+
Passed bare, the flag writes wherever the resolved configuration's own output
|
|
399
|
+
of that kind declares — refused before anything is measured when the
|
|
400
|
+
configuration names no such output, since there is then nowhere to write it.
|
|
401
|
+
Passed with a path, that path is used for this run alone, whether or not the
|
|
402
|
+
configuration declares an output of that kind:
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
codometer --output-json # writes the configured json output's path
|
|
406
|
+
codometer --output-json report.json # writes report.json instead, even with no json output configured
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
**`--format` falls back to the resolved configuration's own `format` field**
|
|
410
|
+
when the flag is left off — never inferred from which other flags are present,
|
|
411
|
+
so omitting it prints the same thing whether or not the run also writes a
|
|
412
|
+
file. `format` is required in every configuration, so this fallback is never
|
|
413
|
+
undefined.
|
|
414
|
+
|
|
415
|
+
**A named destination stands for all of them.** `--output-json` on its own asks
|
|
416
|
+
for the report and nothing else, whatever the configuration file also describes;
|
|
417
|
+
`--output-markdown` on its own writes only the badge block. Each flag governs
|
|
418
|
+
its own destination and never turns another on.
|
|
419
|
+
|
|
420
|
+
**Standard output carries the result; every diagnostic goes to standard error.**
|
|
421
|
+
`codometer --format json > report.json` has to produce a file something can
|
|
422
|
+
parse, so a log line never shares that stream — including the exclusion notice
|
|
423
|
+
below, which is still on the console and still in front of a human, just not
|
|
424
|
+
inside the data. Only `--format` ever writes to that stream: a file sink that
|
|
425
|
+
could also print is how one run put two documents on it.
|
|
426
|
+
|
|
427
|
+
The rendered badges are a description paragraph followed by shields.io badges
|
|
428
|
+
under one `###` heading per language. A run scoped to one project puts its own
|
|
429
|
+
`##` section heading above all of it, inside the markers, because that block
|
|
430
|
+
lands in a document somebody else wrote the rest of and `###` groups with
|
|
431
|
+
nothing above them would read as a continuation of whatever section came
|
|
432
|
+
before. A run measuring a whole repository renders none: that README titles the
|
|
433
|
+
section above the markers itself. Beyond the language groups there is also —
|
|
434
|
+
for a run that measured a declared input's size — a `Measured Targets` group
|
|
435
|
+
carrying each input's size under the compression it was measured with. That
|
|
436
|
+
group is how a project's README reports the size of what it ships; a run that
|
|
437
|
+
declared no such input renders no such group, which is why the whole-repository
|
|
438
|
+
report carries only its own `Repository Size`.
|
|
439
|
+
|
|
440
|
+
Spliced, the badges sit between two markers,
|
|
441
|
+
named `<!-- codometer:start -->
|
|
442
|
+
|
|
443
|
+
## ⏲️ Codometer
|
|
444
|
+
|
|
445
|
+
### Project
|
|
446
|
+
|
|
447
|
+

|
|
448
|
+

|
|
449
|
+

|
|
450
|
+

|
|
451
|
+
|
|
452
|
+
### Measured Targets
|
|
453
|
+
|
|
454
|
+

|
|
455
|
+
|
|
456
|
+
### TypeScript
|
|
457
|
+
|
|
458
|
+

|
|
459
|
+

|
|
460
|
+

|
|
461
|
+

|
|
462
|
+

|
|
463
|
+

|
|
464
|
+

|
|
465
|
+
|
|
466
|
+
### JavaScript
|
|
467
|
+
|
|
468
|
+

|
|
469
|
+

|
|
470
|
+

|
|
471
|
+

|
|
472
|
+

|
|
473
|
+

|
|
474
|
+

|
|
475
|
+

|
|
476
|
+

|
|
477
|
+

|
|
478
|
+

|
|
479
|
+

|
|
480
|
+

|
|
481
|
+

|
|
482
|
+
|
|
483
|
+
### Python
|
|
484
|
+
|
|
485
|
+

|
|
486
|
+

|
|
487
|
+

|
|
488
|
+

|
|
489
|
+

|
|
490
|
+

|
|
491
|
+

|
|
492
|
+

|
|
493
|
+

|
|
494
|
+

|
|
495
|
+

|
|
496
|
+

|
|
497
|
+
|
|
498
|
+
### JSON
|
|
499
|
+
|
|
500
|
+

|
|
501
|
+

|
|
502
|
+

|
|
503
|
+

|
|
504
|
+

|
|
505
|
+

|
|
506
|
+

|
|
507
|
+

|
|
508
|
+

|
|
509
|
+

|
|
510
|
+

|
|
511
|
+

|
|
512
|
+
|
|
513
|
+
### YAML
|
|
514
|
+
|
|
515
|
+

|
|
516
|
+

|
|
517
|
+

|
|
518
|
+

|
|
519
|
+

|
|
520
|
+

|
|
521
|
+

|
|
522
|
+

|
|
523
|
+

|
|
524
|
+

|
|
525
|
+

|
|
526
|
+
|
|
527
|
+
### TOML
|
|
528
|
+
|
|
529
|
+

|
|
530
|
+

|
|
531
|
+

|
|
532
|
+

|
|
533
|
+

|
|
534
|
+

|
|
535
|
+

|
|
536
|
+
|
|
537
|
+
### Shell
|
|
538
|
+
|
|
539
|
+

|
|
540
|
+

|
|
541
|
+

|
|
542
|
+

|
|
543
|
+

|
|
544
|
+

|
|
545
|
+

|
|
546
|
+

|
|
547
|
+

|
|
548
|
+

|
|
549
|
+

|
|
550
|
+
|
|
551
|
+
### SQL
|
|
552
|
+
|
|
553
|
+

|
|
554
|
+

|
|
555
|
+

|
|
556
|
+

|
|
557
|
+

|
|
558
|
+

|
|
559
|
+

|
|
560
|
+

|
|
561
|
+

|
|
562
|
+

|
|
563
|
+

|
|
564
|
+
|
|
565
|
+
### HCL
|
|
566
|
+
|
|
567
|
+

|
|
568
|
+

|
|
569
|
+

|
|
570
|
+

|
|
571
|
+

|
|
572
|
+

|
|
573
|
+

|
|
574
|
+

|
|
575
|
+

|
|
576
|
+
|
|
577
|
+
### CSS
|
|
578
|
+
|
|
579
|
+

|
|
580
|
+

|
|
581
|
+

|
|
582
|
+

|
|
583
|
+

|
|
584
|
+

|
|
585
|
+

|
|
586
|
+

|
|
587
|
+

|
|
588
|
+
|
|
589
|
+
### Conventions
|
|
590
|
+
|
|
591
|
+

|
|
592
|
+

|
|
593
|
+

|
|
594
|
+

|
|
595
|
+

|
|
596
|
+

|
|
597
|
+

|
|
598
|
+

|
|
599
|
+

|
|
600
|
+

|
|
601
|
+

|
|
602
|
+

|
|
603
|
+

|
|
604
|
+

|
|
605
|
+

|
|
606
|
+

|
|
607
|
+

|
|
608
|
+

|
|
609
|
+
|
|
610
|
+
### Jupyter
|
|
611
|
+
|
|
612
|
+

|
|
613
|
+

|
|
614
|
+

|
|
615
|
+

|
|
616
|
+

|
|
617
|
+

|
|
618
|
+

|
|
619
|
+

|
|
620
|
+

|
|
621
|
+

|
|
622
|
+

|
|
623
|
+

|
|
624
|
+

|
|
625
|
+

|
|
626
|
+

|
|
627
|
+

|
|
628
|
+

|
|
629
|
+

|
|
630
|
+

|
|
631
|
+

|
|
632
|
+
|
|
633
|
+
### Markdown
|
|
634
|
+
|
|
635
|
+

|
|
636
|
+

|
|
637
|
+

|
|
638
|
+

|
|
639
|
+

|
|
640
|
+

|
|
641
|
+

|
|
642
|
+

|
|
643
|
+

|
|
644
|
+

|
|
645
|
+

|
|
646
|
+

|
|
647
|
+

|
|
648
|
+

|
|
649
|
+

|
|
650
|
+

|
|
651
|
+

|
|
652
|
+

|
|
653
|
+

|
|
654
|
+

|
|
655
|
+
<!-- codometer:end -->` unless a configuration
|
|
656
|
+
renames them — as this example does, so that documenting the markers does not
|
|
657
|
+
make this document splice its own badges into the example:
|
|
658
|
+
|
|
659
|
+
```markdown
|
|
660
|
+
<!-- STATISTICS_START -->
|
|
661
|
+
<!-- STATISTICS_END -->
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
The block is appended when the markers are absent, and the file is created when
|
|
665
|
+
it does not exist. A markdown output's `write` function is the whole of that
|
|
666
|
+
customizable behavior — it both decides what the report says and where it
|
|
667
|
+
lands, in place of what used to be two separate `render` and `write`
|
|
668
|
+
callbacks — and leaving it unset keeps the built-in rendering and writing. See
|
|
669
|
+
[writing markdown](../codometer-configuration/README.md#writing-markdown).
|
|
670
|
+
|
|
671
|
+
### What codometer writes, it does not measure
|
|
672
|
+
|
|
673
|
+
Every file a run would write is left out of what it measures, and the run says
|
|
674
|
+
so on the console. No configuration, and no ignore-file entry: codometer knows
|
|
675
|
+
its own destinations.
|
|
676
|
+
|
|
677
|
+
A badge is an image inside a link, so a spliced block moves `markdown.images`,
|
|
678
|
+
`markdown.links`, and `markdown.lines`, which moves the badges, which moves the
|
|
679
|
+
counts. Left in, a written report would be stale the moment it landed. The
|
|
680
|
+
exclusion is applied identically whatever the flags say, so a run that writes
|
|
681
|
+
and a `--check reports` run always measure the same tree.
|
|
682
|
+
|
|
683
|
+
### The report
|
|
684
|
+
|
|
685
|
+
Codometer's own shape rather than any other tool's. Every metric carries its
|
|
686
|
+
value, and where something limits it, that limit's value, severity, and whether
|
|
687
|
+
it was breached — a limit that held is written out exactly like one that did
|
|
688
|
+
not, so a consumer can render the headroom rather than only the failures.
|
|
689
|
+
|
|
690
|
+
```json
|
|
691
|
+
{
|
|
692
|
+
"failures": [
|
|
693
|
+
{
|
|
694
|
+
"kind": "limit",
|
|
695
|
+
"reason": "Cannot bind the limit written against \"nowhere.at.all\": nothing measured answers to it.",
|
|
696
|
+
"subject": "nowhere.at.all"
|
|
697
|
+
}
|
|
698
|
+
],
|
|
699
|
+
"targets": [
|
|
700
|
+
{
|
|
701
|
+
"empty": false,
|
|
702
|
+
"files": 1,
|
|
703
|
+
"metrics": [
|
|
704
|
+
{
|
|
705
|
+
"instances": null,
|
|
706
|
+
"limits": [],
|
|
707
|
+
"name": "compiled.files",
|
|
708
|
+
"path": "files",
|
|
709
|
+
"unit": null,
|
|
710
|
+
"value": 1
|
|
711
|
+
},
|
|
712
|
+
{
|
|
713
|
+
"instances": null,
|
|
714
|
+
"limits": [
|
|
715
|
+
{ "breached": true, "label": null, "severity": "warn", "value": 900 },
|
|
716
|
+
{ "breached": true, "label": "Bundle", "severity": "fail", "value": 1000 }
|
|
717
|
+
],
|
|
718
|
+
"name": "compiled.size",
|
|
719
|
+
"path": "size",
|
|
720
|
+
"unit": "bytes",
|
|
721
|
+
"value": 5195
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
"instances": [
|
|
725
|
+
{ "file": "src/modules/codometer/codometer.service.ts", "line": 32, "measured": 9 }
|
|
726
|
+
],
|
|
727
|
+
"limits": [
|
|
728
|
+
{ "breached": true, "label": null, "severity": "fail", "value": 0 }
|
|
729
|
+
],
|
|
730
|
+
"name": "compiled.custom.Class Comment Budget",
|
|
731
|
+
"path": "custom.Class Comment Budget",
|
|
732
|
+
"unit": null,
|
|
733
|
+
"value": 1
|
|
734
|
+
}
|
|
735
|
+
],
|
|
736
|
+
"name": "compiled"
|
|
737
|
+
}
|
|
738
|
+
]
|
|
739
|
+
}
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
| Field | Meaning |
|
|
743
|
+
| ----- | ------- |
|
|
744
|
+
| `name` | The metric's name across runs — its target, then its path. The join key a later run is compared on |
|
|
745
|
+
| `path` | The metric's path within its target, with no target name on the front |
|
|
746
|
+
| `unit` | `"bytes"` where the value counts bytes, `null` for a plain count |
|
|
747
|
+
| `limits` | Every limit declared on the metric, in the order written. Empty where nothing limits it — never an absent key |
|
|
748
|
+
| `instances` | Where each instance a per-instance selector produced was found — a `comment` selector's breaches today. `null` for a metric that only counts, never an empty array standing in for it |
|
|
749
|
+
| `empty` | Said outright when a target's globs matched nothing |
|
|
750
|
+
| `failures` | Whatever the run could not do: a target that would not measure, a limit that bound to nothing |
|
|
751
|
+
|
|
752
|
+
**A `comment` selector's metric reports every breaching block, not the whole
|
|
753
|
+
selector's activity.** `value` is the count of blocks that broke the
|
|
754
|
+
selector's own `maximumCharacters`/`maximumLines`/`maximumWords`, and
|
|
755
|
+
`instances` names each one's `file` and 1-indexed `line` plus how much it
|
|
756
|
+
`measured`. A block that stayed within budget contributes to neither.
|
|
757
|
+
|
|
758
|
+
**A metric may carry more than one limit.** The configuration accepts a `warn`
|
|
759
|
+
short of a `fail` on a single metric on purpose — that is how a repository sees
|
|
760
|
+
a number coming before it stops a change — and the gate enforces all of them, so
|
|
761
|
+
the report lists all of them. A consumer deciding what to show picks
|
|
762
|
+
deliberately: the `fail` limit is what stops a change, and a
|
|
763
|
+
breached `warn` beneath it is advice, not a failure.
|
|
764
|
+
|
|
765
|
+
**Byte values are raw and decimal.** A renderer showing kilobytes divides by
|
|
766
|
+
1000, the same units a limit written `"8 KB"` is read in.
|
|
767
|
+
|
|
768
|
+
**Nothing is signalled by a missing field.** A target that matched nothing says
|
|
769
|
+
`"empty": true` and any limit written against it joins `failures`, rather than
|
|
770
|
+
leaving a consumer to infer an empty match from an absent limit beside a
|
|
771
|
+
passing verdict.
|
|
772
|
+
|
|
773
|
+
A failure is neither a breach nor staleness: it is the run not having finished.
|
|
774
|
+
Every one of them is collected and reported together, so a configuration with
|
|
775
|
+
three broken limits is one run to diagnose rather than three. A failure fails
|
|
776
|
+
any run that writes or gates; a bare run reports it and exits clean, exactly as
|
|
777
|
+
the flag table promises.
|
|
778
|
+
|
|
779
|
+
## Packages
|
|
780
|
+
|
|
781
|
+
| Package | Role |
|
|
782
|
+
| ------- | ---- |
|
|
783
|
+
| [`@codometer/cli`](README.md) | Measures the repository and writes the reports. Knows nothing about any particular repository |
|
|
784
|
+
| [`@codometer/configuration`](../codometer-configuration/README.md) | Reads `codometer.config.ts` and resolves exclusions, output destinations, custom statistics, and the Python interpreter |
|
|
785
|
+
| [`@codometer/examples`](../codometer-examples/README.md) | A sample corpus with known contents and one runnable example per behavior above, each asserted by a test |
|
|
786
|
+
|
|
787
|
+
Which paths to skip, where the output goes, and how Python is reached are all
|
|
788
|
+
configuration. That split is what lets the CLI be a general tool rather than
|
|
789
|
+
one repository's script.
|
|
790
|
+
|
|
791
|
+
## Agent skills
|
|
792
|
+
|
|
793
|
+
Agent skills for coding agents working with codometer are published in
|
|
794
|
+
[`@codometer/agents`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codometer/codometer-agents):
|
|
795
|
+
|
|
796
|
+
| Skill | Description |
|
|
797
|
+
| ----- | ----------- |
|
|
798
|
+
| [`codometer-measure`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codometer/codometer-agents/skills/codometer-measure) | Run code measurements and produce markdown or JSON reports |
|
|
799
|
+
| [`codometer-configure`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codometer/codometer-agents/skills/codometer-configure) | Configure measurement inputs, custom metrics, and limits in `codometer.config.ts` |
|
|
800
|
+
| [`codometer-triage`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codometer/codometer-agents/skills/codometer-triage) | Triage limit breaches and measurement failures |
|
|
801
|
+
|
|
802
|
+
## Examples
|
|
803
|
+
|
|
804
|
+
Everything above has a runnable example in
|
|
805
|
+
[`@codometer/examples`](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codometer/codometer-examples), measured against a
|
|
806
|
+
sample corpus whose counts are stated and checked — including a reproduction of
|
|
807
|
+
each refusal, which is where a reader is most likely to be stuck. An agent that
|
|
808
|
+
has already been handed a refusal and needs the fix should start from that
|
|
809
|
+
package's [AGENTS.md](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codometer/codometer-examples/AGENTS.md), which maps each message
|
|
810
|
+
codometer prints to the example that reproduces it.
|
|
811
|
+
|
|
812
|
+
## Start
|
|
813
|
+
|
|
814
|
+
```bash
|
|
815
|
+
nx run codometer-cli:start
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
Pass the flags from [Usage](#usage) after `--`, so
|
|
819
|
+
`nx run codometer-cli:start -- --check limits` gates the current directory
|
|
820
|
+
from source.
|
|
821
|
+
|
|
822
|
+
## Test
|
|
823
|
+
|
|
824
|
+
```bash
|
|
825
|
+
nx run codometer-cli:vitest
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
## Contributing
|
|
829
|
+
|
|
830
|
+
```bash
|
|
831
|
+
nx run codometer-cli:build # Compile
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
## License
|
|
835
|
+
|
|
836
|
+
MIT — see [LICENSE](../../LICENSE).
|
|
837
|
+
|
|
838
|
+
## 👔 Conformetry
|
|
839
|
+
|
|
840
|
+
This project was generated from the [nestjs-command-project](../../configuration/conformetry-templates/nestjs-command-project) conformetry template.
|
|
841
|
+
|
|
842
|
+
<!-- callidescope:start -->
|
|
843
|
+
|
|
844
|
+
## 🔭 Callidescope
|
|
845
|
+
|
|
846
|
+
Call stacks traced through `packages/ic-suite/codometer/codometer-cli`, deepest first. Each frame shows what it takes, what it returns, and what its documentation says.
|
|
847
|
+
|
|
848
|
+
| Measure | Value |
|
|
849
|
+
| --- | --- |
|
|
850
|
+
| Callables | 40 |
|
|
851
|
+
| Files | 24 |
|
|
852
|
+
| Calls traced | 45 |
|
|
853
|
+
| Call stacks | 11 |
|
|
854
|
+
| Deepest stack | 15 |
|
|
855
|
+
| Stacks through recursion | 0 |
|
|
856
|
+
| Unfollowable calls | 3 |
|
|
857
|
+
|
|
858
|
+
### Limits
|
|
859
|
+
|
|
860
|
+
What this project is judged against, as declared in its own `callidescope.config.ts`.
|
|
861
|
+
|
|
862
|
+
| Limit | Value |
|
|
863
|
+
| --- | --- |
|
|
864
|
+
| `maximumDepth` | 15 |
|
|
865
|
+
| `maximumBreadth` | 9 |
|
|
866
|
+
|
|
867
|
+
### Call stacks (depth)
|
|
868
|
+
|
|
869
|
+
**1. `MeasureCommand.run`** — depth ≥ 15 · decorated-method
|
|
870
|
+
|
|
871
|
+
```text
|
|
872
|
+
🚀 MeasureCommand.run(_passedParameters: string[], options: MeasureCommandOptions): Promise<void> [packages/ic-suite/codometer/codometer-cli/src/modules/measure/measure.command.ts:398]
|
|
873
|
+
↳ Measure the repository and produce every resolved output.
|
|
874
|
+
└─> MeasureService.measure(args: MeasureArguments): MeasurementResult [packages/ic-suite/codometer/codometer-measurement/src/modules/measure/measure.service.ts:312]
|
|
875
|
+
↳ Measure every input the configuration declares.
|
|
876
|
+
└─> MeasureService.measureInput(args: MeasureInputArguments): InputMeasurement [packages/ic-suite/codometer/codometer-measurement/src/modules/measure/measure.service.ts:253]
|
|
877
|
+
↳ Measure one declared input with whichever analyses it asked for.
|
|
878
|
+
└─> MeasureService.analyzeFiles(args: AnalyzeFilesArguments): CodeStatisticsResult [packages/ic-suite/codometer/codometer-measurement/src/modules/measure/measure.service.ts:75]
|
|
879
|
+
↳ Run every analyzer over one set of files and shape the result.
|
|
880
|
+
└─> LanguagesService.analyze(args: AnalyzeLanguagesArguments): LanguageResults [packages/ic-suite/codometer/codometer-languages/src/modules/languages/languages.service.ts:56]
|
|
881
|
+
↳ Analyze every language present in the discovered files.
|
|
882
|
+
└─> LanguageCommentsService.measure(args: MeasureLanguageCommentsArguments): Record<string, CommentMeasurement[]> [packages/ic-suite/codometer/codometer-languages/src/modules/comments/language-comments.service.ts:212]
|
|
883
|
+
↳ Measures every counter that names no declaration kind, keyed by the custom statistic's label.
|
|
884
|
+
└─> LanguageCommentsService.flatMap(…)(…): CodometerCommentMeasurement[] [packages/ic-suite/codometer/codometer-languages/src/modules/comments/language-comments.service.ts:234]
|
|
885
|
+
└─> LanguageCommentsService.measureOneLanguage(…): CodometerCommentMeasurement[] [packages/ic-suite/codometer/codometer-languages/src/modules/comments/language-comments.service.ts:96]
|
|
886
|
+
↳ Measures one counter's budget against one language's discovered files.
|
|
887
|
+
└─> LanguageCommentsService.measurePython(…): CodometerCommentMeasurement[] [packages/ic-suite/codometer/codometer-languages/src/modules/comments/language-comments.service.ts:162]
|
|
888
|
+
↳ Measures Python's comments, which its own analyzer already found.
|
|
889
|
+
└─> LanguageCommentsService.flatMap(…)(…): CodometerCommentMeasurement[] [packages/ic-suite/codometer/codometer-languages/src/modules/comments/language-comments.service.ts:175]
|
|
890
|
+
└─> CommentsService.measure(args: MeasureCommentsArguments): CommentMeasurement[] [packages/ic-suite/codometer/codometer-languages/src/modules/comments/comments.service.ts:164]
|
|
891
|
+
↳ Measures every block a file's comment tokens form, breached or not.
|
|
892
|
+
└─> CommentsService.flatMap(…)(this: undefined, block: CommentBlock): CodometerCommentMeasurement[] [packages/ic-suite/codometer/codometer-languages/src/modules/comments/comments.service.ts:165]
|
|
893
|
+
└─> CommentsService.measureText(args: MeasureCommentTextArguments): CommentMeasurement[] [packages/ic-suite/codometer/codometer-languages/src/modules/comments/comments.service.ts:187]
|
|
894
|
+
↳ Measures one comment's text against every maximum declared for it.
|
|
895
|
+
└─> CommentsService.declaredLimits(…): { limit: number; measured: number; unit: CodometerDocumentationUnit; }[] [packages/ic-suite/codometer/codometer-languages/src/modules/comments/comments.service.ts:64]
|
|
896
|
+
↳ Every declared maximum, paired with what this comment measured.
|
|
897
|
+
└─> CommentsService.countWords(prose: string): number [packages/ic-suite/codometer/codometer-languages/src/modules/comments/comments.service.ts:50]
|
|
898
|
+
↳ Counts the words in a comment's prose, markers already stripped.
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
**2. `ConfigurationCommand.run`** — depth ≥ 12 · decorated-method
|
|
902
|
+
|
|
903
|
+
```text
|
|
904
|
+
🚀 ConfigurationCommand.run(…): Promise<void> [packages/ic-suite/codometer/codometer-cli/src/modules/configuration/configuration.command.ts:110]
|
|
905
|
+
↳ Lists what the tree beneath the given directory configures.
|
|
906
|
+
└─> ConfigurationListingService.describeConfigurations(args: DescribeConfigurationsArguments): Promise<ConfiguredTree> [packages/ic-suite/codometer/codometer-output/src/modules/configuration-listing/configuration-listing.service.ts:155]
|
|
907
|
+
↳ Resolves the configuration each file in a tree answers with.
|
|
908
|
+
└─> ConfigurationListingService.findConfigurationFiles(args: DescribeConfigurationsArguments): Promise<DiscoveredConfigurationFiles> [packages/ic-suite/codometer/codometer-output/src/modules/configuration-listing/configuration-listing.service.ts:188]
|
|
909
|
+
↳ Finds every configuration file beneath a directory.
|
|
910
|
+
└─> ConfigurationListingService.resolveWalkExclusions(args: DescribeConfigurationsArguments): Promise<WalkExclusions> [packages/ic-suite/codometer/codometer-output/src/modules/configuration-listing/configuration-listing.service.ts:120]
|
|
911
|
+
↳ Resolves the exclusions the walk uses, reporting rather than throwing.
|
|
912
|
+
└─> ConfigurationService.loadConfigurationFile(args?: LoadConfigurationArguments): Promise<LoadedConfiguration> [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:85]
|
|
913
|
+
↳ Loads a configuration and says which file answered.
|
|
914
|
+
└─> ConfigurationService.resolveConfiguration(configuration: CodometerConfiguration): ResolvedCodometerConfiguration [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:130]
|
|
915
|
+
↳ Fills in every field a configuration file may leave out.
|
|
916
|
+
└─> ConfigurationResolverService.resolveConfiguration(configuration: CodometerConfiguration): ResolvedCodometerConfiguration [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:336]
|
|
917
|
+
↳ Fills in every field a configuration file may leave out.
|
|
918
|
+
└─> ConfigurationResolverService.resolveLimits(limits: CodometerLimit[] | undefined): ResolvedCodometerLimit[] [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:258]
|
|
919
|
+
↳ Gives every limit its severity and a value read as a number.
|
|
920
|
+
└─> ConfigurationResolverService.map(…)(…): { label: string | undefined; metric: string; severity: CodometerSeverity; value: number; } [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:261]
|
|
921
|
+
└─> ConfigurationResolverService.parseLimitValue(limit: CodometerLimit): number [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:94]
|
|
922
|
+
↳ Reads a limit's value, in decimal units when it was written as a string.
|
|
923
|
+
└─> ConfigurationResolverService.parseLimitValueText(metric: string, text: string): number [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:114]
|
|
924
|
+
↳ Reads a limit written as a string, unit and all.
|
|
925
|
+
└─> InvalidLimitValueError.constructor(metric: string, value: string): InvalidLimitValueError [packages/ic-suite/codometer/codometer-core/src/modules/codometer-core/codometer-core.constants.ts:35]
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
**3. `ChangesCommand.run`** — depth ≥ 11 · decorated-method
|
|
929
|
+
|
|
930
|
+
```text
|
|
931
|
+
🚀 ChangesCommand.run(_passedParameters: string[], options: ChangesCommandOptions): Promise<void> [packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:97]
|
|
932
|
+
↳ Diffs every project's report against the baseline, and emits the result.
|
|
933
|
+
└─> ChangesService.collect(args: CollectRowsArguments): MetricCollection [packages/ic-suite/codometer/codometer-output/src/modules/changes/changes.service.ts:292]
|
|
934
|
+
↳ Joins every current report to the baseline snapshot.
|
|
935
|
+
└─> ChangesService.map(…)(reportPath: string): MetricCollection [packages/ic-suite/codometer/codometer-output/src/modules/changes/changes.service.ts:293]
|
|
936
|
+
└─> ChangesService.collectProjectRows(args: CollectProjectRowsArguments): MetricCollection [packages/ic-suite/codometer/codometer-output/src/modules/changes/changes.service.ts:110]
|
|
937
|
+
↳ Joins one project's current report to its baseline.
|
|
938
|
+
└─> ChangesService.readBaseline(args: CollectProjectRowsArguments): Map<string, ReportMetric> [packages/ic-suite/codometer/codometer-output/src/modules/changes/changes.service.ts:154]
|
|
939
|
+
↳ Reads a baseline report into a name-to-metric lookup.
|
|
940
|
+
└─> ChangesService.readReport(workingDirectory: string, reportPath: string): ProjectReport [packages/ic-suite/codometer/codometer-output/src/modules/changes/changes.service.ts:243]
|
|
941
|
+
↳ Parses a codometer report, tolerating an absent or malformed file.
|
|
942
|
+
└─> ChangesService.flatMap(…)(…): ReportMetric[] [packages/ic-suite/codometer/codometer-output/src/modules/changes/changes.service.ts:259]
|
|
943
|
+
└─> ChangesService.readMetrics(target: ReportTarget): ReportMetric[] [packages/ic-suite/codometer/codometer-output/src/modules/changes/changes.service.ts:222]
|
|
944
|
+
↳ Pulls every metric a target produced out of the report.
|
|
945
|
+
└─> ChangesService.map(…)(…): { breach: MetricSeverity | undefined; empty: boolean; label: string; limit: number | undefined; name: string; unit: "bytes" | null; value: number; } [packages/ic-suite/codometer/codometer-output/src/modules/changes/changes.service.ts:223]
|
|
946
|
+
└─> ChangesService.readBreach(limits: readonly ReportLimit[]): MetricSeverity | undefined [packages/ic-suite/codometer/codometer-output/src/modules/changes/changes.service.ts:175]
|
|
947
|
+
↳ The severity of the worst limit a metric breached, if it breached one.
|
|
948
|
+
└─> ChangesService.filter(…)(…): boolean [packages/ic-suite/codometer/codometer-output/src/modules/changes/changes.service.ts:178]
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
<details>
|
|
952
|
+
<summary>8 more call stacks</summary>
|
|
953
|
+
|
|
954
|
+
**4. `ChangesCommand.parseDirectory`** — depth 5 · decorated-method
|
|
955
|
+
|
|
956
|
+
```text
|
|
957
|
+
🚀 ChangesCommand.parseDirectory(value: unknown): string [packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:70]
|
|
958
|
+
↳ Parse the directory to look for codometer reports in.
|
|
959
|
+
└─> ConfigurationService.parseDirectoryOption(value: unknown): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:120]
|
|
960
|
+
↳ Reads a directory option, falling back to the working directory.
|
|
961
|
+
└─> ConfigurationFlagsService.parseDirectoryOption(value: unknown): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:126]
|
|
962
|
+
↳ Reads a directory option, falling back to the working directory.
|
|
963
|
+
└─> ConfigurationFlagsService.parseDefaultedOption(value: unknown, fallback: string): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:115]
|
|
964
|
+
↳ Reads an option that carries a default when it was left off.
|
|
965
|
+
└─> ConfigurationFlagsService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:142]
|
|
966
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
967
|
+
```
|
|
968
|
+
|
|
969
|
+
**5. `ConfigurationCommand.parseDirectory`** — depth 5 · decorated-method
|
|
970
|
+
|
|
971
|
+
```text
|
|
972
|
+
🚀 ConfigurationCommand.parseDirectory(value: unknown): string [packages/ic-suite/codometer/codometer-cli/src/modules/configuration/configuration.command.ts:74]
|
|
973
|
+
↳ Parse the directory to look for configuration files beneath.
|
|
974
|
+
└─> ConfigurationService.parseDirectoryOption(value: unknown): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:120]
|
|
975
|
+
↳ Reads a directory option, falling back to the working directory.
|
|
976
|
+
└─> ConfigurationFlagsService.parseDirectoryOption(value: unknown): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:126]
|
|
977
|
+
↳ Reads a directory option, falling back to the working directory.
|
|
978
|
+
└─> ConfigurationFlagsService.parseDefaultedOption(value: unknown, fallback: string): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:115]
|
|
979
|
+
↳ Reads an option that carries a default when it was left off.
|
|
980
|
+
└─> ConfigurationFlagsService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:142]
|
|
981
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
982
|
+
```
|
|
983
|
+
|
|
984
|
+
**6. `ConfigurationCommand.parseFormat`** — depth 4 · decorated-method
|
|
985
|
+
|
|
986
|
+
```text
|
|
987
|
+
🚀 ConfigurationCommand.parseFormat(value: unknown): string [packages/ic-suite/codometer/codometer-cli/src/modules/configuration/configuration.command.ts:83]
|
|
988
|
+
↳ Parse the output format the listing is rendered in.
|
|
989
|
+
└─> ConfigurationService.parseDefaultedOption(value: unknown, fallback: string): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:115]
|
|
990
|
+
↳ Reads an option that carries a default when it was left off.
|
|
991
|
+
└─> ConfigurationFlagsService.parseDefaultedOption(value: unknown, fallback: string): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:115]
|
|
992
|
+
↳ Reads an option that carries a default when it was left off.
|
|
993
|
+
└─> ConfigurationFlagsService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:142]
|
|
994
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
**7. `ChangesCommand.parseBaseline`** — depth 3 · decorated-method
|
|
998
|
+
|
|
999
|
+
```text
|
|
1000
|
+
🚀 ChangesCommand.parseBaseline(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:52]
|
|
1001
|
+
↳ Parse the baseline directory holding a snapshot of the reports.
|
|
1002
|
+
└─> ConfigurationService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:125]
|
|
1003
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
1004
|
+
└─> ConfigurationFlagsService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:142]
|
|
1005
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
**8. `ChangesCommand.parseBaselineUrl`** — depth 3 · decorated-method
|
|
1009
|
+
|
|
1010
|
+
```text
|
|
1011
|
+
🚀 ChangesCommand.parseBaselineUrl(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:61]
|
|
1012
|
+
↳ Parse the run URL the baseline came from, linked from the summary.
|
|
1013
|
+
└─> ConfigurationService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:125]
|
|
1014
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
1015
|
+
└─> ConfigurationFlagsService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:142]
|
|
1016
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
1017
|
+
```
|
|
1018
|
+
|
|
1019
|
+
**9. `ChangesCommand.parseMarkdown`** — depth 3 · decorated-method
|
|
1020
|
+
|
|
1021
|
+
```text
|
|
1022
|
+
🚀 ChangesCommand.parseMarkdown(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:79]
|
|
1023
|
+
↳ Parse the markdown document the report is spliced into.
|
|
1024
|
+
└─> ConfigurationService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:125]
|
|
1025
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
1026
|
+
└─> ConfigurationFlagsService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:142]
|
|
1027
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
1028
|
+
```
|
|
1029
|
+
|
|
1030
|
+
**10. `ChangesCommand.parseOutput`** — depth 3 · decorated-method
|
|
1031
|
+
|
|
1032
|
+
```text
|
|
1033
|
+
🚀 ChangesCommand.parseOutput(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:88]
|
|
1034
|
+
↳ Parse the file the report is written to on its own.
|
|
1035
|
+
└─> ConfigurationService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:125]
|
|
1036
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
1037
|
+
└─> ConfigurationFlagsService.parseOptionalOption(value: unknown): string | undefined [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:142]
|
|
1038
|
+
↳ Reads an option that carries text, or nothing at all.
|
|
1039
|
+
```
|
|
1040
|
+
|
|
1041
|
+
**11. `main`** — depth 2 · module-bootstrap
|
|
1042
|
+
|
|
1043
|
+
```text
|
|
1044
|
+
🚀 main(): Promise<void> [packages/ic-suite/codometer/codometer-cli/src/main.ts:26]
|
|
1045
|
+
↳ Bootstraps the codometer CLI command application.
|
|
1046
|
+
└─> withDefaultCommand(argv: readonly string[]): string[] [packages/ic-suite/codometer/codometer-cli/src/main.utilities.ts:14]
|
|
1047
|
+
↳ Inserts the default `measure` subcommand when the command line names no registered command.
|
|
1048
|
+
```
|
|
1049
|
+
|
|
1050
|
+
</details>
|
|
1051
|
+
|
|
1052
|
+
### Breadth
|
|
1053
|
+
|
|
1054
|
+
| Callable | Breadth | Calls directly | Location |
|
|
1055
|
+
| --- | --- | --- | --- |
|
|
1056
|
+
| `MeasureCommand.run` | 9 | `MeasureCommand.resolveWorkingDirectory`, `MeasureCommand.resolveRunPlan`, `DestinationsService.listOutputPaths`, `MeasureCommand.announceOutputPaths`, `MeasureService.measure`, `ReportService.build`, `DeliveryService.deliver`, `DestinationsService.selectScope`, `MeasureCommand.reportFindings` | `packages/ic-suite/codometer/codometer-cli/src/modules/measure/measure.command.ts:398` |
|
|
1057
|
+
| `MeasureCommand.resolveRunPlan` | 7 | `ConfigurationService.selectMode`, `MeasureCommand.rejectCommandLine`, `MeasureCommand.readConfiguration`, `MeasureCommand.applyInputsOverride`, `ConfigurationService.resolveFormat`, `DestinationsService.resolveDestinations`, `DestinationsService.resolveConsoleMarkdown` | `packages/ic-suite/codometer/codometer-cli/src/modules/measure/measure.command.ts:226` |
|
|
1058
|
+
| `ChangesCommand.run` | 5 | `ConfigurationService.parseOptionalOption`, `ConfigurationService.parseDirectoryOption`, `ChangesService.collect`, `RenderService.renderSection`, `DocumentsService.emit` | `packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:97` |
|
|
1059
|
+
|
|
1060
|
+
<details>
|
|
1061
|
+
<summary>12 more callables</summary>
|
|
1062
|
+
|
|
1063
|
+
| Callable | Breadth | Calls directly | Location |
|
|
1064
|
+
| --- | --- | --- | --- |
|
|
1065
|
+
| `ConfigurationCommand.run` | 4 | `ConfigurationListingService.describeConfigurations`, `ConfigurationCommand.filter(…)`, `RenderConfigurationService.render`, `ConfigurationListingService.toLimitRows` | `packages/ic-suite/codometer/codometer-cli/src/modules/configuration/configuration.command.ts:110` |
|
|
1066
|
+
| `MeasureCommand.reportFindings` | 4 | `MeasureCommand.reportFailures`, `MeasureCommand.reportStaleness`, `MeasureCommand.reportBreaches`, `MeasureCommand.filter(…)` | `packages/ic-suite/codometer/codometer-cli/src/modules/measure/measure.command.ts:189` |
|
|
1067
|
+
| `MeasureCommand.reportBreaches` | 3 | `MeasureCommand.filter(…)`, `MeasureCommand.filter(…)`, `MeasureCommand.filter(…)` | `packages/ic-suite/codometer/codometer-cli/src/modules/measure/measure.command.ts:142` |
|
|
1068
|
+
| `ChangesCommand.parseBaseline` | 1 | `ConfigurationService.parseOptionalOption` | `packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:52` |
|
|
1069
|
+
| `ChangesCommand.parseBaselineUrl` | 1 | `ConfigurationService.parseOptionalOption` | `packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:61` |
|
|
1070
|
+
| `ChangesCommand.parseDirectory` | 1 | `ConfigurationService.parseDirectoryOption` | `packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:70` |
|
|
1071
|
+
| `ChangesCommand.parseMarkdown` | 1 | `ConfigurationService.parseOptionalOption` | `packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:79` |
|
|
1072
|
+
| `ChangesCommand.parseOutput` | 1 | `ConfigurationService.parseOptionalOption` | `packages/ic-suite/codometer/codometer-cli/src/modules/changes/changes.command.ts:88` |
|
|
1073
|
+
| `ConfigurationCommand.parseDirectory` | 1 | `ConfigurationService.parseDirectoryOption` | `packages/ic-suite/codometer/codometer-cli/src/modules/configuration/configuration.command.ts:74` |
|
|
1074
|
+
| `ConfigurationCommand.parseFormat` | 1 | `ConfigurationService.parseDefaultedOption` | `packages/ic-suite/codometer/codometer-cli/src/modules/configuration/configuration.command.ts:83` |
|
|
1075
|
+
| `MeasureCommand.readConfiguration` | 1 | `ConfigurationService.loadConfiguration` | `packages/ic-suite/codometer/codometer-cli/src/modules/measure/measure.command.ts:111` |
|
|
1076
|
+
| `main` | 1 | `withDefaultCommand` | `packages/ic-suite/codometer/codometer-cli/src/main.ts:26` |
|
|
1077
|
+
|
|
1078
|
+
</details>
|
|
1079
|
+
<!-- callidescope:end -->
|
|
1080
|
+
|
|
1081
|
+
## 🕸️ Codependix
|
|
1082
|
+
|
|
1083
|
+
Dependency graphs exported by [codependix](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codependix/codependix-cli), regenerated by `nx run codebase:codependix:write`.
|
|
1084
|
+
|
|
1085
|
+
### Nx Neighborhood
|
|
1086
|
+
|
|
1087
|
+
<!-- codependix:start name="codependix-nx-projects" -->
|
|
1088
|
+
```mermaid
|
|
1089
|
+
graph LR
|
|
1090
|
+
codometer_cli["codometer-cli"]
|
|
1091
|
+
codometer_configuration["codometer-configuration"]
|
|
1092
|
+
codometer_core["codometer-core"]
|
|
1093
|
+
codometer_examples["codometer-examples"]
|
|
1094
|
+
codometer_measurement["codometer-measurement"]
|
|
1095
|
+
codometer_output["codometer-output"]
|
|
1096
|
+
logger["logger"]
|
|
1097
|
+
codometer_cli --> codometer_configuration
|
|
1098
|
+
codometer_cli --> codometer_core
|
|
1099
|
+
codometer_cli --> codometer_measurement
|
|
1100
|
+
codometer_cli --> codometer_output
|
|
1101
|
+
codometer_cli --> logger
|
|
1102
|
+
codometer_examples -.-> codometer_cli
|
|
1103
|
+
classDef subject fill:#7c3aed,color:#fff,stroke:#4c1d95,stroke-width:2px
|
|
1104
|
+
class codometer_cli subject
|
|
1105
|
+
```
|
|
1106
|
+
|
|
1107
|
+
_Dashed edges are dependencies Nx inferred from configuration rather than from code._
|
|
1108
|
+
<!-- codependix:end name="codependix-nx-projects" -->
|
|
1109
|
+
|
|
1110
|
+
### NestJS Module Graph
|
|
1111
|
+
|
|
1112
|
+
<!-- codependix:start name="codependix-nestjs-modules" -->
|
|
1113
|
+
```mermaid
|
|
1114
|
+
flowchart LR
|
|
1115
|
+
ChangesModule
|
|
1116
|
+
CommentsModule
|
|
1117
|
+
ConfigModule([ConfigModule])
|
|
1118
|
+
ConfigurationListingModule
|
|
1119
|
+
ConfigurationModule
|
|
1120
|
+
CssModule
|
|
1121
|
+
CustomizationModule
|
|
1122
|
+
DeliveryModule
|
|
1123
|
+
DestinationsModule
|
|
1124
|
+
DiscoveryModule
|
|
1125
|
+
DocumentsModule
|
|
1126
|
+
HclModule
|
|
1127
|
+
InputsModule
|
|
1128
|
+
JsonModule
|
|
1129
|
+
JupyterModule
|
|
1130
|
+
LanguagesModule
|
|
1131
|
+
LimitsModule
|
|
1132
|
+
LoggerModule([LoggerModule])
|
|
1133
|
+
MainModule
|
|
1134
|
+
MarkdownModule
|
|
1135
|
+
MeasureModule
|
|
1136
|
+
PythonModule
|
|
1137
|
+
RenderModule
|
|
1138
|
+
ReportModule
|
|
1139
|
+
ShellModule
|
|
1140
|
+
SizeModule
|
|
1141
|
+
SqlModule
|
|
1142
|
+
TomlModule
|
|
1143
|
+
TypescriptModule
|
|
1144
|
+
YamlModule
|
|
1145
|
+
ChangesModule --> ChangesModule
|
|
1146
|
+
ChangesModule --> ConfigurationModule
|
|
1147
|
+
ChangesModule --> DocumentsModule
|
|
1148
|
+
ChangesModule --> RenderModule
|
|
1149
|
+
ConfigurationListingModule --> ConfigurationModule
|
|
1150
|
+
ConfigurationListingModule --> DiscoveryModule
|
|
1151
|
+
ConfigurationModule --> ConfigurationListingModule
|
|
1152
|
+
ConfigurationModule --> ConfigurationModule
|
|
1153
|
+
DeliveryModule --> JsonModule
|
|
1154
|
+
DeliveryModule --> MarkdownModule
|
|
1155
|
+
JupyterModule --> JsonModule
|
|
1156
|
+
JupyterModule --> MarkdownModule
|
|
1157
|
+
JupyterModule --> PythonModule
|
|
1158
|
+
LanguagesModule --> CommentsModule
|
|
1159
|
+
LanguagesModule --> CssModule
|
|
1160
|
+
LanguagesModule --> HclModule
|
|
1161
|
+
LanguagesModule --> JsonModule
|
|
1162
|
+
LanguagesModule --> JupyterModule
|
|
1163
|
+
LanguagesModule --> MarkdownModule
|
|
1164
|
+
LanguagesModule --> PythonModule
|
|
1165
|
+
LanguagesModule --> ShellModule
|
|
1166
|
+
LanguagesModule --> SqlModule
|
|
1167
|
+
LanguagesModule --> TomlModule
|
|
1168
|
+
LanguagesModule --> TypescriptModule
|
|
1169
|
+
LanguagesModule --> YamlModule
|
|
1170
|
+
MainModule --> ChangesModule
|
|
1171
|
+
MainModule --> ConfigurationModule
|
|
1172
|
+
MainModule --> ConfigurationModule
|
|
1173
|
+
MainModule --> DiscoveryModule
|
|
1174
|
+
MainModule --> DiscoveryModule
|
|
1175
|
+
MainModule --> JsonModule
|
|
1176
|
+
MainModule --> MarkdownModule
|
|
1177
|
+
MainModule --> MeasureModule
|
|
1178
|
+
MeasureModule --> ConfigurationModule
|
|
1179
|
+
MeasureModule --> ConfigurationModule
|
|
1180
|
+
MeasureModule --> CustomizationModule
|
|
1181
|
+
MeasureModule --> DeliveryModule
|
|
1182
|
+
MeasureModule --> DestinationsModule
|
|
1183
|
+
MeasureModule --> DiscoveryModule
|
|
1184
|
+
MeasureModule --> InputsModule
|
|
1185
|
+
MeasureModule --> LanguagesModule
|
|
1186
|
+
MeasureModule --> LimitsModule
|
|
1187
|
+
MeasureModule --> MeasureModule
|
|
1188
|
+
MeasureModule --> ReportModule
|
|
1189
|
+
MeasureModule --> SizeModule
|
|
1190
|
+
TypescriptModule --> CommentsModule
|
|
1191
|
+
```
|
|
1192
|
+
|
|
1193
|
+
_Rounded modules are global: every module can inject them, so their edges are left out._
|
|
1194
|
+
<!-- codependix:end name="codependix-nestjs-modules" -->
|
|
1195
|
+
|
|
1196
|
+
### File Imports
|
|
1197
|
+
|
|
1198
|
+
<!-- codependix:start name="codependix-file-imports" -->
|
|
1199
|
+
```mermaid
|
|
1200
|
+
graph LR
|
|
1201
|
+
file_callidescope_config_ts["callidescope.config.ts"]
|
|
1202
|
+
file_codependix_config_ts["codependix.config.ts"]
|
|
1203
|
+
file_codometer_config_ts["codometer.config.ts"]
|
|
1204
|
+
file_eslint_config_ts["eslint.config.ts"]
|
|
1205
|
+
file_src_constants_ts["src/constants.ts"]
|
|
1206
|
+
file_src_index_ts["src/index.ts"]
|
|
1207
|
+
file_src_main_end_to_end_test_ts["src/main.end-to-end.test.ts"]
|
|
1208
|
+
file_src_main_module_ts["src/main.module.ts"]
|
|
1209
|
+
file_src_main_ts["src/main.ts"]
|
|
1210
|
+
file_src_main_utilities_ts["src/main.utilities.ts"]
|
|
1211
|
+
file_src_main_utilities_unit_test_ts["src/main.utilities.unit.test.ts"]
|
|
1212
|
+
file_src_modules_changes_changes_command_ts["src/modules/changes/changes.command.ts"]
|
|
1213
|
+
file_src_modules_changes_changes_command_unit_test_ts["src/modules/changes/changes.command.unit.test.ts"]
|
|
1214
|
+
file_src_modules_changes_changes_constants_ts["src/modules/changes/changes.constants.ts"]
|
|
1215
|
+
file_src_modules_changes_changes_module_ts["src/modules/changes/changes.module.ts"]
|
|
1216
|
+
file_src_modules_changes_changes_types_ts["src/modules/changes/changes.types.ts"]
|
|
1217
|
+
file_src_modules_configuration_configuration_command_ts["src/modules/configuration/configuration.command.ts"]
|
|
1218
|
+
file_src_modules_configuration_configuration_command_unit_test_ts["src/modules/configuration/configuration.command.unit.test.ts"]
|
|
1219
|
+
file_src_modules_configuration_configuration_constants_ts["src/modules/configuration/configuration.constants.ts"]
|
|
1220
|
+
file_src_modules_configuration_configuration_module_ts["src/modules/configuration/configuration.module.ts"]
|
|
1221
|
+
file_src_modules_configuration_configuration_types_ts["src/modules/configuration/configuration.types.ts"]
|
|
1222
|
+
file_src_modules_measure_measure_command_integration_test_ts["src/modules/measure/measure.command.integration.test.ts"]
|
|
1223
|
+
file_src_modules_measure_measure_command_ts["src/modules/measure/measure.command.ts"]
|
|
1224
|
+
file_src_modules_measure_measure_command_unit_test_ts["src/modules/measure/measure.command.unit.test.ts"]
|
|
1225
|
+
file_src_modules_measure_measure_constants_ts["src/modules/measure/measure.constants.ts"]
|
|
1226
|
+
file_src_modules_measure_measure_module_ts["src/modules/measure/measure.module.ts"]
|
|
1227
|
+
file_src_modules_measure_measure_types_ts["src/modules/measure/measure.types.ts"]
|
|
1228
|
+
file_src_repl_ts["src/repl.ts"]
|
|
1229
|
+
file_src_repl_unit_test_ts["src/repl.unit.test.ts"]
|
|
1230
|
+
file_testing_fixture_tree_ts["testing/fixture-tree.ts"]
|
|
1231
|
+
file_testing_mocks_ts["testing/mocks.ts"]
|
|
1232
|
+
file_testing_setup_ts["testing/setup.ts"]
|
|
1233
|
+
file_testing_target_tree_ts["testing/target-tree.ts"]
|
|
1234
|
+
file_vite_config_ts["vite.config.ts"]
|
|
1235
|
+
file_vitest_config_ts["vitest.config.ts"]
|
|
1236
|
+
file_src_main_end_to_end_test_ts --> file_src_constants_ts
|
|
1237
|
+
file_src_main_end_to_end_test_ts --> file_testing_fixture_tree_ts
|
|
1238
|
+
file_src_main_module_ts --> file_src_constants_ts
|
|
1239
|
+
file_src_main_module_ts --> file_src_modules_changes_changes_module_ts
|
|
1240
|
+
file_src_main_module_ts --> file_src_modules_configuration_configuration_module_ts
|
|
1241
|
+
file_src_main_module_ts --> file_src_modules_measure_measure_module_ts
|
|
1242
|
+
file_src_main_ts --> file_src_main_module_ts
|
|
1243
|
+
file_src_main_ts --> file_src_main_utilities_ts
|
|
1244
|
+
file_src_main_utilities_unit_test_ts --> file_src_main_utilities_ts
|
|
1245
|
+
file_src_modules_changes_changes_command_ts --> file_src_modules_changes_changes_types_ts
|
|
1246
|
+
file_src_modules_changes_changes_command_unit_test_ts --> file_src_modules_changes_changes_command_ts
|
|
1247
|
+
file_src_modules_changes_changes_module_ts --> file_src_modules_changes_changes_command_ts
|
|
1248
|
+
file_src_modules_configuration_configuration_command_ts --> file_src_modules_configuration_configuration_constants_ts
|
|
1249
|
+
file_src_modules_configuration_configuration_command_ts --> file_src_modules_configuration_configuration_types_ts
|
|
1250
|
+
file_src_modules_configuration_configuration_command_unit_test_ts --> file_src_modules_configuration_configuration_command_ts
|
|
1251
|
+
file_src_modules_configuration_configuration_module_ts --> file_src_modules_configuration_configuration_command_ts
|
|
1252
|
+
file_src_modules_measure_measure_command_integration_test_ts --> file_src_main_module_ts
|
|
1253
|
+
file_src_modules_measure_measure_command_integration_test_ts --> file_src_modules_measure_measure_command_ts
|
|
1254
|
+
file_src_modules_measure_measure_command_integration_test_ts --> file_testing_fixture_tree_ts
|
|
1255
|
+
file_src_modules_measure_measure_command_ts --> file_src_modules_measure_measure_types_ts
|
|
1256
|
+
file_src_modules_measure_measure_command_unit_test_ts --> file_src_modules_measure_measure_command_ts
|
|
1257
|
+
file_src_modules_measure_measure_command_unit_test_ts --> file_testing_mocks_ts
|
|
1258
|
+
file_src_modules_measure_measure_module_ts --> file_src_modules_measure_measure_command_ts
|
|
1259
|
+
file_src_repl_ts --> file_src_main_module_ts
|
|
1260
|
+
```
|
|
1261
|
+
<!-- codependix:end name="codependix-file-imports" -->
|
|
1262
|
+
|
|
1263
|
+
<!-- codometer:start -->
|
|
1264
|
+
|
|
1265
|
+
## ⏲️ Codometer Output
|
|
1266
|
+
|
|
1267
|
+
### Project
|
|
1268
|
+
|
|
1269
|
+

|
|
1270
|
+

|
|
1271
|
+

|
|
1272
|
+

|
|
1273
|
+
|
|
1274
|
+
### Measured Targets
|
|
1275
|
+
|
|
1276
|
+

|
|
1277
|
+
|
|
1278
|
+
### TypeScript
|
|
1279
|
+
|
|
1280
|
+

|
|
1281
|
+

|
|
1282
|
+

|
|
1283
|
+

|
|
1284
|
+

|
|
1285
|
+

|
|
1286
|
+

|
|
1287
|
+
|
|
1288
|
+
### JavaScript
|
|
1289
|
+
|
|
1290
|
+

|
|
1291
|
+

|
|
1292
|
+

|
|
1293
|
+

|
|
1294
|
+

|
|
1295
|
+

|
|
1296
|
+

|
|
1297
|
+

|
|
1298
|
+

|
|
1299
|
+

|
|
1300
|
+

|
|
1301
|
+

|
|
1302
|
+

|
|
1303
|
+

|
|
1304
|
+
|
|
1305
|
+
### Python
|
|
1306
|
+
|
|
1307
|
+

|
|
1308
|
+

|
|
1309
|
+

|
|
1310
|
+

|
|
1311
|
+

|
|
1312
|
+

|
|
1313
|
+

|
|
1314
|
+

|
|
1315
|
+

|
|
1316
|
+

|
|
1317
|
+

|
|
1318
|
+

|
|
1319
|
+
|
|
1320
|
+
### JSON
|
|
1321
|
+
|
|
1322
|
+

|
|
1323
|
+

|
|
1324
|
+

|
|
1325
|
+

|
|
1326
|
+

|
|
1327
|
+

|
|
1328
|
+

|
|
1329
|
+

|
|
1330
|
+

|
|
1331
|
+

|
|
1332
|
+

|
|
1333
|
+

|
|
1334
|
+
|
|
1335
|
+
### YAML
|
|
1336
|
+
|
|
1337
|
+

|
|
1338
|
+

|
|
1339
|
+

|
|
1340
|
+

|
|
1341
|
+

|
|
1342
|
+

|
|
1343
|
+

|
|
1344
|
+

|
|
1345
|
+

|
|
1346
|
+

|
|
1347
|
+

|
|
1348
|
+
|
|
1349
|
+
### TOML
|
|
1350
|
+
|
|
1351
|
+

|
|
1352
|
+

|
|
1353
|
+

|
|
1354
|
+

|
|
1355
|
+

|
|
1356
|
+

|
|
1357
|
+

|
|
1358
|
+
|
|
1359
|
+
### Shell
|
|
1360
|
+
|
|
1361
|
+

|
|
1362
|
+

|
|
1363
|
+

|
|
1364
|
+

|
|
1365
|
+

|
|
1366
|
+

|
|
1367
|
+

|
|
1368
|
+

|
|
1369
|
+

|
|
1370
|
+

|
|
1371
|
+

|
|
1372
|
+
|
|
1373
|
+
### SQL
|
|
1374
|
+
|
|
1375
|
+

|
|
1376
|
+

|
|
1377
|
+

|
|
1378
|
+

|
|
1379
|
+

|
|
1380
|
+

|
|
1381
|
+

|
|
1382
|
+

|
|
1383
|
+

|
|
1384
|
+

|
|
1385
|
+

|
|
1386
|
+
|
|
1387
|
+
### HCL
|
|
1388
|
+
|
|
1389
|
+

|
|
1390
|
+

|
|
1391
|
+

|
|
1392
|
+

|
|
1393
|
+

|
|
1394
|
+

|
|
1395
|
+

|
|
1396
|
+

|
|
1397
|
+

|
|
1398
|
+
|
|
1399
|
+
### CSS
|
|
1400
|
+
|
|
1401
|
+

|
|
1402
|
+

|
|
1403
|
+

|
|
1404
|
+

|
|
1405
|
+

|
|
1406
|
+

|
|
1407
|
+

|
|
1408
|
+

|
|
1409
|
+

|
|
1410
|
+
|
|
1411
|
+
### Conventions
|
|
1412
|
+
|
|
1413
|
+

|
|
1414
|
+

|
|
1415
|
+

|
|
1416
|
+

|
|
1417
|
+

|
|
1418
|
+

|
|
1419
|
+

|
|
1420
|
+

|
|
1421
|
+

|
|
1422
|
+

|
|
1423
|
+

|
|
1424
|
+

|
|
1425
|
+

|
|
1426
|
+

|
|
1427
|
+

|
|
1428
|
+

|
|
1429
|
+

|
|
1430
|
+

|
|
1431
|
+
|
|
1432
|
+
### Jupyter
|
|
1433
|
+
|
|
1434
|
+

|
|
1435
|
+

|
|
1436
|
+

|
|
1437
|
+

|
|
1438
|
+

|
|
1439
|
+

|
|
1440
|
+

|
|
1441
|
+

|
|
1442
|
+

|
|
1443
|
+

|
|
1444
|
+

|
|
1445
|
+

|
|
1446
|
+

|
|
1447
|
+

|
|
1448
|
+

|
|
1449
|
+

|
|
1450
|
+

|
|
1451
|
+

|
|
1452
|
+

|
|
1453
|
+

|
|
1454
|
+
|
|
1455
|
+
### Markdown
|
|
1456
|
+
|
|
1457
|
+

|
|
1458
|
+

|
|
1459
|
+

|
|
1460
|
+

|
|
1461
|
+

|
|
1462
|
+

|
|
1463
|
+

|
|
1464
|
+

|
|
1465
|
+

|
|
1466
|
+

|
|
1467
|
+

|
|
1468
|
+

|
|
1469
|
+

|
|
1470
|
+

|
|
1471
|
+

|
|
1472
|
+

|
|
1473
|
+

|
|
1474
|
+

|
|
1475
|
+

|
|
1476
|
+

|
|
1477
|
+
<!-- codometer:end -->
|