import {Unit} from '../../lifecycle/Unit' import {Logging} from '../../service/Logging' import {Singleton, Inject} from '../../di/decorator/injection' import {CommandLine} from './CommandLine' import {UsageDirective} from '../directive/UsageDirective' import {Directive} from '../Directive' import {ShellDirective} from '../directive/ShellDirective' import {TemplateDirective} from '../directive/TemplateDirective' import {RunDirective} from '../directive/RunDirective' /** * Unit that takes the place of the final unit in the application that handles * invocations from the command line. */ @Singleton() export class CommandLineApplication extends Unit { /** The unit that was replaced by the CLI app. */ private static replacement?: typeof Unit /** Set the replaced unit. */ public static setReplacement(unitClass?: typeof Unit): void { this.replacement = unitClass } /** Get the replaced unit. */ public static getReplacement(): typeof Unit | undefined { return this.replacement } @Inject() protected readonly cli!: CommandLine @Inject() protected readonly logging!: Logging constructor() { super() } public async up(): Promise { this.cli.registerDirective(UsageDirective) this.cli.registerDirective(ShellDirective) this.cli.registerDirective(TemplateDirective) this.cli.registerDirective(RunDirective) const argv = process.argv.slice(2) const match = this.cli.getDirectives() .map(dirCls => this.make(dirCls)) .firstWhere(dir => dir.matchesKeyword(argv[0])) if ( match ) { await match.invoke(argv.slice(1)) } else { const usage = this.make(UsageDirective) await usage.handle() } } }