@scientific-method/standard-checker 1.0.0 → 1.1.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/README.md +12 -2
- package/dist/checks/base.d.ts +2 -1
- package/dist/checks/base.js +69 -61
- package/dist/options.d.ts +2 -0
- package/dist/options.js +2 -1
- package/dist/standard-checker.js +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,6 +22,14 @@ step of the check did not run, it ends with `spec check passed with skipped step
|
|
|
22
22
|
`Skipped: Kaitai compilation of 2 definitions (--no-ksy).` A failing run lists the skipped steps
|
|
23
23
|
after its problems.
|
|
24
24
|
|
|
25
|
+
Without `--base`, the checker compares the spec with where HEAD forked from `origin/$GITHUB_BASE_REF`,
|
|
26
|
+
or from `origin/main` when that variable is unset. Outside a git repository, in a shallow clone, or
|
|
27
|
+
when that branch was never fetched, the fork point does not resolve and the comparison does not
|
|
28
|
+
run. The result line then names it, such as `Skipped: comparison with the base branch (HEAD has no
|
|
29
|
+
merge-base with origin/main, fetch it with enough history or pass --base).` Without git on `PATH`
|
|
30
|
+
the skipped step names the missing git instead. With `--require-base`, either case is a problem and
|
|
31
|
+
the run fails.
|
|
32
|
+
|
|
25
33
|
A problem that breaks a numbered rule of the standard ends with the rule's label in brackets, such
|
|
26
34
|
as `[STATUS-14]`. The standard opens that rule with the heading `###### STATUS-14`, anchored at
|
|
27
35
|
`#status-14` on the site and in the copies restorations vendor, so the rule can be read on its
|
|
@@ -34,7 +42,8 @@ problems under other sections carry no label yet.
|
|
|
34
42
|
|---|---|---|
|
|
35
43
|
| `--root <dir>` | The repository to check. | the current directory |
|
|
36
44
|
| `--check` | Fail when an index or `PARITY.md` is stale, instead of rewriting it. | rewrite |
|
|
37
|
-
| `--base <ref>` | Also fail when a spec ID, area or deviation that exists at `<ref>` is gone, or when a superseded format entry has no layout table although it had one at `<ref>`. | where HEAD forked from `origin/$GITHUB_BASE_REF` or `origin/main
|
|
45
|
+
| `--base <ref>` | Also fail when a spec ID, area or deviation that exists at `<ref>` is gone, or when a superseded format entry has no layout table although it had one at `<ref>`. | where HEAD forked from `origin/$GITHUB_BASE_REF` or `origin/main`; when that does not resolve, the comparison is named as skipped |
|
|
46
|
+
| `--require-base` | Fail when no `--base` is given and the fork point does not resolve, instead of passing with the comparison skipped. | pass with the comparison skipped |
|
|
38
47
|
| `--no-ksy` | Skip compiling the Kaitai definitions in `spec/formats/`. The result line names the skipped compilation. | compile |
|
|
39
48
|
| `--require-ksc` | Fail when `spec/formats/` holds Kaitai definitions and no compiler is found, instead of passing with the compilation skipped. | pass with the compilation skipped |
|
|
40
49
|
| `--glossary <path>` | Also accept the terms of a draft glossary file, or of a directory of them. | none |
|
|
@@ -63,7 +72,8 @@ prints a warning naming its path, with its output.
|
|
|
63
72
|
The toolkit's `actions/check-documentation` composite action runs this checker with `--check`,
|
|
64
73
|
installs a pinned Kaitai compiler when the repository has `.ksy` files (and then passes
|
|
65
74
|
`--require-ksc`), and exposes every option
|
|
66
|
-
above as an input.
|
|
75
|
+
above as an input. On a pull request with no `base` input, it fetches the base branch with enough
|
|
76
|
+
history for the fork point and passes `--require-base`. Pin the action to the toolkit commit whose `packages/standard-checker` matches
|
|
67
77
|
the version installed here, so CI and local runs apply the same checks.
|
|
68
78
|
|
|
69
79
|
[The documentation standard check guide](https://github.com/kibertoad/refurbished-dinosaurs-toolkit/blob/main/docs/documentation-standard-check.md)
|
package/dist/checks/base.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { Deviation } from "./deviations.ts";
|
|
|
3
3
|
/**
|
|
4
4
|
* Reports a spec ID, area or deviation that exists at the base (--base, or where HEAD forked from
|
|
5
5
|
* the base branch) and is gone now, and a superseded format entry whose Layout has no table although
|
|
6
|
-
* it had one at the base.
|
|
6
|
+
* it had one at the base. Without --base, a fork point that does not resolve is recorded as a
|
|
7
|
+
* skipped step, or with --require-base reported as a problem.
|
|
7
8
|
*/
|
|
8
9
|
export declare function checkBase(ctx: Context, deviations: Map<string, Deviation>): void;
|
package/dist/checks/base.js
CHANGED
|
@@ -6,15 +6,16 @@ import { splitSections, tables } from "../markdown.js";
|
|
|
6
6
|
/**
|
|
7
7
|
* Reports a spec ID, area or deviation that exists at the base (--base, or where HEAD forked from
|
|
8
8
|
* the base branch) and is gone now, and a superseded format entry whose Layout has no table although
|
|
9
|
-
* it had one at the base.
|
|
9
|
+
* it had one at the base. Without --base, a fork point that does not resolve is recorded as a
|
|
10
|
+
* skipped step, or with --require-base reported as a problem.
|
|
10
11
|
*/
|
|
11
12
|
export function checkBase(ctx, deviations) {
|
|
12
|
-
const { problem } = ctx;
|
|
13
|
+
const { problem, skip } = ctx;
|
|
13
14
|
const { entries, areas } = ctx.spec;
|
|
14
|
-
const { repoDir, baseArg } = ctx.config;
|
|
15
|
+
const { repoDir, baseArg, requireBase } = ctx.config;
|
|
15
16
|
// Without --base, compare with the point this branch left the base branch (the pull request's
|
|
16
17
|
// target in CI), not that branch's tip: an entry added on the base branch after this branch
|
|
17
|
-
// forked is not one this branch deleted.
|
|
18
|
+
// forked is not one this branch deleted. A base that resolves but cannot be listed is a problem.
|
|
18
19
|
const git = (...args) => execFileSync("git", ["-C", repoDir, ...args], { stdio: ["ignore", "pipe", "ignore"] }).toString();
|
|
19
20
|
let base = baseArg;
|
|
20
21
|
if (!base) {
|
|
@@ -22,68 +23,75 @@ export function checkBase(ctx, deviations) {
|
|
|
22
23
|
try {
|
|
23
24
|
base = git("merge-base", "HEAD", target).trim();
|
|
24
25
|
}
|
|
25
|
-
catch {
|
|
26
|
-
base
|
|
26
|
+
catch (error) {
|
|
27
|
+
// Outside a git repository, in a shallow clone, or without the base branch fetched, there is
|
|
28
|
+
// no fork point, and the deleted-ID checks cannot run. The run says so instead of reading as
|
|
29
|
+
// a full check.
|
|
30
|
+
const missing = error.code === "ENOENT"
|
|
31
|
+
? `git was not found to look up HEAD's merge-base with ${target}, install it or pass --base`
|
|
32
|
+
: `HEAD has no merge-base with ${target}, fetch it with enough history or pass --base`;
|
|
33
|
+
if (requireBase)
|
|
34
|
+
problem(null, `${missing}. --require-base requires the comparison with the base branch`);
|
|
35
|
+
else
|
|
36
|
+
skip(`comparison with the base branch (${missing})`);
|
|
37
|
+
return;
|
|
27
38
|
}
|
|
28
39
|
}
|
|
29
|
-
let listing
|
|
30
|
-
|
|
40
|
+
let listing;
|
|
41
|
+
try {
|
|
42
|
+
listing = git("ls-tree", "-r", "--name-only", base, "--", "spec", "deviations");
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
problem(null, `cannot list spec/ at ${base}`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
for (const p of listing.split("\n")) {
|
|
49
|
+
const m = /^spec\/(?:builds|sources|formats|rules|findings|experiments|bugs|screens)\/([A-Z]+-[A-Z0-9.-]+)\.md$/.exec(p);
|
|
50
|
+
if (m && !entries.has(m[1]))
|
|
51
|
+
problem(null, `${m[1]} exists at ${base} and has been deleted or renamed`, "IDENTIFIERS-6");
|
|
52
|
+
const d = /^deviations\/(DEV-[A-Z0-9]+-\d+)\.md$/.exec(p);
|
|
53
|
+
if (d && !deviations.has(d[1]))
|
|
54
|
+
problem(null, `${d[1]} exists at ${base} and has been deleted or renamed`);
|
|
55
|
+
}
|
|
56
|
+
// ./ makes the path relative to --root, which need not be the top of the repository. A file
|
|
57
|
+
// that does not exist at the base has nothing to compare, and each is read on its own so a
|
|
58
|
+
// missing README does not skip the deviation comparison.
|
|
59
|
+
const show = (path) => {
|
|
31
60
|
try {
|
|
32
|
-
|
|
61
|
+
return git("show", `${base}:./${path}`).replace(/\r\n/g, "\n");
|
|
33
62
|
}
|
|
34
63
|
catch {
|
|
35
|
-
|
|
36
|
-
problem(null, `cannot list spec/ at ${base}`);
|
|
64
|
+
return null;
|
|
37
65
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const oldAreaTable = oldAreaSection && tables(oldAreaSection.text)[0];
|
|
63
|
-
for (const row of (oldAreaTable || undefined)?.rows ?? []) {
|
|
64
|
-
const a = row[0].replaceAll("`", "");
|
|
65
|
-
if (!areas.includes(a))
|
|
66
|
-
problem(null, `area ${a} exists at ${base} and has been removed or renamed`, "IDENTIFIERS-5");
|
|
67
|
-
}
|
|
68
|
-
// The format checks let a superseded entry have no layout table, so one retired from unknown
|
|
69
|
-
// keeps its None known. A superseded entry stays as it was when it was replaced (IDENTIFIERS-7),
|
|
70
|
-
// so one that had a table at the base may not drop it on the way.
|
|
71
|
-
const layoutTables = (body) => {
|
|
72
|
-
const layout = splitSections(body).find((s) => s.title === "Layout");
|
|
73
|
-
return layout ? tables(layout.text).length : 0;
|
|
74
|
-
};
|
|
75
|
-
for (const e of entries.values()) {
|
|
76
|
-
if (e.kind !== "FMT" || e.meta.status !== "superseded" || layoutTables(e.body) > 0)
|
|
77
|
-
continue;
|
|
78
|
-
const old = show(relative(repoDir, e.file).replaceAll("\\", "/"));
|
|
79
|
-
if (old && layoutTables(old) > 0)
|
|
80
|
-
problem(e.file, `Layout has no table, but it had one at ${base}`, "IDENTIFIERS-7");
|
|
81
|
-
}
|
|
82
|
-
// A base from before the deviation log became a directory keeps its deviations in DEVIATIONS.md.
|
|
83
|
-
const oldDev = show("DEVIATIONS.md");
|
|
84
|
-
if (oldDev)
|
|
85
|
-
for (const m of oldDev.matchAll(/^## (DEV-[A-Z0-9]+-\d+)$/gm))
|
|
86
|
-
if (!deviations.has(m[1]))
|
|
87
|
-
problem(null, `${m[1]} exists at ${base} and has been removed`);
|
|
66
|
+
};
|
|
67
|
+
const oldReadme = show("spec/README.md");
|
|
68
|
+
// Reads the area table the way the current README is read, so areas with or without
|
|
69
|
+
// backticks are both found.
|
|
70
|
+
const oldAreaSection = oldReadme && splitSections(oldReadme).find((s) => s.title === "Areas");
|
|
71
|
+
const oldAreaTable = oldAreaSection && tables(oldAreaSection.text)[0];
|
|
72
|
+
for (const row of (oldAreaTable || undefined)?.rows ?? []) {
|
|
73
|
+
const a = row[0].replaceAll("`", "");
|
|
74
|
+
if (!areas.includes(a))
|
|
75
|
+
problem(null, `area ${a} exists at ${base} and has been removed or renamed`, "IDENTIFIERS-5");
|
|
76
|
+
}
|
|
77
|
+
// The format checks let a superseded entry have no layout table, so one retired from unknown
|
|
78
|
+
// keeps its None known. A superseded entry stays as it was when it was replaced (IDENTIFIERS-7),
|
|
79
|
+
// so one that had a table at the base may not drop it on the way.
|
|
80
|
+
const layoutTables = (body) => {
|
|
81
|
+
const layout = splitSections(body).find((s) => s.title === "Layout");
|
|
82
|
+
return layout ? tables(layout.text).length : 0;
|
|
83
|
+
};
|
|
84
|
+
for (const e of entries.values()) {
|
|
85
|
+
if (e.kind !== "FMT" || e.meta.status !== "superseded" || layoutTables(e.body) > 0)
|
|
86
|
+
continue;
|
|
87
|
+
const old = show(relative(repoDir, e.file).replaceAll("\\", "/"));
|
|
88
|
+
if (old && layoutTables(old) > 0)
|
|
89
|
+
problem(e.file, `Layout has no table, but it had one at ${base}`, "IDENTIFIERS-7");
|
|
88
90
|
}
|
|
91
|
+
// A base from before the deviation log became a directory keeps its deviations in DEVIATIONS.md.
|
|
92
|
+
const oldDev = show("DEVIATIONS.md");
|
|
93
|
+
if (oldDev)
|
|
94
|
+
for (const m of oldDev.matchAll(/^## (DEV-[A-Z0-9]+-\d+)$/gm))
|
|
95
|
+
if (!deviations.has(m[1]))
|
|
96
|
+
problem(null, `${m[1]} exists at ${base} and has been removed`);
|
|
89
97
|
}
|
package/dist/options.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface Config {
|
|
|
12
12
|
requireKsc: boolean;
|
|
13
13
|
/** --base, or null when it was not given. */
|
|
14
14
|
baseArg: string | null;
|
|
15
|
+
/** --require-base: fail when no --base is given and the base branch's fork point does not resolve. */
|
|
16
|
+
requireBase: boolean;
|
|
15
17
|
/** Every --glossary path, in order. */
|
|
16
18
|
glossaryDrafts: string[];
|
|
17
19
|
/** The --code directories, relative to repoDir. */
|
package/dist/options.js
CHANGED
|
@@ -10,7 +10,7 @@ export const dirList = (value, fallback) => value === undefined
|
|
|
10
10
|
.split(",")
|
|
11
11
|
.map((x) => x.trim())
|
|
12
12
|
.filter(Boolean);
|
|
13
|
-
const FLAGS = ["--check", "--no-ksy", "--require-ksc"];
|
|
13
|
+
const FLAGS = ["--check", "--no-ksy", "--require-ksc", "--require-base"];
|
|
14
14
|
const VALUED = [
|
|
15
15
|
"--root",
|
|
16
16
|
"--base",
|
|
@@ -82,6 +82,7 @@ export function parseOptions(argv) {
|
|
|
82
82
|
skipKsy,
|
|
83
83
|
requireKsc,
|
|
84
84
|
baseArg,
|
|
85
|
+
requireBase: options["require-base"] === true,
|
|
85
86
|
glossaryDrafts: options.glossary,
|
|
86
87
|
codeRoots,
|
|
87
88
|
referenceRoots,
|
package/dist/standard-checker.js
CHANGED
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
// --root <dir> the repository to check (default: the current directory)
|
|
10
10
|
// --check fail when an index or PARITY.md is stale instead of rewriting it
|
|
11
11
|
// --base <ref> also fail when an ID or area that exists at <ref> is gone (default: where
|
|
12
|
-
// HEAD forked from origin/$GITHUB_BASE_REF or origin/main
|
|
12
|
+
// HEAD forked from origin/$GITHUB_BASE_REF or origin/main; when that does not
|
|
13
|
+
// resolve, the result line names the comparison as skipped)
|
|
14
|
+
// --require-base fail when no --base is given and the fork point does not resolve, instead
|
|
15
|
+
// of passing with the comparison skipped
|
|
13
16
|
// --no-ksy skip compiling the Kaitai definitions; the result line names the skip
|
|
14
17
|
// --require-ksc fail when spec/formats/ holds Kaitai definitions and no compiler is found,
|
|
15
18
|
// instead of passing with the compilation skipped
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scientific-method/standard-checker",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Checks a restoration's spec/, parity/ and deviations/ against version 1 of the dinorefurb documentation standard.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|