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
2018-08-30 22:13:05 +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
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
* /
2018-05-03 10:10:39 +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 ,
subject : triggerSubject
} ) ;
} 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 (
triggerObservableObjectArg = > {
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 } ) {
this . addCommand ( 'help' ) . subscribe ( argvArg = > {
2018-12-11 00:50:59 +00:00
plugins . smartlog . defaultLogger . 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 ) {
console . log ( ` note: @pushrocks/smartcli: You called .startParse() on a SmartCli instance. However process.env.CLI_CALL being absent prevented parsing. ` ) ;
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
}