-
-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathvalidate-export-names.ts
More file actions
105 lines (86 loc) · 2.71 KB
/
validate-export-names.ts
File metadata and controls
105 lines (86 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2023-present Eser Ozvataf and other contributors. All rights reserved. Apache-2.0 license.
/**
* Export naming convention checker.
*
* Validates that export paths in deno.json follow kebab-case convention.
*
* @module
*/
import * as primitives from "@eserstack/primitives";
import type * as shellArgs from "@eserstack/shell/args";
import * as span from "@eserstack/streams/span";
import { createCliOutput, runCliMain } from "./cli-support.ts";
import { ensureLib, getLib } from "./ffi-client.ts";
const out = createCliOutput();
export type CheckExportNamesOptions = {
readonly root?: string;
readonly ignoreWords?: string[];
};
export type ExportNameViolation = {
readonly packageName: string;
readonly exportPath: string;
readonly suggestion: string;
};
export type CheckExportNamesResult = {
readonly isValid: boolean;
readonly violations: ExportNameViolation[];
readonly packagesChecked: number;
};
export const checkExportNames = async (
options: CheckExportNamesOptions = {},
): Promise<CheckExportNamesResult> => {
const { root = ".", ignoreWords = [] } = options;
await ensureLib();
const lib = getLib();
if (lib === null) {
throw new Error("native library not available for checkExportNames");
}
const raw = lib.symbols.EserAjanCodebaseCheckExportNames(
JSON.stringify({ dir: root, ignoreWords }),
);
const result = JSON.parse(raw) as CheckExportNamesResult & { error?: string };
if (result.error) {
throw new Error(result.error);
}
return result;
};
export const main = async (
_cliArgs?: readonly string[],
): Promise<shellArgs.CliResult<void>> => {
try {
const value = await checkExportNames({ root: "." });
out.writeln(
span.blue("ℹ"),
span.text(` Checked ${value.packagesChecked} packages.`),
);
if (!value.isValid) {
out.writeln(
span.red("✗"),
span.text(` Found ${value.violations.length} naming violations:`),
);
for (const violation of value.violations) {
out.writeln(span.yellow("⚠"), span.text(" " + violation.packageName));
out.writeln(
span.blue("ℹ"),
span.text(` Export: ${violation.exportPath}`),
);
out.writeln(
span.blue("ℹ"),
span.text(` Suggestion: ${violation.suggestion}`),
);
}
return primitives.results.fail({ exitCode: 1 });
}
out.writeln(
span.green("✓"),
span.text(" All export names follow conventions."),
);
return primitives.results.ok(undefined);
} catch (err) {
out.writeln(span.red("✗"), span.text(` ${String(err)}`));
return primitives.results.fail({ exitCode: 1 });
}
};
if (import.meta.main) {
runCliMain(await main(), out);
}