update.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. 'use strict'
  2. module.exports = update
  3. const url = require('url')
  4. const log = require('npmlog')
  5. const Bluebird = require('bluebird')
  6. const npm = require('./npm.js')
  7. const Installer = require('./install.js').Installer
  8. const usage = require('./utils/usage')
  9. const outdated = Bluebird.promisify(npm.commands.outdated)
  10. update.usage = usage(
  11. 'update',
  12. 'npm update [-g] [<pkg>...]'
  13. )
  14. update.completion = npm.commands.outdated.completion
  15. function update (args, cb) {
  16. return update_(args).asCallback(cb)
  17. }
  18. function update_ (args) {
  19. let dryrun = false
  20. if (npm.config.get('dry-run')) dryrun = true
  21. log.verbose('update', 'computing outdated modules to update')
  22. return outdated(args, true).then((rawOutdated) => {
  23. const outdated = rawOutdated.map(function (ww) {
  24. return {
  25. dep: ww[0],
  26. depname: ww[1],
  27. current: ww[2],
  28. wanted: ww[3],
  29. latest: ww[4],
  30. req: ww[5],
  31. what: ww[1] + '@' + ww[3]
  32. }
  33. })
  34. const wanted = outdated.filter(function (ww) {
  35. if (ww.current === ww.wanted && ww.wanted !== ww.latest) {
  36. log.verbose(
  37. 'outdated',
  38. 'not updating', ww.depname,
  39. "because it's currently at the maximum version that matches its specified semver range"
  40. )
  41. }
  42. return ww.current !== ww.wanted
  43. })
  44. if (wanted.length === 0) return
  45. log.info('outdated', 'updating', wanted)
  46. const toInstall = {}
  47. wanted.forEach(function (ww) {
  48. // use the initial installation method (repo, tar, git) for updating
  49. if (url.parse(ww.req).protocol) ww.what = ww.req
  50. const where = (ww.dep.parent && ww.dep.parent.path) || ww.dep.path
  51. const isTransitive = !(ww.dep.requiredBy || []).some((p) => p.isTop)
  52. const key = where + ':' + String(isTransitive)
  53. if (!toInstall[key]) toInstall[key] = {where: where, opts: {saveOnlyLock: isTransitive}, what: []}
  54. if (toInstall[key].what.indexOf(ww.what) === -1) toInstall[key].what.push(ww.what)
  55. })
  56. return Bluebird.each(Object.keys(toInstall), (key) => {
  57. const deps = toInstall[key]
  58. const inst = new Installer(deps.where, dryrun, deps.what, deps.opts)
  59. return inst.run()
  60. })
  61. })
  62. }