Completed
Push — master ( 1188a3...766e4c )
by Dimas
44:15 queued 35:12
created

libs/bin/syncjs/src/classes/CLI.ts   A

Complexity

Total Complexity 26
Complexity/F 1.73

Size

Lines of Code 239
Function Count 15

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 149
dl 0
loc 239
rs 10
c 0
b 0
f 0
wmc 26
mnd 11
bc 11
fnc 15
bpm 0.7332
cpm 1.7333
noi 0
1
import * as chalk from "chalk";
2
import * as minimist from "minimist";
3
import inquirer = require("inquirer");
4
5
export enum EXIT_CODE {
6
    /**
7
     * Exit normally
8
     */
9
    NORMAL = 0,
10
11
    /**
12
     * Any kind exit with error
13
     */
14
    RUNTIME_FAILURE = 1,
15
16
    /**
17
     * If user terminates with ctrl-c use this
18
     */
19
    TERMINATED = 130,
20
21
    /**
22
     * Tell user that arguments were wrong
23
     */
24
    INVALID_ARGUMENT = 128
25
}
26
27
export default class CLI {
28
29
    private pdTime: Array<NodeJS.Timer> = [];
30
    private lastRun: number;
31
    private timeDiff: number;
32
    private args: minimist.ParsedArgs;
33
    private ui: inquirer.ui.Prompt[] = [];
34
    private activePrompt;
35
    private pauseEvents: Function[] = [];
36
    public paused: boolean;
37
38
    constructor() {
39
        // Parse arguments
40
        this.args = minimist(process.argv.slice(2));
41
        // this.ui = new inquirer.ui.BottomBar();
42
    }
43
44
    /**
45
     * Checks if a command has been passed or not
46
     * @param command string name of the command
47
     */
48
    hasStartupCommand(command: string): boolean {
49
        return this.args._.filter(n => n === command).length > 0;
50
    }
51
52
    /**
53
     * Gets requested argument
54
     * @param name string name of the argument
55
     */
56
    getArgument(name: string, defaultValue: any = null): any {
57
        let value = null;
58
59
        if (name in this.args) {
60
            value = this.args[name];
61
        } else if (name[0] in this.args) {
62
            value = this.args[name[0]];
63
        }
64
65
        return value !== null ? value : defaultValue;
66
    }
67
68
    onPaused(event) {
69
        this.pauseEvents.push(event);
70
    }
71
72
    /**
73
     * Clear the terminal
74
     */
75
    clear() {
76
        this.write(chalk.reset("\x1b[2J\x1b[0;0H"));
77
    }
78
79
    /**
80
     * Write something to terminal
81
     */
82
    write(msg: string | chalk.ChalkChain): boolean {
83
        return process.stdout.write.bind(process.stdout)(msg);
84
    }
85
86
    log(message: string) {
87
        // this.ui.updateBottomBar(message);
88
        console.log(message);
89
        // this.showPrompt();
90
    }
91
92
    read(question: any, hidden = false): Promise<any> {
93
        let scheme = {
94
            type: hidden ? "password" : "input",
95
            message: question,
96
            name: "response"
97
        };
98
99
        // Bad type definition
100
        let promise = <any>inquirer.prompt(scheme);
101
        this.ui.push(promise['ui']);
102
103
        return promise.then((answer) => {
104
            return answer.response;
105
        });
106
    }
107
108
    closePrompts() {
109
        this.ui.map((ui) => {
110
            if (!ui['closed']) {
111
                ui.close();
112
                ui['closed'] = true;
113
                //console.log("closed now")
114
            } else {
115
                //console.log("closed Already")
116
            }
117
        });
118
    }
119
120
    /**
121
     * Start printing dots to screen, show script is working
122
     */
123
    startProgress() {
124
        this.pdTime.push(setInterval(() => {
125
            this.write(chalk.green("."));
126
        }, 200));
127
    }
128
129
    /**
130
     * Stop printing dots when process ends
131
     */
132
    stopProgress() {
133
        clearInterval(this.pdTime.pop());
134
    }
135
136
    /**
137
     * Display the workspace for syncjs
138
     */
139
    workspace() {
140
        this.clear();
141
142
        this.write(`Started monitoring \n`);
143
        this.write(`Quit the script with CONTROL-C".\n`);
144
        this.write(chalk.magenta("-----------------------------------------------------------\n"));
145
        //this.showPrompt();
146
    }
147
148
    usage(message: string = null, code: number = 0): void {
149
        if (message) {
150
            this.write(chalk.red(message) + "\n");
151
        }
152
        this.write(chalk.yellow.underline("\nUSAGE:\n"));
153
        this.write("Make sure you have the config file by running.\n");
154
        this.write(chalk.green("syncjs init\n"));
155
        this.write("--------------------\n");
156
        //this.write("For more details please visit. https://github.com/serkanyersen/sync\n");
157
        process.exit(code);
158
    }
159
160
    /**
161
     * Shorthand command to print help text
162
     */
163
    private getHelp(command, text) {
164
        return `${chalk.green(command)}: ${text}\n`;
165
    }
166
167
    /**
168
     * Display the prompt that asks for input
169
     */
170
    private showPrompt() {
171
        if (this.activePrompt) {
172
            this.closePrompts();
173
        }
174
175
        this.activePrompt = this.read(">>> ");
176
        this.activePrompt.then(answer => {
177
            this.handleInput(answer);
178
            this.activePrompt = false;
179
            // as soon as a command is run, show promt again just a like a real shell
180
            this.showPrompt();
181
        });
182
    }
183
184
    /**
185
     * Handle given input
186
     */
187
    private handleInput(input) {
188
        input = input.split(" ");
189
        let cmd = input[0];
190
        let arg1 = input[1];
191
        switch (cmd) {
192
            case "help":
193
                let helpText = "";
194
                helpText += this.getHelp("pause", "Stops observing file changes");
195
                helpText += this.getHelp("resume", "Continue checking files");
196
                helpText += this.getHelp("resume -u", "Continue checking files and upload all the changed files while paused.");
197
                helpText += this.getHelp("help", "Displays this text");
198
                helpText += this.getHelp("clear", "Clears the screen");
199
                helpText += this.getHelp("exit", "Exits the script");
200
                this.write(helpText);
201
                break;
202
            case "clear":
203
                this.workspace();
204
                break;
205
            case "exit":
206
                process.exit(EXIT_CODE.NORMAL);
207
                break;
208
            case "pause":
209
                this.paused = true;
210
                this.pauseEvents.map((ev) => {
211
                    ev(this.paused);
212
                });
213
                this.workspace();
214
                break;
215
            case "resume":
216
                if (this.paused) {
217
                    if (arg1 != "-u") {
218
                        this.lastRun = +(new Date());
219
                        this.timeDiff = 0;
220
                    }
221
                    this.paused = false;
222
                    this.workspace();
223
                    if (arg1 == "-u") {
224
                        this.write("Finding all changed files while waiting.\n");
225
                    }
226
                    this.pauseEvents.map((ev) => {
227
                        ev(this.paused);
228
                    });
229
                } else {
230
                    this.write("Already running\n");
231
                }
232
                break;
233
            case "": break;
234
            default:
235
                this.write(chalk.red(`Unknown command: ${cmd}\nType "help" to see commands`));
236
        }
237
    }
238
}
239
240