Skip to content

Commit cedb1e1

Browse files
committed
fix(usage): clean up usage declarations
Small refactor of commands to allow usage to be more programmatically generated, leading us in the direction of more tighly coupling each command to the params it accepts.
1 parent bd2545d commit cedb1e1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+626
-711
lines changed

lib/access.js

+20-29
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ const readPackageJson = require('read-package-json-fast')
55

66
const output = require('./utils/output.js')
77
const otplease = require('./utils/otplease.js')
8-
const usageUtil = require('./utils/usage.js')
98
const getIdentity = require('./utils/get-identity.js')
9+
const BaseCommand = require('./base-command.js')
1010

1111
const subcommands = [
1212
'public',
@@ -20,24 +20,25 @@ const subcommands = [
2020
'2fa-not-required',
2121
]
2222

23-
class Access {
24-
constructor (npm) {
25-
this.npm = npm
23+
class Access extends BaseCommand {
24+
/* istanbul ignore next - see test/lib/load-all-commands.js */
25+
static get name () {
26+
return 'access'
2627
}
2728

28-
get usage () {
29-
return usageUtil(
30-
'access',
31-
'npm access public [<package>]\n' +
32-
'npm access restricted [<package>]\n' +
33-
'npm access grant <read-only|read-write> <scope:team> [<package>]\n' +
34-
'npm access revoke <scope:team> [<package>]\n' +
35-
'npm access 2fa-required [<package>]\n' +
36-
'npm access 2fa-not-required [<package>]\n' +
37-
'npm access ls-packages [<user>|<scope>|<scope:team>]\n' +
38-
'npm access ls-collaborators [<package> [<user>]]\n' +
39-
'npm access edit [<package>]'
40-
)
29+
/* istanbul ignore next - see test/lib/load-all-commands.js */
30+
static get usage () {
31+
return [
32+
'public [<package>]',
33+
'restricted [<package>]',
34+
'grant <read-only|read-write> <scope:team> [<package>]',
35+
'revoke <scope:team> [<package>]',
36+
'2fa-required [<package>]',
37+
'2fa-not-required [<package>]',
38+
'ls-packages [<user>|<scope>|<scope:team>]',
39+
'ls-collaborators [<package> [<user>]]',
40+
'edit [<package>]',
41+
]
4142
}
4243

4344
async completion (opts) {
@@ -67,12 +68,7 @@ class Access {
6768
}
6869

6970
exec (args, cb) {
70-
this.access(args)
71-
.then(x => cb(null, x))
72-
.catch(err => err.code === 'EUSAGE'
73-
? cb(err.message)
74-
: cb(err)
75-
)
71+
this.access(args).then(() => cb()).catch(cb)
7672
}
7773

7874
async access ([cmd, ...args]) {
@@ -203,12 +199,7 @@ class Access {
203199
return name
204200
}
205201
}
206-
207-
usageError (msg) {
208-
return Object.assign(new Error(`\nUsage: ${msg}\n\n` + this.usage), {
209-
code: 'EUSAGE',
210-
})
211-
}
212202
}
203+
Access.constructor.name = 'access'
213204

214205
module.exports = Access

lib/adduser.js

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,23 @@
11
const log = require('npmlog')
22
const output = require('./utils/output.js')
3-
const usageUtil = require('./utils/usage.js')
43
const replaceInfo = require('./utils/replace-info.js')
4+
const BaseCommand = require('./base-command.js')
55
const authTypes = {
66
legacy: require('./auth/legacy.js'),
77
oauth: require('./auth/oauth.js'),
88
saml: require('./auth/saml.js'),
99
sso: require('./auth/sso.js'),
1010
}
1111

12-
class AddUser {
13-
constructor (npm) {
14-
this.npm = npm
12+
class AddUser extends BaseCommand {
13+
/* istanbul ignore next - see test/lib/load-all-commands.js */
14+
static get name () {
15+
return 'adduser'
1516
}
1617

1718
/* istanbul ignore next - see test/lib/load-all-commands.js */
18-
get usage () {
19-
return usageUtil(
20-
'adduser',
21-
'npm adduser [--registry=url] [--scope=@orgname] [--always-auth]'
22-
)
19+
static get usage () {
20+
return ['[--registry=url] [--scope=@orgname] [--always-auth]']
2321
}
2422

2523
exec (args, cb) {

lib/audit.js

+10-11
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,20 @@ const auditReport = require('npm-audit-report')
33
const output = require('./utils/output.js')
44
const reifyFinish = require('./utils/reify-finish.js')
55
const auditError = require('./utils/audit-error.js')
6-
const usageUtil = require('./utils/usage.js')
6+
const BaseCommand = require('./base-command.js')
77

8-
class Audit {
9-
constructor (npm) {
10-
this.npm = npm
8+
class Audit extends BaseCommand {
9+
/* istanbul ignore next - see test/lib/load-all-commands.js */
10+
static get name () {
11+
return 'audit'
1112
}
1213

1314
/* istanbul ignore next - see test/lib/load-all-commands.js */
14-
get usage () {
15-
return usageUtil(
16-
'audit',
17-
'npm audit [--json] [--production]' +
18-
'\nnpm audit fix ' +
19-
'[--force|--package-lock-only|--dry-run|--production|--only=(dev|prod)]'
20-
)
15+
static get usage () {
16+
return [
17+
'[--json] [--production]',
18+
'fix [--force|--package-lock-only|--dry-run|--production|--only=(dev|prod)]',
19+
]
2120
}
2221

2322
async completion (opts) {

lib/base-command.js

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Base class for npm.commands[cmd]
2+
const usageUtil = require('./utils/usage.js')
3+
4+
class BaseCommand {
5+
constructor (npm) {
6+
this.npm = npm
7+
}
8+
9+
get usage () {
10+
let usage = ''
11+
if (this.constructor.description)
12+
usage = `${this.constructor.description}\n\n`
13+
14+
if (!this.constructor.usage)
15+
usage = `${usage}npm ${this.constructor.name}`
16+
else
17+
usage = `${usage}${this.constructor.usage.map(u => `npm ${this.constructor.name} ${u}`).join('\n')}`
18+
19+
return usageUtil(this.constructor.name, usage)
20+
}
21+
22+
usageError (msg) {
23+
if (!msg) {
24+
return Object.assign(new Error(`\nUsage: ${this.usage}`), {
25+
code: 'EUSAGE',
26+
})
27+
}
28+
29+
return Object.assign(new Error(`\nUsage: ${msg}\n\n${this.usage}`), {
30+
code: 'EUSAGE',
31+
})
32+
}
33+
}
34+
module.exports = BaseCommand

lib/bin.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
const output = require('./utils/output.js')
22
const envPath = require('./utils/path.js')
3-
const usageUtil = require('./utils/usage.js')
3+
const BaseCommand = require('./base-command.js')
44

5-
class Bin {
6-
constructor (npm) {
7-
this.npm = npm
5+
class Bin extends BaseCommand {
6+
/* istanbul ignore next - see test/lib/load-all-commands.js */
7+
static get name () {
8+
return 'bin'
89
}
910

1011
/* istanbul ignore next - see test/lib/load-all-commands.js */
11-
get usage () {
12-
return usageUtil('bin', 'npm bin [-g]')
12+
static get usage () {
13+
return ['[-g]']
1314
}
1415

1516
exec (args, cb) {

lib/bugs.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
const log = require('npmlog')
22
const pacote = require('pacote')
33
const openUrl = require('./utils/open-url.js')
4-
const usageUtil = require('./utils/usage.js')
54
const hostedFromMani = require('./utils/hosted-git-info-from-manifest.js')
5+
const BaseCommand = require('./base-command.js')
66

7-
class Bugs {
8-
constructor (npm) {
9-
this.npm = npm
7+
class Bugs extends BaseCommand {
8+
/* istanbul ignore next - see test/lib/load-all-commands.js */
9+
static get name () {
10+
return 'bugs'
1011
}
1112

1213
/* istanbul ignore next - see test/lib/load-all-commands.js */
13-
get usage () {
14-
return usageUtil('bugs', 'npm bugs [<pkgname>]')
14+
static get usage () {
15+
return ['[<pkgname>]']
1516
}
1617

1718
exec (args, cb) {

lib/cache.js

+16-14
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,25 @@ const output = require('./utils/output.js')
55
const pacote = require('pacote')
66
const path = require('path')
77
const rimraf = promisify(require('rimraf'))
8+
const BaseCommand = require('./base-command.js')
89

9-
const usageUtil = require('./utils/usage.js')
10-
class Cache {
11-
constructor (npm) {
12-
this.npm = npm
10+
class Cache extends BaseCommand {
11+
/* istanbul ignore next - see test/lib/load-all-commands.js */
12+
static get name () {
13+
return 'cache'
1314
}
1415

15-
get usage () {
16-
return usageUtil('cache',
17-
'npm cache add <tarball file>' +
18-
'\nnpm cache add <folder>' +
19-
'\nnpm cache add <tarball url>' +
20-
'\nnpm cache add <git url>' +
21-
'\nnpm cache add <name>@<version>' +
22-
'\nnpm cache clean' +
23-
'\nnpm cache verify'
24-
)
16+
/* istanbul ignore next - see test/lib/load-all-commands.js */
17+
static get usage () {
18+
return [
19+
'add <tarball file>',
20+
'add <folder>',
21+
'add <tarball url>',
22+
'add <git url>',
23+
'add <name>@<version>',
24+
'clean',
25+
'verify',
26+
]
2527
}
2628

2729
async completion (opts) {

lib/ci.js

+4-8
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const fs = require('fs')
77
const readdir = util.promisify(fs.readdir)
88

99
const log = require('npmlog')
10-
const usageUtil = require('./utils/usage.js')
1110

1211
const removeNodeModules = async where => {
1312
const rimrafOpts = { glob: false }
@@ -18,15 +17,12 @@ const removeNodeModules = async where => {
1817
await Promise.all(entries.map(f => rimraf(`${path}/${f}`, rimrafOpts)))
1918
process.emit('timeEnd', 'npm-ci:rm')
2019
}
20+
const BaseCommand = require('./base-command.js')
2121

22-
class CI {
23-
constructor (npm) {
24-
this.npm = npm
25-
}
26-
22+
class CI extends BaseCommand {
2723
/* istanbul ignore next - see test/lib/load-all-commands.js */
28-
get usage () {
29-
return usageUtil('ci', 'npm ci')
24+
static get name () {
25+
return 'ci'
3026
}
3127

3228
exec (args, cb) {

lib/completion.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,18 @@ const isWindowsShell = require('./utils/is-windows-shell.js')
4242
const output = require('./utils/output.js')
4343
const fileExists = require('./utils/file-exists.js')
4444

45-
const usageUtil = require('./utils/usage.js')
4645
const { promisify } = require('util')
46+
const BaseCommand = require('./base-command.js')
4747

48-
class Completion {
49-
constructor (npm) {
50-
this.npm = npm
48+
class Completion extends BaseCommand {
49+
/* istanbul ignore next - see test/lib/load-all-commands.js */
50+
static get name () {
51+
return 'completion'
5152
}
5253

5354
/* istanbul ignore next - see test/lib/load-all-commands.js */
54-
get usage () {
55-
return usageUtil('completion', 'source <(npm completion)')
55+
static get usage () {
56+
return ['| source']
5657
}
5758

5859
// completion for the completion command

lib/config.js

+14-19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
const { defaults, types } = require('./utils/config.js')
2-
const usageUtil = require('./utils/usage.js')
32
const output = require('./utils/output.js')
43

54
const mkdirp = require('mkdirp-infer-owner')
@@ -29,22 +28,22 @@ const keyValues = args => {
2928

3029
const publicVar = k => !/^(\/\/[^:]+:)?_/.test(k)
3130

32-
class Config {
33-
constructor (npm) {
34-
this.npm = npm
31+
const BaseCommand = require('./base-command.js')
32+
class Config extends BaseCommand {
33+
/* istanbul ignore next - see test/lib/load-all-commands.js */
34+
static get name () {
35+
return 'config'
3536
}
3637

37-
get usage () {
38-
return usageUtil(
39-
'config',
40-
'npm config set <key>=<value> [<key>=<value> ...]' +
41-
'\nnpm config get [<key> [<key> ...]]' +
42-
'\nnpm config delete <key> [<key> ...]' +
43-
'\nnpm config list [--json]' +
44-
'\nnpm config edit' +
45-
'\nnpm set <key>=<value> [<key>=<value> ...]' +
46-
'\nnpm get [<key> [<key> ...]]'
47-
)
38+
/* istanbul ignore next - see test/lib/load-all-commands.js */
39+
static get usage () {
40+
return [
41+
'set <key>=<value> [<key>=<value> ...]',
42+
'get [<key> [<key> ...]]',
43+
'delete <key> [<key> ...]',
44+
'list [--json]',
45+
'edit',
46+
]
4847
}
4948

5049
async completion (opts) {
@@ -254,10 +253,6 @@ ${defData}
254253
}
255254
output(JSON.stringify(publicConf, null, 2))
256255
}
257-
258-
usageError () {
259-
return Object.assign(new Error(this.usage), { code: 'EUSAGE' })
260-
}
261256
}
262257

263258
module.exports = Config

lib/dedupe.js

+4-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
// dedupe duplicated packages, or find them in the tree
22
const Arborist = require('@npmcli/arborist')
3-
const usageUtil = require('./utils/usage.js')
43
const reifyFinish = require('./utils/reify-finish.js')
54

6-
class Dedupe {
7-
constructor (npm) {
8-
this.npm = npm
9-
}
5+
const BaseCommand = require('./base-command.js')
106

7+
class Dedupe extends BaseCommand {
118
/* istanbul ignore next - see test/lib/load-all-commands.js */
12-
get usage () {
13-
return usageUtil('dedupe', 'npm dedupe')
9+
static get name () {
10+
return 'dedupe'
1411
}
1512

1613
exec (args, cb) {

0 commit comments

Comments
 (0)