@trofimyukdev/repo-truth 0.0.0-stage → 0.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.
Files changed (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +273 -2
  3. package/dist/action.d.ts +52 -0
  4. package/dist/action.js +182 -0
  5. package/dist/action.js.map +1 -0
  6. package/dist/checks/action-pins.d.ts +52 -0
  7. package/dist/checks/action-pins.js +196 -0
  8. package/dist/checks/action-pins.js.map +1 -0
  9. package/dist/checks/autosquash.d.ts +23 -0
  10. package/dist/checks/autosquash.js +85 -0
  11. package/dist/checks/autosquash.js.map +1 -0
  12. package/dist/checks/bidi-controls.d.ts +58 -0
  13. package/dist/checks/bidi-controls.js +172 -0
  14. package/dist/checks/bidi-controls.js.map +1 -0
  15. package/dist/checks/binary-files.d.ts +53 -0
  16. package/dist/checks/binary-files.js +157 -0
  17. package/dist/checks/binary-files.js.map +1 -0
  18. package/dist/checks/config-changes.d.ts +57 -0
  19. package/dist/checks/config-changes.js +175 -0
  20. package/dist/checks/config-changes.js.map +1 -0
  21. package/dist/checks/credentials.d.ts +35 -0
  22. package/dist/checks/credentials.js +138 -0
  23. package/dist/checks/credentials.js.map +1 -0
  24. package/dist/checks/install-scripts.d.ts +39 -0
  25. package/dist/checks/install-scripts.js +173 -0
  26. package/dist/checks/install-scripts.js.map +1 -0
  27. package/dist/checks/lint-rules.d.ts +49 -0
  28. package/dist/checks/lint-rules.js +184 -0
  29. package/dist/checks/lint-rules.js.map +1 -0
  30. package/dist/checks/path-policy.d.ts +40 -0
  31. package/dist/checks/path-policy.js +195 -0
  32. package/dist/checks/path-policy.js.map +1 -0
  33. package/dist/checks/raised-timeouts.d.ts +66 -0
  34. package/dist/checks/raised-timeouts.js +248 -0
  35. package/dist/checks/raised-timeouts.js.map +1 -0
  36. package/dist/checks/script-changes.d.ts +51 -0
  37. package/dist/checks/script-changes.js +199 -0
  38. package/dist/checks/script-changes.js.map +1 -0
  39. package/dist/checks/secret-files.d.ts +58 -0
  40. package/dist/checks/secret-files.js +165 -0
  41. package/dist/checks/secret-files.js.map +1 -0
  42. package/dist/checks/strictness.d.ts +59 -0
  43. package/dist/checks/strictness.js +260 -0
  44. package/dist/checks/strictness.js.map +1 -0
  45. package/dist/checks/submodules.d.ts +51 -0
  46. package/dist/checks/submodules.js +172 -0
  47. package/dist/checks/submodules.js.map +1 -0
  48. package/dist/checks/suppressions.d.ts +53 -0
  49. package/dist/checks/suppressions.js +203 -0
  50. package/dist/checks/suppressions.js.map +1 -0
  51. package/dist/checks/workflow-permissions.d.ts +56 -0
  52. package/dist/checks/workflow-permissions.js +237 -0
  53. package/dist/checks/workflow-permissions.js.map +1 -0
  54. package/dist/checks/workflow-weakening.d.ts +38 -0
  55. package/dist/checks/workflow-weakening.js +172 -0
  56. package/dist/checks/workflow-weakening.js.map +1 -0
  57. package/dist/cli.d.ts +31 -0
  58. package/dist/cli.js +300 -0
  59. package/dist/cli.js.map +1 -0
  60. package/dist/commit-range.d.ts +28 -0
  61. package/dist/commit-range.js +152 -0
  62. package/dist/commit-range.js.map +1 -0
  63. package/dist/config.d.ts +35 -0
  64. package/dist/config.js +235 -0
  65. package/dist/config.js.map +1 -0
  66. package/dist/conflict-markers.d.ts +40 -0
  67. package/dist/conflict-markers.js +234 -0
  68. package/dist/conflict-markers.js.map +1 -0
  69. package/dist/dependency-sources.d.ts +32 -0
  70. package/dist/dependency-sources.js +260 -0
  71. package/dist/dependency-sources.js.map +1 -0
  72. package/dist/figure-claims.d.ts +35 -0
  73. package/dist/figure-claims.js +139 -0
  74. package/dist/figure-claims.js.map +1 -0
  75. package/dist/figure-text.d.ts +22 -0
  76. package/dist/figure-text.js +119 -0
  77. package/dist/figure-text.js.map +1 -0
  78. package/dist/index.d.ts +46 -0
  79. package/dist/index.js +38 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/large-blobs.d.ts +35 -0
  82. package/dist/large-blobs.js +163 -0
  83. package/dist/large-blobs.js.map +1 -0
  84. package/dist/lockfile-drift.d.ts +36 -0
  85. package/dist/lockfile-drift.js +206 -0
  86. package/dist/lockfile-drift.js.map +1 -0
  87. package/dist/lowered-thresholds.d.ts +70 -0
  88. package/dist/lowered-thresholds.js +281 -0
  89. package/dist/lowered-thresholds.js.map +1 -0
  90. package/dist/measurement-rule.d.ts +39 -0
  91. package/dist/measurement-rule.js +213 -0
  92. package/dist/measurement-rule.js.map +1 -0
  93. package/dist/portable-paths.d.ts +37 -0
  94. package/dist/portable-paths.js +215 -0
  95. package/dist/portable-paths.js.map +1 -0
  96. package/dist/registry.d.ts +43 -0
  97. package/dist/registry.js +144 -0
  98. package/dist/registry.js.map +1 -0
  99. package/dist/replay-plan.d.ts +36 -0
  100. package/dist/replay-plan.js +196 -0
  101. package/dist/replay-plan.js.map +1 -0
  102. package/dist/replayed-figures.d.ts +36 -0
  103. package/dist/replayed-figures.js +159 -0
  104. package/dist/replayed-figures.js.map +1 -0
  105. package/dist/snapshot-refreshes.d.ts +36 -0
  106. package/dist/snapshot-refreshes.js +202 -0
  107. package/dist/snapshot-refreshes.js.map +1 -0
  108. package/dist/stray-files.d.ts +52 -0
  109. package/dist/stray-files.js +234 -0
  110. package/dist/stray-files.js.map +1 -0
  111. package/dist/symlinks.d.ts +28 -0
  112. package/dist/symlinks.js +193 -0
  113. package/dist/symlinks.js.map +1 -0
  114. package/dist/trailers.d.ts +36 -0
  115. package/dist/trailers.js +110 -0
  116. package/dist/trailers.js.map +1 -0
  117. package/dist/weakened-tests.d.ts +94 -0
  118. package/dist/weakened-tests.js +458 -0
  119. package/dist/weakened-tests.js.map +1 -0
  120. package/package.json +31 -4
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Weakened workflows.
3
+ *
4
+ * The cheapest way to turn a red check green is to change the workflow rather
5
+ * than the code. This check reads every workflow file the range deletes, adds,
6
+ * changes or renames, whole and through git at the merge base and at the
7
+ * candidate, and reports each workflow the range removes (`workflow-removed`)
8
+ * and each line of a weakening shape (`WEAKENING_SHAPES`) that the candidate's
9
+ * file holds more often than its source did. A line moved or re-indented is not
10
+ * a new line. The YAML is not parsed, and the working tree is never read.
11
+ *
12
+ * A finding's id is `<category>:<file>`; it is sanctioned by a
13
+ * `Sanctioned-Weakening: <id> <reason>` line in a commit message of the range
14
+ * or by the caller's `sanctions`.
15
+ */
16
+ import { execFile } from "node:child_process";
17
+ import { SANCTION_KEY } from "../weakened-tests.js";
18
+ export const name = "RT-56";
19
+ const KEY_END = String.raw `\s*(?:#.*)?$`;
20
+ /** The shapes a line may have. A consumer appends to this array; it is read at each run. */
21
+ export const WEAKENING_SHAPES = [
22
+ {
23
+ category: "continue-on-error",
24
+ pattern: new RegExp(String.raw `^(?:-\s+)?continue-on-error\s*:\s*(?:["']?true["']?|\$\{\{\s*true\s*\}\})` + KEY_END),
25
+ },
26
+ {
27
+ category: "if-false",
28
+ pattern: new RegExp(String.raw `^(?:-\s+)?if\s*:\s*(?:["']?false["']?|\$\{\{\s*false\s*\}\})` + KEY_END),
29
+ },
30
+ { category: "or-true", pattern: new RegExp(String.raw `\|\|\s*(?:true|:|exit\s+0)` + KEY_END) },
31
+ ];
32
+ function runGit(cwd, args) {
33
+ return new Promise((resolve, reject) => {
34
+ execFile("git", args, { cwd, maxBuffer: 1024 * 1024 * 1024, encoding: "buffer" }, (error, stdout, stderr) => {
35
+ if (error)
36
+ reject(new Error(stderr.toString("utf8").trim() || error.message));
37
+ else
38
+ resolve(stdout.toString("utf8"));
39
+ });
40
+ });
41
+ }
42
+ /** Escape everything outside printable ASCII, so evidence cannot replay a control sequence. */
43
+ function escapeText(text) {
44
+ let escaped = "";
45
+ for (const char of text) {
46
+ const codePoint = char.codePointAt(0) ?? 0;
47
+ escaped += codePoint >= 0x20 && codePoint <= 0x7e ? char : `\\u{${codePoint.toString(16).padStart(4, "0")}}`;
48
+ }
49
+ return escaped;
50
+ }
51
+ async function resolveCommit(cwd, revision) {
52
+ const fail = (cause) => new Error(`revision "${escapeText(String(revision))}" does not name a commit${cause}`);
53
+ // A revision that begins with a dash would be read as an option.
54
+ if (typeof revision !== "string" || revision.length === 0 || revision.startsWith("-"))
55
+ throw fail("");
56
+ let hash = "";
57
+ try {
58
+ hash = (await runGit(cwd, ["rev-parse", "--verify", "--quiet", `${revision}^{commit}`])).trim();
59
+ }
60
+ catch (error) {
61
+ throw fail(`: ${error.message}`);
62
+ }
63
+ if (hash.length === 0)
64
+ throw fail("");
65
+ return hash;
66
+ }
67
+ const isWorkflowPath = (path) => /^\.github\/workflows\/[^/]+\.ya?ml$/.test(path);
68
+ const isNull = (sha) => /^0+$/.test(sha);
69
+ /** A blob read whole through git; an absent blob is an empty file. */
70
+ const readBlob = async (cwd, sha) => isNull(sha) ? "" : runGit(cwd, ["cat-file", "blob", sha]);
71
+ /** How many times each line's text occurs, lines being split at line feeds, one CR dropped, white space trimmed. */
72
+ function countLines(content) {
73
+ const counts = new Map();
74
+ for (const raw of content.split("\n")) {
75
+ const text = (raw.endsWith("\r") ? raw.slice(0, -1) : raw).trim();
76
+ if (text.length > 0)
77
+ counts.set(text, (counts.get(text) ?? 0) + 1);
78
+ }
79
+ return counts;
80
+ }
81
+ async function compare(cwd, from, to) {
82
+ const out = await runGit(cwd, ["diff", "--raw", "-z", "-M", "--no-abbrev", "--no-ext-diff", "--no-relative", from, to, "--"]);
83
+ const fields = out.split("\0");
84
+ const drafts = [];
85
+ for (let i = 0; i < fields.length; i++) {
86
+ const head = fields[i] ?? "";
87
+ if (!head.startsWith(":"))
88
+ continue;
89
+ const [, , oldSha = "", newSha = "", status = ""] = head.slice(1).split(" ");
90
+ const moved = status.startsWith("R") || status.startsWith("C");
91
+ const oldPath = fields[++i] ?? "";
92
+ const newPath = moved ? (fields[++i] ?? "") : oldPath;
93
+ const letter = status.charAt(0);
94
+ if (letter === "D" || (letter === "R" && !isWorkflowPath(newPath))) {
95
+ if (isWorkflowPath(oldPath))
96
+ drafts.push({ category: "workflow-removed", file: oldPath, line: null });
97
+ continue;
98
+ }
99
+ if (!["A", "M", "R", "C", "T"].includes(letter) || !isWorkflowPath(newPath))
100
+ continue;
101
+ const fromWorkflow = (letter === "M" || letter === "T" || letter === "R") && isWorkflowPath(oldPath);
102
+ const before = countLines(fromWorkflow ? await readBlob(cwd, oldSha) : "");
103
+ const after = countLines(await readBlob(cwd, newSha));
104
+ for (const [text, count] of after) {
105
+ if (count <= (before.get(text) ?? 0))
106
+ continue;
107
+ const shape = WEAKENING_SHAPES.find((entry) => entry.pattern.test(text));
108
+ if (shape !== undefined)
109
+ drafts.push({ category: shape.category, file: newPath, line: text });
110
+ }
111
+ }
112
+ return drafts;
113
+ }
114
+ /** The text after the sanction key on every such line of the range's commit messages. */
115
+ async function readSanctionLines(cwd, from, to) {
116
+ const out = await runGit(cwd, ["log", "--format=%B%x00", `${from}..${to}`, "--"]);
117
+ const prefix = `${SANCTION_KEY}:`;
118
+ return out
119
+ .split(/[\n\0]/)
120
+ .map((line) => line.trim())
121
+ .filter((line) => line.startsWith(prefix))
122
+ .map((line) => line.slice(prefix.length).trim());
123
+ }
124
+ function sanctionFor(id, lines, given) {
125
+ const reason = Object.hasOwn(given, id) ? given[id] : undefined;
126
+ if (typeof reason === "string" && reason.trim().length > 0)
127
+ return reason.trim();
128
+ for (const line of lines) {
129
+ const rest = line.slice(id.length);
130
+ if (line.startsWith(id) && /^\s+\S/.test(rest))
131
+ return rest.trim();
132
+ }
133
+ return null;
134
+ }
135
+ /**
136
+ * Report each workflow `base..candidate` removes and each weakening line it adds.
137
+ * Fails while any finding is unsanctioned, and fails closed: a revision that
138
+ * names no commit, or any git invocation that fails, is a `fail` record naming
139
+ * the cause - never a `pass`, never a throw.
140
+ */
141
+ export async function check(options) {
142
+ try {
143
+ const { cwd, base, candidate } = options;
144
+ const baseCommit = await resolveCommit(cwd, base);
145
+ const candidateCommit = await resolveCommit(cwd, candidate);
146
+ let ancestor;
147
+ try {
148
+ ancestor = (await runGit(cwd, ["merge-base", baseCommit, candidateCommit])).trim();
149
+ }
150
+ catch (error) {
151
+ throw new Error(`no merge base of "${escapeText(base)}" and "${escapeText(candidate)}": ${error.message}`);
152
+ }
153
+ const drafts = await compare(cwd, ancestor, candidateCommit);
154
+ if (drafts.length === 0)
155
+ return { name, status: "pass", evidence: ["no workflow weakened"] };
156
+ const lines = await readSanctionLines(cwd, baseCommit, candidateCommit);
157
+ let open = false;
158
+ const evidence = drafts.map((draft) => {
159
+ const reason = sanctionFor(`${draft.category}:${draft.file}`, lines, options.sanctions ?? {});
160
+ if (reason === null)
161
+ open = true;
162
+ const quoted = draft.line === null ? "" : ` "${escapeText(draft.line)}"`;
163
+ const tail = reason === null ? "" : ` - sanctioned: ${escapeText(reason)}`;
164
+ return `${escapeText(draft.file)}: ${draft.category}${quoted}${tail}`;
165
+ });
166
+ return { name, status: open ? "fail" : "pass", evidence };
167
+ }
168
+ catch (error) {
169
+ return { name, status: "fail", evidence: [escapeText(error instanceof Error ? error.message : String(error))] };
170
+ }
171
+ }
172
+ //# sourceMappingURL=workflow-weakening.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-weakening.js","sourceRoot":"","sources":["../../src/checks/workflow-weakening.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `repo-truth check --base <rev> --candidate <rev>` - run the registered
4
+ * checks over a range and answer with records.
5
+ *
6
+ * EXIT CODES - the one place they are stated:
7
+ * 0 every check that ran passed or skipped
8
+ * 1 at least one check failed
9
+ * 2 bad invocation or unrunnable environment (unknown option, unknown check,
10
+ * `--except` with `--check` or naming every check, a revision that names no
11
+ * commit, a failed fetch, a configuration the command refuses). Never a check's finding.
12
+ *
13
+ * `repo-truth list` answers 0 after printing the registered names, and 2 for any
14
+ * argument but `--help` (which answers 0 with the usage). It writes nothing to stderr
15
+ * on 0 and runs no check and no git command.
16
+ *
17
+ * On exit 2 nothing is written to stdout and no check has run.
18
+ */
19
+ export declare const EXIT_OK = 0;
20
+ export declare const EXIT_CHECK_FAILED = 1;
21
+ export declare const EXIT_BAD_INVOCATION = 2;
22
+ export declare const JSON_SCHEMA_ID = "repo-truth.check/v1";
23
+ export interface CliIo {
24
+ readonly cwd?: string;
25
+ readonly stdout?: (text: string) => void;
26
+ readonly stderr?: (text: string) => void;
27
+ /** Where `GITHUB_EVENT_NAME` is read from; defaults to `process.env`. */
28
+ readonly env?: Readonly<Record<string, string | undefined>>;
29
+ }
30
+ /** Run the command; resolves to the exit code. Output goes through `io`. */
31
+ export declare function main(argv: readonly string[], io?: CliIo): Promise<number>;
package/dist/cli.js ADDED
@@ -0,0 +1,300 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `repo-truth check --base <rev> --candidate <rev>` - run the registered
4
+ * checks over a range and answer with records.
5
+ *
6
+ * EXIT CODES - the one place they are stated:
7
+ * 0 every check that ran passed or skipped
8
+ * 1 at least one check failed
9
+ * 2 bad invocation or unrunnable environment (unknown option, unknown check,
10
+ * `--except` with `--check` or naming every check, a revision that names no
11
+ * commit, a failed fetch, a configuration the command refuses). Never a check's finding.
12
+ *
13
+ * `repo-truth list` answers 0 after printing the registered names, and 2 for any
14
+ * argument but `--help` (which answers 0 with the usage). It writes nothing to stderr
15
+ * on 0 and runs no check and no git command.
16
+ *
17
+ * On exit 2 nothing is written to stdout and no check has run.
18
+ */
19
+ import { execFile } from "node:child_process";
20
+ import { realpathSync } from "node:fs";
21
+ import { fileURLToPath } from "node:url";
22
+ import { assertPullRequestEvent, RangeResolutionError, resolveMergeBase } from "./action.js";
23
+ import { allPassed } from "./index.js";
24
+ import { ConfigError, readConfig } from "./config.js";
25
+ import { optionKindsOf, REGISTRY } from "./registry.js";
26
+ export const EXIT_OK = 0;
27
+ export const EXIT_CHECK_FAILED = 1;
28
+ export const EXIT_BAD_INVOCATION = 2;
29
+ export const JSON_SCHEMA_ID = "repo-truth.check/v1";
30
+ const USAGE = "usage: repo-truth check (--base <rev> | --target <rev>) --candidate <rev> [--check <name>]... [--except <name>]... [--format text|json] [--no-fetch] [--config <path>]\n" +
31
+ " repo-truth list";
32
+ class InvocationError extends Error {
33
+ }
34
+ function parseArgs(argv) {
35
+ const [command, ...rest] = argv;
36
+ const parsed = { base: "", target: undefined, candidate: "", checks: [], except: [], list: false, format: "text", fetch: true, config: undefined, help: false };
37
+ if (command === "--help" || command === "-h") {
38
+ parsed.help = true;
39
+ return parsed;
40
+ }
41
+ if (command === "list") {
42
+ for (const arg of rest) {
43
+ if (arg === "--help" || arg === "-h")
44
+ parsed.help = true;
45
+ else
46
+ throw new InvocationError(`list takes no argument but --help: ${arg}`);
47
+ }
48
+ parsed.list = true;
49
+ return parsed;
50
+ }
51
+ if (command !== "check") {
52
+ throw new InvocationError(command === undefined ? "no command given" : `unknown command: ${command}`);
53
+ }
54
+ let base;
55
+ let target;
56
+ let candidate;
57
+ for (let i = 0; i < rest.length; i++) {
58
+ let arg = rest[i];
59
+ let inline;
60
+ const eq = arg.indexOf("=");
61
+ if (arg.startsWith("--") && eq > 0) {
62
+ inline = arg.slice(eq + 1);
63
+ arg = arg.slice(0, eq);
64
+ }
65
+ const name = arg;
66
+ const value = () => {
67
+ if (inline !== undefined)
68
+ return inline;
69
+ const next = rest[++i];
70
+ if (next === undefined)
71
+ throw new InvocationError(`${name} needs a value`);
72
+ return next;
73
+ };
74
+ switch (name) {
75
+ case "--base":
76
+ base = value();
77
+ break;
78
+ case "--target":
79
+ target = value();
80
+ break;
81
+ case "--candidate":
82
+ candidate = value();
83
+ break;
84
+ case "--check":
85
+ parsed.checks.push(value());
86
+ break;
87
+ case "--except":
88
+ parsed.except.push(value());
89
+ break;
90
+ case "--format": {
91
+ const format = value();
92
+ if (format !== "text" && format !== "json") {
93
+ throw new InvocationError(`unknown format: ${format} (expected text or json)`);
94
+ }
95
+ parsed.format = format;
96
+ break;
97
+ }
98
+ case "--config":
99
+ parsed.config = value();
100
+ break;
101
+ case "--no-fetch":
102
+ parsed.fetch = false;
103
+ break;
104
+ case "--help":
105
+ case "-h":
106
+ parsed.help = true;
107
+ break;
108
+ default:
109
+ throw new InvocationError(`unknown argument: ${name}`);
110
+ }
111
+ }
112
+ if (parsed.help)
113
+ return parsed;
114
+ if (parsed.except.length > 0 && parsed.checks.length > 0) {
115
+ throw new InvocationError("--except and --check are exclusive: give one");
116
+ }
117
+ if (base !== undefined && target !== undefined) {
118
+ throw new InvocationError("--base and --target are exclusive: give one");
119
+ }
120
+ if (base === undefined && target === undefined)
121
+ throw new InvocationError("--base or --target is required");
122
+ if (candidate === undefined)
123
+ throw new InvocationError("--candidate is required");
124
+ parsed.base = base ?? "";
125
+ parsed.target = target;
126
+ parsed.candidate = candidate;
127
+ return parsed;
128
+ }
129
+ function git(cwd, args) {
130
+ return new Promise((resolve, reject) => {
131
+ execFile("git", args, { cwd, maxBuffer: 64 * 1024 * 1024, encoding: "utf8" }, (error, stdout, stderr) => {
132
+ if (error) {
133
+ reject(new Error(stderr.trim() || error.message));
134
+ return;
135
+ }
136
+ resolve(stdout);
137
+ });
138
+ });
139
+ }
140
+ async function resolveCommit(cwd, label, rev) {
141
+ const refusal = new InvocationError(`${label} ${JSON.stringify(rev)} does not name a commit in this repository`);
142
+ if (rev.length === 0 || rev.startsWith("-"))
143
+ throw refusal;
144
+ let id;
145
+ try {
146
+ id = (await git(cwd, ["rev-parse", "--verify", "--quiet", rev + "^{commit}"])).trim();
147
+ }
148
+ catch {
149
+ throw refusal;
150
+ }
151
+ if (id.length === 0)
152
+ throw refusal;
153
+ return id;
154
+ }
155
+ async function runOne(entry, cwd, range, given, config) {
156
+ const repo = config === undefined ? { cwd } : { cwd, config };
157
+ try {
158
+ const options = Object.hasOwn(given, entry.name) ? given[entry.name] : undefined;
159
+ return await (options === undefined ? entry.run(repo, range) : entry.run(repo, range, options));
160
+ }
161
+ catch (error) {
162
+ const message = error instanceof Error ? error.message : String(error);
163
+ return { name: entry.name, status: "fail", evidence: [`check threw: ${message}`] };
164
+ }
165
+ }
166
+ /** Everything outside printable ASCII becomes `\u{hex}`, the form the checks already use. */
167
+ function escapeControl(text) {
168
+ let escaped = "";
169
+ for (const char of text) {
170
+ const codePoint = char.codePointAt(0) ?? 0;
171
+ escaped +=
172
+ codePoint >= 0x20 && codePoint <= 0x7e ? char : `\\u{${codePoint.toString(16).padStart(4, "0")}}`;
173
+ }
174
+ return escaped;
175
+ }
176
+ function renderText(records, ok) {
177
+ const lines = [];
178
+ for (const record of records) {
179
+ lines.push(`${record.status.toUpperCase().padEnd(4)} ${escapeControl(record.name)}`);
180
+ for (const line of record.evidence)
181
+ lines.push(` ${escapeControl(line)}`);
182
+ }
183
+ lines.push(ok ? "repo-truth: all checks passed" : "repo-truth: at least one check failed");
184
+ return lines.join("\n") + "\n";
185
+ }
186
+ /** Run the command; resolves to the exit code. Output goes through `io`. */
187
+ export async function main(argv, io = {}) {
188
+ const cwd = io.cwd ?? process.cwd();
189
+ const out = io.stdout ?? ((text) => void process.stdout.write(text));
190
+ const err = io.stderr ?? ((text) => void process.stderr.write(text));
191
+ try {
192
+ const parsed = parseArgs(argv);
193
+ if (parsed.help) {
194
+ out(USAGE + "\n");
195
+ return EXIT_OK;
196
+ }
197
+ // Read the registry when the command runs: it runs what the registry holds.
198
+ const registry = [...REGISTRY];
199
+ if (parsed.list) {
200
+ out(registry.map((e) => escapeControl(e.name) + "\n").join(""));
201
+ return EXIT_OK;
202
+ }
203
+ for (const name of parsed.checks) {
204
+ if (!registry.some((e) => e.name === name)) {
205
+ throw new InvocationError(`unknown check: ${name} (registered: ${registry.map((e) => e.name).join(", ")})`);
206
+ }
207
+ }
208
+ for (const name of parsed.except) {
209
+ if (!registry.some((e) => e.name === name)) {
210
+ throw new InvocationError(`unknown check: ${name} (registered: ${registry.map((e) => e.name).join(", ")})`);
211
+ }
212
+ }
213
+ const selected = parsed.checks.length > 0
214
+ ? registry.filter((e) => parsed.checks.includes(e.name))
215
+ : registry.filter((e) => !parsed.except.includes(e.name));
216
+ if (selected.length === 0 && parsed.except.length > 0) {
217
+ throw new InvocationError("--except names every registered check: no check is left to run");
218
+ }
219
+ if (parsed.target !== undefined)
220
+ assertPullRequestEvent((io.env ?? process.env).GITHUB_EVENT_NAME);
221
+ try {
222
+ await git(cwd, ["rev-parse", "--git-dir"]);
223
+ }
224
+ catch {
225
+ throw new InvocationError(`${cwd} is not a git repository`);
226
+ }
227
+ if (parsed.fetch) {
228
+ try {
229
+ await git(cwd, ["fetch", "--all", "--quiet"]);
230
+ }
231
+ catch (error) {
232
+ throw new InvocationError(`could not fetch: ${error.message}`);
233
+ }
234
+ }
235
+ let base;
236
+ let candidate;
237
+ if (parsed.target !== undefined) {
238
+ const target = await resolveCommit(cwd, "--target", parsed.target);
239
+ candidate = await resolveCommit(cwd, "--candidate", parsed.candidate);
240
+ base = await resolveMergeBase(cwd, target, candidate);
241
+ }
242
+ else {
243
+ base = await resolveCommit(cwd, "--base", parsed.base);
244
+ candidate = await resolveCommit(cwd, "--candidate", parsed.candidate);
245
+ }
246
+ const read = await readConfig({ cwd, base, ...(parsed.config !== undefined && { path: parsed.config }) }, optionKindsOf(registry));
247
+ const records = [];
248
+ for (const e of selected)
249
+ records.push(await runOne(e, cwd, { base, candidate }, read.options, parsed.config));
250
+ const ok = allPassed(records);
251
+ const exitCode = ok ? EXIT_OK : EXIT_CHECK_FAILED;
252
+ if (parsed.format === "json") {
253
+ const doc = {
254
+ schema: JSON_SCHEMA_ID,
255
+ base,
256
+ candidate,
257
+ config: read.source,
258
+ ok,
259
+ exitCode,
260
+ records: records.map((r) => ({ name: r.name, status: r.status, evidence: [...r.evidence] })),
261
+ };
262
+ out(JSON.stringify(doc, null, 2) + "\n");
263
+ }
264
+ else {
265
+ out(renderText(records, ok));
266
+ }
267
+ return exitCode;
268
+ }
269
+ catch (error) {
270
+ if (error instanceof ConfigError) {
271
+ err(`repo-truth: ${error.message}\n`);
272
+ return EXIT_BAD_INVOCATION;
273
+ }
274
+ const message = error instanceof Error ? error.message : String(error);
275
+ err(`repo-truth: ${escapeControl(message)}\n`);
276
+ if (error instanceof InvocationError || error instanceof RangeResolutionError)
277
+ err(USAGE + "\n");
278
+ return EXIT_BAD_INVOCATION;
279
+ }
280
+ }
281
+ function isEntryPoint() {
282
+ const script = process.argv[1];
283
+ if (!script)
284
+ return false;
285
+ try {
286
+ return realpathSync(script) === realpathSync(fileURLToPath(import.meta.url));
287
+ }
288
+ catch {
289
+ return false;
290
+ }
291
+ }
292
+ if (isEntryPoint()) {
293
+ main(process.argv.slice(2)).then((code) => {
294
+ process.exitCode = code;
295
+ }, (error) => {
296
+ process.stderr.write(`repo-truth: ${escapeControl(error instanceof Error ? error.message : String(error))}\n`);
297
+ process.exitCode = EXIT_BAD_INVOCATION;
298
+ });
299
+ }
300
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC7F,OAAO,EAAE,SAAS,EAAoB,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAsB,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAsB,MAAM,eAAe,CAAC;AAE5E,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAC;AACzB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AACnC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,MAAM,CAAC,MAAM,cAAc,GAAG,qBAAqB,CAAC;AAUpD,MAAM,KAAK,GACT,0KAA0K;IAC1K,wBAAwB,CAAC;AAE3B,MAAM,eAAgB,SAAQ,KAAK;CAAG;AAetC,SAAS,SAAS,CAAC,IAAuB;IACxC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAChC,MAAM,MAAM,GAAW,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACxK,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QAC7C,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;gBAAE,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;;gBACpD,MAAM,IAAI,eAAe,CAAC,sCAAsC,GAAG,EAAE,CAAC,CAAC;QAC9E,CAAC;QACD,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,MAAM,IAAI,eAAe,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACxG,CAAC;IACD,IAAI,IAAwB,CAAC;IAC7B,IAAI,MAA0B,CAAC;IAC/B,IAAI,SAA6B,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,GAAG,GAAG,IAAI,CAAC,CAAC,CAAW,CAAC;QAC5B,IAAI,MAA0B,CAAC;QAC/B,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAC3B,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC;QACjB,MAAM,KAAK,GAAG,GAAW,EAAE;YACzB,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO,MAAM,CAAC;YACxC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YACvB,IAAI,IAAI,KAAK,SAAS;gBAAE,MAAM,IAAI,eAAe,CAAC,GAAG,IAAI,gBAAgB,CAAC,CAAC;YAC3E,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QACF,QAAQ,IAAI,EAAE,CAAC;YACb,KAAK,QAAQ;gBACX,IAAI,GAAG,KAAK,EAAE,CAAC;gBACf,MAAM;YACR,KAAK,UAAU;gBACb,MAAM,GAAG,KAAK,EAAE,CAAC;gBACjB,MAAM;YACR,KAAK,aAAa;gBAChB,SAAS,GAAG,KAAK,EAAE,CAAC;gBACpB,MAAM;YACR,KAAK,SAAS;gBACZ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC5B,MAAM;YACR,KAAK,UAAU;gBACb,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC5B,MAAM;YACR,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC;gBACvB,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;oBAC3C,MAAM,IAAI,eAAe,CAAC,mBAAmB,MAAM,0BAA0B,CAAC,CAAC;gBACjF,CAAC;gBACD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;gBACvB,MAAM;YACR,CAAC;YACD,KAAK,UAAU;gBACb,MAAM,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;gBACxB,MAAM;YACR,KAAK,YAAY;gBACf,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;gBACrB,MAAM;YACR,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;gBACnB,MAAM;YACR;gBACE,MAAM,IAAI,eAAe,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,IAAI;QAAE,OAAO,MAAM,CAAC;IAC/B,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,eAAe,CAAC,8CAA8C,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,IAAI,eAAe,CAAC,6CAA6C,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,IAAI,eAAe,CAAC,gCAAgC,CAAC,CAAC;IAC5G,IAAI,SAAS,KAAK,SAAS;QAAE,MAAM,IAAI,eAAe,CAAC,yBAAyB,CAAC,CAAC;IAClF,MAAM,CAAC,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IACzB,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,GAAG,CAAC,GAAW,EAAE,IAAuB;IAC/C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,QAAQ,CACN,KAAK,EACL,IAAgB,EAChB,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EACtD,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACxB,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;gBAClD,OAAO;YACT,CAAC;YACD,OAAO,CAAC,MAAM,CAAC,CAAC;QAClB,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,KAAa,EAAE,GAAW;IAClE,MAAM,OAAO,GAAG,IAAI,eAAe,CAAC,GAAG,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IACjH,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,MAAM,OAAO,CAAC;IAC3D,IAAI,EAAU,CAAC;IACf,IAAI,CAAC;QACH,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACxF,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,OAAO,CAAC;IAChB,CAAC;IACD,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,OAAO,CAAC;IACnC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,KAAK,UAAU,MAAM,CACnB,KAAoB,EACpB,GAAW,EACX,KAA0C,EAC1C,KAAoB,EACpB,MAA0B;IAE1B,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACjF,OAAO,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;IAClG,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,gBAAgB,OAAO,EAAE,CAAC,EAAE,CAAC;IACrF,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,SAAS,aAAa,CAAC,IAAY;IACjC,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3C,OAAO;YACL,SAAS,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IACtG,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,UAAU,CAAC,OAA+B,EAAE,EAAW;IAC9D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC;IAC3F,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AACjC,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAuB,EAAE,KAAY,EAAE;IAChE,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAE7E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;YAClB,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC/B,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAChE,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;gBAC3C,MAAM,IAAI,eAAe,CAAC,kBAAkB,IAAI,iBAAiB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9G,CAAC;QACH,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;gBAC3C,MAAM,IAAI,eAAe,CAAC,kBAAkB,IAAI,iBAAiB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9G,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GACZ,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YACtB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACxD,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9D,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtD,MAAM,IAAI,eAAe,CAAC,gEAAgE,CAAC,CAAC;QAC9F,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;YAAE,sBAAsB,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAEnG,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,eAAe,CAAC,GAAG,GAAG,0BAA0B,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;YAChD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,eAAe,CAAC,oBAAqB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;QACD,IAAI,IAAY,CAAC;QACjB,IAAI,SAAiB,CAAC;QACtB,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YACnE,SAAS,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;YACtE,IAAI,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YACvD,SAAS,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,UAAU,CAC3B,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAC1E,aAAa,CAAC,QAAQ,CAAC,CACxB,CAAC;QAEF,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,IAAI,QAAQ;YAAE,OAAO,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAE/G,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC;QAClD,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG;gBACV,MAAM,EAAE,cAAc;gBACtB,IAAI;gBACJ,SAAS;gBACT,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,EAAE;gBACF,QAAQ;gBACR,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;aAC7F,CAAC;YACF,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;YACjC,GAAG,CAAC,eAAe,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YACtC,OAAO,mBAAmB,CAAC;QAC7B,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,GAAG,CAAC,eAAe,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,KAAK,YAAY,eAAe,IAAI,KAAK,YAAY,oBAAoB;YAAE,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;QACjG,OAAO,mBAAmB,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,MAAM,CAAC,KAAK,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,IAAI,YAAY,EAAE,EAAE,CAAC;IACnB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAC9B,CAAC,IAAI,EAAE,EAAE;QACP,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC1B,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;QACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,eAAe,aAAa,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CACzF,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,mBAAmB,CAAC;IACzC,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Commit-range ASCII and identity hygiene.
3
+ *
4
+ * `commit-msg` hooks see one commit at a time, at the moment it is written.
5
+ * `cherry-pick`, `revert`, every form of `rebase`, and `git am` all create
6
+ * commits without ever invoking that hook - a property of git, not a defect
7
+ * of the hook. A rule enforced only at commit time is therefore enforced on
8
+ * a subset of history it cannot even name. This check instead reads the
9
+ * whole range `base..candidate` after the fact and answers for all of it.
10
+ */
11
+ import type { CheckRecord } from "./index.js";
12
+ /** Where to look, and what range of commits to look at. */
13
+ export interface CommitRangeOptions {
14
+ /** The git repository to run in. */
15
+ readonly cwd: string;
16
+ /** The revision the range starts after (exclusive). */
17
+ readonly base: string;
18
+ /** The revision the range ends at (inclusive). */
19
+ readonly candidate: string;
20
+ }
21
+ /**
22
+ * Check every commit in `base..candidate` for characters outside printable
23
+ * ASCII plus tab, in the message and in both identities. Fails closed: any
24
+ * git invocation that cannot be completed (unknown revision, unreachable
25
+ * base, non-zero exit) is reported as `fail`, never as `pass`, and never as
26
+ * a thrown error the caller must catch to stay correct.
27
+ */
28
+ export declare function checkCommitRange(options: CommitRangeOptions): Promise<CheckRecord>;