From 9d61e96fb1f48687a85c211e4e0cd44c7f95a38e Mon Sep 17 00:00:00 2001 From: Daijiro Wachi Date: Sat, 24 Jan 2015 14:57:48 +0900 Subject: [PATCH] Supports npm outdated include package type with long option --- lib/outdated.js | 69 +++++++++++++++++++++++++++----------- test/tap/outdated-long.js | 70 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 20 deletions(-) create mode 100644 test/tap/outdated-long.js diff --git a/lib/outdated.js b/lib/outdated.js index fe25a8e910c2d..f69d81550a367 100644 --- a/lib/outdated.js +++ b/lib/outdated.js @@ -35,6 +35,7 @@ var path = require("path") , mapToRegistry = require("./utils/map-to-registry.js") , npa = require("npm-package-arg") , readInstalled = require("read-installed") + , long = npm.config.get("long") function outdated (args, silent, cb) { if (typeof cb !== "function") cb = silent, silent = false @@ -47,12 +48,14 @@ function outdated (args, silent, cb) { console.log(makeParseable(list)) } else { var outList = list.map(makePretty) - var outTable = [[ "Package" - , "Current" - , "Wanted" - , "Latest" - , "Location" - ]].concat(outList) + var outHead = [ "Package" + , "Current" + , "Wanted" + , "Latest" + , "Location" + ] + if (long) outHead.push("Package Type") + var outTable = [outHead].concat(outList) if (npm.color) { outTable[0] = outTable[0].map(function(heading) { @@ -69,13 +72,14 @@ function outdated (args, silent, cb) { }) } -// [[ dir, dep, has, want, latest ]] +// [[ dir, dep, has, want, latest, type ]] function makePretty (p) { var dep = p[1] , dir = path.resolve(p[0], "node_modules", dep) , has = p[2] , want = p[3] , latest = p[4] + , type = p[6] if (!npm.config.get("global")) { dir = path.relative(process.cwd(), dir) @@ -87,12 +91,14 @@ function makePretty (p) { , latest , dirToPrettyLocation(dir) ] + if (long) columns[5] = type if (npm.color) { columns[0] = color[has === want ? "yellow" : "red"](columns[0]) // dep columns[2] = color.green(columns[2]) // want columns[3] = color.magenta(columns[3]) // latest columns[4] = color.brightBlack(columns[4]) // dir + if (long) columns[5] = color.brightBlack(columns[5]) // type } return columns @@ -111,17 +117,22 @@ function dirToPrettyLocation (dir) { function makeParseable (list) { return list.map(function (p) { + var dep = p[1] , dir = path.resolve(p[0], "node_modules", dep) , has = p[2] , want = p[3] , latest = p[4] + , type = p[6] - return [ dir + var out = [ dir , dep + "@" + want , (has ? (dep + "@" + has) : "MISSING") , dep + "@" + latest - ].join(":") + ] + if (long) out.push(type) + + return out.join(":") }).join(os.EOL) } @@ -137,6 +148,7 @@ function makeJSON (list) { , latest: p[4] , location: dir } + if (long) out[p[1]].type = p[6] }) return JSON.stringify(out, null, 2) } @@ -154,13 +166,23 @@ function outdated_ (args, dir, parentHas, depth, cb) { return cb(null, []) } var deps = null + var types = {} readJson(path.resolve(dir, "package.json"), function (er, d) { d = d || {} if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er) deps = (er) ? true : (d.dependencies || {}) + if (!er) { + Object.keys(deps).forEach(function (k) { + types[k] = "dependencies" + }) + } if (npm.config.get("save-dev")) { deps = d.devDependencies || {} + Object.keys(deps).forEach(function (k) { + types[k] = "devDependencies" + }) + return next() } @@ -174,6 +196,9 @@ function outdated_ (args, dir, parentHas, depth, cb) { if (npm.config.get("save-optional")) { deps = d.optionalDependencies || {} + Object.keys(deps).forEach(function (k) { + types[k] = "optionalDependencies" + }) return next() } @@ -186,6 +211,7 @@ function outdated_ (args, dir, parentHas, depth, cb) { Object.keys(d.devDependencies || {}).forEach(function (k) { if (!(k in parentHas)) { deps[k] = d.devDependencies[k] + types[k] = "devDependencies" } }) } @@ -236,12 +262,14 @@ function outdated_ (args, dir, parentHas, depth, cb) { // if has[dep] !== shouldHave[dep], then cb with the data // otherwise dive into the folder asyncMap(Object.keys(deps), function (dep, cb) { - shouldUpdate(args, dir, dep, has, deps[dep], depth, cb) + if (!long) return shouldUpdate(args, dir, dep, has, deps[dep], depth, cb) + + shouldUpdate(args, dir, dep, has, deps[dep], depth, cb, types[dep]) }, cb) } } -function shouldUpdate (args, dir, dep, has, req, depth, cb) { +function shouldUpdate (args, dir, dep, has, req, depth, cb, type) { // look up the most recent version. // if that's what we already have, or if it's not on the args list, // then dive into it. Otherwise, cb() with the data. @@ -260,15 +288,14 @@ function shouldUpdate (args, dir, dep, has, req, depth, cb) { } function doIt (wanted, latest) { - cb(null, [[ dir, dep, curr && curr.version, wanted, latest, req ]]) - } - - if (args.length && args.indexOf(dep) === -1) { - return skip() + if (!long) { + return cb(null, [[ dir, dep, curr && curr.version, wanted, latest, req]]) + } + cb(null, [[ dir, dep, curr && curr.version, wanted, latest, req, type]]) } - if (npa(req).type === "git") - return doIt("git", "git") + if (args.length && args.indexOf(dep) === -1) return skip() + if (npa(req).type === "git") return doIt("git", "git") // search for the latest package mapToRegistry(dep, npm.config, function (er, uri, auth) { @@ -318,10 +345,12 @@ function shouldUpdate (args, dir, dep, has, req, depth, cb) { if (!curr || dFromUrl && cFromUrl && d._from !== curr.from || d.version !== curr.version - || d.version !== l.version) + || d.version !== l.version) { doIt(d.version, l.version) - else + } + else { skip() + } } } } diff --git a/test/tap/outdated-long.js b/test/tap/outdated-long.js new file mode 100644 index 0000000000000..57566132cdd86 --- /dev/null +++ b/test/tap/outdated-long.js @@ -0,0 +1,70 @@ +var path = require("path") + +var mr = require("npm-registry-mock") +var rimraf = require("rimraf") +var test = require("tap").test + +var common = require("../common-tap.js") +var npm = require("../../") + +// config +var pkg = path.resolve(__dirname, "outdated") +var cache = path.resolve(pkg, "cache") +var nodeModules = path.resolve(pkg, "node_modules") + +test("it should not throw", function (t) { + cleanup() + process.chdir(pkg) + + var originalLog = console.log + var output = [] + var expOut = [ path.resolve(__dirname, "outdated/node_modules/underscore"), + path.resolve(__dirname, "outdated/node_modules/underscore") + + ":underscore@1.3.1" + + ":underscore@1.3.1" + + ":underscore@1.5.1" + + ":dependencies" ] + var expData = [ [ path.resolve(__dirname, "outdated"), + "underscore", + "1.3.1", + "1.3.1", + "1.5.1", + "1.3.1", + "dependencies" ] ] + + console.log = function () { + output.push.apply(output, arguments) + } + mr(common.port, function (s) { + npm.load({ + cache : "cache", + loglevel : "silent", + parseable : true, + registry : common.registry + }, + function () { + npm.install(".", function (err) { + t.ifError(err, "install success") + npm.config.set("long", true) + npm.outdated(function (er, d) { + t.ifError(er, "outdated success") + console.log = originalLog + t.same(output, expOut) + t.same(d, expData) + s.close() + t.end() + }) + }) + }) + }) +}) + +test("cleanup", function (t) { + cleanup() + t.end() +}) + +function cleanup () { + rimraf.sync(nodeModules) + rimraf.sync(cache) +}