Welcome to mirror list, hosted at ThFree Co, Russian Federation.

outdated.js « lib - github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 80aef7971aee8a13bf73ae98c3bf2c9c23437e24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*

npm outdated [pkg]

Does the following:

1. check for a new version of pkg

If no packages are specified, then run for all installed
packages.

*/

module.exports = outdated

outdated.usage = "npm outdated [<pkg> [<pkg> ...]]"

outdated.completion = require("./utils/completion/installed-deep")


var readInstalled = require("./utils/read-installed")
  , path = require("path")
  , fs = require("./utils/graceful-fs")
  , readJson = require("./utils/read-json")
  , cache = require("./cache")
  , asyncMap = require("./utils/async-map")
  , npm = require("../npm")
  , log = require("./utils/log")
  , semver = require("./utils/semver")

// outdated(pref)
// deps = pref/package.json dependencies, or {<pref/node_modules/*>:"*"}
// asyncMap over deps
//   if exists and (up to date
//       or (not in args and args is not empty))
//     return outdated(prefix/node_modules/d)
//   else if (in args or args is empty)
//     return [prefix, d]


// for each thing in prefix/node_modules/*
// if there's a newer one, report it
// otherwise, check its children
var output
function outdated (args, silent, cb) {
  if (typeof cb !== "function") cb = silent, silent = false
  outdated_(npm.prefix, args, function (er, list) {
    if (er) return cb(er)
    if (list.length && !silent) {
      var outList = list.map(function (ww) {
        return ww[1] + ": "+ww[0] + (ww[2] ? " (currently: "+ww[2]+")":"")
      })
      output = output || require("./utils/output")
      output.write(outList.join("\n"), function (e) {
        cb(e, list)
      })
    } else cb(null, list)
  })
}

function outdated_ (prefix, args, cb) {
  log(prefix, "outdated_ about to getDeps")
  getDeps(prefix, function (er, deps) {
    log([prefix, er, deps], "back from getDeps")
    if (er) return cb(er)
    // now deps is a "dependencies" object, {<name>:<req version>}
    asyncMap(Object.keys(deps), function (dep, cb) {
      var req = deps[dep]
      log([prefix, dep, req], "outdated_")
      validateDep(prefix, args, dep, req, function (er, exists, needsUpdate) {
        if (er) return cb(er)
        log([prefix, dep, req, exists, needsUpdate], "outdated_")
        if (needsUpdate) return cb(null, [[prefix, dep, exists]])
        else if (!exists) return cb(null, [])
        else outdated_(path.resolve(prefix, "node_modules", dep), args, cb)
      })
    }, cb)
  })
}

// return cb with (er, currentVersion or false, needsUpdate boolean)
function validateDep (prefix, args, dep, req, cb) {
  var canUpdate = args.length === 0 ? true : args.indexOf(dep) !== -1
    , current = -1
    , latest
    , needsUpdate = false

  readJson(path.resolve(prefix, "node_modules", dep,"package.json")
          ,function (er, data) {
    if (er) current = false
    else current = data.version
    log("back from readJson", "validateDep "+dep)
    next()
  })

  // only check for newer version if we can update this thing.
  if (canUpdate) {
    log([dep, req], "about to check")
    cache.add(dep, req, function (er, data) {
      if (er) {
        // ignore 404 errors, since it's probably just that they installed
        // something locally. other errors indicate something is wrong.
        if (er.errno !== npm.E404) return next(er)
        canUpdate = false
        return next()
      }
      latest = data.version
      log([dep, req, latest, current], "dep, req, latest, current")
      next()
    })
  } else next()

  var errState
  function next (er) {
    log([dep, req, current, latest, canUpdate, er], "validateDep next")
    if (errState) return log("error state")
    if (er) return cb(errState = er)
    if (canUpdate && !latest) return log("waiting for latest")
    if (current === -1) return log("waiting for current")
    // now we know the current version (or false if it's not there)
    // and have the version that it ought to be.
    var needsUpdate = canUpdate && semver.gt(latest, current)
    cb(null, current, needsUpdate)
  }
}

// deps is the package.json dependencies,
// plus any node_modules/* that aren't in the dependencies.
function getDeps (prefix, cb) {
  var jsonDeps
    , folderDeps

  readJson(path.resolve(prefix, "package.json"), function (er, data) {
    if (er) jsonDeps = {}
    else jsonDeps = data.dependencies || {}
    next()
  })

  var dir = path.resolve(prefix, "node_modules")
  fs.readdir(dir, function (er, list) {
    if (er) list = []
    log(list, "readdir")
    list = list.filter(function (l) {
      return l.charAt(0) !== "."
    })
    asyncMap(list, function (l, cb) {
      fs.lstat(path.resolve(dir, l), function (er, st) {
        if (er) return cb(null, [])
        if (!st.isDirectory()) return cb(null, [])
        return cb(null, l)
      })
    }, function (er, list) {
      log(list, "asyncMapped over dir")
      if (er) return cb(er)
      folderDeps = list.reduce(function (l, r) {
        l[r] = "*"
        return l
      }, {}) || {}
      next()
    })
  })

  function next () {
    log([jsonDeps, folderDeps], "getDeps next")
    if (!jsonDeps || !folderDeps) return
    Object.keys(jsonDeps).forEach(function (d) {
      folderDeps[d] = jsonDeps[d]
    })
    return cb(null, folderDeps)
  }
}