Setup eslint and enforce rules
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import {Injectable, Inject} from "../di"
|
||||
import {infer, ErrorWithContext} from "../util"
|
||||
import {CLIOption} from "./directive/options/CLIOption"
|
||||
import {PositionalOption} from "./directive/options/PositionalOption";
|
||||
import {FlagOption} from "./directive/options/FlagOption";
|
||||
import {AppClass} from "../lifecycle/AppClass";
|
||||
import {Logging} from "../service/Logging";
|
||||
import {Injectable, Inject} from '../di'
|
||||
import {infer, ErrorWithContext} from '../util'
|
||||
import {CLIOption} from './directive/options/CLIOption'
|
||||
import {PositionalOption} from './directive/options/PositionalOption'
|
||||
import {FlagOption} from './directive/options/FlagOption'
|
||||
import {AppClass} from '../lifecycle/AppClass'
|
||||
import {Logging} from '../service/Logging'
|
||||
|
||||
/**
|
||||
* Type alias for a definition of a command-line option.
|
||||
@@ -35,7 +35,7 @@ export abstract class Directive extends AppClass {
|
||||
protected readonly logging!: Logging
|
||||
|
||||
/** Parsed option values. */
|
||||
private _optionValues: any
|
||||
private optionValues: any
|
||||
|
||||
/**
|
||||
* Get the keyword or array of keywords that will specify this directive.
|
||||
@@ -84,8 +84,8 @@ export abstract class Directive extends AppClass {
|
||||
* @param optionValues
|
||||
* @private
|
||||
*/
|
||||
private _setOptionValues(optionValues: any) {
|
||||
this._optionValues = optionValues;
|
||||
private setOptionValues(optionValues: any) {
|
||||
this.optionValues = optionValues
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,9 +93,9 @@ export abstract class Directive extends AppClass {
|
||||
* @param name
|
||||
* @param defaultValue
|
||||
*/
|
||||
public option(name: string, defaultValue?: any) {
|
||||
if ( name in this._optionValues ) {
|
||||
return this._optionValues[name]
|
||||
public option(name: string, defaultValue?: unknown): any {
|
||||
if ( name in this.optionValues ) {
|
||||
return this.optionValues[name]
|
||||
}
|
||||
|
||||
return defaultValue
|
||||
@@ -110,20 +110,28 @@ export abstract class Directive extends AppClass {
|
||||
*
|
||||
* @param argv
|
||||
*/
|
||||
async invoke(argv: string[]) {
|
||||
async invoke(argv: string[]): Promise<void> {
|
||||
const options = this.getResolvedOptions()
|
||||
|
||||
if ( this.didRequestUsage(argv) ) {
|
||||
// @ts-ignore
|
||||
const positionalArguments: PositionalOption<any>[] = options.filter(opt => opt instanceof PositionalOption)
|
||||
const positionalArguments: PositionalOption<any>[] = []
|
||||
options.forEach(opt => {
|
||||
if ( opt instanceof PositionalOption ) {
|
||||
positionalArguments.push(opt)
|
||||
}
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
const flagArguments: FlagOption<any>[] = options.filter(opt => opt instanceof FlagOption)
|
||||
const flagArguments: FlagOption<any>[] = []
|
||||
options.forEach(opt => {
|
||||
if ( opt instanceof FlagOption ) {
|
||||
flagArguments.push(opt)
|
||||
}
|
||||
})
|
||||
|
||||
const positionalDisplay: string = positionalArguments.map(x => `<${x.getArgumentName()}>`).join(' ')
|
||||
const flagDisplay: string = flagArguments.length ? ' [...flags]' : ''
|
||||
|
||||
console.log([
|
||||
this.nativeOutput([
|
||||
'',
|
||||
`DIRECTIVE: ${this.getMainKeyword()} - ${this.getDescription()}`,
|
||||
'',
|
||||
@@ -131,7 +139,7 @@ export abstract class Directive extends AppClass {
|
||||
].join('\n'))
|
||||
|
||||
if ( positionalArguments.length ) {
|
||||
console.log([
|
||||
this.nativeOutput([
|
||||
'',
|
||||
`POSITIONAL ARGUMENTS:`,
|
||||
...(positionalArguments.map(arg => {
|
||||
@@ -141,7 +149,7 @@ export abstract class Directive extends AppClass {
|
||||
}
|
||||
|
||||
if ( flagArguments.length ) {
|
||||
console.log([
|
||||
this.nativeOutput([
|
||||
'',
|
||||
`FLAGS:`,
|
||||
...(flagArguments.map(arg => {
|
||||
@@ -152,34 +160,34 @@ export abstract class Directive extends AppClass {
|
||||
|
||||
const help = this.getHelpText()
|
||||
if ( help ) {
|
||||
console.log('\n' + help)
|
||||
this.nativeOutput('\n' + help)
|
||||
}
|
||||
|
||||
console.log('\n')
|
||||
this.nativeOutput('\n')
|
||||
} else {
|
||||
try {
|
||||
const optionValues = this.parseOptions(options, argv)
|
||||
this._setOptionValues(optionValues)
|
||||
this.setOptionValues(optionValues)
|
||||
await this.handle(argv)
|
||||
} catch (e) {
|
||||
console.error(e.message)
|
||||
this.nativeOutput(e.message)
|
||||
if ( e instanceof OptionValidationError ) {
|
||||
// expecting, value, requirements
|
||||
if ( e.context.expecting ) {
|
||||
console.error(` - Expecting: ${e.context.expecting}`)
|
||||
this.nativeOutput(` - Expecting: ${e.context.expecting}`)
|
||||
}
|
||||
|
||||
if ( e.context.requirements && Array.isArray(e.context.requirements) ) {
|
||||
for ( const req of e.context.requirements ) {
|
||||
console.error(` - ${req}`)
|
||||
this.nativeOutput(` - ${req}`)
|
||||
}
|
||||
}
|
||||
|
||||
if ( e.context.value ) {
|
||||
console.error(` - ${e.context.value}`)
|
||||
this.nativeOutput(` - ${e.context.value}`)
|
||||
}
|
||||
}
|
||||
console.error('\nUse --help for more info.')
|
||||
this.nativeOutput('\nUse --help for more info.')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,9 +225,11 @@ export abstract class Directive extends AppClass {
|
||||
* Returns true if the given keyword should invoke this directive.
|
||||
* @param name
|
||||
*/
|
||||
public matchesKeyword(name: string) {
|
||||
public matchesKeyword(name: string): boolean {
|
||||
let kws = this.getKeywords()
|
||||
if ( !Array.isArray(kws) ) kws = [kws]
|
||||
if ( !Array.isArray(kws) ) {
|
||||
kws = [kws]
|
||||
}
|
||||
return kws.includes(name)
|
||||
}
|
||||
|
||||
@@ -227,7 +237,7 @@ export abstract class Directive extends AppClass {
|
||||
* Print the given output to the log as success text.
|
||||
* @param output
|
||||
*/
|
||||
success(output: any) {
|
||||
success(output: unknown): void {
|
||||
this.logging.success(output, true)
|
||||
}
|
||||
|
||||
@@ -235,7 +245,7 @@ export abstract class Directive extends AppClass {
|
||||
* Print the given output to the log as error text.
|
||||
* @param output
|
||||
*/
|
||||
error(output: any) {
|
||||
error(output: unknown): void {
|
||||
this.logging.error(output, true)
|
||||
}
|
||||
|
||||
@@ -243,7 +253,7 @@ export abstract class Directive extends AppClass {
|
||||
* Print the given output to the log as warning text.
|
||||
* @param output
|
||||
*/
|
||||
warn(output: any) {
|
||||
warn(output: unknown): void {
|
||||
this.logging.warn(output, true)
|
||||
}
|
||||
|
||||
@@ -251,7 +261,7 @@ export abstract class Directive extends AppClass {
|
||||
* Print the given output to the log as info text.
|
||||
* @param output
|
||||
*/
|
||||
info(output: any) {
|
||||
info(output: unknown): void {
|
||||
this.logging.info(output, true)
|
||||
}
|
||||
|
||||
@@ -259,7 +269,7 @@ export abstract class Directive extends AppClass {
|
||||
* Print the given output to the log as debugging text.
|
||||
* @param output
|
||||
*/
|
||||
debug(output: any) {
|
||||
debug(output: unknown): void {
|
||||
this.logging.debug(output, true)
|
||||
}
|
||||
|
||||
@@ -267,7 +277,7 @@ export abstract class Directive extends AppClass {
|
||||
* Print the given output to the log as verbose text.
|
||||
* @param output
|
||||
*/
|
||||
verbose(output: any) {
|
||||
verbose(output: unknown): void {
|
||||
this.logging.verbose(output, true)
|
||||
}
|
||||
|
||||
@@ -275,7 +285,7 @@ export abstract class Directive extends AppClass {
|
||||
* Get the flag option that signals help. Usually, this is named 'help'
|
||||
* and supports the flags '--help' and '-?'.
|
||||
*/
|
||||
getHelpOption() {
|
||||
getHelpOption(): FlagOption<any> {
|
||||
return new FlagOption('--help', '-?', 'usage information about this directive')
|
||||
}
|
||||
|
||||
@@ -283,12 +293,21 @@ export abstract class Directive extends AppClass {
|
||||
* Process the raw CLI arguments using an array of option class instances to build
|
||||
* a mapping of option names to provided values.
|
||||
*/
|
||||
parseOptions(options: CLIOption<any>[], args: string[]) {
|
||||
// @ts-ignore
|
||||
let positionalArguments: PositionalOption<any>[] = options.filter(cls => cls instanceof PositionalOption)
|
||||
parseOptions(options: CLIOption<any>[], args: string[]): {[key: string]: any} {
|
||||
let positionalArguments: PositionalOption<any>[] = []
|
||||
options.forEach(opt => {
|
||||
if ( opt instanceof PositionalOption ) {
|
||||
positionalArguments.push(opt)
|
||||
}
|
||||
})
|
||||
|
||||
const flagArguments: FlagOption<any>[] = []
|
||||
options.forEach(opt => {
|
||||
if ( opt instanceof FlagOption ) {
|
||||
flagArguments.push(opt)
|
||||
}
|
||||
})
|
||||
|
||||
// @ts-ignore
|
||||
const flagArguments: FlagOption<any>[] = options.filter(cls => cls instanceof FlagOption)
|
||||
const optionValue: any = {}
|
||||
|
||||
flagArguments.push(this.getHelpOption())
|
||||
@@ -325,7 +344,7 @@ export abstract class Directive extends AppClass {
|
||||
const flagArgument = flagArguments.filter(x => x.shortFlag === value)
|
||||
if ( flagArgument.length < 1 ) {
|
||||
throw new OptionValidationError(`Unknown flag argument: ${value}`, {
|
||||
value
|
||||
value,
|
||||
})
|
||||
} else {
|
||||
if ( flagArgument[0].argumentDescription ) {
|
||||
@@ -350,7 +369,7 @@ export abstract class Directive extends AppClass {
|
||||
} else {
|
||||
if ( positionalArguments.length < 1 ) {
|
||||
throw new OptionValidationError(`Unknown positional argument: ${value}`, {
|
||||
value
|
||||
value,
|
||||
})
|
||||
} else {
|
||||
const inferredValue = infer(value)
|
||||
@@ -368,13 +387,13 @@ export abstract class Directive extends AppClass {
|
||||
|
||||
if ( expectingFlagArgument ) {
|
||||
throw new OptionValidationError(`Missing argument for flag: ${positionalFlagName}`, {
|
||||
expecting: positionalFlagName
|
||||
expecting: positionalFlagName,
|
||||
})
|
||||
}
|
||||
|
||||
if ( positionalArguments.length > 0 ) {
|
||||
throw new OptionValidationError(`Missing required argument: ${positionalArguments[0].getArgumentName()}`, {
|
||||
expecting: positionalArguments[0].getArgumentName()
|
||||
expecting: positionalArguments[0].getArgumentName(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -430,14 +449,18 @@ export abstract class Directive extends AppClass {
|
||||
* Determines if, at any point in the arguments, the help option's short or long flag appears.
|
||||
* @returns {boolean} - true if the help flag appeared
|
||||
*/
|
||||
didRequestUsage(argv: string[]) {
|
||||
const help_option = this.getHelpOption()
|
||||
didRequestUsage(argv: string[]): boolean {
|
||||
const helpOption = this.getHelpOption()
|
||||
for ( const arg of argv ) {
|
||||
if ( arg.trim() === help_option.longFlag || arg.trim() === help_option.shortFlag ) {
|
||||
if ( arg.trim() === helpOption.longFlag || arg.trim() === helpOption.shortFlag ) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
protected nativeOutput(...outputs: any[]): void {
|
||||
console.log(...outputs) // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user