-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor and test for main cli script
- Loading branch information
Showing
3 changed files
with
168 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,2 @@ | ||
#!/usr/bin/env node | ||
|
||
process.title = 'npm' | ||
|
||
const { | ||
checkForBrokenNode, | ||
checkForUnsupportedNode | ||
} = require('../lib/utils/unsupported.js') | ||
|
||
checkForBrokenNode() | ||
|
||
const log = require('npmlog') | ||
// pause it here so it can unpause when we've loaded the configs | ||
// and know what loglevel we should be printing. | ||
log.pause() | ||
|
||
checkForUnsupportedNode() | ||
|
||
const npm = require('../lib/npm.js') | ||
const { defs: { shorthands, types } } = require('../lib/config/core.js') | ||
const errorHandler = require('../lib/utils/error-handler.js') | ||
const nopt = require('nopt') | ||
|
||
// if npm is called as "npmg" or "npm_g", then | ||
// run in global mode. | ||
if (process.argv[1][process.argv[1].length - 1] === 'g') { | ||
process.argv.splice(1, 1, 'npm', '-g') | ||
} | ||
|
||
log.verbose('cli', process.argv) | ||
|
||
const conf = nopt(types, shorthands) | ||
npm.argv = conf.argv.remain | ||
|
||
if (conf.version) { | ||
console.log(npm.version) | ||
return errorHandler.exit(0) | ||
} | ||
|
||
if (conf.versions) { | ||
npm.argv = ['version'] | ||
conf.usage = false | ||
} | ||
|
||
log.info('using', 'npm@%s', npm.version) | ||
log.info('using', 'node@%s', process.version) | ||
|
||
process.on('uncaughtException', errorHandler) | ||
process.on('unhandledRejection', errorHandler) | ||
|
||
// now actually fire up npm and run the command. | ||
// this is how to use npm programmatically: | ||
conf._exit = true | ||
const updateNotifier = require('../lib/utils/update-notifier.js') | ||
npm.load(conf, function (er) { | ||
if (er) return errorHandler(er) | ||
|
||
updateNotifier(npm) | ||
|
||
const cmd = npm.argv.shift() | ||
const impl = npm.commands[cmd] | ||
if (impl) { | ||
impl(npm.argv, errorHandler) | ||
} else { | ||
npm.config.set('usage', false) | ||
npm.argv.unshift(cmd) | ||
npm.commands.help(npm.argv, errorHandler) | ||
} | ||
}) | ||
require('../lib/cli.js')(process) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
const t = require('tap') | ||
|
||
let LOAD_ERROR = null | ||
const npmock = { | ||
version: '99.99.99', | ||
load: (config, cb) => cb(LOAD_ERROR), | ||
argv: [], | ||
config: { | ||
settings: {}, | ||
get: (k) => npmock.config.settings[k], | ||
set: (k, v) => { npmock.config.settings[k] = v }, | ||
}, | ||
commands: {} | ||
} | ||
|
||
const unsupportedMock = { | ||
checkForBrokenNode: () => {}, | ||
checkForUnsupportedNode: () => {} | ||
} | ||
|
||
let errorHandlerCalled = null | ||
const errorHandlerMock = (...args) => { | ||
errorHandlerCalled = args | ||
} | ||
let errorHandlerExitCalled = null | ||
errorHandlerMock.exit = code => { | ||
errorHandlerExitCalled = code | ||
} | ||
|
||
const logs = [] | ||
const npmlogMock = { | ||
pause: () => logs.push('pause'), | ||
verbose: (...msg) => logs.push(['verbose', ...msg]), | ||
info: (...msg) => logs.push(['info', ...msg]) | ||
} | ||
|
||
const requireInject = require('require-inject') | ||
const cli = requireInject.installGlobally('../../lib/cli.js', { | ||
'../../lib/npm.js': npmock, | ||
'../../lib/utils/unsupported.js': unsupportedMock, | ||
'../../lib/utils/error-handler.js': errorHandlerMock, | ||
npmlog: npmlogMock | ||
}) | ||
|
||
t.test('print the version, and treat npm_g to npm -g', t => { | ||
const { log } = console | ||
const consoleLogs = [] | ||
console.log = (...msg) => consoleLogs.push(msg) | ||
const proc = { | ||
argv: ['node', 'npm_g', '-v'], | ||
on: () => {} | ||
} | ||
|
||
cli(proc) | ||
|
||
t.strictSame(npmock.argv, []) | ||
t.strictSame(proc.argv, [ 'node', 'npm', '-g', '-v' ]) | ||
t.strictSame(logs, [ | ||
'pause', | ||
[ 'verbose', 'cli', [ 'node', 'npm', '-g', '-v' ] ] | ||
]) | ||
t.strictSame(consoleLogs, [ [ '99.99.99' ] ]) | ||
t.strictSame(errorHandlerExitCalled, 0) | ||
|
||
console.log = log | ||
npmock.argv = 0 | ||
proc.argv.length = 0 | ||
logs.length = 0 | ||
consoleLogs.length = 0 | ||
errorHandlerExitCalled = null | ||
|
||
t.end() | ||
}) | ||
|
||
t.test('calling with --versions calls npm version with no args', t => { | ||
const { log } = console | ||
const consoleLogs = [] | ||
console.log = (...msg) => consoleLogs.push(msg) | ||
const proc = { | ||
argv: ['node', 'npm', 'install', 'or', 'whatever', '--versions'], | ||
on: () => {} | ||
} | ||
|
||
t.teardown(() => { | ||
console.log = log | ||
npmock.argv = 0 | ||
proc.argv.length = 0 | ||
logs.length = 0 | ||
consoleLogs.length = 0 | ||
errorHandlerExitCalled = null | ||
delete npmock.commands.version | ||
}) | ||
|
||
npmock.commands.version = (args, cb) => { | ||
t.equal(proc.title, 'npm') | ||
t.strictSame(npmock.argv, []) | ||
t.strictSame(proc.argv, [ 'node', 'npm', 'install', 'or', 'whatever', '--versions' ]) | ||
t.strictSame(logs, [ | ||
'pause', | ||
[ 'verbose', 'cli', [ 'node', 'npm', 'install', 'or', 'whatever', '--versions' ] ], | ||
[ 'info', 'using', 'npm@%s', '99.99.99' ], | ||
[ 'info', 'using', 'node@%s', undefined ] | ||
]) | ||
|
||
t.strictSame(consoleLogs, []) | ||
t.strictSame(errorHandlerExitCalled, null) | ||
|
||
t.strictSame(args, []) | ||
t.end() | ||
} | ||
|
||
cli(proc) | ||
}) | ||
|
||
t.test('print usage if -h provided', t => { | ||
const { log } = console | ||
const consoleLogs = [] | ||
console.log = (...msg) => consoleLogs.push(msg) | ||
const proc = { | ||
argv: ['node', 'npm', 'asdf'], | ||
on: () => {} | ||
} | ||
|
||
t.teardown(() => { | ||
console.log = log | ||
npmock.argv = 0 | ||
proc.argv.length = 0 | ||
logs.length = 0 | ||
consoleLogs.length = 0 | ||
errorHandlerExitCalled = null | ||
delete npmock.commands.help | ||
}) | ||
|
||
npmock.commands.help = (args, cb) => { | ||
delete npmock.commands.help | ||
t.equal(proc.title, 'npm') | ||
t.strictSame(args, ['asdf']) | ||
t.strictSame(npmock.argv, ['asdf']) | ||
t.strictSame(proc.argv, [ 'node', 'npm', 'asdf' ]) | ||
t.strictSame(logs, [ | ||
'pause', | ||
[ 'verbose', 'cli', [ 'node', 'npm', 'asdf' ] ], | ||
[ 'info', 'using', 'npm@%s', '99.99.99' ], | ||
[ 'info', 'using', 'node@%s', undefined ] | ||
]) | ||
t.strictSame(consoleLogs, []) | ||
t.strictSame(errorHandlerExitCalled, null) | ||
t.end() | ||
} | ||
|
||
cli(proc) | ||
}) | ||
|
||
t.test('load error calls error handler', t => { | ||
const er = new Error('poop') | ||
LOAD_ERROR = er | ||
const proc = { | ||
argv: ['node', 'npm', 'asdf'], | ||
on: () => {} | ||
} | ||
cli(proc) | ||
t.strictSame(errorHandlerCalled, [er]) | ||
LOAD_ERROR = null | ||
t.end() | ||
}) | ||
|