2018-09-30 20:36:30 +00:00
|
|
|
import * as smartpromise from '@pushrocks/smartpromise';
|
2018-05-03 10:10:39 +00:00
|
|
|
import { Subject } from 'rxjs';
|
2016-06-10 00:27:04 +00:00
|
|
|
|
2018-05-03 10:10:39 +00:00
|
|
|
import * as plugins from './smartcli.plugins';
|
2016-08-26 09:52:09 +00:00
|
|
|
|
|
|
|
// import classes
|
2020-05-29 17:48:17 +00:00
|
|
|
import { ObjectMap } from '@pushrocks/lik';
|
2016-08-26 09:52:09 +00:00
|
|
|
|
|
|
|
// interfaces
|
2016-12-18 19:53:50 +00:00
|
|
|
export interface ICommandPromiseObject {
|
2018-05-03 10:10:39 +00:00
|
|
|
commandName: string;
|
|
|
|
promise: Promise<void>;
|
2016-12-18 19:53:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface ITriggerObservableObject {
|
2018-05-03 10:10:39 +00:00
|
|
|
triggerName: string;
|
|
|
|
subject: Subject<any>;
|
2016-10-14 22:56:02 +00:00
|
|
|
}
|
2016-06-10 01:10:21 +00:00
|
|
|
|
2021-04-07 20:25:17 +00:00
|
|
|
const logger = new plugins.smartlog.ConsoleLog();
|
|
|
|
|
2018-05-03 10:10:39 +00:00
|
|
|
/**
|
|
|
|
* class to create a new instance of Smartcli. Handles parsing of command line arguments.
|
|
|
|
*/
|
2016-06-10 00:27:04 +00:00
|
|
|
export class Smartcli {
|
2018-05-03 10:10:39 +00:00
|
|
|
argv: any;
|
|
|
|
questionsDone;
|
2018-09-30 20:36:30 +00:00
|
|
|
parseStarted: smartpromise.Deferred<any>;
|
2018-05-03 10:10:39 +00:00
|
|
|
commands;
|
|
|
|
questions;
|
|
|
|
version: string;
|
2020-04-13 21:53:18 +00:00
|
|
|
private checkForEnvCliCall = true;
|
2017-04-22 19:03:28 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-03 10:10:39 +00:00
|
|
|
* map of all Trigger/Observable objects to keep track
|
2017-04-22 19:03:28 +00:00
|
|
|
*/
|
2020-05-29 17:48:17 +00:00
|
|
|
allTriggerObservablesMap = new ObjectMap<ITriggerObservableObject>();
|
2017-04-22 19:03:28 +00:00
|
|
|
|
|
|
|
/**
|
2018-05-03 10:10:39 +00:00
|
|
|
* The constructor of Smartcli
|
2017-04-22 19:03:28 +00:00
|
|
|
*/
|
2018-05-03 10:10:39 +00:00
|
|
|
constructor() {
|
|
|
|
this.argv = plugins.yargs;
|
2018-09-30 20:36:30 +00:00
|
|
|
this.questionsDone = smartpromise.defer();
|
|
|
|
this.parseStarted = smartpromise.defer();
|
2017-04-22 19:03:28 +00:00
|
|
|
}
|
|
|
|
|
2018-05-03 10:10:39 +00:00
|
|
|
/**
|
|
|
|
* halts any execution of commands if (process.env.CLI_CALL === false)
|
|
|
|
*/
|
2020-04-13 21:53:18 +00:00
|
|
|
disableEnvCliCall() {
|
|
|
|
this.checkForEnvCliCall = false;
|
2017-10-12 20:44:34 +00:00
|
|
|
}
|
|
|
|
|
2017-04-22 19:03:28 +00:00
|
|
|
/**
|
|
|
|
* adds an alias, meaning one equals the other in terms of command execution.
|
|
|
|
*/
|
2018-05-03 10:10:39 +00:00
|
|
|
addCommandAlias(keyArg, aliasArg): void {
|
|
|
|
this.argv = this.argv.alias(keyArg, aliasArg);
|
|
|
|
return;
|
2017-04-22 19:03:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* adds a Command by returning a Promise that reacts to the specific commandString given.
|
|
|
|
* Note: in e.g. "npm install something" the "install" is considered the command.
|
|
|
|
*/
|
2018-05-03 10:10:39 +00:00
|
|
|
addCommand(commandNameArg: string): Subject<any> {
|
2020-04-13 21:44:27 +00:00
|
|
|
const triggerSubject = this.addTrigger(commandNameArg);
|
2018-05-03 10:10:39 +00:00
|
|
|
this.parseStarted.promise.then(() => {
|
|
|
|
if (this.argv._.indexOf(commandNameArg) === 0) {
|
|
|
|
this.trigger(commandNameArg);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return triggerSubject;
|
2017-04-22 19:03:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-10-12 18:38:34 +00:00
|
|
|
* adds a Trigger. Like addCommand(), but returns an subscribable observable
|
2017-04-22 19:03:28 +00:00
|
|
|
*/
|
2018-05-03 10:10:39 +00:00
|
|
|
addTrigger(triggerNameArg: string) {
|
2020-04-13 21:44:27 +00:00
|
|
|
const triggerSubject = new Subject<any>();
|
2018-05-03 10:10:39 +00:00
|
|
|
if (!this.getTriggerSubject(triggerNameArg)) {
|
|
|
|
this.allTriggerObservablesMap.add({
|
|
|
|
triggerName: triggerNameArg,
|
2021-04-07 20:25:17 +00:00
|
|
|
subject: triggerSubject,
|
2018-05-03 10:10:39 +00:00
|
|
|
});
|
|
|
|
} else {
|
|
|
|
throw new Error(`you can't add a trigger twice`);
|
|
|
|
}
|
|
|
|
return triggerSubject;
|
2017-04-22 19:03:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* execute trigger by name
|
|
|
|
* @param commandNameArg - the name of the command to trigger
|
|
|
|
*/
|
2018-05-03 10:10:39 +00:00
|
|
|
trigger(triggerName: string) {
|
2020-04-13 21:44:27 +00:00
|
|
|
const triggerSubject = this.getTriggerSubject(triggerName);
|
2018-05-03 10:10:39 +00:00
|
|
|
triggerSubject.next(this.argv);
|
|
|
|
return triggerSubject;
|
|
|
|
}
|
|
|
|
|
|
|
|
getTriggerSubject(triggerName: string) {
|
|
|
|
const triggerObservableObject = this.allTriggerObservablesMap.find(
|
2021-04-07 20:25:17 +00:00
|
|
|
(triggerObservableObjectArg) => {
|
2018-05-03 10:10:39 +00:00
|
|
|
return triggerObservableObjectArg.triggerName === triggerName;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
if (triggerObservableObject) {
|
|
|
|
return triggerObservableObject.subject;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
2017-04-22 19:03:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* allows to specify help text to be printed above the rest of the help text
|
|
|
|
*/
|
2018-05-03 10:10:39 +00:00
|
|
|
addHelp(optionsArg: { helpText: string }) {
|
2021-04-07 20:25:17 +00:00
|
|
|
this.addCommand('help').subscribe((argvArg) => {
|
|
|
|
logger.log('info', optionsArg.helpText);
|
2018-05-03 10:10:39 +00:00
|
|
|
});
|
2017-04-22 19:03:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* specify version to be printed for -v --version
|
|
|
|
*/
|
2018-05-03 10:10:39 +00:00
|
|
|
addVersion(versionArg: string) {
|
|
|
|
this.version = versionArg;
|
|
|
|
this.addCommandAlias('v', 'version');
|
|
|
|
this.parseStarted.promise.then(() => {
|
|
|
|
if (this.argv.v) {
|
|
|
|
console.log(this.version);
|
|
|
|
}
|
|
|
|
});
|
2017-04-22 19:03:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-05-03 10:10:39 +00:00
|
|
|
* adds a trigger that is called when no command is specified
|
2017-04-22 19:03:28 +00:00
|
|
|
*/
|
2018-05-03 10:10:39 +00:00
|
|
|
standardTask(): Subject<any> {
|
2020-04-13 21:44:27 +00:00
|
|
|
const standardSubject = this.addTrigger('standardTask');
|
2018-05-03 10:10:39 +00:00
|
|
|
this.parseStarted.promise.then(() => {
|
2020-04-13 21:44:27 +00:00
|
|
|
if (
|
|
|
|
(this.argv._.length === 0 ||
|
|
|
|
(this.argv._.length === 1 && this.argv._[0].startsWith('test/'))) &&
|
|
|
|
!this.argv.v
|
|
|
|
) {
|
2020-04-13 21:53:18 +00:00
|
|
|
this.trigger('standardTask');
|
2018-05-03 10:10:39 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
return standardSubject;
|
2017-04-22 19:03:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* start the process of evaluating commands
|
|
|
|
*/
|
2018-05-03 10:10:39 +00:00
|
|
|
startParse(): void {
|
2020-04-13 21:53:18 +00:00
|
|
|
if (!process.env.CLI_CALL && this.checkForEnvCliCall) {
|
2020-05-29 17:48:17 +00:00
|
|
|
console.log(
|
|
|
|
`note: @pushrocks/smartcli: You called .startParse() on a SmartCli instance. However process.env.CLI_CALL being absent prevented parsing.`
|
|
|
|
);
|
2020-04-13 21:53:18 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-05-03 10:10:39 +00:00
|
|
|
this.argv = this.argv.argv;
|
|
|
|
this.parseStarted.resolve();
|
|
|
|
return;
|
2017-04-22 19:03:28 +00:00
|
|
|
}
|
2016-10-14 22:56:02 +00:00
|
|
|
}
|