11// tslint:disable:no-any
2- import { logging , tags } from '@angular-devkit/core' ;
3- import { camelize } from '@angular-devkit/core/src/utils/strings' ;
2+ import { logging , strings as coreStrings , tags } from '@angular-devkit/core' ;
43import {
54 ArgumentStrategy ,
65 CommandConstructor ,
@@ -17,6 +16,28 @@ export interface CommandMap {
1716 [ key : string ] : CommandConstructor ;
1817}
1918
19+ // Based off https://en.wikipedia.org/wiki/Levenshtein_distance
20+ // No optimization, really.
21+ function levenshtein ( a : string , b : string ) : number {
22+ /* base case: empty strings */
23+ if ( a . length == 0 ) {
24+ return b . length ;
25+ }
26+ if ( b . length == 0 ) {
27+ return a . length ;
28+ }
29+
30+ // Test if last characters of the strings match.
31+ const cost = a [ a . length - 1 ] == b [ b . length - 1 ] ? 0 : 1 ;
32+
33+ /* return minimum of delete char from s, delete char from t, and delete char from both */
34+ return Math . min (
35+ levenshtein ( a . slice ( 0 , - 1 ) , b ) + 1 ,
36+ levenshtein ( a , b . slice ( 0 , - 1 ) ) + 1 ,
37+ levenshtein ( a . slice ( 0 , - 1 ) , b . slice ( 0 , - 1 ) ) + cost ,
38+ ) ;
39+ }
40+
2041/**
2142 * Run a command.
2243 * @param commandMap Map of available commands.
@@ -42,7 +63,7 @@ export async function runCommand(commandMap: CommandMap,
4263 ? CommandScope . inProject
4364 : CommandScope . outsideProject ;
4465
45- let Cmd : CommandConstructor ;
66+ let Cmd : CommandConstructor | null ;
4667 Cmd = findCommand ( commandMap , commandName ) ;
4768
4869 if ( ! Cmd && ! commandName && ( rawOptions . v || rawOptions . version ) ) {
@@ -56,28 +77,6 @@ export async function runCommand(commandMap: CommandMap,
5677 }
5778
5879 if ( ! Cmd ) {
59- // Based off https://en.wikipedia.org/wiki/Levenshtein_distance
60- // No optimization, really.
61- function levenshtein ( a : string , b : string ) : number {
62- /* base case: empty strings */
63- if ( a . length == 0 ) {
64- return b . length ;
65- }
66- if ( b . length == 0 ) {
67- return a . length ;
68- }
69-
70- // Test if last characters of the strings match.
71- const cost = a [ a . length - 1 ] == b [ b . length - 1 ] ? 0 : 1 ;
72-
73- /* return minimum of delete char from s, delete char from t, and delete char from both */
74- return Math . min (
75- levenshtein ( a . slice ( 0 , - 1 ) , b ) + 1 ,
76- levenshtein ( a , b . slice ( 0 , - 1 ) ) + 1 ,
77- levenshtein ( a . slice ( 0 , - 1 ) , b . slice ( 0 , - 1 ) ) + cost ,
78- ) ;
79- }
80-
8180 const commandsDistance = { } as { [ name : string ] : number } ;
8281 const allCommands = listAllCommandNames ( commandMap ) . sort ( ( a , b ) => {
8382 if ( ! ( a in commandsDistance ) ) {
@@ -111,7 +110,9 @@ export async function runCommand(commandMap: CommandMap,
111110 }
112111
113112 if ( options . help ) {
114- return command . printHelp ( options ) ;
113+ command . printHelp ( options ) ;
114+
115+ return ;
115116 } else {
116117 if ( command . scope !== undefined && command . scope !== CommandScope . everywhere ) {
117118 if ( command . scope !== executionScope ) {
@@ -176,7 +177,7 @@ export function parseOptions<T = any>(
176177 const aliases = cmdOpts . concat ( )
177178 . filter ( o => o . aliases && o . aliases . length > 0 )
178179 . reduce ( ( aliases : any , opt : Option ) => {
179- aliases [ opt . name ] = opt . aliases
180+ aliases [ opt . name ] = ( opt . aliases || [ ] )
180181 . filter ( a => a . length === 1 ) ;
181182
182183 return aliases ;
@@ -230,7 +231,7 @@ export function parseOptions<T = any>(
230231 // Remove undefined booleans
231232 booleans
232233 . filter ( b => parsedOptions [ b ] === undefined )
233- . map ( b => camelize ( b ) )
234+ . map ( b => coreStrings . camelize ( b ) )
234235 . forEach ( b => delete parsedOptions [ b ] ) ;
235236
236237 // remove options with dashes.
0 commit comments