Comparing version 2.0.0 to 2.0.1
@@ -0,1 +1,5 @@ | ||
## 2.0.1 (December 16, 2019) | ||
- Fixed multiline description output in help | ||
## 2.0.0 (December 8, 2019) | ||
@@ -2,0 +6,0 @@ |
242
lib/help.js
@@ -1,21 +0,10 @@ | ||
var MAX_LINE_WIDTH = process.stdout.columns || 200; | ||
var MIN_OFFSET = 25; | ||
var reAstral = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; | ||
var ansiRegex = /\x1B\[([0-9]{1,3}(;[0-9]{1,3})*)?[m|K]/g; | ||
var chalk; | ||
const MAX_LINE_WIDTH = process.stdout.columns || 200; | ||
const MIN_OFFSET = 25; | ||
const reAstral = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; | ||
const ansiRegex = /\x1B\[([0-9]{1,3}(;[0-9]{1,3})*)?[m|K]/g; | ||
let chalk; | ||
function stringLength(str) { | ||
return str | ||
.replace(ansiRegex, '') | ||
.replace(reAstral, ' ') | ||
.length; | ||
} | ||
function pad(width, str) { | ||
return str + Array(Math.max(0, width - stringLength(str)) + 1).join(' '); | ||
} | ||
function getChalk() { | ||
function initChalk() { | ||
if (!chalk) { | ||
var ChalkInstance = require('chalk').Instance; | ||
const ChalkInstance = require('chalk').Instance; | ||
@@ -30,114 +19,122 @@ chalk = new ChalkInstance({ | ||
/** | ||
* Return program help documentation. | ||
* | ||
* @return {String} | ||
* @api private | ||
*/ | ||
function stringLength(str) { | ||
return str | ||
.replace(ansiRegex, '') | ||
.replace(reAstral, ' ') | ||
.length; | ||
} | ||
module.exports = function showCommandHelp(command, commandPath) { | ||
function breakByLines(str, offset) { | ||
var words = str.split(' '); | ||
var maxWidth = MAX_LINE_WIDTH - offset || 0; | ||
var lines = []; | ||
var line = ''; | ||
function pad(width, str) { | ||
// str.padEnd(width + str.length - stringLength(str)) | ||
return str + ' '.repeat(width - stringLength(str)); | ||
} | ||
while (words.length) { | ||
var word = words.shift(); | ||
if (!line || (line.length + word.length + 1) < maxWidth) { | ||
line += (line ? ' ' : '') + word; | ||
} else { | ||
lines.push(line); | ||
words.unshift(word); | ||
line = ''; | ||
} | ||
} | ||
function breakByLines(str, offset) { | ||
const words = str.split(' '); | ||
const maxWidth = MAX_LINE_WIDTH - offset || 0; | ||
const lines = []; | ||
let line = ''; | ||
lines.push(line); | ||
while (words.length) { | ||
const word = words.shift(); | ||
return lines.map(function(line, idx) { | ||
return (idx && offset ? pad(offset, '') : '') + line; | ||
}).join('\n'); | ||
if (!line || (line.length + word.length + 1) < maxWidth) { | ||
line += (line ? ' ' : '') + word; | ||
} else { | ||
lines.push(line); | ||
words.unshift(word); | ||
line = ''; | ||
} | ||
} | ||
function args(command) { | ||
return command.params.args.map(function(arg) { | ||
return arg.required | ||
? '<' + arg.name + '>' | ||
: '[' + arg.name + ']'; | ||
}).join(' '); | ||
} | ||
lines.push(line); | ||
function commandsHelp() { | ||
if (!command.hasCommands()) { | ||
return ''; | ||
} | ||
return lines | ||
.map((line, idx) => (idx && offset ? pad(offset, '') : '') + line) | ||
.join('\n'); | ||
} | ||
var maxNameLength = MIN_OFFSET - 2; | ||
var lines = Object.keys(command.commands).sort().map(function(name) { | ||
var subcommand = command.commands[name]; | ||
function args(command) { | ||
return command.params.args | ||
.map(({ name, required }) => required ? '<' + name + '>' : '[' + name + ']') | ||
.join(' '); | ||
} | ||
var line = { | ||
name: chalk.green(name) + chalk.gray( | ||
(subcommand.params ? ' ' + args(subcommand) : '') | ||
// (subcommand.hasOptions() ? ' [options]' : '') | ||
), | ||
description: subcommand.description_ || '' | ||
}; | ||
function valuesSortedByKey(dict) { | ||
return Object.keys(dict) | ||
.sort() | ||
.map(key => dict[key]); | ||
} | ||
maxNameLength = Math.max(maxNameLength, stringLength(line.name)); | ||
function commandsHelp(command) { | ||
if (!command.hasCommands()) { | ||
return ''; | ||
} | ||
return line; | ||
}); | ||
const lines = valuesSortedByKey(command.commands).map(subcommand => ({ | ||
name: chalk.green(subcommand.name) + chalk.gray( | ||
(subcommand.params ? ' ' + args(subcommand) : '') | ||
), | ||
description: subcommand.description_ || '' | ||
})); | ||
const maxNameLength = lines.reduce( | ||
(max, line) => Math.max(max, stringLength(line.name)), | ||
MIN_OFFSET - 2 | ||
); | ||
return [ | ||
'', | ||
'Commands:', | ||
'', | ||
lines.map(function(line) { | ||
return ' ' + pad(maxNameLength, line.name) + ' ' + breakByLines(line.description, maxNameLength + 4); | ||
}).join('\n'), | ||
'' | ||
].join('\n'); | ||
return [ | ||
'', | ||
'Commands:', | ||
'', | ||
...lines.map(line => ( | ||
' ' + pad(maxNameLength, line.name) + | ||
' ' + breakByLines(line.description, maxNameLength + 8) | ||
)), | ||
'' | ||
].join('\n'); | ||
} | ||
function optionsHelp(command) { | ||
if (!command.hasOptions()) { | ||
return ''; | ||
} | ||
function optionsHelp() { | ||
if (!command.hasOptions()) { | ||
return ''; | ||
} | ||
const hasShortOptions = Object.keys(command.short).length > 0; | ||
const lines = valuesSortedByKey(command.long).map(option => ({ | ||
name: option.usage | ||
.replace(/^(?:-., |)/, (m) => | ||
m || (hasShortOptions ? ' ' : '') | ||
) | ||
.replace(/(^|\s)(-[^\s,]+)/ig, (m, p, flag) => | ||
p + chalk.yellow(flag) | ||
), | ||
description: option.description | ||
})); | ||
const maxNameLength = lines.reduce( | ||
(max, line) => Math.max(max, stringLength(line.name)), | ||
MIN_OFFSET - 2 | ||
); | ||
var hasShortOptions = Object.keys(command.short).length > 0; | ||
var maxNameLength = MIN_OFFSET - 2; | ||
var lines = Object.keys(command.long).sort().map(function(name) { | ||
var option = command.long[name]; | ||
var line = { | ||
name: option.usage | ||
.replace(/^(?:-., |)/, function(m) { | ||
return m || (hasShortOptions ? ' ' : ''); | ||
}) | ||
.replace(/(^|\s)(-[^\s,]+)/ig, function(m, p, flag) { | ||
return p + chalk.yellow(flag); | ||
}), | ||
description: option.description | ||
}; | ||
// Prepend the help information | ||
return [ | ||
'', | ||
'Options:', | ||
'', | ||
...lines.map(line => ( | ||
' ' + pad(maxNameLength, line.name) + | ||
' ' + breakByLines(line.description, maxNameLength + 8) | ||
)), | ||
'' | ||
].join('\n'); | ||
} | ||
maxNameLength = Math.max(maxNameLength, stringLength(line.name)); | ||
/** | ||
* Return program help documentation. | ||
* | ||
* @return {String} | ||
* @api private | ||
*/ | ||
module.exports = function showCommandHelp(command, commandPath) { | ||
initChalk(); | ||
return line; | ||
}); | ||
// Prepend the help information | ||
return [ | ||
'', | ||
'Options:', | ||
'', | ||
lines.map(function(line) { | ||
return ' ' + pad(maxNameLength, line.name) + ' ' + breakByLines(line.description, maxNameLength + 4); | ||
}).join('\n'), | ||
'' | ||
].join('\n'); | ||
} | ||
var chalk = getChalk(); | ||
var output = []; | ||
commandPath = Array.isArray(commandPath) && commandPath.length | ||
@@ -147,19 +144,14 @@ ? commandPath.concat(command.name).join(' ') | ||
if (command.description_) { | ||
output.push(command.description_ + '\n'); | ||
} | ||
output.push( | ||
'Usage:\n\n ' + | ||
chalk.cyan(commandPath) + | ||
return [ | ||
(command.description_ ? command.description_ + '\n\n' : '') + | ||
'Usage:\n\n' + | ||
' ' + chalk.cyan(commandPath) + | ||
(command.params ? ' ' + chalk.magenta(args(command)) : '') + | ||
(command.hasOptions() ? ' [' + chalk.yellow('options') + ']' : '') + | ||
(command.hasCommands() ? ' [' + chalk.green('command') + ']' : ''), | ||
commandsHelp() + | ||
optionsHelp() | ||
); | ||
return output.join('\n'); | ||
commandsHelp(command) + | ||
optionsHelp(command) | ||
].join('\n'); | ||
}; | ||
module.exports.color = true; |
@@ -8,3 +8,3 @@ { | ||
"license": "MIT", | ||
"version": "2.0.0", | ||
"version": "2.0.1", | ||
"keywords": [ | ||
@@ -11,0 +11,0 @@ "cli", |
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
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
0
29430
732