-
-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(command): add
ArgumentsParser
util class
- Loading branch information
Showing
3 changed files
with
132 additions
and
148 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { green, magenta, red, yellow } from 'https://deno.land/std@v0.52.0/fmt/colors.ts'; | ||
import { OptionType } from '../../flags/lib/types.ts'; | ||
import { IArgumentDetails } from './types.ts'; | ||
|
||
export class ArgumentsParser { | ||
|
||
private static readonly ARGUMENT_REGEX = /^[<\[].+[\]>]$/; | ||
private static readonly ARGUMENT_DETAILS_REGEX = /[<\[:>\]]/; | ||
|
||
public static splitArguments( args: string ): { args: string[], typeDefinition: string } { | ||
|
||
const parts = args.trim().split( /[, =] */g ); | ||
const typeParts = []; | ||
|
||
while ( parts[ parts.length - 1 ] && this.ARGUMENT_REGEX.test( parts[ parts.length - 1 ] ) ) { | ||
typeParts.unshift( parts.pop() ); | ||
} | ||
|
||
const typeDefinition: string = typeParts.join( ' ' ); | ||
|
||
return { args: parts, typeDefinition }; | ||
} | ||
|
||
public static parseArgumentsDefinition( argsDefinition: string ): IArgumentDetails[] { | ||
|
||
const argumentDetails: IArgumentDetails[] = []; | ||
|
||
let hasOptional = false; | ||
let hasVariadic = false; | ||
const parts: string[] = argsDefinition.split( / +/ ); | ||
|
||
for ( const arg of parts ) { | ||
|
||
if ( hasVariadic ) { | ||
throw new Error( 'An argument can not follow an variadic argument.' ); | ||
} | ||
|
||
const parts: string[] = arg.split( this.ARGUMENT_DETAILS_REGEX ); | ||
const type: OptionType | string | undefined = parts[ 2 ] ? parts[ 2 ] : OptionType.STRING; | ||
|
||
let details: IArgumentDetails = { | ||
optionalValue: arg[ 0 ] !== '<', | ||
name: parts[ 1 ], | ||
action: parts[ 3 ] || type, | ||
variadic: false, | ||
list: type ? arg.indexOf( type + '[]' ) !== -1 : false, | ||
type | ||
}; | ||
|
||
if ( !details.optionalValue && hasOptional ) { | ||
throw new Error( 'An required argument can not follow an optional argument.' ); | ||
} | ||
|
||
if ( arg[ 0 ] === '[' ) { | ||
hasOptional = true; | ||
} | ||
|
||
if ( details.name.length > 3 ) { | ||
|
||
const istVariadicLeft = details.name.slice( 0, 3 ) === '...'; | ||
const istVariadicRight = details.name.slice( -3 ) === '...'; | ||
|
||
hasVariadic = details.variadic = istVariadicLeft || istVariadicRight; | ||
|
||
if ( istVariadicLeft ) { | ||
details.name = details.name.slice( 3 ); | ||
} else if ( istVariadicRight ) { | ||
details.name = details.name.slice( 0, -3 ); | ||
} | ||
} | ||
|
||
if ( details.name ) { | ||
argumentDetails.push( details ); | ||
} | ||
} | ||
|
||
return argumentDetails; | ||
} | ||
|
||
public static highlightArguments( argsDefinition: string ) { | ||
|
||
if ( !argsDefinition ) { | ||
return ''; | ||
} | ||
|
||
return this.parseArgumentsDefinition( argsDefinition ) | ||
.map( ( arg: IArgumentDetails ) => this.highlightArgumentDetails( arg ) ).join( ' ' ); | ||
} | ||
|
||
public static highlightArgumentDetails( arg: IArgumentDetails ): string { | ||
|
||
let str = ''; | ||
|
||
str += yellow( arg.optionalValue ? '[' : '<' ); | ||
|
||
let name = ''; | ||
name += arg.name; | ||
if ( arg.variadic ) { | ||
name += '...'; | ||
} | ||
name = magenta( name ); | ||
|
||
str += name; | ||
|
||
// if ( arg.name !== arg.type ) { | ||
str += yellow( ':' ); | ||
str += red( arg.type ); | ||
// } | ||
|
||
if ( arg.list ) { | ||
str += green( '[]' ); | ||
} | ||
|
||
str += yellow( arg.optionalValue ? ']' : '>' ); | ||
|
||
return str; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters