1+ // `import Yargs from "yargs"` is the Yargs singleton and namespace
2+ // `import yargs from "yargs/yargs"` is the non-singleton interface
3+ // See https://github.com/yargs/yargs/issues/1648
4+ import Yargs , { Options } from "yargs" ;
5+ import yargs from "yargs/yargs" ;
6+
17import { TruffleColors } from "@ganache/colors" ;
2- import yargs , { Options } from "yargs" ;
38import {
49 DefaultFlavor ,
510 FilecoinFlavorName ,
@@ -26,7 +31,7 @@ marked.setOptions({
2631 } )
2732} ) ;
2833
29- const wrapWidth = Math . min ( 120 , yargs . terminalWidth ( ) ) ;
34+ const wrapWidth = Math . min ( 120 , Yargs . terminalWidth ( ) ) ;
3035const NEED_HELP = "Need more help? Reach out to the Truffle community at" ;
3136const COMMUNITY_LINK = "https://trfl.io/support" ;
3237
@@ -43,7 +48,7 @@ const highlight = (t: string) => unescapeEntities(marked.parseInline(t));
4348const center = ( str : string ) =>
4449 " " . repeat ( Math . max ( 0 , Math . floor ( ( wrapWidth - str . length ) / 2 ) ) ) + str ;
4550
46- const addAliases = ( args : yargs . Argv < { } > , aliases : string [ ] , key : string ) => {
51+ const addAliases = ( args : Yargs . Argv < { } > , aliases : string [ ] , key : string ) => {
4752 const options = { hidden : true , alias : key } ;
4853 return aliases . reduce ( ( args , a ) => args . option ( a , options ) , args ) ;
4954} ;
@@ -54,7 +59,7 @@ function processOption(
5459 group : string ,
5560 option : string ,
5661 optionObj : Definitions < Base . Config > [ string ] ,
57- argv : yargs . Argv ,
62+ argv : Yargs . Argv ,
5863 flavor : string
5964) {
6065 if ( optionObj . disableInCLI !== true ) {
@@ -122,7 +127,7 @@ function applyDefaults(
122127 flavorDefaults :
123128 | typeof DefaultOptionsByName [ keyof typeof DefaultOptionsByName ]
124129 | typeof _DefaultServerOptions ,
125- flavorArgs : yargs . Argv < { } > ,
130+ flavorArgs : Yargs . Argv < { } > ,
126131 flavor : keyof typeof DefaultOptionsByName
127132) {
128133 for ( const category in flavorDefaults ) {
@@ -160,8 +165,9 @@ export default function (
160165
161166 // disable dot-notation because yargs just can't coerce args properly...
162167 // ...on purpose! https://github.com/yargs/yargs/issues/1021#issuecomment-352324693
163- yargs
168+ const yargsParser = yargs ( )
164169 . parserConfiguration ( { "dot-notation" : false } )
170+ . exitProcess ( false )
165171 . strict ( )
166172 . usage ( versionUsageOutputText )
167173 . epilogue (
@@ -188,12 +194,9 @@ export default function (
188194 command = [ "$0" , flavor ] ;
189195 defaultPort = 8545 ;
190196 break ;
191- default :
192- command = flavor ;
193- defaultPort = 8545 ;
194197 }
195198
196- yargs . command (
199+ yargsParser . command (
197200 command ,
198201 chalk `Use the {bold ${ flavor } } flavor of Ganache` ,
199202 flavorArgs => {
@@ -214,14 +217,19 @@ export default function (
214217 description : chalk `Port to listen on.${ EOL } {dim deprecated aliases: --port}${ EOL } ` ,
215218 alias : [ "p" , "port" ] ,
216219 type : "number" ,
217- default : defaultPort
220+ default : defaultPort ,
221+ // `string: true` to allow raw value to be used in validation below
222+ // (otherwise string values becomes NaN)
223+ string : true ,
224+ coerce : port => ( isFinite ( port ) ? + port : port )
218225 } )
219226 . check ( argv => {
220227 const { "server.port" : port , "server.host" : host } = argv ;
221- if ( port < 1 || port > 65535 ) {
222- throw new Error ( `Invalid port number '${ port } '` ) ;
228+ if ( ! isFinite ( port ) || port < 1 || port > 65535 ) {
229+ throw new Error (
230+ `Port should be >= 0 and < 65536. Received ${ port } .`
231+ ) ;
223232 }
224-
225233 if ( host . trim ( ) === "" ) {
226234 throw new Error ( "Cannot leave host blank; please provide a host" ) ;
227235 }
@@ -244,7 +252,7 @@ export default function (
244252 ) ;
245253 }
246254
247- yargs
255+ yargsParser
248256 . command (
249257 "instances" ,
250258 highlight (
@@ -272,6 +280,14 @@ export default function (
272280 stopArgs . action = "stop" ;
273281 }
274282 )
283+ . check ( instancesArgs => {
284+ if ( instancesArgs [ "_" ] . length <= 1 ) {
285+ throw new Error (
286+ "No sub-command given. See `ganache instances --help` for more information."
287+ ) ;
288+ }
289+ return true ;
290+ } )
275291 . version ( false ) ;
276292 }
277293 )
@@ -280,7 +296,7 @@ export default function (
280296 . wrap ( wrapWidth )
281297 . version ( version ) ;
282298
283- const parsedArgs = yargs . parse ( rawArgs ) ;
299+ const parsedArgs = yargsParser . parse ( rawArgs ) ;
284300
285301 let finalArgs : GanacheArgs ;
286302 if ( parsedArgs . action === "stop" ) {
@@ -308,7 +324,7 @@ export default function (
308324 > )
309325 } ;
310326 } else {
311- throw new Error ( `Unknown action: ${ parsedArgs . action } ` ) ;
327+ finalArgs = { action : "help" } ;
312328 }
313329
314330 return finalArgs ;
0 commit comments