-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmod.ts
68 lines (64 loc) · 1.76 KB
/
mod.ts
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
import yargs from "npm:[email protected]";
import esprima from "npm:[email protected]";
import { paramCase } from "https://deno.land/x/[email protected]/mod.ts";
import { basename } from "https://deno.land/[email protected]/path/mod.ts";
function makeHandler(fun: (...args: unknown[]) => void, params: string[]) {
return (argv: { [x: string]: unknown }) => {
fun(...params.map((a: string) => argv[a]));
};
}
function parseDesc(
prefix: string,
key: string,
comments: { type: string; value: string }[],
) {
let desc = "";
for (const { type, value } of comments) {
if (type === "Line") {
const [_, rest] = value.split(`${prefix}${key}`);
if (rest) {
desc = rest.trim();
}
}
}
return desc;
}
async function run() {
const exports = await import(Deno.mainModule);
const commands = [];
for (const exp of Object.entries(exports)) {
const name = exp[0];
const fun = exp[1] as (...args: unknown[]) => void;
const {
body: [{ params }],
comments,
} = esprima.parseScript(fun.toString(), { comment: true });
const builder: Record<string, { desc: string }> = {};
const params2 = params.map(({ name }: { name: string }) => paramCase(name));
for (const name of params2) {
builder[name] = { desc: parseDesc("--", name, comments) };
}
commands.push({
command: name,
desc: parseDesc("@", name, comments),
builder,
handler: makeHandler(fun, params2),
});
}
yargs(Deno.args)
.commands(commands)
.demandCommand()
.recommendCommands()
.strict()
.parserConfiguration({
"sort-commands": true,
"camel-case-expansion": false,
})
.scriptName(basename(Deno.mainModule))
.usage("$0")
.version(false)
.help()
.hide("help")
.parse();
}
run();