Comparing version 1.11.0 to 1.12.0
@@ -7,6 +7,7 @@ /** | ||
var p = console.log; | ||
var assert = require('assert-plus'); | ||
var format = require('util').format; | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var assert = require('assert-plus'); | ||
@@ -24,2 +25,9 @@ var DEBUG = true; | ||
// Replace {{variable}} in `s` with the template data in `d`. | ||
function renderTemplate(s, d) { | ||
return s.replace(/{{([a-zA-Z]+)}}/g, function (match, key) { | ||
return d.hasOwnProperty(key) ? d[key] : match; | ||
}); | ||
} | ||
/** | ||
@@ -739,3 +747,133 @@ * Return a shallow copy of the given object; | ||
/** | ||
* Return a string suitable for a Bash completion file for this tool. | ||
* | ||
* @param args.name {String} The tool name. | ||
* @param args.specExtra {String} Optional. Extra Bash code content to add | ||
* to the end of the "spec". Typically this is used to append Bash | ||
* "complete_TYPE" functions for custom option types. See | ||
* "examples/ddcompletion.js" for an example. | ||
*/ | ||
Parser.prototype.bashCompletion = function bashCompletion(args) { | ||
assert.object(args, 'args'); | ||
assert.string(args.name, 'args.name'); | ||
assert.optionalString(args.specExtra, 'args.specExtra'); | ||
return bashCompletionFromOptions({ | ||
name: args.name, | ||
specExtra: args.specExtra, | ||
options: this.options | ||
}); | ||
}; | ||
// ---- Bash completion | ||
const BASH_COMPLETION_TEMPLATE_PATH = path.join( | ||
__dirname, '../etc/dashdash.bash_completion.in'); | ||
/** | ||
* Return the Bash completion "spec" (the string value for the "{{spec}}" | ||
* var in the "dashdash.bash_completion.in" template) for this tool. | ||
* | ||
* The "spec" is Bash code that defines the CLI options and subcmds for | ||
* the template's completion code. It looks something like this: | ||
* | ||
* local cmd_shortopts="-J ..." | ||
* local cmd_longopts="--help ..." | ||
* local cmd_optargs="-p=tritonprofile ..." | ||
* | ||
* @param args.options {Array} The array of dashdash option specs. | ||
* @param args.context {String} Optional. A context string for the "local cmd*" | ||
* vars in the spec. By default it is the empty string. When used to | ||
* scope for completion on a *sub-command* (e.g. for "git log" on a "git" | ||
* tool), then it would have a value (e.g. "__log"). See | ||
* <http://github.com/trentm/node-cmdln> Bash completion for details. | ||
*/ | ||
function bashCompletionSpecFromOptions(args) { | ||
assert.object(args, 'args'); | ||
assert.object(args.options, 'args.options'); | ||
assert.optionalString(args.context, 'args.context'); | ||
var context = args.context || ''; | ||
var spec = []; | ||
var shortopts = []; | ||
var longopts = []; | ||
var optargs = []; | ||
(args.options || []).forEach(function (o) { | ||
if (o.group) { | ||
// Skip group headers. | ||
return; | ||
} | ||
var optNames = o.names || [o.name]; | ||
var optType = getOptionType(o.type); | ||
if (optType.takesArg) { | ||
var completionType = o.completionType || | ||
optType.completionType || o.type; | ||
optNames.forEach(function (optName) { | ||
if (optName.length === 1) { | ||
shortopts.push('-' + optName); | ||
optargs.push('-' + optName + '=' + completionType); | ||
} else { | ||
longopts.push('--' + optName); | ||
optargs.push('--' + optName + '=' + completionType); | ||
} | ||
}); | ||
} else { | ||
optNames.forEach(function (optName) { | ||
if (optName.length === 1) { | ||
shortopts.push('-' + optName); | ||
} else { | ||
longopts.push('--' + optName); | ||
} | ||
}); | ||
} | ||
}); | ||
spec.push(format('local cmd%s_shortopts="%s"', | ||
context, shortopts.sort().join(' '))); | ||
spec.push(format('local cmd%s_longopts="%s"', | ||
context, longopts.sort().join(' '))); | ||
spec.push(format('local cmd%s_optargs="%s"', | ||
context, optargs.sort().join(' '))); | ||
return spec.join('\n'); | ||
} | ||
/** | ||
* Return a string suitable for a Bash completion file for this tool. | ||
* | ||
* @param args.name {String} The tool name. | ||
* @param args.options {Array} The array of dashdash option specs. | ||
* @param args.specExtra {String} Optional. Extra Bash code content to add | ||
* to the end of the "spec". Typically this is used to append Bash | ||
* "complete_TYPE" functions for custom option types. See | ||
* "examples/ddcompletion.js" for an example. | ||
*/ | ||
function bashCompletionFromOptions(args) { | ||
assert.object(args, 'args'); | ||
assert.object(args.options, 'args.options'); | ||
assert.string(args.name, 'args.name'); | ||
assert.optionalString(args.specExtra, 'args.specExtra'); | ||
// Gather template data. | ||
var data = { | ||
name: args.name, | ||
date: new Date(), | ||
spec: bashCompletionSpecFromOptions({options: args.options}) | ||
}; | ||
if (args.specExtra) { | ||
data.spec += '\n\n' + args.specExtra; | ||
} | ||
// Render template. | ||
var template = fs.readFileSync(BASH_COMPLETION_TEMPLATE_PATH, 'utf8'); | ||
return renderTemplate(template, data); | ||
} | ||
// ---- exports | ||
@@ -811,2 +949,8 @@ | ||
function getOptionType(name) { | ||
assert.string(name, 'name'); | ||
return optionTypes[name]; | ||
} | ||
module.exports = { | ||
@@ -817,3 +961,9 @@ createParser: createParser, | ||
addOptionType: addOptionType, | ||
getOptionType: getOptionType, | ||
// Bash completion-related exports | ||
BASH_COMPLETION_TEMPLATE_PATH: BASH_COMPLETION_TEMPLATE_PATH, | ||
bashCompletionFromOptions: bashCompletionFromOptions, | ||
bashCompletionSpecFromOptions: bashCompletionSpecFromOptions, | ||
// Export the parseFoo parsers because they might be useful as primitives | ||
@@ -820,0 +970,0 @@ // for custom option types. |
{ | ||
"name": "dashdash", | ||
"description": "A light, featureful and explicit option parsing library.", | ||
"version": "1.11.0", | ||
"version": "1.12.0", | ||
"author": "Trent Mick <trentm@gmail.com> (http://trentm.com)", | ||
"keywords": ["option", "parser", "parsing", "cli", "command", "args"], | ||
"keywords": ["option", "parser", "parsing", "cli", "command", "args", | ||
"bash", "completion"], | ||
"repository": { | ||
@@ -8,0 +9,0 @@ "type": "git", |
@@ -235,2 +235,43 @@ A light, featureful and explicit option parsing library for node.js. | ||
# Bash completion | ||
Dashdash provides a simple way to create a Bash completion file that you | ||
can place in your "bash_completion.d" directory -- sometimes that is | ||
"/usr/local/etc/bash_completion.d/"). Features: | ||
- Support for short and long opts | ||
- Support for knowing which options take arguments | ||
- Support for subcommands (e.g. 'git log <TAB>' to show just options for the | ||
log subcommand). See | ||
[node-cmdln](https://github.com/trentm/node-cmdln#bash-completion) for | ||
how to integrate that. | ||
- Does the right thing with "--" to stop options. | ||
- Custom optarg and arg types for custom completions. | ||
Dashdash will return bash completion file content given a parser instance: | ||
var parser = dashdash.createParser({options: options}); | ||
console.log( parser.bashCompletion({name: 'mycli'}) ); | ||
or directly from a `options` array of options specs: | ||
var code = dashdash.bashCompletionFromOptions({ | ||
name: 'mycli', | ||
options: OPTIONS | ||
}); | ||
Write that content to "/usr/local/etc/bash_completion.d/mycli" and you will | ||
have Bash completions for `mycli`. Alternatively you can write it to | ||
any file (e.g. "~/.bashrc") and source it. | ||
You could add a `--completion` hidden option to your tool that emits the | ||
completion content and document for your users to call that to install | ||
Bash completions. | ||
See [examples/ddcompletion.js](examples/ddcompletion.js) for a complete | ||
example, including how one can define bash functions for completion of custom | ||
option types. Also see [node-cmdln](https://github.com/trentm/node-cmdln) for | ||
how it uses this for Bash completion for full multi-subcommand tools. | ||
# Parser config | ||
@@ -237,0 +278,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
61865
4
880
553
2