@shivaedev/quality 0.22.0 → 0.24.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 +13 -0
- package/README.md +4 -0
- package/dist/baseline/compare.d.ts +2 -2
- package/dist/baseline/compare.d.ts.map +1 -1
- package/dist/baseline/compare.js +5 -3
- package/dist/baseline/compare.js.map +1 -1
- package/dist/baseline/format.d.ts +5 -5
- package/dist/baseline/format.d.ts.map +1 -1
- package/dist/baseline/format.js +23 -13
- package/dist/baseline/format.js.map +1 -1
- package/dist/baseline/legacy.d.ts +2 -2
- package/dist/baseline/legacy.d.ts.map +1 -1
- package/dist/baseline/legacy.js +4 -4
- package/dist/baseline/legacy.js.map +1 -1
- package/dist/baseline/rewrite.d.ts +1 -1
- package/dist/baseline/rewrite.d.ts.map +1 -1
- package/dist/baseline/rewrite.js +2 -2
- package/dist/baseline/rewrite.js.map +1 -1
- package/dist/baseline/update.d.ts +2 -2
- package/dist/baseline/update.d.ts.map +1 -1
- package/dist/baseline/update.js +24 -18
- package/dist/baseline/update.js.map +1 -1
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +15 -9
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/baseline.d.ts +1 -1
- package/dist/cli/baseline.d.ts.map +1 -1
- package/dist/cli/baseline.js +10 -6
- package/dist/cli/baseline.js.map +1 -1
- package/dist/cli/fix.d.ts +2 -2
- package/dist/cli/fix.d.ts.map +1 -1
- package/dist/cli/fix.js +34 -40
- package/dist/cli/fix.js.map +1 -1
- package/dist/cli/lint.d.ts +1 -1
- package/dist/cli/lint.d.ts.map +1 -1
- package/dist/cli/lint.js +1 -1
- package/dist/cli/lint.js.map +1 -1
- package/dist/cli/migrate.d.ts.map +1 -1
- package/dist/cli/migrate.js +1 -1
- package/dist/cli/migrate.js.map +1 -1
- package/dist/cli/program.d.ts +9 -0
- package/dist/cli/program.d.ts.map +1 -0
- package/dist/cli/program.js +44 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/run-main.d.ts +5 -2
- package/dist/cli/run-main.d.ts.map +1 -1
- package/dist/cli/run-main.js +16 -12
- package/dist/cli/run-main.js.map +1 -1
- package/dist/cli/shrink.d.ts +2 -2
- package/dist/cli/shrink.d.ts.map +1 -1
- package/dist/cli/shrink.js +9 -3
- package/dist/cli/shrink.js.map +1 -1
- package/dist/cli.js +2 -49
- package/dist/cli.js.map +1 -1
- package/dist/config/decode.d.ts +1 -1
- package/dist/config/decode.d.ts.map +1 -1
- package/dist/config/decode.js +13 -9
- package/dist/config/decode.js.map +1 -1
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +26 -20
- package/dist/config/load.js.map +1 -1
- package/dist/config/resolve.d.ts +22 -2
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +18 -10
- package/dist/config/resolve.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -1
- package/dist/config.js.map +1 -1
- package/dist/decoded.d.ts +2 -2
- package/dist/decoded.d.ts.map +1 -1
- package/dist/decoded.js +7 -5
- package/dist/decoded.js.map +1 -1
- package/dist/engine/baseline-file.d.ts +1 -1
- package/dist/engine/baseline-file.d.ts.map +1 -1
- package/dist/engine/baseline-file.js +4 -2
- package/dist/engine/baseline-file.js.map +1 -1
- package/dist/engine/evaluate.d.ts +2 -2
- package/dist/engine/evaluate.d.ts.map +1 -1
- package/dist/engine/evaluate.js +5 -3
- package/dist/engine/evaluate.js.map +1 -1
- package/dist/engine/run-rules.d.ts +1 -1
- package/dist/engine/run-rules.d.ts.map +1 -1
- package/dist/engine/run-rules.js +24 -14
- package/dist/engine/run-rules.js.map +1 -1
- package/dist/engine/session.d.ts.map +1 -1
- package/dist/engine/session.js +8 -4
- package/dist/engine/session.js.map +1 -1
- package/dist/engine/violation.d.ts +7 -7
- package/dist/engine/violation.d.ts.map +1 -1
- package/dist/engine/violation.js +22 -10
- package/dist/engine/violation.js.map +1 -1
- package/dist/exceptions/registry.d.ts +2 -2
- package/dist/exceptions/registry.d.ts.map +1 -1
- package/dist/exceptions/registry.js +10 -6
- package/dist/exceptions/registry.js.map +1 -1
- package/dist/git/base.d.ts +1 -2
- package/dist/git/base.d.ts.map +1 -1
- package/dist/git/base.js +22 -10
- package/dist/git/base.js.map +1 -1
- package/dist/git/command.d.ts +2 -2
- package/dist/git/command.d.ts.map +1 -1
- package/dist/git/command.js +13 -9
- package/dist/git/command.js.map +1 -1
- package/dist/git/history.d.ts +1 -1
- package/dist/git/history.d.ts.map +1 -1
- package/dist/git/history.js +5 -3
- package/dist/git/history.js.map +1 -1
- package/dist/inventory/collect.d.ts +1 -1
- package/dist/inventory/collect.d.ts.map +1 -1
- package/dist/inventory/collect.js +7 -5
- package/dist/inventory/collect.js.map +1 -1
- package/dist/inventory/filesystem.d.ts +1 -1
- package/dist/inventory/filesystem.d.ts.map +1 -1
- package/dist/inventory/filesystem.js +11 -7
- package/dist/inventory/filesystem.js.map +1 -1
- package/dist/inventory/ignore-scope.d.ts +4 -4
- package/dist/inventory/ignore-scope.d.ts.map +1 -1
- package/dist/inventory/ignore-scope.js +18 -9
- package/dist/inventory/ignore-scope.js.map +1 -1
- package/dist/manifests/sorted.d.ts +1 -1
- package/dist/manifests/sorted.d.ts.map +1 -1
- package/dist/manifests/sorted.js +14 -16
- package/dist/manifests/sorted.js.map +1 -1
- package/dist/report/plural.d.ts +1 -1
- package/dist/report/plural.d.ts.map +1 -1
- package/dist/report/plural.js +3 -1
- package/dist/report/plural.js.map +1 -1
- package/dist/report/render.d.ts +1 -1
- package/dist/report/render.d.ts.map +1 -1
- package/dist/report/render.js +29 -21
- package/dist/report/render.js.map +1 -1
- package/dist/report/stale.d.ts +1 -1
- package/dist/report/stale.d.ts.map +1 -1
- package/dist/report/stale.js +18 -8
- package/dist/report/stale.js.map +1 -1
- package/dist/rule.d.ts +13 -13
- package/dist/rule.d.ts.map +1 -1
- package/dist/rule.js +10 -8
- package/dist/rule.js.map +1 -1
- package/dist/rules/built-in.d.ts +2 -2
- package/dist/rules/built-in.d.ts.map +1 -1
- package/dist/rules/built-in.js +6 -0
- package/dist/rules/built-in.js.map +1 -1
- package/dist/rules/comments/kinds.d.ts +4 -4
- package/dist/rules/comments/kinds.d.ts.map +1 -1
- package/dist/rules/comments/kinds.js +16 -8
- package/dist/rules/comments/kinds.js.map +1 -1
- package/dist/rules/comments/max-per-file.d.ts.map +1 -1
- package/dist/rules/comments/max-per-file.js +13 -9
- package/dist/rules/comments/max-per-file.js.map +1 -1
- package/dist/rules/comments/pattern-rule.d.ts +1 -1
- package/dist/rules/comments/pattern-rule.d.ts.map +1 -1
- package/dist/rules/comments/pattern-rule.js +12 -10
- package/dist/rules/comments/pattern-rule.js.map +1 -1
- package/dist/rules/comments/scan.d.ts +3 -3
- package/dist/rules/comments/scan.d.ts.map +1 -1
- package/dist/rules/comments/scan.js +23 -19
- package/dist/rules/comments/scan.js.map +1 -1
- package/dist/rules/max-lines.d.ts.map +1 -1
- package/dist/rules/max-lines.js +12 -10
- package/dist/rules/max-lines.js.map +1 -1
- package/dist/rules/maxDepth.d.ts +2 -0
- package/dist/rules/maxDepth.d.ts.map +1 -0
- package/dist/rules/maxDepth.js +20 -0
- package/dist/rules/maxDepth.js.map +1 -0
- package/dist/rules/noBarrel.d.ts +2 -0
- package/dist/rules/noBarrel.d.ts.map +1 -0
- package/dist/rules/noBarrel.js +14 -0
- package/dist/rules/noBarrel.js.map +1 -0
- package/dist/rules/stories/origins.d.ts +10 -0
- package/dist/rules/stories/origins.d.ts.map +1 -0
- package/dist/rules/stories/origins.js +129 -0
- package/dist/rules/stories/origins.js.map +1 -0
- package/dist/rules/stories/prerequisites.d.ts +4 -0
- package/dist/rules/stories/prerequisites.d.ts.map +1 -0
- package/dist/rules/stories/prerequisites.js +32 -0
- package/dist/rules/stories/prerequisites.js.map +1 -0
- package/dist/rules/stories/program.d.ts +5 -0
- package/dist/rules/stories/program.d.ts.map +1 -0
- package/dist/rules/stories/program.js +22 -0
- package/dist/rules/stories/program.js.map +1 -0
- package/dist/rules/stories/specs.d.ts +2 -0
- package/dist/rules/stories/specs.d.ts.map +1 -0
- package/dist/rules/stories/specs.js +80 -0
- package/dist/rules/stories/specs.js.map +1 -0
- package/dist/rules/suppressions/biome/configs.d.ts +1 -1
- package/dist/rules/suppressions/biome/configs.d.ts.map +1 -1
- package/dist/rules/suppressions/biome/configs.js +23 -17
- package/dist/rules/suppressions/biome/configs.js.map +1 -1
- package/dist/rules/suppressions/biome/declarations.d.ts +4 -4
- package/dist/rules/suppressions/biome/declarations.d.ts.map +1 -1
- package/dist/rules/suppressions/biome/declarations.js +15 -7
- package/dist/rules/suppressions/biome/declarations.js.map +1 -1
- package/dist/rules/suppressions/biome/json.d.ts +6 -6
- package/dist/rules/suppressions/biome/json.d.ts.map +1 -1
- package/dist/rules/suppressions/biome/json.js +27 -13
- package/dist/rules/suppressions/biome/json.js.map +1 -1
- package/dist/rules/suppressions/biome/resolve.d.ts +1 -1
- package/dist/rules/suppressions/biome/resolve.d.ts.map +1 -1
- package/dist/rules/suppressions/biome/resolve.js +23 -17
- package/dist/rules/suppressions/biome/resolve.js.map +1 -1
- package/dist/rules/suppressions/biome/weakenings.d.ts +1 -1
- package/dist/rules/suppressions/biome/weakenings.d.ts.map +1 -1
- package/dist/rules/suppressions/biome/weakenings.js +78 -52
- package/dist/rules/suppressions/biome/weakenings.js.map +1 -1
- package/dist/rules/suppressions/biome-overrides.d.ts.map +1 -1
- package/dist/rules/suppressions/biome-overrides.js +45 -33
- package/dist/rules/suppressions/biome-overrides.js.map +1 -1
- package/dist/rules/suppressions/directives.d.ts +1 -1
- package/dist/rules/suppressions/directives.d.ts.map +1 -1
- package/dist/rules/suppressions/directives.js +5 -3
- package/dist/rules/suppressions/directives.js.map +1 -1
- package/dist/rules/suppressions/no-double-cast.d.ts.map +1 -1
- package/dist/rules/suppressions/no-double-cast.js +14 -10
- package/dist/rules/suppressions/no-double-cast.js.map +1 -1
- package/dist/rules/suppressions/no-inline.d.ts.map +1 -1
- package/dist/rules/suppressions/no-inline.js +8 -6
- package/dist/rules/suppressions/no-inline.js.map +1 -1
- package/dist/rules/suppressions/stylesheet-comments.d.ts +1 -1
- package/dist/rules/suppressions/stylesheet-comments.d.ts.map +1 -1
- package/dist/rules/suppressions/stylesheet-comments.js +11 -5
- package/dist/rules/suppressions/stylesheet-comments.js.map +1 -1
- package/dist/rules/syntax.d.ts +1 -1
- package/dist/rules/syntax.d.ts.map +1 -1
- package/dist/rules/syntax.js +2 -2
- package/dist/rules/syntax.js.map +1 -1
- package/dist/standard-schema.d.ts +6 -6
- package/dist/standard-schema.d.ts.map +1 -1
- package/docs/modules.md +19 -1
- package/docs/roadmap.md +1 -1
- package/docs/rules.md +9 -1
- package/package.json +2 -2
- package/src/baseline/compare.ts +5 -3
- package/src/baseline/format.ts +17 -10
- package/src/baseline/legacy.ts +4 -4
- package/src/baseline/rewrite.ts +2 -2
- package/src/baseline/update.ts +20 -16
- package/src/cli/args.ts +15 -10
- package/src/cli/baseline.ts +36 -35
- package/src/cli/fix.ts +39 -42
- package/src/cli/lint.ts +17 -19
- package/src/cli/migrate.ts +20 -21
- package/src/cli/program.ts +50 -0
- package/src/cli/run-main.ts +19 -13
- package/src/cli/shrink.ts +11 -8
- package/src/cli.ts +2 -51
- package/src/config/decode.ts +15 -10
- package/src/config/load.ts +44 -37
- package/src/config/resolve.ts +32 -27
- package/src/config.ts +3 -1
- package/src/decoded.ts +5 -4
- package/src/engine/baseline-file.ts +14 -12
- package/src/engine/evaluate.ts +6 -5
- package/src/engine/run-rules.ts +21 -13
- package/src/engine/session.ts +32 -25
- package/src/engine/violation.ts +22 -11
- package/src/exceptions/registry.ts +10 -8
- package/src/git/base.ts +45 -37
- package/src/git/command.ts +6 -4
- package/src/git/history.ts +5 -4
- package/src/inventory/collect.ts +39 -34
- package/src/inventory/filesystem.ts +38 -30
- package/src/inventory/ignore-scope.ts +20 -10
- package/src/manifests/sorted.ts +18 -18
- package/src/report/plural.ts +3 -1
- package/src/report/render.ts +23 -18
- package/src/report/stale.ts +33 -25
- package/src/rule.ts +25 -19
- package/src/rules/built-in.ts +6 -0
- package/src/rules/comments/kinds.ts +16 -9
- package/src/rules/comments/max-per-file.ts +15 -11
- package/src/rules/comments/pattern-rule.ts +5 -4
- package/src/rules/comments/scan.ts +18 -15
- package/src/rules/max-lines.ts +3 -2
- package/src/rules/maxDepth.ts +24 -0
- package/src/rules/noBarrel.ts +16 -0
- package/src/rules/stories/origins.ts +147 -0
- package/src/rules/stories/prerequisites.ts +37 -0
- package/src/rules/stories/program.ts +29 -0
- package/src/rules/stories/specs.ts +93 -0
- package/src/rules/suppressions/biome/configs.ts +23 -17
- package/src/rules/suppressions/biome/declarations.ts +15 -10
- package/src/rules/suppressions/biome/json.ts +25 -13
- package/src/rules/suppressions/biome/resolve.ts +23 -18
- package/src/rules/suppressions/biome/weakenings.ts +60 -41
- package/src/rules/suppressions/biome-overrides.ts +32 -22
- package/src/rules/suppressions/directives.ts +5 -4
- package/src/rules/suppressions/no-double-cast.ts +14 -10
- package/src/rules/suppressions/no-inline.ts +5 -4
- package/src/rules/suppressions/stylesheet-comments.ts +11 -6
- package/src/rules/syntax.ts +2 -2
- package/src/standard-schema.ts +4 -4
package/src/baseline/format.ts
CHANGED
|
@@ -16,18 +16,22 @@ export interface BaselineEntry {
|
|
|
16
16
|
readonly rule: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
function codepoints(left: string, right: string): number {
|
|
20
|
+
return left < right ? -1 : Number(left > right);
|
|
21
|
+
}
|
|
20
22
|
|
|
21
|
-
export
|
|
22
|
-
codepoints(left.file, right.file) || codepoints(left.rule, right.rule);
|
|
23
|
+
export function byPathAndRule(left: BaselineEntry, right: BaselineEntry): number {
|
|
24
|
+
return codepoints(left.file, right.file) || codepoints(left.rule, right.rule);
|
|
25
|
+
}
|
|
23
26
|
|
|
24
|
-
export
|
|
25
|
-
(raw ?? "")
|
|
27
|
+
export function linesOf(raw: string | undefined): ReadonlyArray<{ readonly line: number; readonly text: string }> {
|
|
28
|
+
return (raw ?? "")
|
|
26
29
|
.split("\n")
|
|
27
30
|
.map((text, index) => ({ line: index + 1, text }))
|
|
28
31
|
.filter((row) => row.text.trim() !== "");
|
|
32
|
+
}
|
|
29
33
|
|
|
30
|
-
export
|
|
34
|
+
export async function decodeBaseline(raw: string | undefined): Promise<Decoded<readonly BaselineEntry[]>> {
|
|
31
35
|
const issues: string[] = [];
|
|
32
36
|
const entries: BaselineEntry[] = [];
|
|
33
37
|
const seen = new Set<string>();
|
|
@@ -45,14 +49,17 @@ export const decodeBaseline = async (raw: string | undefined): Promise<Decoded<r
|
|
|
45
49
|
entries.push({ ...stored, file: path });
|
|
46
50
|
}
|
|
47
51
|
return issues.length === 0 ? { _tag: "Valid", value: entries } : { _tag: "Invalid", issues };
|
|
48
|
-
}
|
|
52
|
+
}
|
|
49
53
|
|
|
50
54
|
const LINE_KEYS = ["path", "rule", "count"];
|
|
51
55
|
|
|
52
|
-
export
|
|
56
|
+
export function encodeEntry(entry: BaselineEntry): string {
|
|
57
|
+
return JSON.stringify({ count: entry.count, path: entry.file, rule: entry.rule }, LINE_KEYS);
|
|
58
|
+
}
|
|
53
59
|
|
|
54
|
-
export
|
|
55
|
-
[...entries]
|
|
60
|
+
export function encodeBaseline(entries: readonly BaselineEntry[]): string {
|
|
61
|
+
return [...entries]
|
|
56
62
|
.sort(byPathAndRule)
|
|
57
63
|
.map((entry) => `${encodeEntry(entry)}\n`)
|
|
58
64
|
.join("");
|
|
65
|
+
}
|
package/src/baseline/legacy.ts
CHANGED
|
@@ -19,7 +19,7 @@ export interface LegacyEntry extends BaselineEntry {
|
|
|
19
19
|
readonly measure?: number | undefined;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export
|
|
22
|
+
export async function decodeLegacyBaseline(raw: string): Promise<Decoded<readonly LegacyEntry[]>> {
|
|
23
23
|
const decoded = await decodeWith(standard, raw);
|
|
24
24
|
if (decoded._tag === "Invalid") {
|
|
25
25
|
return decoded;
|
|
@@ -28,9 +28,9 @@ export const decodeLegacyBaseline = async (raw: string): Promise<Decoded<readonl
|
|
|
28
28
|
Object.entries(files).map(([file, stored]) => ({ ...stored, file, rule })),
|
|
29
29
|
);
|
|
30
30
|
return { _tag: "Valid", value: entries };
|
|
31
|
-
}
|
|
31
|
+
}
|
|
32
32
|
|
|
33
|
-
export
|
|
33
|
+
export function convertLegacy(legacy: readonly LegacyEntry[], violations: readonly Violation[]): readonly BaselineEntry[] {
|
|
34
34
|
const current = groupBy(violations, (violation) => keyOf(violation.rule, violation.file));
|
|
35
35
|
return legacy.flatMap(({ count, file, measure, rule }) => {
|
|
36
36
|
if (measure === undefined) {
|
|
@@ -41,4 +41,4 @@ export const convertLegacy = (legacy: readonly LegacyEntry[], violations: readon
|
|
|
41
41
|
const converted = threshold === undefined ? countOf(group) : Math.ceil(measure - threshold);
|
|
42
42
|
return converted > 0 ? [{ count: converted, file, rule }] : [];
|
|
43
43
|
});
|
|
44
|
-
}
|
|
44
|
+
}
|
package/src/baseline/rewrite.ts
CHANGED
|
@@ -7,7 +7,7 @@ interface Row {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
// An untouched entry keeps its exact line and a new one goes before the first line that sorts after it, so two branches conflict only on the same or neighbouring entries.
|
|
10
|
-
export
|
|
10
|
+
export function rewriteBaseline(raw: string | undefined, before: readonly BaselineEntry[], after: readonly BaselineEntry[]): string {
|
|
11
11
|
const wanted = new Map(after.map((entry) => [keyOf(entry.rule, entry.file), entry]));
|
|
12
12
|
const lines = linesOf(raw);
|
|
13
13
|
const rows: Row[] = before.flatMap((old, index) => {
|
|
@@ -21,4 +21,4 @@ export const rewriteBaseline = (raw: string | undefined, before: readonly Baseli
|
|
|
21
21
|
rows.splice(at === -1 ? rows.length : at, 0, { entry, text: encodeEntry(entry) });
|
|
22
22
|
}
|
|
23
23
|
return rows.map((row) => `${row.text}\n`).join("");
|
|
24
|
-
}
|
|
24
|
+
}
|
package/src/baseline/update.ts
CHANGED
|
@@ -13,8 +13,8 @@ export interface Pruned {
|
|
|
13
13
|
readonly removed: number;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
[...groupBy(violations, (violation) => keyOf(violation.rule, violation.file)).values()].flatMap((group) => {
|
|
16
|
+
function record(violations: readonly Violation[]): readonly BaselineEntry[] {
|
|
17
|
+
return [...groupBy(violations, (violation) => keyOf(violation.rule, violation.file)).values()].flatMap((group) => {
|
|
18
18
|
const first = group[0];
|
|
19
19
|
if (first === undefined) {
|
|
20
20
|
return [];
|
|
@@ -22,21 +22,22 @@ const record = (violations: readonly Violation[]): readonly BaselineEntry[] =>
|
|
|
22
22
|
const count = countOf(group);
|
|
23
23
|
return count > 0 ? [{ count, file: first.file, rule: first.rule }] : [];
|
|
24
24
|
});
|
|
25
|
+
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
function refusal(id: string, index: RuleIndex): readonly string[] {
|
|
27
28
|
const level = levelOf(index, id);
|
|
28
29
|
if (level === undefined) {
|
|
29
30
|
return [`${id}: no built-in or local rule has this id.`];
|
|
30
31
|
}
|
|
31
32
|
return level === "error" ? [] : [`${id}: the rule is ${level}. Set it to error before baselining it.`];
|
|
32
|
-
}
|
|
33
|
+
}
|
|
33
34
|
|
|
34
|
-
export
|
|
35
|
+
export function adopt(
|
|
35
36
|
existing: readonly BaselineEntry[] | undefined,
|
|
36
37
|
rules: readonly string[],
|
|
37
38
|
violations: readonly Violation[],
|
|
38
39
|
index: RuleIndex,
|
|
39
|
-
): Adoption
|
|
40
|
+
): Adoption {
|
|
40
41
|
if (existing !== undefined && rules.length === 0) {
|
|
41
42
|
return { _tag: "Refused", reasons: ["a baseline exists. Record a rule with --rule <id>, or drop fixed debt with prune."] };
|
|
42
43
|
}
|
|
@@ -44,38 +45,41 @@ export const adopt = (
|
|
|
44
45
|
if (reasons.length > 0) {
|
|
45
46
|
return { _tag: "Refused", reasons };
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
function named(rule: string): boolean {
|
|
49
|
+
return rules.some((name) => covers(name, rule));
|
|
50
|
+
}
|
|
48
51
|
const kept = (existing ?? []).filter((entry) => !named(entry.rule));
|
|
49
52
|
const adopted = violations.filter((violation) => violation.level === "error" && (rules.length === 0 || named(violation.rule)));
|
|
50
53
|
const added = record(adopted);
|
|
51
54
|
return { _tag: "Adopted", added: added.length, entries: [...kept, ...added], replaced: (existing ?? []).length - kept.length };
|
|
52
|
-
}
|
|
55
|
+
}
|
|
53
56
|
|
|
54
57
|
export interface Scope {
|
|
55
58
|
readonly files?: ReadonlySet<string> | undefined;
|
|
56
59
|
readonly moves: ReadonlyMap<string, string>;
|
|
57
60
|
}
|
|
58
61
|
|
|
59
|
-
|
|
60
|
-
scope.files === undefined || scope.files.has(entry.file) || scope.moves.has(entry.file);
|
|
62
|
+
function inScope(entry: BaselineEntry, scope: Scope): boolean {
|
|
63
|
+
return scope.files === undefined || scope.files.has(entry.file) || scope.moves.has(entry.file);
|
|
64
|
+
}
|
|
61
65
|
|
|
62
|
-
|
|
66
|
+
function destination(
|
|
63
67
|
before: BaselineEntry,
|
|
64
68
|
current: ReadonlyMap<string, BaselineEntry>,
|
|
65
69
|
moves: ReadonlyMap<string, string>,
|
|
66
70
|
taken: ReadonlySet<string>,
|
|
67
|
-
)
|
|
71
|
+
) {
|
|
68
72
|
const to = moves.get(before.file);
|
|
69
73
|
const key = to === undefined ? undefined : keyOf(before.rule, to);
|
|
70
74
|
return key === undefined || taken.has(key) ? undefined : current.get(key);
|
|
71
|
-
}
|
|
75
|
+
}
|
|
72
76
|
|
|
73
|
-
export
|
|
77
|
+
export function prune(
|
|
74
78
|
existing: readonly BaselineEntry[],
|
|
75
79
|
violations: readonly Violation[],
|
|
76
80
|
index: RuleIndex,
|
|
77
81
|
scope: Scope = { moves: new Map() },
|
|
78
|
-
): Pruned
|
|
82
|
+
): Pruned {
|
|
79
83
|
const current = new Map(record(violations).map((entry) => [keyOf(entry.rule, entry.file), entry]));
|
|
80
84
|
const taken = new Set(existing.map((entry) => keyOf(entry.rule, entry.file)));
|
|
81
85
|
let moved = 0;
|
|
@@ -97,4 +101,4 @@ export const prune = (
|
|
|
97
101
|
moved,
|
|
98
102
|
removed: existing.length - kept.length,
|
|
99
103
|
};
|
|
100
|
-
}
|
|
104
|
+
}
|
package/src/cli/args.ts
CHANGED
|
@@ -31,7 +31,9 @@ const OPTIONS = {
|
|
|
31
31
|
warnings: { type: "string" },
|
|
32
32
|
} as const;
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
function usage(problem: string): Parsed {
|
|
35
|
+
return { _tag: "Usage", problem };
|
|
36
|
+
}
|
|
35
37
|
|
|
36
38
|
const SUBCOMMANDS: Readonly<Record<string, string>> = {
|
|
37
39
|
baseline: "baseline takes write, prune, tighten or migrate.",
|
|
@@ -39,7 +41,9 @@ const SUBCOMMANDS: Readonly<Record<string, string>> = {
|
|
|
39
41
|
hooks: "hooks takes install, uninstall or pre-commit.",
|
|
40
42
|
};
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
function parsed(command: Command): Parsed {
|
|
45
|
+
return { _tag: "Parsed", command };
|
|
46
|
+
}
|
|
43
47
|
|
|
44
48
|
type Values = ReturnType<typeof parseArgs<{ options: typeof OPTIONS; allowPositionals: true }>>["values"];
|
|
45
49
|
|
|
@@ -60,16 +64,17 @@ const ACCEPTS: Readonly<Record<string, readonly Option[]>> = {
|
|
|
60
64
|
lint: ["warnings"],
|
|
61
65
|
};
|
|
62
66
|
|
|
63
|
-
|
|
67
|
+
function misplaced(name: string, values: Values): string | undefined {
|
|
64
68
|
const option = COMMAND_OPTIONS.find((key) => values[key] !== undefined && !(ACCEPTS[name] ?? []).includes(key));
|
|
65
69
|
const owners = Object.keys(ACCEPTS).filter((owner) => option !== undefined && (ACCEPTS[owner] ?? []).includes(option));
|
|
66
70
|
return option === undefined ? undefined : `--${option} applies only to ${owners.join(" and ")}.`;
|
|
67
|
-
}
|
|
71
|
+
}
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
against?.startsWith("-") === true ? usage(`--against takes a git ref, not "${against}".`) : parsed(command);
|
|
73
|
+
function ref(against: string | undefined, command: Command): Parsed {
|
|
74
|
+
return against?.startsWith("-") === true ? usage(`--against takes a git ref, not "${against}".`) : parsed(command);
|
|
75
|
+
}
|
|
71
76
|
|
|
72
|
-
|
|
77
|
+
function commandFor(name: string, values: Values): Parsed {
|
|
73
78
|
const config = values.config;
|
|
74
79
|
switch (name) {
|
|
75
80
|
case "lint": {
|
|
@@ -97,9 +102,9 @@ const commandFor = (name: string, values: Values): Parsed => {
|
|
|
97
102
|
default:
|
|
98
103
|
return parsed({ _tag: "BaselineMigrate", config, from: values.from });
|
|
99
104
|
}
|
|
100
|
-
}
|
|
105
|
+
}
|
|
101
106
|
|
|
102
|
-
export
|
|
107
|
+
export function parseCommand(args: readonly string[]): Parsed {
|
|
103
108
|
const result = Result.try({
|
|
104
109
|
catch: (error) => (error instanceof Error ? error.message : String(error)),
|
|
105
110
|
try: () => parseArgs({ allowPositionals: true, args: [...args], options: OPTIONS, strict: true }),
|
|
@@ -122,4 +127,4 @@ export const parseCommand = (args: readonly string[]): Parsed => {
|
|
|
122
127
|
}
|
|
123
128
|
const problem = misplaced(name, values);
|
|
124
129
|
return problem === undefined ? commandFor(name, values) : usage(problem);
|
|
125
|
-
}
|
|
130
|
+
}
|
package/src/cli/baseline.ts
CHANGED
|
@@ -9,57 +9,58 @@ import { SetupFailure } from "#failure.ts";
|
|
|
9
9
|
import { writeText } from "#inventory/filesystem.ts";
|
|
10
10
|
import { plural } from "#report/plural.ts";
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
Effect.mapError(
|
|
12
|
+
function save(session: Session, entries: readonly BaselineEntry[]): Effect.Effect<void, SetupFailure, FileSystem.FileSystem> {
|
|
13
|
+
return Effect.mapError(
|
|
14
14
|
writeText(join(session.config.root, session.config.baseline), rewriteBaseline(session.baseline.raw, session.baseline.entries, entries)),
|
|
15
15
|
(failure) => new SetupFailure({ message: failure.message }),
|
|
16
16
|
);
|
|
17
|
+
}
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
function unregistered(session: Session) {
|
|
20
|
+
return applyRegistry(session.violations, session.registry, session.config).kept;
|
|
21
|
+
}
|
|
19
22
|
|
|
20
|
-
export const writeBaseline = (
|
|
23
|
+
export const writeBaseline = Effect.fn("Cli.writeBaseline")(function* (
|
|
21
24
|
cwd: string,
|
|
22
25
|
config: string | undefined,
|
|
23
26
|
rules: readonly string[],
|
|
24
|
-
): Effect.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
});
|
|
27
|
+
): Effect.fn.Return<void, SetupFailure, FileSystem.FileSystem> {
|
|
28
|
+
const session = yield* openSession(cwd, config);
|
|
29
|
+
const existing = session.baseline.raw === undefined ? undefined : session.baseline.entries;
|
|
30
|
+
const adoption = adopt(existing, rules, unregistered(session), session.config);
|
|
31
|
+
if (adoption._tag === "Refused") {
|
|
32
|
+
return yield* new SetupFailure({ message: `baseline write refused:\n${adoption.reasons.map((reason) => ` - ${reason}`).join("\n")}` });
|
|
33
|
+
}
|
|
34
|
+
if (adoption.added === 0 && adoption.replaced === 0) {
|
|
35
|
+
return yield* Console.log(`quality: no error-level violations to record; ${session.config.baseline} is unchanged.`);
|
|
36
|
+
}
|
|
37
|
+
yield* save(session, adoption.entries);
|
|
38
|
+
const replaced = adoption.replaced > 0 ? `, replacing ${plural(adoption.replaced, "entry", "entries")}` : "";
|
|
39
|
+
yield* Console.log(`quality: recorded ${plural(adoption.added, "entry", "entries")} in ${session.config.baseline}${replaced}.`);
|
|
40
|
+
});
|
|
39
41
|
|
|
40
|
-
|
|
42
|
+
function changes(pruned: Pruned): string {
|
|
41
43
|
const parts = [
|
|
42
44
|
`removed ${plural(pruned.removed, "entry", "entries")}`,
|
|
43
45
|
`lowered ${plural(pruned.lowered, "entry", "entries")}`,
|
|
44
46
|
...(pruned.moved > 0 ? [`carried ${plural(pruned.moved, "entry", "entries")} to moved files`] : []),
|
|
45
47
|
];
|
|
46
48
|
return `${parts.slice(0, -1).join(", ")} and ${parts.at(-1)}`;
|
|
47
|
-
}
|
|
49
|
+
}
|
|
48
50
|
|
|
49
|
-
export const shrinkBaseline = <TRequirements>(
|
|
51
|
+
export const shrinkBaseline = Effect.fn("Cli.shrinkBaseline")(function* <TRequirements>(
|
|
50
52
|
cwd: string,
|
|
51
53
|
config: string | undefined,
|
|
52
54
|
scopeOf: (session: Session) => Effect.Effect<Scope, SetupFailure, TRequirements>,
|
|
53
|
-
): Effect.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
});
|
|
55
|
+
): Effect.fn.Return<void, SetupFailure, FileSystem.FileSystem | TRequirements> {
|
|
56
|
+
const session = yield* openSession(cwd, config);
|
|
57
|
+
if (session.baseline.raw === undefined) {
|
|
58
|
+
return yield* Console.log(`quality: no baseline at ${session.config.baseline}; nothing to lower.`);
|
|
59
|
+
}
|
|
60
|
+
const pruned = prune(session.baseline.entries, unregistered(session), session.config, yield* scopeOf(session));
|
|
61
|
+
if (pruned.removed === 0 && pruned.lowered === 0 && pruned.moved === 0) {
|
|
62
|
+
return yield* Console.log(`quality: ${session.config.baseline} is current.`);
|
|
63
|
+
}
|
|
64
|
+
yield* save(session, pruned.entries);
|
|
65
|
+
yield* Console.log(`quality: ${changes(pruned)} in ${session.config.baseline}.`);
|
|
66
|
+
});
|
package/src/cli/fix.ts
CHANGED
|
@@ -62,24 +62,22 @@ function biomePasses(root: string, exceptions: readonly ExceptionDeclaration[]):
|
|
|
62
62
|
];
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
function
|
|
65
|
+
const round = Effect.fn("Cli.round")(function* <TFailure, TRequirements>(
|
|
66
66
|
passes: readonly Pass<TFailure, TRequirements>[],
|
|
67
67
|
index: number,
|
|
68
68
|
afterEachPass: Effect.Effect<void, TFailure, TRequirements>,
|
|
69
|
-
): Effect.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
});
|
|
82
|
-
}
|
|
69
|
+
): Effect.fn.Return<number, TFailure, TRequirements> {
|
|
70
|
+
let total = 0;
|
|
71
|
+
const parts: string[] = [];
|
|
72
|
+
for (const pass of passes) {
|
|
73
|
+
const changed = yield* pass.run;
|
|
74
|
+
total += changed;
|
|
75
|
+
parts.push(`${plural(changed, "file")} ${pass.label}`);
|
|
76
|
+
yield* afterEachPass;
|
|
77
|
+
}
|
|
78
|
+
yield* Console.log(`quality: Biome round ${index} rewrote ${parts.join(" and ")}.`);
|
|
79
|
+
return total;
|
|
80
|
+
});
|
|
83
81
|
|
|
84
82
|
function changedBetween(before: ReadonlyMap<string, string>, after: ReadonlyMap<string, string>): readonly string[] {
|
|
85
83
|
return [...new Set([...before.keys(), ...after.keys()])].filter((path) => before.get(path) !== after.get(path));
|
|
@@ -100,36 +98,35 @@ function unsettled(changed: ReadonlySet<string>): SetupFailure {
|
|
|
100
98
|
});
|
|
101
99
|
}
|
|
102
100
|
|
|
103
|
-
export function
|
|
101
|
+
export const settle = Effect.fn("Cli.settle")(function* <TFailure, TRequirements>({
|
|
104
102
|
passes,
|
|
105
103
|
snapshot,
|
|
106
|
-
}: Settling<TFailure, TRequirements>): Effect.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if ((yield* round(passes, index, Effect.void)) === 0) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
const changed = new Set<string>();
|
|
114
|
-
let previous = yield* snapshot;
|
|
115
|
-
const record = Effect.map(snapshot, (current) => {
|
|
116
|
-
for (const path of changedBetween(previous, current)) {
|
|
117
|
-
changed.add(path);
|
|
118
|
-
}
|
|
119
|
-
previous = current;
|
|
120
|
-
});
|
|
121
|
-
if ((yield* round(passes, MAX_FIX_ROUNDS, record)) === 0) {
|
|
104
|
+
}: Settling<TFailure, TRequirements>): Effect.fn.Return<void, TFailure | SetupFailure, TRequirements> {
|
|
105
|
+
for (let index = 1; index < MAX_FIX_ROUNDS; index += 1) {
|
|
106
|
+
if ((yield* round(passes, index, Effect.void)) === 0) {
|
|
122
107
|
return;
|
|
123
108
|
}
|
|
124
|
-
|
|
109
|
+
}
|
|
110
|
+
const changed = new Set<string>();
|
|
111
|
+
let previous = yield* snapshot;
|
|
112
|
+
const record = Effect.map(snapshot, (current) => {
|
|
113
|
+
for (const path of changedBetween(previous, current)) {
|
|
114
|
+
changed.add(path);
|
|
115
|
+
}
|
|
116
|
+
previous = current;
|
|
125
117
|
});
|
|
126
|
-
|
|
118
|
+
if ((yield* round(passes, MAX_FIX_ROUNDS, record)) === 0) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
return yield* unsettled(changed);
|
|
122
|
+
});
|
|
127
123
|
|
|
128
|
-
export
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
});
|
|
135
|
-
}
|
|
124
|
+
export const fix = Effect.fn("Cli.fix")(function* (
|
|
125
|
+
cwd: string,
|
|
126
|
+
config: string | undefined,
|
|
127
|
+
): Effect.fn.Return<void, SetupFailure, FileSystem.FileSystem> {
|
|
128
|
+
const { root, exceptions } = yield* loadConfig(cwd, config);
|
|
129
|
+
const sorted = yield* Effect.mapError(sortManifests(root), (failure) => new SetupFailure({ message: failure.message }));
|
|
130
|
+
yield* Console.log(`quality: sort-package-json rewrote ${plural(sorted, "manifest")}.`);
|
|
131
|
+
yield* settle({ passes: biomePasses(root, exceptions), snapshot: snapshotOf(root) });
|
|
132
|
+
});
|
package/src/cli/lint.ts
CHANGED
|
@@ -5,25 +5,23 @@ import { openSession } from "#engine/session.ts";
|
|
|
5
5
|
import { GateFailed, type SetupFailure } from "#failure.ts";
|
|
6
6
|
import { render, type WarningDetail } from "#report/render.ts";
|
|
7
7
|
|
|
8
|
-
export const lint = (
|
|
8
|
+
export const lint = Effect.fn("Cli.lint")(function* (
|
|
9
9
|
cwd: string,
|
|
10
10
|
config: string | undefined,
|
|
11
11
|
warnings: WarningDetail,
|
|
12
|
-
): Effect.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
});
|
|
12
|
+
): Effect.fn.Return<void, SetupFailure | GateFailed, FileSystem.FileSystem> {
|
|
13
|
+
const session = yield* openSession(cwd, config);
|
|
14
|
+
const outcome = evaluate(session.violations, session.registry, session.baseline.entries, session.config);
|
|
15
|
+
yield* Console.log(
|
|
16
|
+
render(outcome, {
|
|
17
|
+
baseline: session.config.baseline,
|
|
18
|
+
checked: session.inventory.sources.length,
|
|
19
|
+
descriptions: new Map(session.config.active.map((rule) => [rule.id, rule.description])),
|
|
20
|
+
registry: session.config.exceptions.length === 0 ? session.config.registry : `${relative(session.config.root, session.config.file)} exceptions`,
|
|
21
|
+
warnings,
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
24
|
+
if (!passes(outcome)) {
|
|
25
|
+
return yield* new GateFailed();
|
|
26
|
+
}
|
|
27
|
+
});
|
package/src/cli/migrate.ts
CHANGED
|
@@ -10,27 +10,26 @@ import { SetupFailure } from "#failure.ts";
|
|
|
10
10
|
import { writeText } from "#inventory/filesystem.ts";
|
|
11
11
|
import { plural } from "#report/plural.ts";
|
|
12
12
|
|
|
13
|
-
export const migrateBaseline = (
|
|
13
|
+
export const migrateBaseline = Effect.fn("Cli.migrateBaseline")(function* (
|
|
14
14
|
cwd: string,
|
|
15
15
|
configPath: string | undefined,
|
|
16
16
|
from: string | undefined,
|
|
17
|
-
): Effect.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
});
|
|
17
|
+
): Effect.fn.Return<void, SetupFailure, FileSystem.FileSystem> {
|
|
18
|
+
const config = yield* loadConfig(cwd, configPath);
|
|
19
|
+
const source = from ?? LEGACY_BASELINE;
|
|
20
|
+
if (source === config.baseline || (yield* readInput(config.root, config.baseline)) !== undefined) {
|
|
21
|
+
return yield* new SetupFailure({ message: `${config.baseline} already exists. Migrate into a baseline file that does not exist yet.` });
|
|
22
|
+
}
|
|
23
|
+
const raw = yield* readInput(config.root, source);
|
|
24
|
+
if (raw === undefined) {
|
|
25
|
+
return yield* new SetupFailure({ message: `no baseline at ${source} to migrate. Name it with --from <file>.` });
|
|
26
|
+
}
|
|
27
|
+
const legacy = yield* validOrFail(source, yield* Effect.promise(() => decodeLegacyBaseline(raw)));
|
|
28
|
+
const entries = convertLegacy(legacy, (yield* scan(config)).violations);
|
|
29
|
+
const fs = yield* FileSystem.FileSystem;
|
|
30
|
+
const written = Effect.andThen(writeText(join(config.root, config.baseline), encodeBaseline(entries)), fs.remove(join(config.root, source)));
|
|
31
|
+
yield* Effect.mapError(written, (failure) => new SetupFailure({ message: failure.message }));
|
|
32
|
+
const fixed = legacy.length - entries.length;
|
|
33
|
+
const dropped = fixed > 0 ? `, dropping ${plural(fixed, "fixed entry", "fixed entries")}` : "";
|
|
34
|
+
yield* Console.log(`quality: moved ${plural(entries.length, "entry", "entries")} from ${source} to ${config.baseline}${dropped}.`);
|
|
35
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Console, Effect } from "effect";
|
|
2
|
+
import { parseCommand, USAGE } from "#cli/args.ts";
|
|
3
|
+
import { writeBaseline } from "#cli/baseline.ts";
|
|
4
|
+
import { fix } from "#cli/fix.ts";
|
|
5
|
+
import { lint } from "#cli/lint.ts";
|
|
6
|
+
import { migrateBaseline } from "#cli/migrate.ts";
|
|
7
|
+
import { migrateExceptions } from "#cli/migrateExceptions.ts";
|
|
8
|
+
import { pruneBaseline, tightenBaseline } from "#cli/shrink.ts";
|
|
9
|
+
import { SetupFailure } from "#failure.ts";
|
|
10
|
+
import type { Launch } from "#hooks/command.ts";
|
|
11
|
+
import { installHook } from "#hooks/install.ts";
|
|
12
|
+
import { preCommitHook } from "#hooks/preCommit.ts";
|
|
13
|
+
import { uninstallHook } from "#hooks/uninstall.ts";
|
|
14
|
+
|
|
15
|
+
export interface Invocation {
|
|
16
|
+
readonly cwd: string;
|
|
17
|
+
readonly launch: Launch;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const program = Effect.fn("Cli.program")(function* (args: readonly string[], { cwd, launch }: Invocation) {
|
|
21
|
+
const parsed = parseCommand(args);
|
|
22
|
+
if (parsed._tag === "Usage") {
|
|
23
|
+
return yield* new SetupFailure({ message: `${parsed.problem}\n\n${USAGE}` });
|
|
24
|
+
}
|
|
25
|
+
const command = parsed.command;
|
|
26
|
+
switch (command._tag) {
|
|
27
|
+
case "Help":
|
|
28
|
+
return yield* Console.log(USAGE);
|
|
29
|
+
case "Lint":
|
|
30
|
+
return yield* lint(cwd, command.config, command.warnings);
|
|
31
|
+
case "Fix":
|
|
32
|
+
return yield* fix(cwd, command.config);
|
|
33
|
+
case "BaselineWrite":
|
|
34
|
+
return yield* writeBaseline(cwd, command.config, command.rules);
|
|
35
|
+
case "BaselinePrune":
|
|
36
|
+
return yield* pruneBaseline(cwd, command.config, command.against);
|
|
37
|
+
case "BaselineTighten":
|
|
38
|
+
return yield* tightenBaseline(cwd, command.config, command.staged);
|
|
39
|
+
case "ExceptionsMigrate":
|
|
40
|
+
return yield* migrateExceptions(cwd, command.config, command.from);
|
|
41
|
+
case "BaselineMigrate":
|
|
42
|
+
return yield* migrateBaseline(cwd, command.config, command.from);
|
|
43
|
+
case "HooksInstall":
|
|
44
|
+
return yield* installHook({ config: command.config, cwd, force: command.force, launch });
|
|
45
|
+
case "HooksUninstall":
|
|
46
|
+
return yield* uninstallHook(cwd);
|
|
47
|
+
case "HooksPreCommit":
|
|
48
|
+
return yield* preCommitHook(cwd, command.config);
|
|
49
|
+
}
|
|
50
|
+
});
|