-
-
Notifications
You must be signed in to change notification settings - Fork 197
/
Copy pathdispatchers.ts
102 lines (84 loc) · 3.15 KB
/
dispatchers.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
import * as queue from "./queue";
import * as path from "path";
import { hook } from "./helpers";
export class CommandDispatcher implements ICommandDispatcher {
constructor(private $logger: ILogger,
// required by the hooksService
protected $injector: IInjector,
private $cancellation: ICancellationService,
private $commandsService: ICommandsService,
private $staticConfig: Config.IStaticConfig,
private $sysInfo: ISysInfo,
private $options: IOptions,
private $fs: IFileSystem) { }
public async dispatchCommand(): Promise<void> {
if (this.$options.version) {
return this.printVersion();
}
if (this.$logger.getLevel() === "TRACE") {
// CommandDispatcher is called from external CLI's only, so pass the path to their package.json
const sysInfo = await this.$sysInfo.getSysInfo({ pathToNativeScriptCliPackageJson: path.join(__dirname, "..", "..", "package.json") });
this.$logger.trace("System information:");
this.$logger.trace(JSON.stringify(sysInfo, null, 2));
this.$logger.trace("Current CLI version: ", this.$staticConfig.version);
}
let commandName = this.getCommandName();
let commandArguments = this.$options.argv._.slice(1);
const lastArgument: string = _.last(commandArguments);
if (this.$options.help) {
commandArguments.unshift(commandName);
commandName = "help";
} else if (lastArgument === "/?" || lastArgument === "?") {
commandArguments.pop();
commandArguments.unshift(commandName);
commandName = "help";
}
({ commandName, commandArguments, argv: process.argv } = await this.resolveCommand(commandName, commandArguments, process.argv));
await this.$cancellation.begin("cli");
await this.$commandsService.tryExecuteCommand(commandName, commandArguments);
}
public async completeCommand(): Promise<boolean> {
return this.$commandsService.completeCommand();
}
@hook("resolveCommand")
private async resolveCommand(commandName: string, commandArguments: string[], argv: string[]) {
// just a hook point
return { commandName, commandArguments, argv };
}
private getCommandName(): string {
const remaining: string[] = this.$options.argv._;
if (remaining.length > 0) {
return remaining[0].toString().toLowerCase();
}
// if only <CLI_NAME> is specified on console, show console help
this.$options.help = true;
return "";
}
private printVersion(): void {
let version = this.$staticConfig.version;
const json = this.$fs.readJson(this.$staticConfig.pathToPackageJson);
if (json && json.buildVersion) {
version = `${version}-${json.buildVersion}`;
}
this.$logger.info(version);
}
}
$injector.register("commandDispatcher", CommandDispatcher);
class FutureDispatcher implements IFutureDispatcher {
private actions: IQueue<any>;
public constructor(private $errors: IErrors) { }
public async run(): Promise<void> {
if (this.actions) {
this.$errors.fail("You cannot run a running future dispatcher.");
}
this.actions = new queue.Queue<any>();
while (true) {
const action = await this.actions.dequeue();
await action();
}
}
public dispatch(action: () => Promise<void>) {
this.actions.enqueue(action);
}
}
$injector.register("dispatcher", FutureDispatcher, false);