-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.ts
executable file
·171 lines (154 loc) · 4.82 KB
/
main.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
167
168
169
170
171
import { colors } from "./deps.ts";
import { DfmOptions, Plugin, Subcmd, SubcmdOptions } from "./types.ts";
import { isatty, resolvePath } from "./util/util.ts";
const { blue, bold, green, red, yellow, setColorEnabled, inverse } = colors;
const version = "v0.3";
export default class Dfm {
private options: DfmOptions;
private plugins: Plugin[] = [];
private subcmds: Subcmd[];
dfmFilePath: string;
dotfilesDir: string;
constructor(options: {
dotfilesDir: string;
dfmFilePath: string;
}) {
this.dfmFilePath = resolvePath(options.dfmFilePath);
this.dotfilesDir = resolvePath(options.dotfilesDir);
this.options = parse_argment(Deno.args);
// サブコマンドの定義
this.subcmds = [
{
// 状態を確認する
name: "stat",
info: "show status of settings",
func: (options: SubcmdOptions) => {
return this.cmd_base.bind(this)(options, "stat");
},
},
{
name: "list",
info: "show list of settings",
func: (options: SubcmdOptions) => {
// プラグインの一覧を表示
console.log(inverse(blue(bold("PLUGINS"))));
this.plugins.forEach((plugin) => {
console.log(`・ ${plugin.name}`);
});
console.log();
return this.cmd_base.bind(this)(options, "list");
},
},
{
// 設定を同期する
name: "sync",
info: "apply settings",
func: (options: SubcmdOptions) => {
return this.cmd_base.bind(this)(options, "sync");
},
},
{
// ヘルプを表示する
name: "help",
info: "show this help",
func: this.cmd_help.bind(this),
},
];
}
use(...plugins: Plugin[]) {
// プラグインを登録する
plugins.forEach((plugin) => {
this.plugins.push(plugin);
if (plugin.subcmds !== undefined) {
plugin.subcmds.forEach((subcmd) => {
this.subcmds.push({
name: subcmd.name,
info: subcmd.info,
func: subcmd.func.bind(plugin),
});
});
}
});
}
async end() {
// コマンドを実行する
// もし他のコマンドにパイプされていた場合、エスケープシーケンスを利用しない
if (!isatty()) {
setColorEnabled(false);
}
// サブコマンドを実行
if (this.options.subcmdOptions === undefined) {
// 無引数で呼ばれた場合、ヘルプを表示する
this.cmd_help({ cmdName: "help", args: [] });
} else {
const subcmd = this.options.subcmdOptions;
const cmd = this.subcmds.find((sc: Subcmd) => sc.name === subcmd.cmdName);
if (cmd !== undefined) {
const status = await cmd.func(subcmd);
if (!status) {
// コマンドの実行に失敗した場合、プロセスを終了する
Deno.exit(1);
}
} else {
// サブコマンドが見つからない場合、プロセスを終了する
console.log(bold(red("Err: subcmd not found")));
Deno.exit(1);
}
}
}
private async cmd_base(
_: SubcmdOptions,
func: "stat" | "sync" | "list",
): Promise<boolean> {
// statとlist, syncは性質が似ているため、処理を共通化している
const exit_status: { name: string; is_failed: boolean }[] = [];
for (const s of this.plugins) {
const command = s[func];
if (command != undefined) {
console.log(inverse(blue(bold(s.name.toUpperCase()))));
const is_failed = !(await command.bind(s)());
console.log();
exit_status.push({ name: s.name, is_failed: is_failed });
}
}
const noerr = exit_status.filter((s) => s.is_failed).length === 0;
if (noerr) {
console.log(bold(green("✔ NO Error was detected")));
return true;
} else {
console.log(bold(red("✘ Error was detected")));
exit_status.forEach((s) => {
if (s.is_failed) {
console.log(`・${s.name}`);
}
});
return false;
}
}
private cmd_help(_: SubcmdOptions): boolean {
// ヘルプ
const p = console.log;
p(inverse(yellow(bold(`dfm(3) ${version}`))));
p(" A dotfiles manager written in deno (typescript)\n");
p(inverse(yellow(bold("USAGE:"))));
p(" deno run -A [filename] [SUBCOMMANDS]\n");
p(inverse(yellow(bold("SUBCOMMANDS:"))));
this.subcmds.forEach((c) => {
console.log(` ${green(c.name)} ${c.info}`);
});
return true;
}
}
function parse_argment(args: typeof Deno.args): DfmOptions {
// コマンドライン引数を解析
let subcmdOptions: SubcmdOptions | undefined = undefined;
if (args.length !== 0) {
subcmdOptions = {
cmdName: Deno.args[0],
args: Deno.args.slice(1),
};
}
return {
subcmdOptions: subcmdOptions,
};
}