Commit d0b894eb authored by Jérémy Lal's avatar Jérémy Lal

New upstream version 2.12.2

parent 40d3ff9f
2.12.2 / 2017-11-28
==================
* fix: typings are not shipped
2.12.1 / 2017-11-23
==================
* Move @types/node to dev dependency
2.12.0 / 2017-11-22
==================
* add attributeName() method to Option objects
* Documentation updated for options with --no prefix
* typings: `outputHelp` takes a string as the first parameter
* typings: use overloads
* feat(typings): update to match js api
* Print default value in option help
* Fix translation error
* Fail when using same command and alias (#491)
* feat(typings): add help callback
* fix bug when description is add after command with options (#662)
* Format js code
* Rename History.md to CHANGELOG.md (#668)
* feat(typings): add typings to support TypeScript (#646)
* use current node
2.11.0 / 2017-07-03
==================
......
......@@ -44,6 +44,25 @@ console.log(' - %s cheese', program.cheese);
Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc.
Note that multi-word options starting with `--no` prefix negate the boolean value of the following word. For example, `--no-sauce` sets the value of `program.sauce` to false.
```js
#!/usr/bin/env node
/**
* Module dependencies.
*/
var program = require('commander');
program
.option('--no-sauce', 'Remove sauce')
.parse(process.argv);
console.log('you ordered a pizza');
if (program.sauce) console.log(' with sauce');
else console.log(' without sauce');
```
## Coercion
......@@ -285,9 +304,9 @@ program
.command('getstream [url]', 'get stream URL')
.parse(process.argv);
if (!process.argv.slice(2).length) {
program.outputHelp(make_red);
}
if (!process.argv.slice(2).length) {
program.outputHelp(make_red);
}
function make_red(txt) {
return colors.red(txt); //display the help text in red on the console
......
......@@ -15,7 +15,7 @@
$ npm install commander
## 参数解析
`.option()` 方法用来定义带选项的 commander,同时也作为这些选项的文档。下面的例子会解析来自 `progress.argv` 指定的参数和选项,没有匹配任何选项的参数将会放到 `program.args` 数组中。
`.option()` 方法用来定义带选项的 commander,同时也作为这些选项的文档。下面的例子会解析来自 `process.argv` 指定的参数和选项,没有匹配任何选项的参数将会放到 `program.args` 数组中。
```js
#!/usr/bin/env node
......
......@@ -59,6 +59,18 @@ Option.prototype.name = function() {
.replace('no-', '');
};
/**
* Return option name, in a camelcase format that can be used
* as a object attribute key.
*
* @return {String}
* @api private
*/
Option.prototype.attributeName = function() {
return camelcase( this.name() );
};
/**
* Check if `arg` matches the short or long flag.
*
......@@ -155,6 +167,10 @@ Command.prototype.__proto__ = EventEmitter.prototype;
*/
Command.prototype.command = function(name, desc, opts) {
if(typeof desc === 'object' && desc !== null){
opts = desc;
desc = null;
}
opts = opts || {};
var args = name.split(/ +/);
var cmd = new Command(args.shift());
......@@ -165,7 +181,6 @@ Command.prototype.command = function(name, desc, opts) {
this._execs[cmd._name] = true;
if (opts.isDefault) this.defaultExecutable = cmd._name;
}
cmd._noHelp = !!opts.noHelp;
this.commands.push(cmd);
cmd.parseExpectedArgs(args);
......@@ -359,7 +374,7 @@ Command.prototype.option = function(flags, description, fn, defaultValue) {
var self = this
, option = new Option(flags, description)
, oname = option.name()
, name = camelcase(oname);
, name = option.attributeName();
// default as 3rd arg
if (typeof fn != 'function') {
......@@ -381,7 +396,10 @@ Command.prototype.option = function(flags, description, fn, defaultValue) {
// when --no-* we make sure default is true
if (false == option.bool) defaultValue = true;
// preassign only if we have a default
if (undefined !== defaultValue) self[name] = defaultValue;
if (undefined !== defaultValue) {
self[name] = defaultValue;
option.defaultValue = defaultValue;
}
}
// register the option
......@@ -541,7 +559,7 @@ Command.prototype.executeSubCommand = function(argv, args, unknown) {
// add executable arguments to spawn
args = (process.execArgv || []).concat(args);
proc = spawn('node', args, { stdio: 'inherit', customFds: [0, 1, 2] });
proc = spawn(process.argv[0], args, { stdio: 'inherit', customFds: [0, 1, 2] });
} else {
proc = spawn(bin, args, { stdio: 'inherit', customFds: [0, 1, 2] });
}
......@@ -755,7 +773,7 @@ Command.prototype.opts = function() {
, len = this.options.length;
for (var i = 0 ; i < len; i++) {
var key = camelcase(this.options[i].name());
var key = this.options[i].attributeName();
result[key] = key === 'version' ? this._version : this[key];
}
return result;
......@@ -877,6 +895,8 @@ Command.prototype.alias = function(alias) {
if (arguments.length === 0) return command._alias;
if (alias === command._name) throw new Error('Command alias can\'t be the same as its name');
command._alias = alias;
return this;
};
......@@ -943,8 +963,9 @@ Command.prototype.optionHelp = function() {
// Append the help information
return this.options.map(function(option) {
return pad(option.flags, width) + ' ' + option.description;
}).concat([pad('-h, --help', width) + ' ' + 'output usage information'])
return pad(option.flags, width) + ' ' + option.description
+ (option.defaultValue !== undefined ? ' (default: ' + option.defaultValue + ')' : '');
}).concat([pad('-h, --help', width) + ' ' + 'output usage information'])
.join('\n');
};
......
{
"name": "commander",
"version": "2.10.0",
"version": "2.12.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"diff": {
"version": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz",
"integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=",
"dev": true
},
"formatio": {
"version": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz",
"integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=",
"dev": true
},
"isarray": {
"version": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
},
"lolex": {
"version": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz",
"integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=",
"dev": true
},
"native-promise-only": {
"version": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz",
"integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=",
"dev": true
},
"path-to-regexp": {
"version": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
"dev": true
},
"samsam": {
"version": "https://registry.npmjs.org/samsam/-/samsam-1.2.1.tgz",
"integrity": "sha1-7dOQk6MYQ3DLhZJDsr3yVefY6mc=",
"@types/node": {
"version": "7.0.48",
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.48.tgz",
"integrity": "sha512-LLlXafM3BD52MH056tHxTXO8JFCnpJJQkdzIU3+m8ew+CXJY/5zIXgDNb4TK/QFvlI8QexLS5tL+sE0Qhegr1w==",
"dev": true
},
"should": {
......@@ -43,18 +15,32 @@
"resolved": "https://registry.npmjs.org/should/-/should-11.2.1.tgz",
"integrity": "sha1-kPVRRVUtAc/CAGZuToGKHJZw7aI=",
"dev": true,
"requires": {
"should-equal": "1.0.1",
"should-format": "3.0.3",
"should-type": "1.4.0",
"should-type-adaptors": "1.0.1",
"should-util": "1.0.0"
},
"dependencies": {
"should-equal": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/should-equal/-/should-equal-1.0.1.tgz",
"integrity": "sha1-C26VFvJgGp+wuy3MNpr6HH4gCvc=",
"dev": true
"dev": true,
"requires": {
"should-type": "1.4.0"
}
},
"should-format": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz",
"integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=",
"dev": true
"dev": true,
"requires": {
"should-type": "1.4.0",
"should-type-adaptors": "1.0.1"
}
},
"should-type": {
"version": "1.4.0",
......@@ -69,6 +55,10 @@
"resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.0.1.tgz",
"integrity": "sha1-7+VVPN9oz/ZuXF9RtxLcNRx3vqo=",
"dev": true,
"requires": {
"should-type": "1.4.0",
"should-util": "1.0.0"
},
"dependencies": {
"should-type": {
"version": "1.4.0",
......@@ -85,19 +75,87 @@
"dev": true
},
"sinon": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-2.3.5.tgz",
"integrity": "sha1-mi/A/41SbacW8wlTqixl1RiRf2w=",
"dev": true
},
"text-encoding": {
"version": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz",
"integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=",
"dev": true
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz",
"integrity": "sha512-vFTrO9Wt0ECffDYIPSP/E5bBugt0UjcBQOfQUMh66xzkyPEnhl/vM2LRZi2ajuTdkH07sA6DzrM6KvdvGIH8xw==",
"dev": true,
"requires": {
"diff": "3.4.0",
"formatio": "1.2.0",
"lolex": "1.6.0",
"native-promise-only": "0.8.1",
"path-to-regexp": "1.7.0",
"samsam": "1.3.0",
"text-encoding": "0.6.4",
"type-detect": "4.0.5"
},
"dependencies": {
"diff": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz",
"integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==",
"dev": true
},
"formatio": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz",
"integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=",
"dev": true,
"requires": {
"samsam": "1.3.0"
}
},
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
},
"lolex": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz",
"integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=",
"dev": true
},
"native-promise-only": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz",
"integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=",
"dev": true
},
"path-to-regexp": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
"integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
"dev": true,
"requires": {
"isarray": "0.0.1"
}
},
"samsam": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz",
"integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==",
"dev": true
},
"text-encoding": {
"version": "0.6.4",
"resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz",
"integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=",
"dev": true
},
"type-detect": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz",
"integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==",
"dev": true
}
}
},
"type-detect": {
"version": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.0.tgz",
"integrity": "sha1-YgU4g1QqMh8veyV0bcaWR4sY/2s=",
"typescript": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz",
"integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=",
"dev": true
}
}
......
{
"name": "commander",
"version": "2.11.0",
"version": "2.12.2",
"description": "the complete solution for node.js command-line programs",
"keywords": [
"commander",
......@@ -14,16 +14,21 @@
"type": "git",
"url": "https://github.com/tj/commander.js.git"
},
"devDependencies": {
"should": "^11.2.1",
"sinon": "^2.3.5"
},
"scripts": {
"test": "make test"
"test": "make test && npm run test-typings",
"test-typings": "node_modules/typescript/bin/tsc -p tsconfig.json"
},
"main": "index",
"files": [
"index.js"
"index.js",
"typings/index.d.ts"
],
"dependencies": {}
"dependencies": {},
"devDependencies": {
"@types/node": "^7.0.48",
"should": "^11.2.1",
"sinon": "^2.4.1",
"typescript": "^2.6.2"
},
"typings": "typings/index.d.ts"
}
var program = require('../')
, should = require('should');
var error;
try {
program
.command('fail')
.alias('fail');
} catch (e) {
error = e;
}
error.should.deepEqual(new Error('Command alias can\'t be the same as its name'));
......@@ -17,19 +17,25 @@ program
.command('hideagain [options]', null, { noHelp: true })
.action(function() { return; });
program.command('hiddencommandwithoutdescription [options]', { noHelp: true });
program.parse(['node', 'test']);
program.name.should.be.a.Function;
program.name.should.be.a.Function();
program.name().should.equal('test');
program.commands[0].name().should.equal('mycommand');
program.commands[0]._noHelp.should.be.false();
program.commands[1].name().should.equal('anothercommand');
program.commands[1]._noHelp.should.be.false();
program.commands[2].name().should.equal('hiddencommand');
program.commands[2]._noHelp.should.be.true;
program.commands[2]._noHelp.should.be.true();
program.commands[3].name().should.equal('hideagain');
program.commands[3]._noHelp.should.be.true();
program.commands[4].name().should.equal('help');
program.commands[4].name().should.equal('hiddencommandwithoutdescription');
program.commands[4]._noHelp.should.be.true();
program.commands[5].name().should.equal('help');
sinon.restore();
sinon.stub(process.stdout, 'write');
......
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": false,
"types": [
"node"
],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"typings/index.d.ts",
"typings/commander-tests.ts"
]
}
\ No newline at end of file
import * as program from './index';
interface ExtendedOptions extends program.CommandOptions {
isNew: any;
}
const commandInstance = new program.Command('-f');
const optionsInstance = new program.Option('-f');
const name = program.name();
program
.name('set name')
.version('0.0.1')
.option('-p, --peppers', 'Add peppers')
.option('-P, --pineapple', 'Add pineapple')
.option('-b, --bbq', 'Add bbq sauce')
.option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
.parse(process.argv);
console.log('you ordered a pizza with:');
if (program['peppers']) console.log(' - peppers');
if (program['pineapple']) console.log(' - pineapple');
if (program['bbq']) console.log(' - bbq');
console.log(' - %s cheese', program['cheese']);
function range(val: string) {
return val.split('..').map(Number);
}
function list(val: string) {
return val.split(',');
}
function collect(val: string, memo: string[]) {
memo.push(val);
return memo;
}
function increaseVerbosity(v: any, total: number) {
return total + 1;
}
program
.version('0.0.1')
.usage('[options] <file ...>')
.option('-i, --integer <n>', 'An integer argument', parseInt)
.option('-f, --float <n>', 'A float argument', parseFloat)
.option('-r, --range <a>..<b>', 'A range', range)
.option('-l, --list <items>', 'A list', list)
.option('-o, --optional [value]', 'An optional value')
.option('-c, --collect [value]', 'A repeatable value', collect, [])
.option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
.parse(process.argv);
console.log(' int: %j', program['integer']);
console.log(' float: %j', program['float']);
console.log(' optional: %j', program['optional']);
program['range'] = program['range'] || [];
console.log(' range: %j..%j', program['range'][0], program['range'][1]);
console.log(' list: %j', program['list']);
console.log(' collect: %j', program['collect']);
console.log(' verbosity: %j', program['verbose']);
console.log(' args: %j', program['args']);
program
.version('0.0.1')
.option('-f, --foo', 'enable some foo')
.option('-b, --bar', 'enable some bar')
.option('-B, --baz', 'enable some baz');
// must be before .parse() since
// node's emit() is immediate
program.on('--help', () => {
console.log(' Examples:');
console.log('');
console.log(' $ custom-help --help');
console.log(' $ custom-help -h');
console.log('');
});
program
.command('allow-unknown-option')
.allowUnknownOption()
.action(() => {
console.log('unknown option is allowed');
});
program
.version('0.0.1')
.arguments('<cmd> [env]')
.action((cmd, env) => {
console.log(cmd, env);
});
program.parse(process.argv);
console.log('stuff');
\ No newline at end of file
// Project: https://github.com/visionmedia/commander.js
// Definitions by: Alan Agius <https://github.com/alan-agius4>, Marcelo Dezem <https://github.com/mdezem>, vvakame <https://github.com/vvakame>
declare class Option {
flags: string;
required: boolean;
optional: boolean;
bool: boolean;
short?: string;
long: string;
description: string;
/**
* Initialize a new `Option` with the given `flags` and `description`.
*
* @param {string} flags
* @param {string} [description]
*/
constructor(flags: string, description?: string);
}
declare class Command extends NodeJS.EventEmitter {
[key: string]: any;
args: string[];
/**
* Initialize a new `Command`.
*
* @param {string} [name]
*/
constructor(name?: string);
/**
* Set the program version to `str`.
*
* This method auto-registers the "-V, --version" flag
* which will print the version number when passed.
*
* @param {string} str
* @param {string} [flags]
* @returns {Command} for chaining
*/
version(str: string, flags?: string): Command;
/**
* Add command `name`.
*
* The `.action()` callback is invoked when the
* command `name` is specified via __ARGV__,
* and the remaining arguments are applied to the
* function for access.
*
* When the `name` is "*" an un-matched command
* will be passed as the first arg, followed by
* the rest of __ARGV__ remaining.
*
* @example
* program
* .version('0.0.1')
* .option('-C, --chdir <path>', 'change the working directory')
* .option('-c, --config <path>', 'set config path. defaults to ./deploy.conf')
* .option('-T, --no-tests', 'ignore test hook')
*
* program
* .command('setup')
* .description('run remote setup commands')
* .action(function() {
* console.log('setup');
* });
*
* program
* .command('exec <cmd>')
* .description('run the given remote command')
* .action(function(cmd) {
* console.log('exec "%s"', cmd);
* });
*
* program
* .command('teardown <dir> [otherDirs...]')
* .description('run teardown commands')
* .action(function(dir, otherDirs) {
* console.log('dir "%s"', dir);
* if (otherDirs) {
* otherDirs.forEach(function (oDir) {
* console.log('dir "%s"', oDir);
* });
* }
* });
*
* program
* .command('*')
* .description('deploy the given env')
* .action(function(env) {
* console.log('deploying "%s"', env);
* });
*
* program.parse(process.argv);
*
* @param {string} name
* @param {string} [desc] for git-style sub-commands
* @param {CommandOptions} [opts] command options
* @returns {Command} the new command
*/
command(name: string, desc?: string, opts?: commander.CommandOptions): Command;
/**
* Define argument syntax for the top-level command.
*
* @param {string} desc
* @returns {Command} for chaining
*/
arguments(desc: string): Command;
/**
* Parse expected `args`.
*
* For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`.
*
* @param {string[]} args
* @returns {Command} for chaining
*/
parseExpectedArgs(args: string[]): Command;
/**
* Register callback `fn` for the command.
*
* @example
* program
* .command('help')
* .description('display verbose help')
* .action(function() {
* // output help here
* });
*
* @param {(...args: any[]) => void} fn
* @returns {Command} for chaining
*/
action(fn: (...args: any[]) => void): Command;
/**
* Define option with `flags`, `description` and optional
* coercion `fn`.
*
* The `flags` string should contain both the short and long flags,
* separated by comma, a pipe or space. The following are all valid
* all will output this way when `--help` is used.
*
* "-p, --pepper"
* "-p|--pepper"
* "-p --pepper"
*
* @example
* // simple boolean defaulting to false
* program.option('-p, --pepper', 'add pepper');
*
* --pepper
* program.pepper
* // => Boolean
*
* // simple boolean defaulting to true
* program.option('-C, --no-cheese', 'remove cheese');
*
* program.cheese
* // => true
*
* --no-cheese