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 a08a768
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 14 deletions.
27 changes: 16 additions & 11 deletions lib/command.js
Expand Up @@ -57,13 +57,13 @@ 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._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 +421,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
return this;
}

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

/**
* Register callback to use as replacement for calling process.exit.
*
Expand Down Expand Up @@ -802,7 +809,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 +1620,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 a08a768

Please sign in to comment.