Skip to content

Commit

Permalink
implement strict priorities.
Browse files Browse the repository at this point in the history
  • Loading branch information
mshima committed Sep 1, 2022
1 parent 8bea61c commit c2c90ba
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 14 deletions.
28 changes: 17 additions & 11 deletions lib/command.js
Expand Up @@ -57,13 +57,14 @@ class Command extends EventEmitter {
this._showHelpAfterError = false;
this._showSuggestionAfterError = true;

// 'unknown' value is left out on purpose, should be treated as such
this._precedence = [
'default',
'implied', // implied by others configs
'config', // placeholder for configuration files
this._strictPriority = false;
this._priorities = [
'cli',
'env',
'cli'
'config', // placeholder for configuration files
'implied', // implied by others configs
'default', // default option value
undefined // initial state, not touched yet
];

// see .configureOutput() for docs
Expand Down Expand Up @@ -421,6 +422,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
return this;
}

strictPriority(priorities) {
this._strictPriority = true;
if (priorities) {
this._priorities = priorities;
}
}

/**
* Register callback to use as replacement for calling process.exit.
*
Expand Down Expand Up @@ -802,7 +810,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
* @return {Command} `this` command for chaining
*/

setOptionValueWithSource(key, value, source = 'unknown') {
setOptionValueWithSource(key, value, source = null) {
if (this._strictPriority && !this._isNewSourcePreferred(source, this.getOptionValueSource(key))) return;
if (this._storeOptionsAsProperties) {
this[key] = value;
} else {
Expand Down Expand Up @@ -1612,10 +1621,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
* @api private
*/
_isNewSourcePreferred(newSource, existingSource) {
// unknown source should always take precedence. undefined existingSource means option not set.
if (newSource == null || !this._precedence.includes(newSource) || existingSource === undefined) return true;
if (existingSource === null || !this._precedence.includes(existingSource)) return false;
return this._precedence.indexOf(newSource) >= this._precedence.indexOf(existingSource);
return this._priorities.indexOf(newSource) <= this._priorities.indexOf(existingSource);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions typings/index.d.ts
Expand Up @@ -266,7 +266,7 @@ export interface OutputConfiguration {

export type AddHelpTextPosition = 'beforeAll' | 'before' | 'after' | 'afterAll';
export type HookEvent = 'preSubcommand' | 'preAction' | 'postAction';
export type OptionValueSource = 'default' | 'implied' | 'config' | 'env' | 'cli' | 'unknown';
export type OptionValueSource = 'default' | 'implied' | 'config' | 'env' | 'cli' | null;

export interface OptionValues {
[key: string]: any;
Expand Down Expand Up @@ -595,7 +595,7 @@ export class Command {
/**
* Retrieve option value source.
*/
getOptionValueSource(key: string): OptionValueSource;
getOptionValueSource(key: string): OptionValueSource | undefined;

/**
* Alter parsing of short flags with optional values.
Expand Down
2 changes: 1 addition & 1 deletion typings/index.test-d.ts
Expand Up @@ -172,7 +172,7 @@ expectType<commander.Command>(program.setOptionValue('example', true));
expectType<commander.Command>(program.setOptionValueWithSource('example', [], 'cli'));

// getOptionValueSource
expectType<commander.OptionValueSource>(program.getOptionValueSource('example'));
expectType<commander.OptionValueSource | undefined>(program.getOptionValueSource('example'));

// combineFlagAndOptionalValue
expectType<commander.Command>(program.combineFlagAndOptionalValue());
Expand Down

0 comments on commit c2c90ba

Please sign in to comment.