@@ -53,22 +53,27 @@ export abstract class CommandLineParameter {
5353 /** {@inheritdoc IBaseCommandLineDefinition.description } */
5454 public readonly description : string ;
5555
56+ /** {@inheritdoc IBaseCommandLineDefinition.required } */
57+ public readonly required : boolean ;
58+
5659 /** @internal */
5760 constructor ( definition : IBaseCommandLineDefinition ) {
58- if ( ! CommandLineParameter . _longNameRegExp . test ( definition . parameterLongName ) ) {
59- throw new Error ( `Invalid name: "${ definition . parameterLongName } ". The parameter long name must be`
61+ this . longName = definition . parameterLongName ;
62+ this . shortName = definition . parameterShortName ;
63+ this . description = definition . description ;
64+ this . required = ! ! definition . required ;
65+
66+ if ( ! CommandLineParameter . _longNameRegExp . test ( this . longName ) ) {
67+ throw new Error ( `Invalid name: "${ this . longName } ". The parameter long name must be`
6068 + ` lower-case and use dash delimiters (e.g. "--do-a-thing")` ) ;
6169 }
62- this . longName = definition . parameterLongName ;
6370
64- if ( definition . parameterShortName ) {
65- if ( ! CommandLineParameter . _shortNameRegExp . test ( definition . parameterShortName ) ) {
66- throw new Error ( `Invalid name: "${ definition . parameterShortName } ". The parameter short name must be`
71+ if ( this . shortName ) {
72+ if ( ! CommandLineParameter . _shortNameRegExp . test ( this . shortName ) ) {
73+ throw new Error ( `Invalid name: "${ this . shortName } ". The parameter short name must be`
6774 + ` a dash followed by a single upper-case or lower-case letter (e.g. "-a")` ) ;
6875 }
6976 }
70- this . shortName = definition . parameterShortName ;
71- this . description = definition . description ;
7277 }
7378
7479 /**
@@ -89,6 +94,18 @@ export abstract class CommandLineParameter {
8994 throw new Error ( `Unexpected data object for parameter "${ this . longName } ": `
9095 + JSON . stringify ( data ) ) ;
9196 }
97+
98+ protected validateDefaultValue ( hasDefaultValue : boolean ) : void {
99+ if ( this . required && hasDefaultValue ) {
100+ // If a parameter is "required", then the user understands that they always need to
101+ // specify a value for this parameter (either via the command line or via an environment variable).
102+ // It would be confusing to allow a default value that sometimes allows the "required" parameter
103+ // to be omitted. If you sometimes don't have a suitable default value, then the better approach
104+ // is to throw a custom error explaining why the parameter is required in that case.
105+ throw new Error ( `A default value cannot be specified for "${ this . longName } "`
106+ + ` because it is a "required" parameter` ) ;
107+ }
108+ }
92109}
93110
94111/**
@@ -134,7 +151,7 @@ export class CommandLineChoiceParameter extends CommandLineParameter {
134151 /** {@inheritdoc ICommandLineChoiceDefinition.alternatives } */
135152 public readonly alternatives : ReadonlyArray < string > ;
136153
137- /** {@inheritdoc ICommandLineChoiceDefinition .defaultValue } */
154+ /** {@inheritdoc ICommandLineStringDefinition .defaultValue } */
138155 public readonly defaultValue : string | undefined ;
139156
140157 private _value : string | undefined = undefined ;
@@ -153,6 +170,7 @@ export class CommandLineChoiceParameter extends CommandLineParameter {
153170
154171 this . alternatives = definition . alternatives ;
155172 this . defaultValue = definition . defaultValue ;
173+ this . validateDefaultValue ( ! ! this . defaultValue ) ;
156174 }
157175
158176 /** {@inheritdoc CommandLineParameter.kind } */
@@ -236,11 +254,16 @@ export class CommandLineFlagParameter extends CommandLineParameter {
236254 * @public
237255 */
238256export class CommandLineIntegerParameter extends CommandLineParameterWithArgument {
257+ /** {@inheritdoc ICommandLineStringDefinition.defaultValue } */
258+ public readonly defaultValue : number | undefined ;
259+
239260 private _value : number | undefined = undefined ;
240261
241262 /** @internal */
242263 constructor ( definition : ICommandLineIntegerDefinition ) {
243264 super ( definition ) ;
265+ this . defaultValue = definition . defaultValue ;
266+ this . validateDefaultValue ( ! ! this . defaultValue ) ;
244267 }
245268
246269 /** {@inheritdoc CommandLineParameter.kind } */
@@ -280,11 +303,17 @@ export class CommandLineIntegerParameter extends CommandLineParameterWithArgumen
280303 * @public
281304 */
282305export class CommandLineStringParameter extends CommandLineParameterWithArgument {
306+ /** {@inheritdoc ICommandLineStringDefinition.defaultValue } */
307+ public readonly defaultValue : string | undefined ;
308+
283309 private _value : string | undefined = undefined ;
284310
285311 /** @internal */
286312 constructor ( definition : ICommandLineStringDefinition ) {
287313 super ( definition ) ;
314+
315+ this . defaultValue = definition . defaultValue ;
316+ this . validateDefaultValue ( ! ! this . defaultValue ) ;
288317 }
289318
290319 /** {@inheritdoc CommandLineParameter.kind } */
0 commit comments