The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / npm / lib / outdated.js @ 5aef65a9

History | View | Annotate | Download (4.09 KB)

1
/*
2

3
npm outdated [pkg]
4

5
Does the following:
6

7
1. check for a new version of pkg
8

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

12
*/
13

    
14
module.exports = outdated
15

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

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

    
20

    
21
var path = require("path")
22
  , fs = require("graceful-fs")
23
  , readJson = require("read-package-json")
24
  , cache = require("./cache.js")
25
  , asyncMap = require("slide").asyncMap
26
  , npm = require("./npm.js")
27
  , semver = require("semver")
28

    
29
function outdated (args, silent, cb) {
30
  if (typeof cb !== "function") cb = silent, silent = false
31
  var dir = path.resolve(npm.dir, "..")
32
  outdated_(args, dir, {}, function (er, list) {
33
    if (er || silent) return cb(er, list)
34
    var outList = list.map(makePretty)
35
    console.log(outList.join("\n"))
36
    cb(null, list)
37
  })
38
}
39

    
40
// [[ dir, dep, has, want ]]
41
function makePretty (p) {
42
  var parseable = npm.config.get("parseable")
43
    , long = npm.config.get("long")
44
    , dep = p[1]
45
    , dir = path.resolve(p[0], "node_modules", dep)
46
    , has = p[2]
47
    , want = p[3]
48

    
49
  // XXX add --json support
50
  // Should match (more or less) the output of ls --json
51

    
52
  if (parseable) {
53
    var str = dir
54
    if (npm.config.get("long")) {
55
      str += ":" + dep + "@" + want
56
           + ":" + (has ? (dep + "@" + has) : "MISSING")
57
    }
58
    return str
59
  }
60

    
61
  if (!npm.config.get("global")) {
62
    dir = path.relative(process.cwd(), dir)
63
  }
64
  return dep + "@" + want + " " + dir
65
       + " current=" + (has || "MISSING")
66
}
67

    
68
function outdated_ (args, dir, parentHas, cb) {
69
  // get the deps from package.json, or {<dir/node_modules/*>:"*"}
70
  // asyncMap over deps:
71
  //   shouldHave = cache.add(dep, req).version
72
  //   if has === shouldHave then
73
  //     return outdated(args, dir/node_modules/dep, parentHas + has)
74
  //   else if dep in args or args is empty
75
  //     return [dir, dep, has, shouldHave]
76

    
77
  var deps = null
78
  readJson(path.resolve(dir, "package.json"), function (er, d) {
79
    if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
80
    deps = (er) ? true : (d.dependencies || {})
81
    return next()
82
  })
83

    
84
  var has = null
85
  fs.readdir(path.resolve(dir, "node_modules"), function (er, pkgs) {
86
    if (er) {
87
      has = Object.create(parentHas)
88
      return next()
89
    }
90
    pkgs = pkgs.filter(function (p) {
91
      return !p.match(/^[\._-]/)
92
    })
93
    asyncMap(pkgs, function (pkg, cb) {
94
      var jsonFile = path.resolve(dir, "node_modules", pkg, "package.json")
95
      readJson(jsonFile, function (er, d) {
96
        if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
97
        cb(null, er ? [] : [[d.name, d.version]])
98
      })
99
    }, function (er, pvs) {
100
      if (er) return cb(er)
101
      has = Object.create(parentHas)
102
      pvs.forEach(function (pv) {
103
        has[pv[0]] = pv[1]
104
      })
105

    
106
      next()
107
    })
108
  })
109

    
110
  function next () {
111
    if (!has || !deps) return
112
    if (deps === true) {
113
      deps = Object.keys(has).reduce(function (l, r) {
114
        l[r] = "*"
115
        return l
116
      }, {})
117
    }
118

    
119
    // now get what we should have, based on the dep.
120
    // if has[dep] !== shouldHave[dep], then cb with the data
121
    // otherwise dive into the folder
122
    asyncMap(Object.keys(deps), function (dep, cb) {
123
      shouldUpdate(args, dir, dep, has, deps[dep], cb)
124
    }, cb)
125
  }
126
}
127

    
128
function shouldUpdate (args, dir, dep, has, req, cb) {
129
  // look up the most recent version.
130
  // if that's what we already have, or if it's not on the args list,
131
  // then dive into it.  Otherwise, cb() with the data.
132

    
133
  function skip () {
134
    outdated_( args
135
             , path.resolve(dir, "node_modules", dep)
136
             , has
137
             , cb )
138
  }
139

    
140
  function doIt (shouldHave) {
141
    cb(null, [[ dir, dep, has[dep], shouldHave ]])
142
  }
143

    
144
  if (args.length && args.indexOf(dep) === -1) {
145
    return skip()
146
  }
147

    
148
  // so, we can conceivably update this.  find out if we need to.
149
  cache.add(dep, req, function (er, d) {
150
    // if this fails, then it means we can't update this thing.
151
    // it's probably a thing that isn't published.
152
    return (er || d.version === has[dep]) ? skip() : doIt(d.version)
153
  })
154
}