Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(usage): clean up usage declarations #2821

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
51 changes: 19 additions & 32 deletions lib/access.js
Expand Up @@ -3,10 +3,9 @@ const path = require('path')
const libaccess = require('libnpmaccess')
const readPackageJson = require('read-package-json-fast')

const output = require('./utils/output.js')
const otplease = require('./utils/otplease.js')
const usageUtil = require('./utils/usage.js')
const getIdentity = require('./utils/get-identity.js')
const BaseCommand = require('./base-command.js')

const subcommands = [
'public',
Expand All @@ -20,24 +19,23 @@ const subcommands = [
'2fa-not-required',
]

class Access {
constructor (npm) {
this.npm = npm
class Access extends BaseCommand {
static get name () {
return 'access'
}

get usage () {
return usageUtil(
'access',
'npm access public [<package>]\n' +
'npm access restricted [<package>]\n' +
'npm access grant <read-only|read-write> <scope:team> [<package>]\n' +
'npm access revoke <scope:team> [<package>]\n' +
'npm access 2fa-required [<package>]\n' +
'npm access 2fa-not-required [<package>]\n' +
'npm access ls-packages [<user>|<scope>|<scope:team>]\n' +
'npm access ls-collaborators [<package> [<user>]]\n' +
'npm access edit [<package>]'
)
static get usage () {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉🎉🎉 💖

return [
'public [<package>]',
'restricted [<package>]',
'grant <read-only|read-write> <scope:team> [<package>]',
'revoke <scope:team> [<package>]',
'2fa-required [<package>]',
'2fa-not-required [<package>]',
'ls-packages [<user>|<scope>|<scope:team>]',
'ls-collaborators [<package> [<user>]]',
'edit [<package>]',
]
}

async completion (opts) {
Expand Down Expand Up @@ -67,12 +65,7 @@ class Access {
}

exec (args, cb) {
this.access(args)
.then(x => cb(null, x))
.catch(err => err.code === 'EUSAGE'
? cb(err.message)
: cb(err)
)
this.access(args).then(() => cb()).catch(cb)
}

async access ([cmd, ...args]) {
Expand Down Expand Up @@ -157,7 +150,7 @@ class Access {
const pkgs = await libaccess.lsPackages(owner, opts)

// TODO - print these out nicely (breaking change)
output(JSON.stringify(pkgs, null, 2))
this.npm.output(JSON.stringify(pkgs, null, 2))
}

get ['ls-collaborators'] () {
Expand All @@ -169,7 +162,7 @@ class Access {
const collabs = await libaccess.lsCollaborators(pkgName, usr, opts)

// TODO - print these out nicely (breaking change)
output(JSON.stringify(collabs, null, 2))
this.npm.output(JSON.stringify(collabs, null, 2))
}

async edit () {
Expand Down Expand Up @@ -203,12 +196,6 @@ class Access {
return name
}
}

usageError (msg) {
return Object.assign(new Error(`\nUsage: ${msg}\n\n` + this.usage), {
code: 'EUSAGE',
})
}
}

module.exports = Access
19 changes: 7 additions & 12 deletions lib/adduser.js
@@ -1,25 +1,20 @@
const log = require('npmlog')
const output = require('./utils/output.js')
const usageUtil = require('./utils/usage.js')
const replaceInfo = require('./utils/replace-info.js')
const BaseCommand = require('./base-command.js')
const authTypes = {
legacy: require('./auth/legacy.js'),
oauth: require('./auth/oauth.js'),
saml: require('./auth/saml.js'),
sso: require('./auth/sso.js'),
}

class AddUser {
constructor (npm) {
this.npm = npm
class AddUser extends BaseCommand {
static get name () {
return 'adduser'
}

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

exec (args, cb) {
Expand Down Expand Up @@ -49,7 +44,7 @@ class AddUser {
scope,
})

output(message)
this.npm.output(message)
}

getRegistry ({ scope, registry }) {
Expand Down
24 changes: 11 additions & 13 deletions lib/audit.js
@@ -1,23 +1,21 @@
const Arborist = require('@npmcli/arborist')
const auditReport = require('npm-audit-report')
const output = require('./utils/output.js')
const reifyFinish = require('./utils/reify-finish.js')
const auditError = require('./utils/audit-error.js')
const usageUtil = require('./utils/usage.js')
const BaseCommand = require('./base-command.js')

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

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

async completion (opts) {
Expand Down Expand Up @@ -57,7 +55,7 @@ class Audit {
reporter,
})
process.exitCode = process.exitCode || result.exitCode
output(result.report)
this.npm.output(result.report)
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions lib/base-command.js
@@ -0,0 +1,38 @@
// Base class for npm.commands[cmd]
const usageUtil = require('./utils/usage.js')

class BaseCommand {
constructor (npm) {
this.npm = npm
}

get usage () {
let usage = `npm ${this.constructor.name}\n\n`
if (this.constructor.description)
usage = `${usage}${this.constructor.description}\n\n`

usage = `${usage}Usage:\n`
if (!this.constructor.usage)
usage = `${usage}npm ${this.constructor.name}`
else
usage = `${usage}${this.constructor.usage.map(u => `npm ${this.constructor.name} ${u}`).join('\n')}`

// Mostly this just appends aliases, this could be more clear
usage = usageUtil(this.constructor.name, usage)
usage = `${usage}\n\nRun "npm ${this.constructor.name} help" for more info`
return usage
}

usageError (msg) {
if (!msg) {
return Object.assign(new Error(`\nUsage: ${this.usage}`), {
code: 'EUSAGE',
})
}

return Object.assign(new Error(`\nUsage: ${msg}\n\n${this.usage}`), {
code: 'EUSAGE',
})
}
}
module.exports = BaseCommand
16 changes: 7 additions & 9 deletions lib/bin.js
@@ -1,15 +1,13 @@
const output = require('./utils/output.js')
const envPath = require('./utils/path.js')
const usageUtil = require('./utils/usage.js')
const BaseCommand = require('./base-command.js')

class Bin {
constructor (npm) {
this.npm = npm
class Bin extends BaseCommand {
static get name () {
return 'bin'
}

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

exec (args, cb) {
Expand All @@ -18,7 +16,7 @@ class Bin {

async bin (args) {
const b = this.npm.bin
output(b)
this.npm.output(b)
if (this.npm.flatOptions.global && !envPath.includes(b))
console.error('(not in PATH env variable)')
}
Expand Down
13 changes: 6 additions & 7 deletions lib/bugs.js
@@ -1,17 +1,16 @@
const log = require('npmlog')
const pacote = require('pacote')
const openUrl = require('./utils/open-url.js')
const usageUtil = require('./utils/usage.js')
const hostedFromMani = require('./utils/hosted-git-info-from-manifest.js')
const BaseCommand = require('./base-command.js')

class Bugs {
constructor (npm) {
this.npm = npm
class Bugs extends BaseCommand {
static get name () {
return 'bugs'
}

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

exec (args, cb) {
Expand Down
45 changes: 23 additions & 22 deletions lib/cache.js
@@ -1,27 +1,28 @@
const cacache = require('cacache')
const { promisify } = require('util')
const log = require('npmlog')
const output = require('./utils/output.js')
const pacote = require('pacote')
const path = require('path')
const rimraf = promisify(require('rimraf'))
const BaseCommand = require('./base-command.js')

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

get usage () {
return usageUtil('cache',
'npm cache add <tarball file>' +
'\nnpm cache add <folder>' +
'\nnpm cache add <tarball url>' +
'\nnpm cache add <git url>' +
'\nnpm cache add <name>@<version>' +
'\nnpm cache clean' +
'\nnpm cache verify'
)
/* istanbul ignore next - see test/lib/load-all-commands.js */
static get usage () {
return [
'add <tarball file>',
'add <folder>',
'add <tarball url>',
'add <git url>',
'add <name>@<version>',
'clean',
'verify',
]
}

async completion (opts) {
Expand Down Expand Up @@ -116,13 +117,13 @@ with --force.`)
? `~${cache.substr(process.env.HOME.length)}`
: cache
const stats = await cacache.verify(cache)
output(`Cache verified and compressed (${prefix})`)
output(`Content verified: ${stats.verifiedContent} (${stats.keptSize} bytes)`)
stats.badContentCount && output(`Corrupted content removed: ${stats.badContentCount}`)
stats.reclaimedCount && output(`Content garbage-collected: ${stats.reclaimedCount} (${stats.reclaimedSize} bytes)`)
stats.missingContent && output(`Missing content: ${stats.missingContent}`)
output(`Index entries: ${stats.totalEntries}`)
output(`Finished in ${stats.runTime.total / 1000}s`)
this.npm.output(`Cache verified and compressed (${prefix})`)
this.npm.output(`Content verified: ${stats.verifiedContent} (${stats.keptSize} bytes)`)
stats.badContentCount && this.npm.output(`Corrupted content removed: ${stats.badContentCount}`)
stats.reclaimedCount && this.npm.output(`Content garbage-collected: ${stats.reclaimedCount} (${stats.reclaimedSize} bytes)`)
stats.missingContent && this.npm.output(`Missing content: ${stats.missingContent}`)
this.npm.output(`Index entries: ${stats.totalEntries}`)
this.npm.output(`Finished in ${stats.runTime.total / 1000}s`)
}
}

Expand Down
12 changes: 4 additions & 8 deletions lib/ci.js
Expand Up @@ -7,7 +7,6 @@ const fs = require('fs')
const readdir = util.promisify(fs.readdir)

const log = require('npmlog')
const usageUtil = require('./utils/usage.js')

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

class CI {
constructor (npm) {
this.npm = npm
}

class CI extends BaseCommand {
/* istanbul ignore next - see test/lib/load-all-commands.js */
get usage () {
return usageUtil('ci', 'npm ci')
static get name () {
return 'ci'
}

exec (args, cb) {
Expand Down