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

added addArguments method #1467

Merged
merged 10 commits into from
Mar 27, 2021
24 changes: 24 additions & 0 deletions examples/advanced-argument.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env node

// This example shows specifying the arguments using addArgument() function.

// const { Command } = require('commander'); // (normal include)
const { Command, Argument } = require('../'); // include commander in git clone of commander repo
const program = new Command();

program
.version('0.1.0')
.addArgument(new Argument('<username>', 'user to login'))
.addArgument(new Argument('[password]', 'password'))
.description('test command')
.action((username, password) => {
console.log('username:', username);
console.log('environment:', password || 'no password given');
});

program.parse();

// Try the following:
// node arguments.js --help
// node arguments.js user
// node arguments.js user secret
92 changes: 66 additions & 26 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,20 @@ class Help {
}
}

class Argument {
/**
* Initialize a new argument with description.
*
* @param {string} arg
* @param {object} [description]
*/

constructor(arg, description) {
this.argDetails = parseArg(arg);
shadowspawn marked this conversation as resolved.
Show resolved Hide resolved
this.description = description || '';
}
}

class Option {
/**
* Initialize a new `Option` with the given `flags` and `description`.
Expand Down Expand Up @@ -755,6 +769,20 @@ class Command extends EventEmitter {
return this._parseExpectedArgs(desc.split(/ +/));
};

/**
* Define argument syntax for the command.
* @param {Argument} argument
*/
addArgument(argument) {
this._args.push(argument.argDetails);
shadowspawn marked this conversation as resolved.
Show resolved Hide resolved
if (!this._argsDescription) {
this._argsDescription = {};
}
this._argsDescription[argument.argDetails.name] = argument.description;
shadowspawn marked this conversation as resolved.
Show resolved Hide resolved
this._validateArgs();
return this;
}

/**
* Override default decision whether to add implicit help command.
*
Expand Down Expand Up @@ -804,37 +832,20 @@ class Command extends EventEmitter {
_parseExpectedArgs(args) {
if (!args.length) return;
args.forEach((arg) => {
const argDetails = {
required: false,
name: '',
variadic: false
};

switch (arg[0]) {
case '<':
argDetails.required = true;
argDetails.name = arg.slice(1, -1);
break;
case '[':
argDetails.name = arg.slice(1, -1);
break;
}

if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') {
argDetails.variadic = true;
argDetails.name = argDetails.name.slice(0, -3);
}
if (argDetails.name) {
this._args.push(argDetails);
}
const argDetails = parseArg(arg);
argDetails && this._args.push(argDetails);
shadowspawn marked this conversation as resolved.
Show resolved Hide resolved
});
this._validateArgs();
return this;
};

_validateArgs() {
shadowspawn marked this conversation as resolved.
Show resolved Hide resolved
this._args.forEach((arg, i) => {
if (arg.variadic && i < this._args.length - 1) {
throw new Error(`only the last argument can be variadic '${arg.name}'`);
}
});
return this;
};
}

/**
* Register callback to use as replacement for calling process.exit.
Expand Down Expand Up @@ -1834,7 +1845,9 @@ class Command extends EventEmitter {
description(str, argsDescription) {
if (str === undefined && argsDescription === undefined) return this._description;
this._description = str;
this._argsDescription = argsDescription;
if (argsDescription) {
this._argsDescription = argsDescription;
}
return this;
};

Expand Down Expand Up @@ -2079,6 +2092,7 @@ exports.program = exports; // More explicit access to global command.

exports.Command = Command;
exports.Option = Option;
exports.Argument = Argument;
exports.CommanderError = CommanderError;
exports.InvalidOptionArgumentError = InvalidOptionArgumentError;
exports.Help = Help;
Expand Down Expand Up @@ -2198,3 +2212,29 @@ function incrementNodeInspectorPort(args) {
return arg;
});
}

function parseArg(arg) {
shadowspawn marked this conversation as resolved.
Show resolved Hide resolved
const argDetails = {
required: false,
name: '',
variadic: false
};

switch (arg[0]) {
case '<':
argDetails.required = true;
argDetails.name = arg.slice(1, -1);
break;
case '[':
argDetails.name = arg.slice(1, -1);
break;
}

if (argDetails.name.length > 3 && argDetails.name.slice(-3) === '...') {
argDetails.variadic = true;
argDetails.name = argDetails.name.slice(0, -3);
}
if (argDetails.name) {
return argDetails;
}
}