@heroiclands/package-build 8.0.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +173 -0
- package/bin/content-build.mjs +44 -118
- package/bin/package-build.mjs +27 -69
- package/bin/report.mjs +1 -2
- package/bundle.mjs +2 -10
- package/config.mjs +31 -106
- package/container.mjs +13 -57
- package/content-config.mjs +45 -164
- package/coverage.mjs +14 -55
- package/deploy.mjs +4 -13
- package/e2e.mjs +16 -55
- package/engine/address-diff.mjs +1 -4
- package/engine/base-compiler.mjs +10 -28
- package/engine/code-fences.mjs +4 -13
- package/engine/compendiums.mjs +13 -37
- package/engine/content-address.mjs +2 -6
- package/engine/content-links.mjs +13 -44
- package/engine/content-lint.mjs +4 -15
- package/engine/content-slug.mjs +2 -6
- package/engine/content-tables.mjs +26 -79
- package/engine/diagnostics.mjs +4 -15
- package/engine/field-reference.mjs +6 -20
- package/engine/field-spec.mjs +1 -3
- package/engine/foreign-catalog.mjs +7 -22
- package/engine/foreign-manifests.mjs +1 -4
- package/engine/frontmatter-lint.mjs +6 -18
- package/engine/frontmatter.mjs +3 -8
- package/engine/generate.mjs +4 -16
- package/engine/helpers.mjs +13 -52
- package/engine/homepage.mjs +4 -15
- package/engine/ids.mjs +3 -12
- package/engine/item-registry.mjs +2 -6
- package/engine/journals.mjs +4 -14
- package/engine/kb-manifest.mjs +5 -17
- package/engine/macros.mjs +2 -10
- package/engine/manifest-emit.mjs +6 -17
- package/engine/map-notes.mjs +19 -69
- package/engine/note-package.mjs +1 -4
- package/engine/pack-config.mjs +17 -38
- package/engine/pack-router.mjs +1 -2
- package/engine/prose-config.mjs +20 -4
- package/engine/prose-lint.mjs +6 -14
- package/engine/region-events.mjs +1 -3
- package/engine/scene-levels.mjs +8 -22
- package/engine/scenes.mjs +13 -47
- package/engine/schema-check.mjs +1 -4
- package/engine/schema-extract.mjs +70 -45
- package/engine/site-build.mjs +12 -37
- package/engine/site-index.mjs +3 -15
- package/engine/web-wikilinks.mjs +4 -13
- package/engine/wikilinks.mjs +115 -167
- package/index.mjs +1 -5
- package/lang.mjs +1 -3
- package/manifest.mjs +10 -37
- package/markdownlint-config.mjs +1 -5
- package/package.json +1 -1
- package/sohl/actors.mjs +10 -40
- package/sohl/being-info.mjs +3 -6
- package/sohl/index.mjs +1 -6
- package/sohl/item-builders.mjs +1 -3
- package/sohl/item-fields.mjs +16 -34
- package/sohl/items.mjs +1 -3
- package/sohl/kb-passes.mjs +29 -39
- package/sohl/skill-base.mjs +7 -23
- package/stage.mjs +3 -13
- package/templates.mjs +4 -15
- package/types/bundle.d.mts +1 -1
- package/types/container.d.mts +2 -2
- package/types/coverage.d.mts +1 -1
- package/types/e2e.d.mts +4 -4
- package/types/engine/generate.d.mts +1 -1
- package/types/engine/helpers.d.mts +1 -1
- package/types/engine/schema-extract.d.mts +1 -1
- package/types/engine/site-index.d.mts +1 -1
- package/types/manifest.d.mts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,178 @@
|
|
|
1
1
|
# @heroiclands/package-build
|
|
2
2
|
|
|
3
|
+
## 9.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 8e48f7e: Raise the shared `printWidth` from 80 to 100.
|
|
8
|
+
|
|
9
|
+
**Breaking for every consumer**, in the one way this configuration always is: a
|
|
10
|
+
repository that updates and runs `lint:format` will find every file reported
|
|
11
|
+
until it reformats. Nothing about a built package, an emitted document or a
|
|
12
|
+
manifest changes — this is hygiene, and it reaches users not at all.
|
|
13
|
+
|
|
14
|
+
**80 was inherited, not chosen.** The usual argument for it is reading measure,
|
|
15
|
+
and that argument does not apply here: `proseWrap` is left at Prettier's default
|
|
16
|
+
of `preserve`, so authored prose is **never reflowed**. Measured across the
|
|
17
|
+
content trees, prose lines run to a p90 of 378 characters and a maximum of
|
|
18
|
+
5,531, entirely untouched by this number. What `printWidth` actually governs is
|
|
19
|
+
TypeScript and the YAML of a note's frontmatter.
|
|
20
|
+
|
|
21
|
+
**Both were measurably cramped.** Reformatting a third of the SoHL source at
|
|
22
|
+
each width:
|
|
23
|
+
|
|
24
|
+
| width | total lines | vs 80 | lines still over width |
|
|
25
|
+
| ----- | ----------- | ----- | ---------------------- |
|
|
26
|
+
| 80 | 31,198 | — | **1,399** |
|
|
27
|
+
| 90 | 30,328 | −2.8% | 193 |
|
|
28
|
+
| 100 | 29,672 | −4.9% | 75 |
|
|
29
|
+
| 120 | 28,850 | −7.5% | 25 |
|
|
30
|
+
|
|
31
|
+
The last column is the argument. At 80, Prettier _cannot_ honour the limit on
|
|
32
|
+
1,399 lines — long string literals, `@src/…` specifiers, generic signatures — so
|
|
33
|
+
those lines are over-width regardless and their surroundings were broken up for
|
|
34
|
+
nothing. At 100 that falls to 75.
|
|
35
|
+
|
|
36
|
+
The same knee appears in content. An item entry written in flow style —
|
|
37
|
+
`{ shortcode: X, type: skill, name: …, system: { … } }` — typically lands in the
|
|
38
|
+
low 90s, so of 318,030 entries across the two largest trees, 90.8% fit on one
|
|
39
|
+
line at 80 and **95.3% at 100**, with almost nothing gained in between. 120 buys
|
|
40
|
+
another 0.8 points and is not worth a second reformat.
|
|
41
|
+
|
|
42
|
+
**This package's own config stops restating the values.** `prettier.config.js`
|
|
43
|
+
carried its own copy of all twelve options with a comment saying they were
|
|
44
|
+
"matched to" the SoHL repository — already the wrong authority once
|
|
45
|
+
`PRETTIER_BASE` existed here, and a copy is a copy: raising the width would have
|
|
46
|
+
left the package that _defines_ the shared style as the one repository not
|
|
47
|
+
written in it. It now re-exports `PRETTIER_CONFIG`, so there is nothing left to
|
|
48
|
+
drift.
|
|
49
|
+
|
|
50
|
+
This release reformats this repository: 147 files, 2,677 lines shorter.
|
|
51
|
+
|
|
52
|
+
**Bump**
|
|
53
|
+
|
|
54
|
+
_Major._ Consumers' `lint:format` fails until they reformat, which is the whole
|
|
55
|
+
of the breakage and is a one-command fix.
|
|
56
|
+
|
|
57
|
+
## 8.1.0
|
|
58
|
+
|
|
59
|
+
### Minor Changes
|
|
60
|
+
|
|
61
|
+
- 333c340: Follow a spread of an imported schema function, and refuse a computed field name.
|
|
62
|
+
|
|
63
|
+
Two defects in `package-build schema`, both found by running it against real
|
|
64
|
+
content rather than by reading it.
|
|
65
|
+
|
|
66
|
+
**A shared base schema spread from another file was dropped, in silence.** A
|
|
67
|
+
concrete DataModel spreads a shared builder by name — `...defineSohlDataSchema()`
|
|
68
|
+
— and the resolver looked for that function only in the file doing the
|
|
69
|
+
spreading. When it was imported, the lookup found nothing and the spread
|
|
70
|
+
contributed nothing, with no error: a spread of a missing function read exactly
|
|
71
|
+
like a spread of an empty one.
|
|
72
|
+
|
|
73
|
+
The effect was not small. Every SoHL Item and Actor subtype lost `shortcode`,
|
|
74
|
+
`actionDefs`, `lastRun` and `scheduledActions` from the published schema. So
|
|
75
|
+
content correctly authoring `system.shortcode` — which SoHL requires to be
|
|
76
|
+
unique per `(type, shortcode)` on an actor, and which content therefore sets
|
|
77
|
+
deliberately — was reported as emitting a field no DataModel declares. The check
|
|
78
|
+
was accusing the content of the reader's own blind spot, which is worse than not
|
|
79
|
+
checking: it is a false accusation delivered with the same confidence as a true
|
|
80
|
+
one.
|
|
81
|
+
|
|
82
|
+
An imported spread is now resolved through the import, with a same-file
|
|
83
|
+
definition still taking precedence.
|
|
84
|
+
|
|
85
|
+
**A computed field name is now refused rather than published as source text.**
|
|
86
|
+
`[`${name}Date`]: worldTimeDateField()` takes its real name from an argument
|
|
87
|
+
this reader does not evaluate, and the previous behaviour handed back the source
|
|
88
|
+
text — putting a field called ``[`${name}Date`]`` into the schema. That field
|
|
89
|
+
matches nothing any builder could emit: absent for checking purposes while
|
|
90
|
+
looking present, and permanently reported as unemitted.
|
|
91
|
+
|
|
92
|
+
It now stops, naming the file and the key:
|
|
93
|
+
|
|
94
|
+
```text
|
|
95
|
+
temporal-fields.ts declares a schema field with a computed name,
|
|
96
|
+
`[`${name}DurationFormula`]`, whose value depends on an argument this reader
|
|
97
|
+
does not evaluate. Write the keys out so the published schema can name them.
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Stopping is the same stance `compareFields` already takes on an artifact of the
|
|
101
|
+
wrong version: the schema is a contract other repositories read, so a contract
|
|
102
|
+
this cannot state is worth failing for rather than approximating. The fix
|
|
103
|
+
belongs at the source, where the names are actually decided.
|
|
104
|
+
|
|
105
|
+
**Bump**
|
|
106
|
+
|
|
107
|
+
_Minor._ Repositories whose schemas spread an imported builder will publish more
|
|
108
|
+
fields than before — which is the correction. A repository using computed field
|
|
109
|
+
names now fails where it previously produced a wrong artifact; none does today
|
|
110
|
+
except the one this was found on, and that is being fixed at the source.
|
|
111
|
+
|
|
112
|
+
### Patch Changes
|
|
113
|
+
|
|
114
|
+
- 2319a56: Bump `markdown-it` from 15.0.0 to 15.0.1 (#121).
|
|
115
|
+
|
|
116
|
+
The surface is unchanged from the 15.0.0 adoption: one constructor,
|
|
117
|
+
`markdownit({ html: true })` in `engine/helpers.mjs`, and three `md.render()`
|
|
118
|
+
call sites — `engine/helpers.mjs`, `engine/journals.mjs` and `sohl/actors.mjs`.
|
|
119
|
+
No plugin is installed, no renderer rule is overridden, and `linkify` is left at
|
|
120
|
+
its default `false`. That last fact decides most of this release.
|
|
121
|
+
|
|
122
|
+
**Two of the five changes cannot reach a build that never linkifies.**
|
|
123
|
+
|
|
124
|
+
| Release note | Reaches here? |
|
|
125
|
+
| --------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
126
|
+
| _Security:_ quadratic complexity replacing fuzzy links | No — `linkify` is `false`, so the fuzzy-link replacer never runs |
|
|
127
|
+
| _Security:_ quadratic complexity in scheme backscan | No — same; the rule is the inline **linkify** rule |
|
|
128
|
+
| Preserve brackets around IPv6 literals in `normalizeLink` | Yes, in principle — no content in any consumer writes one |
|
|
129
|
+
| Preserve spaces in all-space code spans (#1180) | Yes, for runs of three or more spaces only |
|
|
130
|
+
| Code spans after unclosed link/image labels (#1201) | Yes, for an unclosed `[` followed by an odd-length backtick run |
|
|
131
|
+
|
|
132
|
+
Calling the first two "security" fixes is upstream's framing and the honest
|
|
133
|
+
reading of it here is that this package was never exposed: both are complexity
|
|
134
|
+
bounds on `linkify-it` code paths that are unreachable with the linkifier off.
|
|
135
|
+
Taking the bump is hygiene, not remediation.
|
|
136
|
+
|
|
137
|
+
**The three real fixes were measured, not assumed.** Both versions were rendered
|
|
138
|
+
through `markdownit({ html: true })` — this package's exact configuration — and
|
|
139
|
+
compared:
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
a ` ` b 15.0.0 → <p>a <code> </code> b</p> 15.0.1 → <p>a <code> </code> b</p>
|
|
143
|
+
[`a`b` 15.0.0 → <p>[`a`b`</p> 15.0.1 → <p>[<code>a</code>b`</p>
|
|
144
|
+
[x](http://[::1]/)
|
|
145
|
+
15.0.0 → href="http://%5B::1%5D/" 15.0.1 → href="http://[::1]/"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Each has a narrow trigger. The code-span fix moves output only at three spaces
|
|
149
|
+
or more — 15.0.0 stripped one space from each end of an all-space span, so one-
|
|
150
|
+
and two-space spans were already correct and stay byte-identical. The unclosed-
|
|
151
|
+
label fix needs the backtick run to be **odd**: `[Sword `hp`and`ac`` renders
|
|
152
|
+
the same on both, because its four backticks close. And the IPv6 fix only fires
|
|
153
|
+
on a bracketed address literal in a link, image or autolink destination, which
|
|
154
|
+
15.0.0 percent-encoded into a host no browser resolves.
|
|
155
|
+
|
|
156
|
+
**Verified against every consumer, and against a search rather than a guess.**
|
|
157
|
+
All 14,995 `.md` files across the six HeroicLands content repositories — `sohl`,
|
|
158
|
+
`hm3`, `thalorna`, `kethira`, `harnensemble` and `harnadventures` — were parsed
|
|
159
|
+
the way `parseMarkdownFile` parses them and rendered through both versions.
|
|
160
|
+
Every one is byte-identical. Scanning the same corpus explains why rather than
|
|
161
|
+
leaving it to luck: zero files contain an IPv6 URL, zero contain an all-space
|
|
162
|
+
code span of three or more spaces, and the 109 files that do use `` ` ` `` use
|
|
163
|
+
the one-space form the fix does not touch. Beyond the corpus, an exhaustive
|
|
164
|
+
render of all 488,280 strings up to eight characters over `[`, `]`, `` ` ``,
|
|
165
|
+
`x` and `!` — the alphabet the label-and-backtick fix is about — found the
|
|
166
|
+
divergence set to be exactly the shapes above and nothing else. The repository's
|
|
167
|
+
1,713 tests pass unchanged.
|
|
168
|
+
|
|
169
|
+
**Bump**
|
|
170
|
+
|
|
171
|
+
_Patch, not minor._ No export, option, or emitted document changes shape. The
|
|
172
|
+
only behaviour that moves is markdown that was rendered wrongly before, on
|
|
173
|
+
constructs no consumer writes, and the two changes advertised as security fixes
|
|
174
|
+
are unreachable from this configuration.
|
|
175
|
+
|
|
3
176
|
## 8.0.0
|
|
4
177
|
|
|
5
178
|
### Major Changes
|
package/bin/content-build.mjs
CHANGED
|
@@ -59,11 +59,7 @@ import log from "loglevel";
|
|
|
59
59
|
import prefix from "loglevel-plugin-prefix";
|
|
60
60
|
import yargs from "yargs";
|
|
61
61
|
import { hideBin } from "yargs/helpers";
|
|
62
|
-
import {
|
|
63
|
-
compilePacks,
|
|
64
|
-
cleanPacks,
|
|
65
|
-
unpackPacks,
|
|
66
|
-
} from "../engine/compendiums.mjs";
|
|
62
|
+
import { compilePacks, cleanPacks, unpackPacks } from "../engine/compendiums.mjs";
|
|
67
63
|
import { loadPackConfig } from "../engine/pack-config.mjs";
|
|
68
64
|
import {
|
|
69
65
|
fetchAllCatalogs,
|
|
@@ -93,11 +89,7 @@ import {
|
|
|
93
89
|
gatesFailed,
|
|
94
90
|
formatUnaddressableFinding as formatUnaddressable,
|
|
95
91
|
} from "../engine/site-build.mjs";
|
|
96
|
-
import {
|
|
97
|
-
auditLinks,
|
|
98
|
-
buildLinkIndex,
|
|
99
|
-
walkReachability,
|
|
100
|
-
} from "../engine/content-links.mjs";
|
|
92
|
+
import { auditLinks, buildLinkIndex, walkReachability } from "../engine/content-links.mjs";
|
|
101
93
|
import { emitDiagnostic, positionOfLiteral } from "../engine/diagnostics.mjs";
|
|
102
94
|
import {
|
|
103
95
|
readItemAddresses,
|
|
@@ -143,9 +135,7 @@ function configuredPacks() {
|
|
|
143
135
|
* @returns {string} The `version` field of this package's manifest.
|
|
144
136
|
*/
|
|
145
137
|
function ownVersion() {
|
|
146
|
-
return JSON.parse(
|
|
147
|
-
fs.readFileSync(new URL("../package.json", import.meta.url), "utf8"),
|
|
148
|
-
).version;
|
|
138
|
+
return JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
149
139
|
}
|
|
150
140
|
|
|
151
141
|
// Configure loglevel
|
|
@@ -176,8 +166,7 @@ prefix.apply(log, {
|
|
|
176
166
|
*/
|
|
177
167
|
function reportFailure(err) {
|
|
178
168
|
const message = err instanceof Error ? err.message : String(err);
|
|
179
|
-
if (/** @type {{located?: boolean}} */ (err)?.located)
|
|
180
|
-
console.error(message);
|
|
169
|
+
if (/** @type {{located?: boolean}} */ (err)?.located) console.error(message);
|
|
181
170
|
else log.error(message);
|
|
182
171
|
}
|
|
183
172
|
|
|
@@ -245,13 +234,11 @@ function docsCommand() {
|
|
|
245
234
|
choices: ["item-fields"],
|
|
246
235
|
});
|
|
247
236
|
yargs.option("out", {
|
|
248
|
-
describe:
|
|
249
|
-
"Write to this file instead of the configured location.",
|
|
237
|
+
describe: "Write to this file instead of the configured location.",
|
|
250
238
|
type: "string",
|
|
251
239
|
});
|
|
252
240
|
yargs.option("check", {
|
|
253
|
-
describe:
|
|
254
|
-
"Compare against the file already there; write nothing.",
|
|
241
|
+
describe: "Compare against the file already there; write nothing.",
|
|
255
242
|
type: "boolean",
|
|
256
243
|
default: false,
|
|
257
244
|
});
|
|
@@ -274,13 +261,10 @@ function docsCommand() {
|
|
|
274
261
|
const config = loadPackConfig();
|
|
275
262
|
const spec = config.docs?.itemFields ?? {};
|
|
276
263
|
const destination =
|
|
277
|
-
argv.out ??
|
|
278
|
-
(spec.out ? path.resolve(config.rootDir, spec.out) : null);
|
|
264
|
+
argv.out ?? (spec.out ? path.resolve(config.rootDir, spec.out) : null);
|
|
279
265
|
|
|
280
266
|
const page = `${renderItemFieldReference({
|
|
281
|
-
...((title ?? spec.title) ?
|
|
282
|
-
{ title: title ?? spec.title }
|
|
283
|
-
: {}),
|
|
267
|
+
...((title ?? spec.title) ? { title: title ?? spec.title } : {}),
|
|
284
268
|
...(spec.preamble ? { preamble: spec.preamble } : {}),
|
|
285
269
|
generatedBy: "`content-build docs item-fields`",
|
|
286
270
|
config,
|
|
@@ -296,9 +280,7 @@ function docsCommand() {
|
|
|
296
280
|
}
|
|
297
281
|
const relative = path.relative(config.rootDir, destination);
|
|
298
282
|
const current =
|
|
299
|
-
fs.existsSync(destination) ?
|
|
300
|
-
fs.readFileSync(destination, "utf8")
|
|
301
|
-
: "";
|
|
283
|
+
fs.existsSync(destination) ? fs.readFileSync(destination, "utf8") : "";
|
|
302
284
|
if (current !== page) {
|
|
303
285
|
// Staleness belongs to the whole file, so no line is
|
|
304
286
|
// named — the diagnostics contract drops a field it
|
|
@@ -321,9 +303,7 @@ function docsCommand() {
|
|
|
321
303
|
recursive: true,
|
|
322
304
|
});
|
|
323
305
|
fs.writeFileSync(destination, page);
|
|
324
|
-
log.info(
|
|
325
|
-
`Wrote ${path.relative(config.rootDir, destination)}`,
|
|
326
|
-
);
|
|
306
|
+
log.info(`Wrote ${path.relative(config.rootDir, destination)}`);
|
|
327
307
|
} else {
|
|
328
308
|
process.stdout.write(page);
|
|
329
309
|
}
|
|
@@ -353,8 +333,7 @@ function lintCommand() {
|
|
|
353
333
|
describe: "Check a content tree's addresses and frontmatter",
|
|
354
334
|
builder: (yargs) => {
|
|
355
335
|
yargs.positional("root", {
|
|
356
|
-
describe:
|
|
357
|
-
"Content tree to lint. Defaults to the configured contentBase.",
|
|
336
|
+
describe: "Content tree to lint. Defaults to the configured contentBase.",
|
|
358
337
|
type: "string",
|
|
359
338
|
});
|
|
360
339
|
yargs.option("references", {
|
|
@@ -468,9 +447,7 @@ function lintCommand() {
|
|
|
468
447
|
];
|
|
469
448
|
for (const finding of findings) emitDiagnostic(finding);
|
|
470
449
|
if (findings.length) {
|
|
471
|
-
log.error(
|
|
472
|
-
`${findings.length} finding(s) across ${addresses.notes} note(s).`,
|
|
473
|
-
);
|
|
450
|
+
log.error(`${findings.length} finding(s) across ${addresses.notes} note(s).`);
|
|
474
451
|
process.exitCode = 1;
|
|
475
452
|
} else {
|
|
476
453
|
log.info(
|
|
@@ -510,19 +487,16 @@ function formatCommand() {
|
|
|
510
487
|
describe: "Check formatting with the shared Prettier configuration",
|
|
511
488
|
builder: (yargs) => {
|
|
512
489
|
yargs.positional("paths", {
|
|
513
|
-
describe:
|
|
514
|
-
"Files or directories to check. Defaults to the whole repository.",
|
|
490
|
+
describe: "Files or directories to check. Defaults to the whole repository.",
|
|
515
491
|
type: "string",
|
|
516
492
|
});
|
|
517
493
|
yargs.option("write", {
|
|
518
|
-
describe:
|
|
519
|
-
"Rewrite unformatted files in place instead of reporting them.",
|
|
494
|
+
describe: "Rewrite unformatted files in place instead of reporting them.",
|
|
520
495
|
type: "boolean",
|
|
521
496
|
default: false,
|
|
522
497
|
});
|
|
523
498
|
yargs.option("check", {
|
|
524
|
-
describe:
|
|
525
|
-
"Report unformatted files without rewriting them (the default).",
|
|
499
|
+
describe: "Report unformatted files without rewriting them (the default).",
|
|
526
500
|
type: "boolean",
|
|
527
501
|
});
|
|
528
502
|
},
|
|
@@ -532,17 +506,15 @@ function formatCommand() {
|
|
|
532
506
|
// it contradicts `--write`; naming both is a mistake worth
|
|
533
507
|
// saying out loud rather than silently resolving.
|
|
534
508
|
if (argv.check === true && argv.write) {
|
|
535
|
-
log.error(
|
|
536
|
-
"--check and --write ask for opposite things; name one.",
|
|
537
|
-
);
|
|
509
|
+
log.error("--check and --write ask for opposite things; name one.");
|
|
538
510
|
process.exitCode = 1;
|
|
539
511
|
return;
|
|
540
512
|
}
|
|
541
513
|
const root = process.cwd();
|
|
542
|
-
const { findings, checked, written } = await checkFormatting(
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
);
|
|
514
|
+
const { findings, checked, written } = await checkFormatting(root, {
|
|
515
|
+
paths: argv.paths,
|
|
516
|
+
write: argv.write,
|
|
517
|
+
});
|
|
546
518
|
if (argv.write) {
|
|
547
519
|
log.info(
|
|
548
520
|
written.length ?
|
|
@@ -553,9 +525,7 @@ function formatCommand() {
|
|
|
553
525
|
}
|
|
554
526
|
for (const finding of findings) emitDiagnostic(finding);
|
|
555
527
|
if (findings.length) {
|
|
556
|
-
log.error(
|
|
557
|
-
`${findings.length} of ${checked} file(s) are not formatted.`,
|
|
558
|
-
);
|
|
528
|
+
log.error(`${findings.length} of ${checked} file(s) are not formatted.`);
|
|
559
529
|
process.exitCode = 1;
|
|
560
530
|
} else {
|
|
561
531
|
log.info(`Formatting is clean (${checked} file(s)).`);
|
|
@@ -586,8 +556,7 @@ function markdownCommand() {
|
|
|
586
556
|
describe: "Lint markdown with the shared markdownlint rule set",
|
|
587
557
|
builder: (yargs) => {
|
|
588
558
|
yargs.positional("paths", {
|
|
589
|
-
describe:
|
|
590
|
-
"Globs to lint. Defaults to every markdown file in the repository.",
|
|
559
|
+
describe: "Globs to lint. Defaults to every markdown file in the repository.",
|
|
591
560
|
type: "string",
|
|
592
561
|
});
|
|
593
562
|
yargs.option("fix", {
|
|
@@ -635,8 +604,7 @@ function linksCommand() {
|
|
|
635
604
|
describe: "Check that every link in a content tree lands somewhere",
|
|
636
605
|
builder: (yargs) => {
|
|
637
606
|
yargs.positional("root", {
|
|
638
|
-
describe:
|
|
639
|
-
"Content tree to check. Defaults to the configured contentBase.",
|
|
607
|
+
describe: "Content tree to check. Defaults to the configured contentBase.",
|
|
640
608
|
type: "string",
|
|
641
609
|
});
|
|
642
610
|
yargs.option("manifests", {
|
|
@@ -665,9 +633,7 @@ function linksCommand() {
|
|
|
665
633
|
message: `unusable link manifest: ${s.reason}`,
|
|
666
634
|
});
|
|
667
635
|
}
|
|
668
|
-
log.error(
|
|
669
|
-
"Refresh the vendored copy from that package's own build.",
|
|
670
|
-
);
|
|
636
|
+
log.error("Refresh the vendored copy from that package's own build.");
|
|
671
637
|
process.exitCode = 1;
|
|
672
638
|
return;
|
|
673
639
|
}
|
|
@@ -675,14 +641,10 @@ function linksCommand() {
|
|
|
675
641
|
// Readable is not the same as addressable: a key shape the
|
|
676
642
|
// lookup cannot parse makes every cross-package link miss, and
|
|
677
643
|
// the audit then blames the *notes*.
|
|
678
|
-
const drifted = unaddressableForeignPackages(
|
|
679
|
-
index.foreign.index,
|
|
680
|
-
);
|
|
644
|
+
const drifted = unaddressableForeignPackages(index.foreign.index);
|
|
681
645
|
if (drifted.length) {
|
|
682
646
|
for (const f of drifted) {
|
|
683
|
-
console.error(
|
|
684
|
-
formatUnaddressableFinding(f, manifestDir),
|
|
685
|
-
);
|
|
647
|
+
console.error(formatUnaddressableFinding(f, manifestDir));
|
|
686
648
|
}
|
|
687
649
|
process.exitCode = 1;
|
|
688
650
|
return;
|
|
@@ -744,9 +706,7 @@ function linksCommand() {
|
|
|
744
706
|
frontmatterLinks.length +
|
|
745
707
|
homepageLinks.length;
|
|
746
708
|
if (failures) {
|
|
747
|
-
log.error(
|
|
748
|
-
`${failures} link problem(s) across ${index.notes.length} note(s).`,
|
|
749
|
-
);
|
|
709
|
+
log.error(`${failures} link problem(s) across ${index.notes.length} note(s).`);
|
|
750
710
|
process.exitCode = 1;
|
|
751
711
|
} else {
|
|
752
712
|
log.info(
|
|
@@ -789,14 +749,12 @@ function manifestCommand() {
|
|
|
789
749
|
describe: "Emit this package's cross-package link manifest",
|
|
790
750
|
builder: (yargs) => {
|
|
791
751
|
yargs.positional("root", {
|
|
792
|
-
describe:
|
|
793
|
-
"Content tree to read. Defaults to the configured contentBase.",
|
|
752
|
+
describe: "Content tree to read. Defaults to the configured contentBase.",
|
|
794
753
|
type: "string",
|
|
795
754
|
});
|
|
796
755
|
yargs.option("out", {
|
|
797
756
|
describe:
|
|
798
|
-
"Directory to write into. Defaults to the configured " +
|
|
799
|
-
"`paths.manifestOut`.",
|
|
757
|
+
"Directory to write into. Defaults to the configured " + "`paths.manifestOut`.",
|
|
800
758
|
type: "string",
|
|
801
759
|
});
|
|
802
760
|
},
|
|
@@ -825,10 +783,7 @@ function manifestCommand() {
|
|
|
825
783
|
// lost its address becomes a dead link in every consumer.
|
|
826
784
|
for (const s of skipped) {
|
|
827
785
|
emitDiagnostic({
|
|
828
|
-
file: path.join(
|
|
829
|
-
argv.root ?? config.paths.content,
|
|
830
|
-
s.file,
|
|
831
|
-
),
|
|
786
|
+
file: path.join(argv.root ?? config.paths.content, s.file),
|
|
832
787
|
severity: "warning",
|
|
833
788
|
message: `no address, so it is absent from the manifest: ${s.reason}`,
|
|
834
789
|
});
|
|
@@ -864,8 +819,7 @@ function siteCommand() {
|
|
|
864
819
|
describe: "Build a Hugo content tree from the content tree",
|
|
865
820
|
builder: (yargs) => {
|
|
866
821
|
yargs.option("out", {
|
|
867
|
-
describe:
|
|
868
|
-
"Write the mount here instead of the configured `site.out`.",
|
|
822
|
+
describe: "Write the mount here instead of the configured `site.out`.",
|
|
869
823
|
type: "string",
|
|
870
824
|
});
|
|
871
825
|
},
|
|
@@ -903,26 +857,16 @@ function siteCommand() {
|
|
|
903
857
|
}
|
|
904
858
|
for (const s of gates.staleManifests) {
|
|
905
859
|
emitDiagnostic({
|
|
906
|
-
file: path.join(
|
|
907
|
-
loadPackConfig().paths.manifests,
|
|
908
|
-
`${s.package}.json`,
|
|
909
|
-
),
|
|
860
|
+
file: path.join(loadPackConfig().paths.manifests, `${s.package}.json`),
|
|
910
861
|
severity: "error",
|
|
911
862
|
message: `unusable link manifest: ${s.reason}`,
|
|
912
863
|
});
|
|
913
864
|
}
|
|
914
865
|
for (const f of gates.unaddressable) {
|
|
915
|
-
console.error(
|
|
916
|
-
formatUnaddressable(
|
|
917
|
-
f,
|
|
918
|
-
loadPackConfig().paths.manifests,
|
|
919
|
-
),
|
|
920
|
-
);
|
|
866
|
+
console.error(formatUnaddressable(f, loadPackConfig().paths.manifests));
|
|
921
867
|
}
|
|
922
868
|
for (const c of gates.conflicts) {
|
|
923
|
-
log.error(
|
|
924
|
-
`address ${c.key} is also published by ${c.package}`,
|
|
925
|
-
);
|
|
869
|
+
log.error(`address ${c.key} is also published by ${c.package}`);
|
|
926
870
|
}
|
|
927
871
|
if (gatesFailed(gates)) {
|
|
928
872
|
process.exitCode = 1;
|
|
@@ -937,9 +881,7 @@ function siteCommand() {
|
|
|
937
881
|
log.error(`bad content table: ${e.reason} (${e.source})`);
|
|
938
882
|
}
|
|
939
883
|
for (const e of result.wikiErrors) {
|
|
940
|
-
log.error(
|
|
941
|
-
`bad wikilink [[${e.target}]]: ${e.reason} (${e.file})`,
|
|
942
|
-
);
|
|
884
|
+
log.error(`bad wikilink [[${e.target}]]: ${e.reason} (${e.file})`);
|
|
943
885
|
}
|
|
944
886
|
if (result.tableErrors.length || result.wikiErrors.length) {
|
|
945
887
|
process.exitCode = 1;
|
|
@@ -989,8 +931,7 @@ function reachabilityCommand() {
|
|
|
989
931
|
describe: "Check that every document in a corpus is reachable",
|
|
990
932
|
builder: (yargs) => {
|
|
991
933
|
yargs.positional("dir", {
|
|
992
|
-
describe:
|
|
993
|
-
"The corpus directory, relative to the content tree root.",
|
|
934
|
+
describe: "The corpus directory, relative to the content tree root.",
|
|
994
935
|
type: "string",
|
|
995
936
|
});
|
|
996
937
|
yargs.positional("file", {
|
|
@@ -1008,8 +949,7 @@ function reachabilityCommand() {
|
|
|
1008
949
|
default: [],
|
|
1009
950
|
});
|
|
1010
951
|
yargs.option("root", {
|
|
1011
|
-
describe:
|
|
1012
|
-
"Content tree to read. Defaults to the configured contentBase.",
|
|
952
|
+
describe: "Content tree to read. Defaults to the configured contentBase.",
|
|
1013
953
|
type: "string",
|
|
1014
954
|
});
|
|
1015
955
|
},
|
|
@@ -1026,9 +966,7 @@ function reachabilityCommand() {
|
|
|
1026
966
|
stopAt: (n) => indexes.has(String(n.fm.shortcode)),
|
|
1027
967
|
});
|
|
1028
968
|
|
|
1029
|
-
const total = index.notes.filter((n) =>
|
|
1030
|
-
n.rel.startsWith(`${dir}/`),
|
|
1031
|
-
).length;
|
|
969
|
+
const total = index.notes.filter((n) => n.rel.startsWith(`${dir}/`)).length;
|
|
1032
970
|
|
|
1033
971
|
for (const o of orphans) {
|
|
1034
972
|
// Unreachability is a property of the whole document, so
|
|
@@ -1052,8 +990,7 @@ function reachabilityCommand() {
|
|
|
1052
990
|
process.exitCode = 1;
|
|
1053
991
|
} else {
|
|
1054
992
|
log.info(
|
|
1055
|
-
`All ${total} document(s) in ${dir} are reachable ` +
|
|
1056
|
-
`from ${argv.file}.`,
|
|
993
|
+
`All ${total} document(s) in ${dir} are reachable ` + `from ${argv.file}.`,
|
|
1057
994
|
);
|
|
1058
995
|
}
|
|
1059
996
|
} catch (err) {
|
|
@@ -1144,8 +1081,7 @@ function depsCommand() {
|
|
|
1144
1081
|
return;
|
|
1145
1082
|
}
|
|
1146
1083
|
const count = await fetchAllCatalogs(config);
|
|
1147
|
-
if (count)
|
|
1148
|
-
log.info(`Fetched ${count} dependency catalogue(s).`);
|
|
1084
|
+
if (count) log.info(`Fetched ${count} dependency catalogue(s).`);
|
|
1149
1085
|
} catch (err) {
|
|
1150
1086
|
reportFailure(err);
|
|
1151
1087
|
process.exitCode = 1;
|
|
@@ -1192,24 +1128,15 @@ async function diffAddresses(config, argv) {
|
|
|
1192
1128
|
...config,
|
|
1193
1129
|
paths: {
|
|
1194
1130
|
...config.paths,
|
|
1195
|
-
foreignCache: path.join(
|
|
1196
|
-
path.dirname(config.paths.foreignCache),
|
|
1197
|
-
"baseline",
|
|
1198
|
-
),
|
|
1131
|
+
foreignCache: path.join(path.dirname(config.paths.foreignCache), "baseline"),
|
|
1199
1132
|
},
|
|
1200
1133
|
};
|
|
1201
|
-
const dir = await fetchCatalogFromPath(
|
|
1202
|
-
cacheConfig,
|
|
1203
|
-
{ id: config.foundryPackage },
|
|
1204
|
-
argv.from,
|
|
1205
|
-
);
|
|
1134
|
+
const dir = await fetchCatalogFromPath(cacheConfig, { id: config.foundryPackage }, argv.from);
|
|
1206
1135
|
// `<id>@<version>`, which is what the diagnostics name the baseline by.
|
|
1207
1136
|
const label = path.basename(dir);
|
|
1208
1137
|
|
|
1209
1138
|
const itemsRoot = path.join(dir, "items");
|
|
1210
|
-
const baselineDirs = fs
|
|
1211
|
-
.readdirSync(itemsRoot)
|
|
1212
|
-
.map((name) => path.join(itemsRoot, name));
|
|
1139
|
+
const baselineDirs = fs.readdirSync(itemsRoot).map((name) => path.join(itemsRoot, name));
|
|
1213
1140
|
const currentDirs = itemPackJsonDirs(config);
|
|
1214
1141
|
if (!currentDirs.length) {
|
|
1215
1142
|
throw new Error(
|
|
@@ -1254,8 +1181,7 @@ async function diffAddresses(config, argv) {
|
|
|
1254
1181
|
function addressesCommand() {
|
|
1255
1182
|
return {
|
|
1256
1183
|
command: "addresses <action>",
|
|
1257
|
-
describe:
|
|
1258
|
-
"Compare the addresses this build publishes against a release's",
|
|
1184
|
+
describe: "Compare the addresses this build publishes against a release's",
|
|
1259
1185
|
builder: (yargs) => {
|
|
1260
1186
|
// Required, for the reason every other action is (#57): an
|
|
1261
1187
|
// optional one exits 0 having compared nothing.
|