@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.
- package/LICENSE +21 -0
- package/README.md +273 -2
- package/dist/action.d.ts +52 -0
- package/dist/action.js +182 -0
- package/dist/action.js.map +1 -0
- package/dist/checks/action-pins.d.ts +52 -0
- package/dist/checks/action-pins.js +196 -0
- package/dist/checks/action-pins.js.map +1 -0
- package/dist/checks/autosquash.d.ts +23 -0
- package/dist/checks/autosquash.js +85 -0
- package/dist/checks/autosquash.js.map +1 -0
- package/dist/checks/bidi-controls.d.ts +58 -0
- package/dist/checks/bidi-controls.js +172 -0
- package/dist/checks/bidi-controls.js.map +1 -0
- package/dist/checks/binary-files.d.ts +53 -0
- package/dist/checks/binary-files.js +157 -0
- package/dist/checks/binary-files.js.map +1 -0
- package/dist/checks/config-changes.d.ts +57 -0
- package/dist/checks/config-changes.js +175 -0
- package/dist/checks/config-changes.js.map +1 -0
- package/dist/checks/credentials.d.ts +35 -0
- package/dist/checks/credentials.js +138 -0
- package/dist/checks/credentials.js.map +1 -0
- package/dist/checks/install-scripts.d.ts +39 -0
- package/dist/checks/install-scripts.js +173 -0
- package/dist/checks/install-scripts.js.map +1 -0
- package/dist/checks/lint-rules.d.ts +49 -0
- package/dist/checks/lint-rules.js +184 -0
- package/dist/checks/lint-rules.js.map +1 -0
- package/dist/checks/path-policy.d.ts +40 -0
- package/dist/checks/path-policy.js +195 -0
- package/dist/checks/path-policy.js.map +1 -0
- package/dist/checks/raised-timeouts.d.ts +66 -0
- package/dist/checks/raised-timeouts.js +248 -0
- package/dist/checks/raised-timeouts.js.map +1 -0
- package/dist/checks/script-changes.d.ts +51 -0
- package/dist/checks/script-changes.js +199 -0
- package/dist/checks/script-changes.js.map +1 -0
- package/dist/checks/secret-files.d.ts +58 -0
- package/dist/checks/secret-files.js +165 -0
- package/dist/checks/secret-files.js.map +1 -0
- package/dist/checks/strictness.d.ts +59 -0
- package/dist/checks/strictness.js +260 -0
- package/dist/checks/strictness.js.map +1 -0
- package/dist/checks/submodules.d.ts +51 -0
- package/dist/checks/submodules.js +172 -0
- package/dist/checks/submodules.js.map +1 -0
- package/dist/checks/suppressions.d.ts +53 -0
- package/dist/checks/suppressions.js +203 -0
- package/dist/checks/suppressions.js.map +1 -0
- package/dist/checks/workflow-permissions.d.ts +56 -0
- package/dist/checks/workflow-permissions.js +237 -0
- package/dist/checks/workflow-permissions.js.map +1 -0
- package/dist/checks/workflow-weakening.d.ts +38 -0
- package/dist/checks/workflow-weakening.js +172 -0
- package/dist/checks/workflow-weakening.js.map +1 -0
- package/dist/cli.d.ts +31 -0
- package/dist/cli.js +300 -0
- package/dist/cli.js.map +1 -0
- package/dist/commit-range.d.ts +28 -0
- package/dist/commit-range.js +152 -0
- package/dist/commit-range.js.map +1 -0
- package/dist/config.d.ts +35 -0
- package/dist/config.js +235 -0
- package/dist/config.js.map +1 -0
- package/dist/conflict-markers.d.ts +40 -0
- package/dist/conflict-markers.js +234 -0
- package/dist/conflict-markers.js.map +1 -0
- package/dist/dependency-sources.d.ts +32 -0
- package/dist/dependency-sources.js +260 -0
- package/dist/dependency-sources.js.map +1 -0
- package/dist/figure-claims.d.ts +35 -0
- package/dist/figure-claims.js +139 -0
- package/dist/figure-claims.js.map +1 -0
- package/dist/figure-text.d.ts +22 -0
- package/dist/figure-text.js +119 -0
- package/dist/figure-text.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/large-blobs.d.ts +35 -0
- package/dist/large-blobs.js +163 -0
- package/dist/large-blobs.js.map +1 -0
- package/dist/lockfile-drift.d.ts +36 -0
- package/dist/lockfile-drift.js +206 -0
- package/dist/lockfile-drift.js.map +1 -0
- package/dist/lowered-thresholds.d.ts +70 -0
- package/dist/lowered-thresholds.js +281 -0
- package/dist/lowered-thresholds.js.map +1 -0
- package/dist/measurement-rule.d.ts +39 -0
- package/dist/measurement-rule.js +213 -0
- package/dist/measurement-rule.js.map +1 -0
- package/dist/portable-paths.d.ts +37 -0
- package/dist/portable-paths.js +215 -0
- package/dist/portable-paths.js.map +1 -0
- package/dist/registry.d.ts +43 -0
- package/dist/registry.js +144 -0
- package/dist/registry.js.map +1 -0
- package/dist/replay-plan.d.ts +36 -0
- package/dist/replay-plan.js +196 -0
- package/dist/replay-plan.js.map +1 -0
- package/dist/replayed-figures.d.ts +36 -0
- package/dist/replayed-figures.js +159 -0
- package/dist/replayed-figures.js.map +1 -0
- package/dist/snapshot-refreshes.d.ts +36 -0
- package/dist/snapshot-refreshes.js +202 -0
- package/dist/snapshot-refreshes.js.map +1 -0
- package/dist/stray-files.d.ts +52 -0
- package/dist/stray-files.js +234 -0
- package/dist/stray-files.js.map +1 -0
- package/dist/symlinks.d.ts +28 -0
- package/dist/symlinks.js +193 -0
- package/dist/symlinks.js.map +1 -0
- package/dist/trailers.d.ts +36 -0
- package/dist/trailers.js +110 -0
- package/dist/trailers.js.map +1 -0
- package/dist/weakened-tests.d.ts +94 -0
- package/dist/weakened-tests.js +458 -0
- package/dist/weakened-tests.js.map +1 -0
- package/package.json +31 -4
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Weakened tests.
|
|
3
|
+
*
|
|
4
|
+
* The cheapest way to make a red suite green is to make it ask less: skip the
|
|
5
|
+
* failing test, focus the run on the passing ones, delete the test or the
|
|
6
|
+
* assertion that fails. Each of those leaves the build green, and each is
|
|
7
|
+
* legitimate sometimes, so this check does not judge intent. It reports every
|
|
8
|
+
* such move in `base..candidate` for a human to sanction, and fails while one
|
|
9
|
+
* is unsanctioned.
|
|
10
|
+
*
|
|
11
|
+
* Only the DIFF is read. A marker that predates the range is never reported,
|
|
12
|
+
* and a marker line the range removes and adds back unchanged is a move, not
|
|
13
|
+
* a new marker. File contents are read by blob id through git, never from the
|
|
14
|
+
* working tree, and the diff is taken from the merge base of the two
|
|
15
|
+
* revisions, as in the portable-paths check.
|
|
16
|
+
*
|
|
17
|
+
* What counts as a test file, a marker, a test or an assertion lives in one
|
|
18
|
+
* table, `WEAKENING_SPELLINGS`; a caller on another runner passes its own.
|
|
19
|
+
*/
|
|
20
|
+
import { execFile } from "node:child_process";
|
|
21
|
+
const NAME = "RT-04";
|
|
22
|
+
const TEST_DECLARATION = "\\b[xf]?(?:it|test|specify)(?:\\s*\\.\\s*[A-Za-z]+)*\\s*\\(\\s*([\"'`])(?<name>.*?)\\1";
|
|
23
|
+
export const WEAKENING_SPELLINGS = Object.freeze({
|
|
24
|
+
testFiles: Object.freeze([
|
|
25
|
+
/\.(?:test|spec)\.[cm]?[jt]sx?$/,
|
|
26
|
+
/(?:^|\/)__tests__\/.+\.[cm]?[jt]sx?$/,
|
|
27
|
+
/(?:^|\/)test_[^/]*\.py$/,
|
|
28
|
+
/_test\.(?:py|go)$/,
|
|
29
|
+
]),
|
|
30
|
+
configFiles: Object.freeze([
|
|
31
|
+
/(?:^|\/)(?:vitest|vite|jest|playwright|cypress|karma|ava)\.config\.[cm]?[jt]s$/,
|
|
32
|
+
/(?:^|\/)\.mocharc\.[a-z]+$/,
|
|
33
|
+
/(?:^|\/)(?:pytest\.ini|conftest\.py)$/,
|
|
34
|
+
]),
|
|
35
|
+
markers: Object.freeze([
|
|
36
|
+
{
|
|
37
|
+
category: "skip",
|
|
38
|
+
scope: ["test"],
|
|
39
|
+
pattern: /\b(?:describe|suite|context|it|test|specify|bench)\s*\.\s*(?:skip|skipIf|todo|fixme)\b/,
|
|
40
|
+
example: 'it.skip("parses the header", () => {});',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
category: "skip",
|
|
44
|
+
scope: ["test"],
|
|
45
|
+
pattern: /\bx(?:describe|context|it|test|specify)\s*\(/,
|
|
46
|
+
example: 'xit("parses the header", () => {});',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
category: "skip",
|
|
50
|
+
scope: ["test"],
|
|
51
|
+
pattern: /\b(?:this|ctx|context)\s*\.\s*skip\s*\(/,
|
|
52
|
+
example: "this.skip();",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
category: "skip",
|
|
56
|
+
scope: ["test", "config"],
|
|
57
|
+
pattern: /@(?:pytest\.mark\.(?:skip|skipif|xfail)|unittest\.skip)\b/,
|
|
58
|
+
example: "@pytest.mark.skip(reason=\"flaky\")",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
category: "skip",
|
|
62
|
+
scope: ["test"],
|
|
63
|
+
pattern: /\bt\.Skip(?:f|Now)?\s*\(/,
|
|
64
|
+
example: 't.Skip("flaky")',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
category: "only",
|
|
68
|
+
scope: ["test"],
|
|
69
|
+
pattern: /\b(?:describe|suite|context|it|test|specify|bench)\s*\.\s*only\b/,
|
|
70
|
+
example: 'it.only("parses the header", () => {});',
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
category: "only",
|
|
74
|
+
scope: ["test"],
|
|
75
|
+
pattern: /\bf(?:describe|it)\s*\(/,
|
|
76
|
+
example: 'fit("parses the header", () => {});',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
category: "only",
|
|
80
|
+
scope: ["config"],
|
|
81
|
+
pattern: /\btestNamePattern\b/,
|
|
82
|
+
example: 'testNamePattern: "header",',
|
|
83
|
+
},
|
|
84
|
+
]),
|
|
85
|
+
tests: Object.freeze([
|
|
86
|
+
new RegExp(TEST_DECLARATION),
|
|
87
|
+
/^\s*(?:async\s+)?def\s+(?<name>test\w*)\s*\(/,
|
|
88
|
+
/^func\s+(?<name>Test\w*)\s*\(/,
|
|
89
|
+
]),
|
|
90
|
+
assertions: Object.freeze([
|
|
91
|
+
/\b(?:expect|assert)\w*(?:\s*\.\s*\w+)*\s*\(/,
|
|
92
|
+
/^\s*assert\s/,
|
|
93
|
+
/\.should\b/,
|
|
94
|
+
/\bt\.(?:Error|Errorf|Fatal|Fatalf)\s*\(/,
|
|
95
|
+
]),
|
|
96
|
+
});
|
|
97
|
+
/** The key that sanctions a finding in a commit message of the range. */
|
|
98
|
+
export const SANCTION_KEY = "Sanctioned-Weakening";
|
|
99
|
+
function runGit(cwd, args) {
|
|
100
|
+
return new Promise((resolve, reject) => {
|
|
101
|
+
execFile("git", args, { cwd, maxBuffer: 1024 * 1024 * 1024, encoding: "utf8" }, (error, stdout, stderr) => {
|
|
102
|
+
if (error) {
|
|
103
|
+
reject(new Error(stderr.trim() || error.message));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
resolve(stdout);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/** Escape everything outside printable ASCII, so evidence cannot replay a control sequence. */
|
|
111
|
+
function escapeText(text) {
|
|
112
|
+
let escaped = "";
|
|
113
|
+
for (const char of text) {
|
|
114
|
+
const codePoint = char.codePointAt(0) ?? 0;
|
|
115
|
+
escaped += codePoint >= 0x20 && codePoint <= 0x7e ? char : `\\u{${codePoint.toString(16).padStart(4, "0")}}`;
|
|
116
|
+
}
|
|
117
|
+
return escaped;
|
|
118
|
+
}
|
|
119
|
+
function quote(text) {
|
|
120
|
+
return `"${escapeText(text)}"`;
|
|
121
|
+
}
|
|
122
|
+
async function resolveCommit(cwd, revision) {
|
|
123
|
+
// A revision that begins with a dash would be read as an option.
|
|
124
|
+
if (typeof revision !== "string" || revision.length === 0 || revision.startsWith("-")) {
|
|
125
|
+
throw new Error(`revision ${quote(String(revision))} does not name a commit`);
|
|
126
|
+
}
|
|
127
|
+
let hash = "";
|
|
128
|
+
try {
|
|
129
|
+
hash = (await runGit(cwd, ["rev-parse", "--verify", "--quiet", `${revision}^{commit}`])).trim();
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
throw new Error(`revision ${quote(revision)} does not name a commit: ${error.message}`);
|
|
133
|
+
}
|
|
134
|
+
if (hash.length === 0) {
|
|
135
|
+
throw new Error(`revision ${quote(revision)} does not name a commit`);
|
|
136
|
+
}
|
|
137
|
+
return hash;
|
|
138
|
+
}
|
|
139
|
+
function toLines(text) {
|
|
140
|
+
if (text.includes("\0")) {
|
|
141
|
+
return [];
|
|
142
|
+
}
|
|
143
|
+
const lines = text.split("\n");
|
|
144
|
+
if (lines[lines.length - 1] === "") {
|
|
145
|
+
lines.pop();
|
|
146
|
+
}
|
|
147
|
+
return lines.map((line) => line.replace(/\r$/, ""));
|
|
148
|
+
}
|
|
149
|
+
async function readBlob(cwd, blob) {
|
|
150
|
+
return blob === null ? [] : toLines(await runGit(cwd, ["cat-file", "blob", blob]));
|
|
151
|
+
}
|
|
152
|
+
/** The removed and added lines of a blob-to-blob diff, numbered on their own side. */
|
|
153
|
+
async function diffBlobs(cwd, oldBlob, newBlob) {
|
|
154
|
+
const out = await runGit(cwd, ["diff", "-U0", "--no-color", "--no-ext-diff", "--no-textconv", oldBlob, newBlob]);
|
|
155
|
+
const removed = [];
|
|
156
|
+
const added = [];
|
|
157
|
+
let oldLine = 0;
|
|
158
|
+
let newLine = 0;
|
|
159
|
+
let inHunk = false;
|
|
160
|
+
for (const raw of out.split("\n")) {
|
|
161
|
+
const hunk = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(raw);
|
|
162
|
+
if (hunk !== null) {
|
|
163
|
+
oldLine = Number(hunk[1]);
|
|
164
|
+
newLine = Number(hunk[2]);
|
|
165
|
+
inHunk = true;
|
|
166
|
+
}
|
|
167
|
+
else if (inHunk && raw.startsWith("-")) {
|
|
168
|
+
removed.push({ number: oldLine, text: raw.slice(1).replace(/\r$/, "") });
|
|
169
|
+
oldLine += 1;
|
|
170
|
+
}
|
|
171
|
+
else if (inHunk && raw.startsWith("+")) {
|
|
172
|
+
added.push({ number: newLine, text: raw.slice(1).replace(/\r$/, "") });
|
|
173
|
+
newLine += 1;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return { removed, added };
|
|
177
|
+
}
|
|
178
|
+
function numbered(lines) {
|
|
179
|
+
return lines.map((text, index) => ({ number: index + 1, text }));
|
|
180
|
+
}
|
|
181
|
+
/** Every file pair between two commits, from git's raw diff, with its lines. */
|
|
182
|
+
async function readChanges(cwd, from, to) {
|
|
183
|
+
const out = await runGit(cwd, ["diff", "--raw", "-z", "--no-abbrev", "--find-renames", "--no-relative", from, to, "--"]);
|
|
184
|
+
const fields = out.split("\0");
|
|
185
|
+
const changes = [];
|
|
186
|
+
let i = 0;
|
|
187
|
+
while (i < fields.length) {
|
|
188
|
+
const head = fields[i] ?? "";
|
|
189
|
+
i += 1;
|
|
190
|
+
if (!head.startsWith(":")) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const [oldMode = "", newMode = "", oldSha = "", newSha = "", status = ""] = head.slice(1).split(" ");
|
|
194
|
+
const first = fields[i] ?? "";
|
|
195
|
+
i += 1;
|
|
196
|
+
let second = first;
|
|
197
|
+
if (status.startsWith("R") || status.startsWith("C")) {
|
|
198
|
+
second = fields[i] ?? "";
|
|
199
|
+
i += 1;
|
|
200
|
+
}
|
|
201
|
+
const regular = (mode, sha) => mode.startsWith("100") && !/^0+$/.test(sha) ? sha : null;
|
|
202
|
+
const oldBlob = regular(oldMode, oldSha);
|
|
203
|
+
const newBlob = regular(newMode, newSha);
|
|
204
|
+
let lines;
|
|
205
|
+
if (oldBlob !== null && newBlob !== null) {
|
|
206
|
+
lines = await diffBlobs(cwd, oldBlob, newBlob);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
lines = { removed: numbered(await readBlob(cwd, oldBlob)), added: numbered(await readBlob(cwd, newBlob)) };
|
|
210
|
+
}
|
|
211
|
+
changes.push({
|
|
212
|
+
oldPath: status.startsWith("A") ? null : first,
|
|
213
|
+
newPath: status.startsWith("D") ? null : second,
|
|
214
|
+
oldBlob,
|
|
215
|
+
newBlob,
|
|
216
|
+
...lines,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
return changes;
|
|
220
|
+
}
|
|
221
|
+
function matches(pattern, text) {
|
|
222
|
+
pattern.lastIndex = 0;
|
|
223
|
+
return pattern.exec(text);
|
|
224
|
+
}
|
|
225
|
+
function kindsOf(path, spellings) {
|
|
226
|
+
const kinds = new Set(["any"]);
|
|
227
|
+
if (spellings.testFiles.some((pattern) => matches(pattern, path) !== null)) {
|
|
228
|
+
kinds.add("test");
|
|
229
|
+
}
|
|
230
|
+
if (spellings.configFiles.some((pattern) => matches(pattern, path) !== null)) {
|
|
231
|
+
kinds.add("config");
|
|
232
|
+
}
|
|
233
|
+
return kinds;
|
|
234
|
+
}
|
|
235
|
+
/** A comment, kept whole, or a string literal on one line, whose text is dropped. */
|
|
236
|
+
const COMMENT_OR_STRING = /\/\/.*|\/\*.*?(?:\*\/|$)|(['"`])(?:\\.|(?!\1)[^\\])*\1/g;
|
|
237
|
+
function markersOn(rawText, kinds, spellings) {
|
|
238
|
+
const text = kinds.has("test")
|
|
239
|
+
? rawText.replace(COMMENT_OR_STRING, (all, mark) => (mark === undefined ? all : mark + mark))
|
|
240
|
+
: rawText;
|
|
241
|
+
const categories = new Set();
|
|
242
|
+
for (const marker of spellings.markers) {
|
|
243
|
+
if (marker.scope.some((scope) => kinds.has(scope)) && matches(marker.pattern, text) !== null) {
|
|
244
|
+
categories.add(marker.category);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return categories;
|
|
248
|
+
}
|
|
249
|
+
/** Skip and focus markers the range adds, less the ones it only moves. */
|
|
250
|
+
function markerFindings(changes, spellings) {
|
|
251
|
+
const moved = new Map();
|
|
252
|
+
for (const change of changes) {
|
|
253
|
+
if (change.oldPath === null) {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
const kinds = kindsOf(change.oldPath, spellings);
|
|
257
|
+
for (const line of change.removed) {
|
|
258
|
+
if (markersOn(line.text, kinds, spellings).size > 0) {
|
|
259
|
+
const key = line.text.trim();
|
|
260
|
+
moved.set(key, (moved.get(key) ?? 0) + 1);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
const drafts = [];
|
|
265
|
+
for (const change of changes) {
|
|
266
|
+
if (change.newPath === null) {
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
const kinds = kindsOf(change.newPath, spellings);
|
|
270
|
+
for (const line of change.added) {
|
|
271
|
+
const categories = markersOn(line.text, kinds, spellings);
|
|
272
|
+
if (categories.size === 0) {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
const key = line.text.trim();
|
|
276
|
+
const count = moved.get(key) ?? 0;
|
|
277
|
+
if (count > 0) {
|
|
278
|
+
moved.set(key, count - 1);
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
for (const category of categories) {
|
|
282
|
+
const what = category === "skip" ? "test newly skipped" : "run newly focused";
|
|
283
|
+
drafts.push({ category, file: change.newPath, line: line.number, side: "candidate", detail: `${what}: ${key}` });
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return drafts;
|
|
288
|
+
}
|
|
289
|
+
function declarations(lines, spellings) {
|
|
290
|
+
const found = [];
|
|
291
|
+
lines.forEach((text, index) => {
|
|
292
|
+
for (const pattern of spellings.tests) {
|
|
293
|
+
const match = matches(pattern, text);
|
|
294
|
+
if (match !== null) {
|
|
295
|
+
found.push({ line: index + 1, name: match.groups?.["name"] ?? match[1] ?? text.trim() });
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
return found;
|
|
301
|
+
}
|
|
302
|
+
function countNames(found) {
|
|
303
|
+
const counts = new Map();
|
|
304
|
+
for (const { name } of found) {
|
|
305
|
+
counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
306
|
+
}
|
|
307
|
+
return counts;
|
|
308
|
+
}
|
|
309
|
+
/** The test a line falls in: the nearest declaration at or above it. */
|
|
310
|
+
function enclosing(found, line) {
|
|
311
|
+
let within = null;
|
|
312
|
+
for (const declaration of found) {
|
|
313
|
+
if (declaration.line > line) {
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
within = declaration;
|
|
317
|
+
}
|
|
318
|
+
return within;
|
|
319
|
+
}
|
|
320
|
+
function isAssertion(text, spellings) {
|
|
321
|
+
return spellings.assertions.some((pattern) => matches(pattern, text) !== null);
|
|
322
|
+
}
|
|
323
|
+
/** Lines grouped by the name of the test they fall in, leaving out the tests in `dropped`. */
|
|
324
|
+
function byTest(lines, found, dropped = new Set()) {
|
|
325
|
+
const groups = new Map();
|
|
326
|
+
for (const line of lines) {
|
|
327
|
+
const within = enclosing(found, line.number);
|
|
328
|
+
if (within !== null && dropped.has(within)) {
|
|
329
|
+
continue; // the whole test went, and `test-removed` says so
|
|
330
|
+
}
|
|
331
|
+
const name = within?.name ?? null;
|
|
332
|
+
groups.set(name, [...(groups.get(name) ?? []), line]);
|
|
333
|
+
}
|
|
334
|
+
return groups;
|
|
335
|
+
}
|
|
336
|
+
/** Tests removed from a test file that still exists, and assertions removed from tests that remain. */
|
|
337
|
+
async function testFindings(cwd, change, file, spellings) {
|
|
338
|
+
const before = declarations(await readBlob(cwd, change.oldBlob), spellings);
|
|
339
|
+
const after = declarations(await readBlob(cwd, change.newBlob), spellings);
|
|
340
|
+
const beforeCounts = countNames(before);
|
|
341
|
+
const afterCounts = countNames(after);
|
|
342
|
+
const removedLines = new Set(change.removed.map((line) => line.number));
|
|
343
|
+
const drafts = [];
|
|
344
|
+
const dropped = new Set();
|
|
345
|
+
for (const [name, count] of beforeCounts) {
|
|
346
|
+
const deficit = count - (afterCounts.get(name) ?? 0);
|
|
347
|
+
const gone = before.filter((declaration) => declaration.name === name && removedLines.has(declaration.line));
|
|
348
|
+
for (const declaration of gone.slice(0, Math.max(deficit, 0))) {
|
|
349
|
+
dropped.add(declaration);
|
|
350
|
+
drafts.push({ category: "test-removed", file, line: declaration.line, side: "base", detail: `test ${quote(name)} removed` });
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
const removed = byTest(change.removed.filter((line) => isAssertion(line.text, spellings)), before, dropped);
|
|
354
|
+
const added = byTest(change.added.filter((line) => isAssertion(line.text, spellings)), after);
|
|
355
|
+
for (const [name, lines] of removed) {
|
|
356
|
+
const replacements = (added.get(name) ?? []).map((line) => line.text.trim());
|
|
357
|
+
const left = lines.filter((line) => {
|
|
358
|
+
const at = replacements.indexOf(line.text.trim());
|
|
359
|
+
if (at === -1) {
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
362
|
+
replacements.splice(at, 1);
|
|
363
|
+
return false;
|
|
364
|
+
});
|
|
365
|
+
const where = name === null ? "outside any test" : `from test ${quote(name)}`;
|
|
366
|
+
for (const line of left.slice(0, Math.max(left.length - replacements.length, 0))) {
|
|
367
|
+
drafts.push({
|
|
368
|
+
category: "assertion-removed",
|
|
369
|
+
file,
|
|
370
|
+
line: line.number,
|
|
371
|
+
side: "base",
|
|
372
|
+
detail: `assertion removed ${where}: ${line.text.trim()}`,
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return drafts;
|
|
377
|
+
}
|
|
378
|
+
/** The text after the sanction key on every such line of the range's commit messages. */
|
|
379
|
+
async function readSanctionLines(cwd, from, to) {
|
|
380
|
+
const out = await runGit(cwd, ["log", "--format=%B%x00", `${from}..${to}`, "--"]);
|
|
381
|
+
const prefix = `${SANCTION_KEY}:`;
|
|
382
|
+
return out
|
|
383
|
+
.split(/[\n\0]/)
|
|
384
|
+
.map((line) => line.trim())
|
|
385
|
+
.filter((line) => line.startsWith(prefix))
|
|
386
|
+
.map((line) => line.slice(prefix.length).trim());
|
|
387
|
+
}
|
|
388
|
+
function sanctionFor(draft, id, lines, given) {
|
|
389
|
+
for (const key of [id, `${draft.category}:${draft.file}`]) {
|
|
390
|
+
const reason = Object.hasOwn(given, key) ? given[key] : undefined;
|
|
391
|
+
if (typeof reason === "string" && reason.trim().length > 0) {
|
|
392
|
+
return reason.trim();
|
|
393
|
+
}
|
|
394
|
+
for (const line of lines) {
|
|
395
|
+
const rest = line.slice(key.length);
|
|
396
|
+
if (line.startsWith(key) && /^\s+\S/.test(rest)) {
|
|
397
|
+
return rest.trim();
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
function failed(evidence) {
|
|
404
|
+
return { name: NAME, status: "fail", evidence, findings: [] };
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Report the moves of `base..candidate` that lower what the suite asserts.
|
|
408
|
+
* Fails while any finding is unsanctioned, and fails closed: a revision that
|
|
409
|
+
* names no commit, or any git invocation that fails, is a `fail` record naming
|
|
410
|
+
* the cause - never a `pass`, and never a thrown error.
|
|
411
|
+
*/
|
|
412
|
+
export async function checkWeakenedTests(options) {
|
|
413
|
+
try {
|
|
414
|
+
const { cwd, base, candidate } = options;
|
|
415
|
+
const spellings = { ...WEAKENING_SPELLINGS, ...options.spellings };
|
|
416
|
+
const baseCommit = await resolveCommit(cwd, base);
|
|
417
|
+
const candidateCommit = await resolveCommit(cwd, candidate);
|
|
418
|
+
let ancestor;
|
|
419
|
+
try {
|
|
420
|
+
ancestor = (await runGit(cwd, ["merge-base", baseCommit, candidateCommit])).trim();
|
|
421
|
+
}
|
|
422
|
+
catch (error) {
|
|
423
|
+
throw new Error(`no merge base of ${quote(base)} and ${quote(candidate)}: ${error.message}`);
|
|
424
|
+
}
|
|
425
|
+
const changes = await readChanges(cwd, ancestor, candidateCommit);
|
|
426
|
+
const drafts = markerFindings(changes, spellings);
|
|
427
|
+
for (const change of changes) {
|
|
428
|
+
if (change.oldPath === null || !kindsOf(change.oldPath, spellings).has("test")) {
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
if (change.newPath === null || !kindsOf(change.newPath, spellings).has("test")) {
|
|
432
|
+
const lines = await readBlob(cwd, change.oldBlob);
|
|
433
|
+
const detail = change.newPath === null ? "test file deleted" : `test file renamed to ${quote(change.newPath)}, which is not a test file`;
|
|
434
|
+
drafts.push({ category: "test-file-deleted", file: change.oldPath, line: lines.length > 0 ? 1 : 0, side: "base", detail });
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
drafts.push(...(await testFindings(cwd, change, change.oldPath, spellings)));
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const lines = await readSanctionLines(cwd, baseCommit, candidateCommit);
|
|
441
|
+
const findings = drafts.map((draft) => {
|
|
442
|
+
const id = `${draft.category}:${draft.file}:${draft.line}`;
|
|
443
|
+
return { id, ...draft, sanction: sanctionFor(draft, id, lines, options.sanctions ?? {}) };
|
|
444
|
+
});
|
|
445
|
+
const range = `${quote(base)}..${quote(candidate)}`;
|
|
446
|
+
if (findings.length === 0) {
|
|
447
|
+
return { name: NAME, status: "pass", evidence: [`no move in ${range} lowers what the suite asserts`], findings };
|
|
448
|
+
}
|
|
449
|
+
const evidence = findings.map((finding) => `${escapeText(finding.id)} [${finding.category}] ${escapeText(finding.detail)} - ` +
|
|
450
|
+
(finding.sanction === null ? "not sanctioned" : `sanctioned: ${escapeText(finding.sanction)}`));
|
|
451
|
+
const open = findings.filter((finding) => finding.sanction === null).length;
|
|
452
|
+
return { name: NAME, status: open > 0 ? "fail" : "pass", evidence, findings };
|
|
453
|
+
}
|
|
454
|
+
catch (error) {
|
|
455
|
+
return failed([escapeText(error instanceof Error ? error.message : String(error))]);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
//# sourceMappingURL=weakened-tests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weakened-tests.js","sourceRoot":"","sources":["../src/weakened-tests.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trofimyukdev/repo-truth",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Checks over a git commit range for the moves that make a repository look healthier than it is: weakened tests, lowered thresholds, loosened workflows, committed credentials and more.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"repo-truth": "dist/cli.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/trofimyukdev/repo-truth.git"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc -p tsconfig.build.json",
|
|
25
|
+
"typecheck": "tsc --noEmit",
|
|
26
|
+
"test": "vitest run"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/node": "^22.10.2",
|
|
30
|
+
"typescript": "^5.7.2",
|
|
31
|
+
"vitest": "^2.1.8"
|
|
32
|
+
}
|
|
33
|
+
}
|