-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcli.ts
167 lines (156 loc) · 5.57 KB
/
cli.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
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import * as stdFs from "https://deno.land/[email protected]/fs/mod.ts";
import {Command} from "https://deno.land/x/[email protected]/command/command.ts";
const taskfiles = ["Taskfile.ts", "Taskfile.js"]
function detectTaskfile(): string | undefined {
return taskfiles.filter(file => {
return stdFs.existsSync(file);
})[0];
}
function convertFileToUri(fileName: string) {
let fileLocation = fileName;
if (!fileName.startsWith("http://") && !fileName.startsWith("https://")) {
if (fileName.startsWith("/")) {
fileLocation = `file://${fileLocation}`;
} else {
fileLocation = `file://${Deno.cwd()}/${fileLocation}`;
}
}
return fileLocation;
}
async function runScriptFile(fileName: string): Promise<void> {
await import((convertFileToUri(fileName)));
}
function runTaskfile(taskfile: string, ...tasks: Array<string>) {
const fileUri = convertFileToUri(taskfile);
import(fileUri).then(module => {
if (tasks.length > 0) {
const runners = tasks.filter(task => {
return task in module;
}).map(task => {
console.log("===Task: " + task);
// @ts-ignore correct
return module[task]();
});
if (runners && runners.length > 0) {
// @ts-ignore correct
return Promise.all([...runners]);
} else {
console.log(`No '${tasks.join(",")}' tasks found in ${taskfile}.`);
Deno.exit(2);
}
} else {
if ("default" in module) {
console.log("===Task: default");
return module["default"]();
} else {
//console.log("No default task found in Taskfile, please use 'export default xxx;' to add default task.")
return command.parse(["-h"]);
}
}
}
);
}
function printTasks() {
const taskfile = detectTaskfile();
if (taskfile) {
import(convertFileToUri(taskfile)).then(module => {
console.log("Available tasks:")
Object.entries(module).forEach(pair => {
if (pair[0] !== 'default' && typeof pair[1] === 'function') {
const funObj = module[pair[0]];
if ("desc" in funObj) {
console.log(` ${pair[0]} # ${funObj.desc}`);
} else {
console.log(" " + pair[0]);
}
}
});
});
} else {
taskfileNotFound();
}
}
function generateShellCompletion(shell: string) {
if (shell === "zsh") {
console.log("#compdef dx\n" +
"#autload\n" +
"\n" +
"local subcmds=()\n" +
"\n" +
"while read -r line ; do\n" +
" if [[ ! $line == Available* ]] ;\n" +
" then\n" +
" subcmds+=(${line/[[:space:]]*\\#/:})\n" +
" fi\n" +
"done < <(dx --tasks)\n" +
"\n" +
"_describe 'command' subcmds")
} else {
console.log("Not available now for ", shell);
}
}
function taskfileNotFound() {
console.log("Failed to find 'Taskfile.ts' or 'Taskfile.js' file.");
Deno.exit(2);
}
const command = new Command()
.name("dx")
.version("0.3.1")
.versionOption("-v, --version")
.description("A tool for writing better scripts with Deno")
.option("-t, --tasks", "List tasks in Taskfile", {
standalone: true,
action: () => {
printTasks();
}
})
.option("-u, --upgrade", "Upgrade dx to last version", {
standalone: true,
action: async () => {
console.log("Begin to upgrade dx to last version.")
const p = Deno.run({
cmd: "deno install -q -A --unstable --no-check -r -f -n dx https://denopkg.com/linux-china/dx/cli.ts".split(" ")
});
await p.status();
p.close();
}
})
.option("-c, --completion <shell:string>", "Generate shell completion for zsh, zsh.", {
standalone: true,
action: async (options: any) => {
await generateShellCompletion(options.completion);
}
})
.arguments("[script:string] [args...:string]")
.action(async (options: any, script: string | undefined, args: string[] | undefined) => {
// run default task from Taskfile
if (typeof script === 'undefined') {
const taskfile = detectTaskfile();
if (taskfile) {
await runTaskfile(taskfile);
} else { // display help
await command.parse(["-h"])
}
} else {
//run ts file
if (script.endsWith(".ts") || script.endsWith(".js")) {
if (script.endsWith("Taskfile.ts") || script.endsWith("Taskfiles.js")) {
await runTaskfile(script, ...(args ?? []));
} else {
await runScriptFile(script);
}
} else { // run tasks
const taskfile = detectTaskfile();
if (taskfile) {
//script is task name now
const tasks = args ? [script, ...args] : [script];
await runTaskfile(taskfile, ...tasks);
} else {
taskfileNotFound();
}
}
}
});
if (import.meta.main) {
await command.parse(Deno.args);
}