npm-cli.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #!/usr/bin/env node
  2. ;(function () { // wrapper in case we're in module_context mode
  3. // windows: running "npm blah" in this folder will invoke WSH, not node.
  4. /* global WScript */
  5. if (typeof WScript !== 'undefined') {
  6. WScript.echo(
  7. 'npm does not work when run\n' +
  8. 'with the Windows Scripting Host\n\n' +
  9. "'cd' to a different directory,\n" +
  10. "or type 'npm.cmd <args>',\n" +
  11. "or type 'node npm <args>'."
  12. )
  13. WScript.quit(1)
  14. return
  15. }
  16. process.title = 'npm'
  17. var unsupported = require('../lib/utils/unsupported.js')
  18. unsupported.checkForBrokenNode()
  19. var log = require('npmlog')
  20. log.pause() // will be unpaused when config is loaded.
  21. log.info('it worked if it ends with', 'ok')
  22. unsupported.checkForUnsupportedNode()
  23. var npm = require('../lib/npm.js')
  24. var npmconf = require('../lib/config/core.js')
  25. var errorHandler = require('../lib/utils/error-handler.js')
  26. var replaceInfo = require('../lib/utils/replace-info.js')
  27. var configDefs = npmconf.defs
  28. var shorthands = configDefs.shorthands
  29. var types = configDefs.types
  30. var nopt = require('nopt')
  31. // if npm is called as "npmg" or "npm_g", then
  32. // run in global mode.
  33. if (process.argv[1][process.argv[1].length - 1] === 'g') {
  34. process.argv.splice(1, 1, 'npm', '-g')
  35. }
  36. var args = replaceInfo(process.argv)
  37. log.verbose('cli', args)
  38. var conf = nopt(types, shorthands)
  39. npm.argv = conf.argv.remain
  40. if (npm.deref(npm.argv[0])) npm.command = npm.argv.shift()
  41. else conf.usage = true
  42. if (conf.version) {
  43. console.log(npm.version)
  44. return errorHandler.exit(0)
  45. }
  46. if (conf.versions) {
  47. npm.command = 'version'
  48. conf.usage = false
  49. npm.argv = []
  50. }
  51. log.info('using', 'npm@%s', npm.version)
  52. log.info('using', 'node@%s', process.version)
  53. process.on('uncaughtException', errorHandler)
  54. process.on('unhandledRejection', errorHandler)
  55. if (conf.usage && npm.command !== 'help') {
  56. npm.argv.unshift(npm.command)
  57. npm.command = 'help'
  58. }
  59. var isGlobalNpmUpdate = conf.global && ['install', 'update'].includes(npm.command) && npm.argv.includes('npm')
  60. // now actually fire up npm and run the command.
  61. // this is how to use npm programmatically:
  62. conf._exit = true
  63. npm.load(conf, function (er) {
  64. if (er) return errorHandler(er)
  65. if (
  66. !isGlobalNpmUpdate &&
  67. npm.config.get('update-notifier') &&
  68. !unsupported.checkVersion(process.version).unsupported
  69. ) {
  70. const pkg = require('../package.json')
  71. let notifier = require('update-notifier')({pkg})
  72. const isCI = require('ci-info').isCI
  73. if (
  74. notifier.update &&
  75. notifier.update.latest !== pkg.version &&
  76. !isCI
  77. ) {
  78. const color = require('ansicolors')
  79. const useColor = npm.config.get('color')
  80. const useUnicode = npm.config.get('unicode')
  81. const old = notifier.update.current
  82. const latest = notifier.update.latest
  83. let type = notifier.update.type
  84. if (useColor) {
  85. switch (type) {
  86. case 'major':
  87. type = color.red(type)
  88. break
  89. case 'minor':
  90. type = color.yellow(type)
  91. break
  92. case 'patch':
  93. type = color.green(type)
  94. break
  95. }
  96. }
  97. const changelog = `https://github.com/npm/cli/releases/tag/v${latest}`
  98. notifier.notify({
  99. message: `New ${type} version of ${pkg.name} available! ${
  100. useColor ? color.red(old) : old
  101. } ${useUnicode ? '→' : '->'} ${
  102. useColor ? color.green(latest) : latest
  103. }\n` +
  104. `${
  105. useColor ? color.yellow('Changelog:') : 'Changelog:'
  106. } ${
  107. useColor ? color.cyan(changelog) : changelog
  108. }\n` +
  109. `Run ${
  110. useColor
  111. ? color.green(`npm install -g ${pkg.name}`)
  112. : `npm i -g ${pkg.name}`
  113. } to update!`
  114. })
  115. }
  116. }
  117. npm.commands[npm.command](npm.argv, function (err) {
  118. // https://genius.com/Lin-manuel-miranda-your-obedient-servant-lyrics
  119. if (
  120. !err &&
  121. npm.config.get('ham-it-up') &&
  122. !npm.config.get('json') &&
  123. !npm.config.get('parseable') &&
  124. npm.command !== 'completion'
  125. ) {
  126. console.error(
  127. `\n ${
  128. npm.config.get('unicode') ? '🎵 ' : ''
  129. } I Have the Honour to Be Your Obedient Servant,${
  130. npm.config.get('unicode') ? '🎵 ' : ''
  131. } ~ npm ${
  132. npm.config.get('unicode') ? '📜🖋 ' : ''
  133. }\n`
  134. )
  135. }
  136. errorHandler.apply(this, arguments)
  137. })
  138. })
  139. })()