Setup eslint and enforce rules
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2021-06-02 22:36:25 -05:00
parent 82e7a1f299
commit 1d5056b753
149 changed files with 6104 additions and 3114 deletions

View File

@@ -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
}
}