@avi2dg/checks 0.24.2 → 0.26.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 +22 -0
- package/README.md +29 -22
- package/dist/effect-channel/index.js +4 -4
- package/dist/readability/index.js +5 -5
- package/docs/configs/commit-messages.md +1 -1
- package/docs/configs/effect-rules.md +2 -2
- package/docs/configs/native-settings.md +4 -2
- package/docs/design.md +10 -4
- package/docs/gates/checks-comment-gate.md +3 -4
- package/docs/gates/checks-docs.md +16 -14
- package/docs/gates/checks-exports.md +104 -0
- package/docs/gates/checks-flake.md +1 -1
- package/docs/gates/checks-lint.md +1 -1
- package/docs/gates/checks-quarantine-clock.md +1 -1
- package/docs/gates/checks-test-layout.md +14 -9
- package/docs/gates/checks-test.md +1 -1
- package/docs/gates/checks-unused.md +65 -0
- package/knip-base.json +4 -0
- package/package.json +75 -108
- package/src/complexity/exports.ts +196 -0
- package/src/complexity/knip.ts +70 -0
- package/{scripts → src/complexity}/repetition.ts +2 -2
- package/{scripts → src/complexity}/suppressions-ratchet.ts +2 -2
- package/src/complexity/unused.ts +48 -0
- package/src/core/gates.ts +46 -0
- package/{scripts → src/core}/lint.ts +2 -2
- package/{scripts → src/core}/swc.ts +1 -1
- package/{scripts → src/delivery}/changelog-write.ts +2 -2
- package/{scripts → src/delivery}/changelog.ts +3 -3
- package/{scripts → src/delivery}/ci-wiring.ts +3 -3
- package/{scripts → src/delivery}/commit-identity.ts +2 -2
- package/{scripts → src/delivery}/release-notes.ts +1 -1
- package/{scripts → src/delivery}/release-report.ts +2 -2
- package/{scripts → src/dependencies}/vendor-args.ts +1 -1
- package/{scripts → src/dependencies}/vendor.ts +2 -2
- package/{scripts → src/docs}/doc-references.ts +1 -1
- package/{scripts → src/docs}/doc-snapshot.ts +2 -2
- package/{scripts → src/docs}/doc-templates.ts +3 -3
- package/{scripts → src/docs}/docs.ts +2 -2
- package/{scripts → src/quality}/comment-gate.ts +2 -2
- package/{scripts → src/quality}/comment-matchers.ts +1 -1
- package/{scripts → src/quality}/comments.ts +2 -2
- package/{scripts → src/testing}/flake.ts +1 -1
- package/{scripts → src/testing}/mutation-compare.ts +1 -1
- package/{scripts → src/testing}/quarantine-clock.ts +2 -2
- package/{scripts → src/testing}/subsumed-tests.ts +2 -2
- package/{scripts → src/testing}/test-layout.ts +47 -14
- package/{scripts → src/testing}/test-report.ts +1 -1
- package/{scripts → src/testing}/test-skips.ts +1 -1
- package/{scripts → src/testing}/test.ts +2 -2
- package/CONTRIBUTING.md +0 -94
- package/docs/gates/checks-backtest.md +0 -54
- package/scripts/backtest.ts +0 -122
- package/scripts/gates.ts +0 -37
- package/scripts/range-gate.ts +0 -8
- /package/{templates → dist/templates}/adr.md +0 -0
- /package/{templates → dist/templates}/agents.md +0 -0
- /package/{templates → dist/templates}/changelog.md +0 -0
- /package/{templates → dist/templates}/claude.md +0 -0
- /package/{templates → dist/templates}/explanation.md +0 -0
- /package/{templates → dist/templates}/how-to.md +0 -0
- /package/{templates → dist/templates}/readme.md +0 -0
- /package/{templates → dist/templates}/reference.md +0 -0
- /package/{templates → dist/templates}/tutorial.md +0 -0
- /package/{scripts → src/core}/git.ts +0 -0
- /package/{scripts → src/core}/main.ts +0 -0
- /package/{scripts → src/delivery}/shell-command.ts +0 -0
- /package/{scripts → src/docs}/doc-outline.ts +0 -0
- /package/{scripts → src/docs}/doc-rules.ts +0 -0
- /package/{scripts → src/docs}/prose-matchers.ts +0 -0
- /package/{scripts → src/quality}/lint-coverage.sh +0 -0
- /package/{presets → src/quality/presets}/effect.language-service.json +0 -0
- /package/{presets → src/quality/presets}/effect.oxlint.json +0 -0
package/scripts/backtest.ts
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
import { Console, Effect, Option } from "effect";
|
|
3
|
-
import { comments, refused, syntaxOf } from "./comments.ts";
|
|
4
|
-
import { git } from "./git.ts";
|
|
5
|
-
import { runMain, Usage } from "./main.ts";
|
|
6
|
-
|
|
7
|
-
type Landed = {
|
|
8
|
-
readonly sha: string;
|
|
9
|
-
readonly subject: string;
|
|
10
|
-
readonly added: number;
|
|
11
|
-
readonly comments: number;
|
|
12
|
-
readonly refusals: readonly string[];
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
const USAGE = "usage: backtest.ts [commit-count]";
|
|
16
|
-
|
|
17
|
-
const EXCLUDED = ["generated/", "vendor/", "repos/", "node_modules/", "dist/"];
|
|
18
|
-
|
|
19
|
-
function readable(path: string): boolean {
|
|
20
|
-
if (EXCLUDED.some((prefix) => path.startsWith(prefix))) return false;
|
|
21
|
-
return syntaxOf(path) !== undefined;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const at = (sha: string, path: string) => git(["show", `${sha}:${path}`]).pipe(Effect.option);
|
|
25
|
-
|
|
26
|
-
function withoutLine(refusal: string): string {
|
|
27
|
-
return refusal.replace(/^(\S+?):\d+ /, "$1 ");
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
type Commit = {
|
|
31
|
-
readonly sha: string;
|
|
32
|
-
readonly parent: string;
|
|
33
|
-
readonly subject: string;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const firstParentCommits = Effect.fn("firstParentCommits")(function* (count: string) {
|
|
37
|
-
return (yield* git(["log", "--first-parent", "--format=%H%x09%P%x09%s", "-n", count]))
|
|
38
|
-
.trim()
|
|
39
|
-
.split("\n")
|
|
40
|
-
.map((row): Commit => {
|
|
41
|
-
const [sha = "", parents = "", subject = ""] = row.split("\t");
|
|
42
|
-
return { sha, parent: parents.split(" ")[0] ?? "", subject };
|
|
43
|
-
})
|
|
44
|
-
.filter((commit) => commit.sha !== "" && commit.parent !== "");
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
const addedLines = Effect.fn("addedLines")(function* ({ sha, parent }: Commit, changed: readonly string[]) {
|
|
48
|
-
const numstat = (yield* git(["diff", "--numstat", parent, sha, "--", ...changed])).trim();
|
|
49
|
-
return numstat === "" ? 0 : numstat.split("\n").reduce((sum, row) => sum + Number(row.split("\t")[0] ?? 0), 0);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
const pathLanded = Effect.fn("pathLanded")(function* ({ sha, parent }: Commit, path: string) {
|
|
53
|
-
const after = yield* at(sha, path);
|
|
54
|
-
if (Option.isNone(after)) return { comments: 0, refusals: [] };
|
|
55
|
-
const before = Option.getOrElse(yield* at(parent, path), () => "");
|
|
56
|
-
|
|
57
|
-
const wasRefused = new Set((yield* refused(path, before)).map(withoutLine));
|
|
58
|
-
const refusals = (yield* refused(path, after.value)).filter((refusal) => !wasRefused.has(withoutLine(refusal)));
|
|
59
|
-
|
|
60
|
-
const wasComment = new Set((yield* comments(path, before)).map((one) => one.text));
|
|
61
|
-
const added = (yield* comments(path, after.value)).filter((one) => !wasComment.has(one.text));
|
|
62
|
-
return { comments: added.reduce((sum, one) => sum + one.text.split("\n").length, 0), refusals };
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const commitLanded = Effect.fn("commitLanded")(function* (commit: Commit) {
|
|
66
|
-
const changed = (yield* git(["diff", "--name-only", "--diff-filter=d", commit.parent, commit.sha]))
|
|
67
|
-
.trim()
|
|
68
|
-
.split("\n")
|
|
69
|
-
.filter((path) => path !== "" && readable(path));
|
|
70
|
-
if (changed.length === 0) return Option.none<Landed>();
|
|
71
|
-
|
|
72
|
-
const added = yield* addedLines(commit, changed);
|
|
73
|
-
let commentLines = 0;
|
|
74
|
-
const refusals: string[] = [];
|
|
75
|
-
for (const path of changed) {
|
|
76
|
-
const one = yield* pathLanded(commit, path);
|
|
77
|
-
commentLines += one.comments;
|
|
78
|
-
refusals.push(...one.refusals);
|
|
79
|
-
}
|
|
80
|
-
return Option.some<Landed>({ sha: commit.sha.slice(0, 7), subject: commit.subject, added, comments: commentLines, refusals });
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
function summary(landed: readonly Landed[]): string {
|
|
84
|
-
const lines: string[] = [];
|
|
85
|
-
const total = (pick: (one: Landed) => number): number => landed.reduce((sum, one) => sum + pick(one), 0);
|
|
86
|
-
const added = total((one) => one.added);
|
|
87
|
-
const commentLines = total((one) => one.comments);
|
|
88
|
-
const refusalCount = total((one) => one.refusals.length);
|
|
89
|
-
|
|
90
|
-
for (const one of landed) {
|
|
91
|
-
lines.push(`${one.sha}\t${one.added}\t${one.comments}\t${one.refusals.length}\t${one.subject.slice(0, 58)}`);
|
|
92
|
-
}
|
|
93
|
-
lines.push(`${landed.length} commits touching code, ${added} added lines`);
|
|
94
|
-
lines.push(
|
|
95
|
-
`comment lines added: ${commentLines} (${((commentLines / Math.max(added, 1)) * 100).toFixed(1)}% of added lines)`,
|
|
96
|
-
);
|
|
97
|
-
lines.push(`refusals introduced: ${refusalCount}`);
|
|
98
|
-
for (const one of landed) {
|
|
99
|
-
if (one.refusals.length === 0) continue;
|
|
100
|
-
lines.push(`\n ${one.sha} ${one.subject}`);
|
|
101
|
-
for (const refusal of one.refusals) lines.push(` ${refusal}`);
|
|
102
|
-
}
|
|
103
|
-
return lines.join("\n");
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export const backtest = Effect.fn("backtest")(function* (count: string) {
|
|
107
|
-
const landed: Landed[] = [];
|
|
108
|
-
for (const commit of yield* firstParentCommits(count)) {
|
|
109
|
-
const one = yield* commitLanded(commit);
|
|
110
|
-
if (Option.isSome(one)) landed.push(one.value);
|
|
111
|
-
}
|
|
112
|
-
return summary(landed);
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
const main = Effect.gen(function* () {
|
|
116
|
-
const [count = "60", ...extra] = process.argv.slice(2);
|
|
117
|
-
if (extra.length > 0) return yield* new Usage({ message: USAGE });
|
|
118
|
-
yield* Console.log(yield* backtest(count));
|
|
119
|
-
return true;
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
if (import.meta.main) runMain("backtest", main);
|
package/scripts/gates.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
export type Program = {
|
|
2
|
-
readonly bin: string;
|
|
3
|
-
readonly script: string;
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
type TrackedContent = {
|
|
7
|
-
readonly pathspecs: readonly string[];
|
|
8
|
-
readonly content: string;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export const EVERY_REPOSITORY = "every repository";
|
|
12
|
-
|
|
13
|
-
export type KitGate = Program & {
|
|
14
|
-
readonly reads: "tree" | "range";
|
|
15
|
-
readonly args?: readonly string[];
|
|
16
|
-
readonly appliesTo: typeof EVERY_REPOSITORY | TrackedContent;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const ENTRY_POINT: Program = { bin: "checks-lint", script: "lint.ts" };
|
|
20
|
-
|
|
21
|
-
export const TEST_ENTRY_POINT: Program = { bin: "checks-test", script: "test.ts" };
|
|
22
|
-
|
|
23
|
-
export const DEFAULT_BRANCH = "main";
|
|
24
|
-
|
|
25
|
-
const TYPESCRIPT_SOURCE: TrackedContent = { pathspecs: ["*.ts", "*.tsx"], content: "TypeScript source" };
|
|
26
|
-
|
|
27
|
-
export const KIT_GATES = [
|
|
28
|
-
{ bin: "checks-lint-coverage", script: "lint-coverage.sh", reads: "tree", appliesTo: TYPESCRIPT_SOURCE },
|
|
29
|
-
{ bin: "checks-test-layout", script: "test-layout.ts", reads: "tree", appliesTo: TYPESCRIPT_SOURCE },
|
|
30
|
-
{ bin: "checks-commit-identity", script: "commit-identity.ts", reads: "range", appliesTo: EVERY_REPOSITORY },
|
|
31
|
-
{ bin: "checks-comment-gate", script: "comment-gate.ts", reads: "range", appliesTo: EVERY_REPOSITORY },
|
|
32
|
-
{ bin: "checks-suppressions-ratchet", script: "suppressions-ratchet.ts", reads: "range", appliesTo: EVERY_REPOSITORY },
|
|
33
|
-
{ bin: "checks-ci-wiring", script: "ci-wiring.ts", reads: "tree", appliesTo: EVERY_REPOSITORY },
|
|
34
|
-
{ bin: "checks-docs", script: "docs.ts", reads: "range", appliesTo: EVERY_REPOSITORY },
|
|
35
|
-
{ bin: "checks-repetition", script: "repetition.ts", reads: "range", appliesTo: TYPESCRIPT_SOURCE },
|
|
36
|
-
{ bin: "checks-quarantine-clock", script: "quarantine-clock.ts", reads: "range", appliesTo: EVERY_REPOSITORY },
|
|
37
|
-
] as const satisfies readonly KitGate[];
|
package/scripts/range-gate.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
2
|
-
import { git, refArgs } from "./git.ts";
|
|
3
|
-
|
|
4
|
-
export const rangeGateInputs = Effect.fn("rangeGateInputs")(function* (usage: string) {
|
|
5
|
-
const refs = yield* refArgs(process.argv.slice(2), usage);
|
|
6
|
-
const root = (yield* git(["rev-parse", "--show-toplevel"])).trim();
|
|
7
|
-
return { refs, root };
|
|
8
|
-
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|