Skip to content

Commit

Permalink
fix(usage): tie usage to config
Browse files Browse the repository at this point in the history
This starts us down the path of tying the params our commands accept to
their config items.  For now it is optional, and not every current
config item would cleanly render if we added them today.

The ones that are added here DO render nicely, and we can iterate from
here.  We can also at a later date do the same kind of appraoch with our
positional args.

PR-URL: #2908
Credit: @wraithgar
Close: #2908
Reviewed-by: @nlf, @isaacs
  • Loading branch information
wraithgar committed Mar 22, 2021
1 parent 629aaf3 commit b876442
Show file tree
Hide file tree
Showing 27 changed files with 297 additions and 45 deletions.
30 changes: 30 additions & 0 deletions docs/content/using-npm/config.md
Expand Up @@ -96,6 +96,8 @@ The following shorthands are parsed on the command-line:
* `-H`: `--usage`
* `--help`: `--usage`
* `-v`: `--version`
* `-w`: `--workspace`
* `--ws`: `--workspaces`
* `-y`: `--yes`

<!-- AUTOGENERATED CONFIG SHORTHANDS END -->
Expand Down Expand Up @@ -1311,6 +1313,34 @@ The program to use to view help content.

Set to `"browser"` to view html help content in the default web browser.

#### `which`

* Default: null
* Type: null or Number

If there are multiple funding sources, which 1-indexed source URL to open.

#### `workspace`

* Default:
* Type: String (can be set multiple times)

Enable running a command in the context of the configured workspaces of the
current project while filtering by running only the workspaces defined by
this configuration option.

Valid values for the `workspace` config are either: - Workspace names - Path
to a workspace directory - Path to a parent workspace directory (will result
to selecting all of the nested workspaces)

#### `workspaces`

* Default: false
* Type: Boolean

Enable running a command in the context of **all** the configured
workspaces.

#### `yes`

* Default: false
Expand Down
8 changes: 6 additions & 2 deletions lib/adduser.js
Expand Up @@ -17,8 +17,12 @@ class AddUser extends BaseCommand {
return 'adduser'
}

static get usage () {
return ['[--registry=url] [--scope=@orgname] [--always-auth]']
static get params () {
return [
'registry',
'scope',
'always-auth',
]
}

exec (args, cb) {
Expand Down
14 changes: 11 additions & 3 deletions lib/audit.js
Expand Up @@ -16,13 +16,21 @@ class Audit extends BaseCommand {
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
static get params () {
return [
'[--json] [--production]',
'fix [--force|--package-lock-only|--dry-run|--production|--only=(dev|prod)]',
'dry-run',
'force',
'json',
'package-lock-only',
'production',
]
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return ['[fix]']
}

async completion (opts) {
const argv = opts.conf.argv.remain

Expand Down
4 changes: 4 additions & 0 deletions lib/base-command.js
@@ -1,5 +1,6 @@
// Base class for npm.commands[cmd]
const usageUtil = require('./utils/usage.js')
const ConfigDefinitions = require('./utils/config/definitions.js')

class BaseCommand {
constructor (npm) {
Expand All @@ -25,6 +26,9 @@ class BaseCommand {
else
usage = `${usage}${this.constructor.usage.map(u => `npm ${this.constructor.name} ${u}`).join('\n')}`

if (this.constructor.params)
usage = `${usage}\n\nOptions:\n[${this.constructor.params.map(p => ConfigDefinitions[p].usage).join('] [')}]`

// Mostly this just appends aliases, this could be more clear
usage = usageUtil(this.constructor.name, usage)
usage = `${usage}\n\nRun "npm help ${this.constructor.name}" for more info`
Expand Down
4 changes: 2 additions & 2 deletions lib/bin.js
Expand Up @@ -10,8 +10,8 @@ class Bin extends BaseCommand {
return 'bin'
}

static get usage () {
return ['[-g]']
static get params () {
return ['global']
}

exec (args, cb) {
Expand Down
12 changes: 11 additions & 1 deletion lib/fund.js
Expand Up @@ -32,9 +32,19 @@ class Fund extends BaseCommand {
return 'fund'
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get params () {
return [
'json',
'browser',
'unicode',
'which',
]
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return ['[--json] [--browser] [--unicode] [[<@scope>/]<pkg> [--which=<fundingSourceNumber>]']
return ['[[<@scope>/]<pkg>]']
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
Expand Down
10 changes: 9 additions & 1 deletion lib/install.js
Expand Up @@ -21,6 +21,14 @@ class Install extends BaseCommand {
return 'install'
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get params () {
return [
'save',
'save-exact',
]
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return [
Expand All @@ -33,7 +41,7 @@ class Install extends BaseCommand {
'<tarball file>',
'<tarball url>',
'<git:// url>',
'<github username>/<github project> [--save-prod|--save-dev|--save-optional|--save-peer] [--save-exact] [--no-save]',
'<github username>/<github project>',
]
}

Expand Down
7 changes: 5 additions & 2 deletions lib/logout.js
Expand Up @@ -15,8 +15,11 @@ class Logout extends BaseCommand {
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return ['[--registry=<url>] [--scope=<@scope>]']
static get params () {
return [
'registry',
'scope',
]
}

exec (args, cb) {
Expand Down
7 changes: 6 additions & 1 deletion lib/pack.js
Expand Up @@ -21,9 +21,14 @@ class Pack extends BaseCommand {
return 'pack'
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get params () {
return ['dry-run']
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return ['[[<@scope>/]<pkg>...] [--dry-run]']
return ['[[<@scope>/]<pkg>...]']
}

exec (args, cb) {
Expand Down
5 changes: 5 additions & 0 deletions lib/ping.js
Expand Up @@ -8,6 +8,11 @@ class Ping extends BaseCommand {
return 'Ping npm registry'
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get params () {
return ['registry']
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get name () {
return 'ping'
Expand Down
7 changes: 6 additions & 1 deletion lib/prune.js
Expand Up @@ -14,9 +14,14 @@ class Prune extends BaseCommand {
return 'prune'
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get params () {
return ['production']
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return ['[[<@scope>/]<pkg>...] [--production]']
return ['[[<@scope>/]<pkg>...]']
}

exec (args, cb) {
Expand Down
7 changes: 6 additions & 1 deletion lib/publish.js
Expand Up @@ -28,10 +28,15 @@ class Publish extends BaseCommand {
return 'publish'
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get params () {
return ['tag', 'access', 'dry-run']
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return [
'[<folder>] [--tag <tag>] [--access <public|restricted>] [--dry-run]',
'[<folder>]',
]
}

Expand Down
4 changes: 2 additions & 2 deletions lib/root.js
Expand Up @@ -11,8 +11,8 @@ class Root extends BaseCommand {
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return ['[-g]']
static get params () {
return ['global']
}

exec (args, cb) {
Expand Down
12 changes: 11 additions & 1 deletion lib/search.js
Expand Up @@ -36,9 +36,19 @@ class Search extends BaseCommand {
return 'search'
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get params () {
return [
'long',
'json',
'parseable',
'description',
]
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return ['[-l|--long] [--json] [--parseable] [--no-description] [search terms ...]']
return ['[search terms ...]']
}

exec (args, cb) {
Expand Down
7 changes: 6 additions & 1 deletion lib/uninstall.js
Expand Up @@ -16,9 +16,14 @@ class Uninstall extends BaseCommand {
return 'uninstall'
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get params () {
return ['save']
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return ['[<@scope>/]<pkg>[@<version>]... [-S|--save|--no-save]']
return ['[<@scope>/]<pkg>...']
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
Expand Down
7 changes: 6 additions & 1 deletion lib/update.js
Expand Up @@ -18,9 +18,14 @@ class Update extends BaseCommand {
return 'update'
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get params () {
return ['global']
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return ['[-g] [<pkg>...]']
return ['[<pkg>...]']
}

/* istanbul ignore next - see test/lib/load-all-commands.js */
Expand Down
36 changes: 32 additions & 4 deletions lib/utils/config/definition.js
Expand Up @@ -15,14 +15,16 @@ const required = [

const allowed = [
'default',
'type',
'defaultDescription',
'deprecated',
'description',
'flatten',
'hint',
'key',
'short',
'type',
'typeDescription',
'defaultDescription',
'deprecated',
'key',
'usage',
]

const {
Expand All @@ -43,6 +45,10 @@ class Definition {
this.defaultDescription = describeValue(this.default)
if (!this.typeDescription)
this.typeDescription = describeType(this.type)
if (!this.hint)
this.hint = `<${this.key}>`
if (!this.usage)
this.usage = describeUsage(this)
}

validate () {
Expand Down Expand Up @@ -73,6 +79,28 @@ ${description}
}
}

// Usage for a single param, abstracted because we have arrays of types in
// config definition
const paramUsage = (type, def) => {
let key = `--${def.key}`
if (def.short && typeof def.short === 'string')
key = `-${def.short}|${key}`
if (type === Boolean)
return `${key}`
else
return `${key} ${def.hint}`
}

const describeUsage = (def) => {
if (Array.isArray(def.type)) {
if (!def.type.some(d => d !== null && typeof d !== 'string'))
return `--${def.key} <${def.type.filter(d => d).join('|')}>`
else
return def.type.filter(d => d).map((t) => paramUsage(t, def)).join('|')
}
return paramUsage(def.type, def)
}

const describeType = type => {
if (Array.isArray(type)) {
const descriptions = type
Expand Down

0 comments on commit b876442

Please sign in to comment.