Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for multiple aliases #1236

Merged
merged 5 commits into from Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 13 additions & 11 deletions index.js
Expand Up @@ -117,7 +117,7 @@ class Command extends EventEmitter {
this._executableFile = null; // custom name for executable
this._defaultCommandName = null;
this._exitCallback = null;
this._alias = null;
this._alias = [];

this._hidden = false;
this._helpFlags = '-h, --help';
Expand Down Expand Up @@ -937,7 +937,7 @@ class Command extends EventEmitter {
*/
_findCommand(name) {
if (!name) return undefined;
return this.commands.find(cmd => cmd._name === name || cmd._alias === name);
return this.commands.find(cmd => cmd._name === name || cmd._alias.includes(name));
};

/**
Expand Down Expand Up @@ -1201,7 +1201,7 @@ class Command extends EventEmitter {
*
* @param {string} str
* @param {Object} [argsDescription]
* @return {String|Command}
* @return {string|Command}
* @api public
*/

Expand All @@ -1213,10 +1213,12 @@ class Command extends EventEmitter {
};

/**
* Set an alias for the command
* Set an alias for the command.
*
* @param {string} alias
* @return {String|Command}
* You may call more than once to add multiple aliases, Only the first alias is shown in the auto-generated help.
*
* @param {string} [alias]
* @return {string|Command}
* @api public
*/

Expand All @@ -1226,11 +1228,11 @@ class Command extends EventEmitter {
command = this.commands[this.commands.length - 1];
}

if (arguments.length === 0) return command._alias;
if (arguments.length === 0) return command._alias[0]; // just return first, and return string not array for backwards compatibility

if (alias === command._name) throw new Error('Command alias can\'t be the same as its name');

shadowspawn marked this conversation as resolved.
Show resolved Hide resolved
command._alias = alias;
command._alias.push(alias);
return this;
};

Expand Down Expand Up @@ -1288,7 +1290,7 @@ class Command extends EventEmitter {

return [
cmd._name +
(cmd._alias ? '|' + cmd._alias : '') +
(cmd._alias[0] ? '|' + cmd._alias[0] : '') +
(cmd.options.length ? ' [options]' : '') +
(args ? ' ' + args : ''),
cmd._description
Expand Down Expand Up @@ -1448,8 +1450,8 @@ class Command extends EventEmitter {
}

let cmdName = this._name;
if (this._alias) {
cmdName = cmdName + '|' + this._alias;
if (this._alias[0]) {
cmdName = cmdName + '|' + this._alias[0];
}
let parentCmdNames = '';
for (let parentCmd = this.parent; parentCmd; parentCmd = parentCmd.parent) {
Expand Down
35 changes: 34 additions & 1 deletion tests/command.alias.test.js
Expand Up @@ -12,11 +12,44 @@ test('when command has alias then appears in help', () => {
expect(helpInformation).toMatch('info|i');
});

test('when command = alias then error', () => {
test('when command has more than one alias then only first appears in help', () => {
const program = new commander.Command();
program
.command('list [thing]')
.alias('ls')
.alias('dir');
const helpInformation = program.helpInformation();
expect(helpInformation).toMatch('list|ls ');
});

test('when command name = alias then error', () => {
const program = new commander.Command();
expect(() => {
program
.command('fail')
.alias('fail');
}).toThrow("Command alias can't be the same as its name");
});

test('when use alias then action handler called', () => {
const program = new commander.Command();
const actionMock = jest.fn();
program
.command('list')
.alias('ls')
.action(actionMock);
program.parse(['ls'], { from: 'user' });
expect(actionMock).toHaveBeenCalled();
});

test('when use second alias then action handler called', () => {
const program = new commander.Command();
const actionMock = jest.fn();
program
.command('list')
.alias('ls')
.alias('dir')
.action(actionMock);
program.parse(['dir'], { from: 'user' });
expect(actionMock).toHaveBeenCalled();
});
2 changes: 2 additions & 0 deletions typings/index.d.ts
Expand Up @@ -275,6 +275,8 @@ declare namespace commander {
/**
* Set an alias for the command.
*
* You may call more than once to add multiple aliases, Only the first alias is shown in the auto-generated help.
shadowspawn marked this conversation as resolved.
Show resolved Hide resolved
*
* @returns `this` command for chaining
*/
alias(alias: string): this;
Expand Down