aboutsummaryrefslogtreecommitdiff
path: root/deps/npm/lib/ls.js
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-05-05 22:33:06 -0700
committerisaacs <i@izs.me>2012-05-05 22:33:12 -0700
commit33a9ac6087732da48e7d12ea7f7fbb41926fe46c (patch)
treea914e333e80a3401ce8726355b38f1d636500cb5 /deps/npm/lib/ls.js
parent1858d1c340ca2631e28a32eb542c85ee8f725cac (diff)
downloadandroid-node-v8-33a9ac6087732da48e7d12ea7f7fbb41926fe46c.tar.gz
android-node-v8-33a9ac6087732da48e7d12ea7f7fbb41926fe46c.tar.bz2
android-node-v8-33a9ac6087732da48e7d12ea7f7fbb41926fe46c.zip
Upgrade npm to 1.1.21
Somehow this got downgraded in the last v0.6 merge. Very strange.
Diffstat (limited to 'deps/npm/lib/ls.js')
-rw-r--r--deps/npm/lib/ls.js280
1 files changed, 191 insertions, 89 deletions
diff --git a/deps/npm/lib/ls.js b/deps/npm/lib/ls.js
index 33336cf63e..276530c354 100644
--- a/deps/npm/lib/ls.js
+++ b/deps/npm/lib/ls.js
@@ -13,6 +13,7 @@ var npm = require("./npm.js")
, log = require("./utils/log.js")
, relativize = require("./utils/relativize.js")
, path = require("path")
+ , archy = require("archy")
ls.usage = "npm ls"
@@ -26,13 +27,102 @@ function ls (args, silent, cb) {
var dir = path.resolve(npm.dir, "..")
readInstalled(dir, function (er, data) {
- if (er || silent) return cb(er, data)
+ var lite = getLite(bfsify(data))
+ if (er || silent) return cb(er, data, lite)
+
var long = npm.config.get("long")
- var out = makePretty(bfsify(data), long, dir).join("\n")
- output.write(out, function (er) { cb(er, data) })
+ , json = npm.config.get("json")
+ , out
+ if (json) {
+ var seen = []
+ var d = long ? bfsify(data) : lite
+ // the raw data can be circular
+ out = JSON.stringify(d, function (k, o) {
+ if (typeof o === "object") {
+ if (-1 !== seen.indexOf(o)) return "[Circular]"
+ seen.push(o)
+ }
+ return o
+ }, 2)
+ } else if (npm.config.get("parseable")) {
+ out = makeParseable(bfsify(data), long, dir)
+ } else if (data) {
+ out = makeArchy(bfsify(data), long, dir)
+ }
+ output.write(out, function (er) { cb(er, data, lite) })
})
}
+function alphasort (a, b) {
+ a = a.toLowerCase()
+ b = b.toLowerCase()
+ return a > b ? 1
+ : a < b ? -1 : 0
+}
+
+function getLite (data, noname) {
+ var lite = {}
+ , maxDepth = npm.config.get("depth")
+ , url = require("url")
+
+ if (!noname && data.name) lite.name = data.name
+ if (data.version) lite.version = data.version
+ if (data.extraneous) {
+ lite.extraneous = true
+ lite.problems = lite.problems || []
+ lite.problems.push( "extraneous: "
+ + data.name + "@" + data.version
+ + " " + (data.path || "") )
+ }
+
+ if (data._from) {
+ var from = data._from
+ if (from.indexOf(data.name + "@") === 0) {
+ from = from.substr(data.name.length + 1)
+ }
+ var u = url.parse(from)
+ if (u.protocol) lite.from = from
+ }
+
+ if (data.invalid) {
+ lite.invalid = true
+ lite.problems = lite.problems || []
+ lite.problems.push( "invalid: "
+ + data.name + "@" + data.version
+ + " " + (data.path || "") )
+ }
+
+ if (data.dependencies) {
+ var deps = Object.keys(data.dependencies)
+ if (deps.length) lite.dependencies = deps.map(function (d) {
+ var dep = data.dependencies[d]
+ if (typeof dep === "string") {
+ lite.problems = lite.problems || []
+ var p
+ if (data.depth >= maxDepth) {
+ p = "max depth reached: "
+ } else {
+ p = "missing: "
+ }
+ p += d + "@" + dep
+ + ", required by "
+ + data.name + "@" + data.version
+ lite.problems.push(p)
+ return [d, { required: dep, missing: true }]
+ }
+ return [d, getLite(dep, true)]
+ }).reduce(function (deps, d) {
+ if (d[1].problems) {
+ lite.problems = lite.problems || []
+ lite.problems.push.apply(lite.problems, d[1].problems)
+ }
+ deps[d[0]] = d[1]
+ return deps
+ }, {})
+ }
+ return lite
+}
+
function bfsify (root, current, queue, seen) {
// walk over the data, and turn it from this:
// +-- a
@@ -45,7 +135,7 @@ function bfsify (root, current, queue, seen) {
// which looks nicer
current = current || root
queue = queue || []
- seen = seen || []
+ seen = seen || [root]
var deps = current.dependencies = current.dependencies || {}
Object.keys(deps).forEach(function (d) {
var dep = deps[d]
@@ -67,103 +157,115 @@ function bfsify (root, current, queue, seen) {
}
-function makePretty (data, long, dir, prefix, list) {
- var top = !list
- list = list || []
- prefix = prefix || ""
- list.push(format(data, long, prefix, dir))
- var deps = data.dependencies || {}
- , childPref = prefix.split("├─").join("│ ")
- .split("└─").join(" ")
- , depList = Object.keys(deps)
- , depLast = depList.length - 1
- , maxDepth = npm.config.get("depth")
- Object.keys(deps).sort(function (a, b) {
- return a > b ? 1 : -1
- }).forEach(function (d, i) {
- var depData = deps[d]
- if (typeof depData === "string") {
- if (data.depth < maxDepth) {
- var p = data.link || data.path
- log.warn("Unmet dependency in "+p, d+" "+deps[d])
- depData = npm.config.get("parseable")
- ? ( npm.config.get("long")
- ? path.resolve(data.path, "node_modules", d)
- + ":"+d+"@"+JSON.stringify(depData)+":INVALID:MISSING"
- : "" )
- : "─ \033[31;40mUNMET DEPENDENCY\033[0m "+d+" "+depData
- } else {
- if (npm.config.get("parseable")) {
- depData = path.resolve(data.path, "node_modules", d)
- + (npm.config.get("long")
- ? ":" + d + "@" + JSON.stringify(depData)
- + ":" // no realpath resolved
- + ":MAXDEPTH"
- : "")
- } else {
- depData = "─ "+d+"@'"+depData +"' (max depth reached)"
- }
- }
- }
- var c = i === depLast ? "└─" : "├─"
- makePretty(depData, long, dir, childPref + c, list)
- })
- if (top && list.length === 1 && !data._id) {
- if (!npm.config.get("parseable")) {
- list.push("(empty)")
- } else if (npm.config.get("long")) list[0] += ":EMPTY"
- }
- return list.filter(function (l) { return l && l.trim() })
+function makeArchy (data, long, dir) {
+ var out = makeArchy_(data, long, dir, 0)
+ return archy(out, "", { unicode: npm.config.get("unicode") })
}
-function ugly (data) {
+function makeArchy_ (data, long, dir, depth, parent, d) {
if (typeof data === "string") {
+ if (depth < npm.config.get("depth")) {
+ // just missing
+ var p = parent.link || parent.path
+ log.warn("Unmet dependency in "+p, d+" "+data)
+ data = "\033[31;40mUNMET DEPENDENCY\033[0m " + d + " " + data
+ } else {
+ data = d+"@'"+ data +"' (max depth reached)"
+ }
return data
}
- if (!npm.config.get("long")) return data.path
- return data.path
- + ":" + (data._id || "")
- + ":" + (data.realPath !== data.path ? data.realPath : "")
- + (data.extraneous ? ":EXTRANEOUS" : "")
- + (data.invalid ? ":INVALID" : "")
-}
+ var out = {}
+ // the top level is a bit special.
+ out.label = data._id ? data._id + " " : ""
+ if (data.link) out.label += "-> " + data.link
-function format (data, long, prefix, dir) {
- if (npm.config.get("parseable")) return ugly(data)
- if (typeof data === "string") {
- return prefix + data
- }
-// console.log([data.path, dir], "relativize")
- var depLen = Object.keys(data.dependencies).length
- , space = prefix.split("├─").join("│ ")
- .split("└─").join(" ")
- + (depLen ? "" : " ")
- , rel = relativize(data.path || "", dir)
- , l = prefix
- + (rel === "." ? "" : depLen ? "┬ " : "─ ")
- + (data._id ? data._id + " " : "")
- + (data.link ? "-> " + data.link : "") + ""
- + (rel === "." && !(long && data._id) ? dir : "")
if (data.invalid) {
- if (data.realName !== data.name) l += " ("+data.realName+")"
- l += " \033[31;40minvalid\033[0m"
+ if (data.realName !== data.name) out.label += " ("+data.realName+")"
+ out.label += " \033[31;40minvalid\033[0m"
}
- if (data.extraneous && rel !== ".") {
- l += " \033[32;40mextraneous\033[0m"
+
+ if (data.extraneous && data.path !== dir) {
+ out.label += " \033[32;40mextraneous\033[0m"
+ }
+
+ if (long) {
+ if (dir === data.path) out.label += "\n" + dir
+ out.label += "\n" + getExtras(data, dir)
+ } else if (dir === data.path) {
+ out.label += dir
+ }
+
+ // now all the children.
+ out.nodes = Object.keys(data.dependencies || {})
+ .sort(alphasort).map(function (d) {
+ return makeArchy_(data.dependencies[d], long, dir, depth + 1, data, d)
+ })
+
+ if (out.nodes.length === 0 && data.path === dir) {
+ out.nodes = ["(empty)"]
}
- if (!long || !data._id) return l
+
+ return out
+}
+
+function getExtras (data, dir) {
var extras = []
- if (rel !== ".") extras.push(rel)
- else extras.push(dir)
+ , rel = relativize(data.path || "", dir)
+ , url = require("url")
+
if (data.description) extras.push(data.description)
if (data.repository) extras.push(data.repository.url)
if (data.homepage) extras.push(data.homepage)
- extras = extras.filter(function (e) { return e })
- var lastExtra = !depLen && extras.length - 1
- l += extras.map(function (e, i) {
- var indent = !depLen ? " " : "│ "
- return "\n" + space + indent + e
- }).join("")
- return l
+ if (data._from) {
+ var from = data._from
+ if (from.indexOf(data.name + "@") === 0) {
+ from = from.substr(data.name.length + 1)
+ }
+ var u = url.parse(from)
+ if (u.protocol) extras.push(from)
+ }
+ return extras.join("\n")
+}
+
+
+function makeParseable (data, long, dir, depth, parent, d) {
+ depth = depth || 0
+
+ return [ makeParseable_(data, long, dir, depth, parent, d) ]
+ .concat(Object.keys(data.dependencies || {})
+ .sort(alphasort).map(function (d) {
+ return makeParseable(data.dependencies[d], long, dir, depth + 1, data, d)
+ }))
+ .join("\n")
+}
+
+function makeParseable_ (data, long, dir, depth, parent, d) {
+ if (typeof data === "string") {
+ if (data.depth < npm.config.get("depth")) {
+ var p = parent.link || parent.path
+ log.warn("Unmet dependency in "+p, d+" "+data)
+ data = npm.config.get("long")
+ ? path.resolve(parent.path, "node_modules", d)
+ + ":"+d+"@"+JSON.stringify(data)+":INVALID:MISSING"
+ : ""
+ } else {
+ data = path.resolve(data.path, "node_modules", d)
+ + (npm.config.get("long")
+ ? ":" + d + "@" + JSON.stringify(data)
+ + ":" // no realpath resolved
+ + ":MAXDEPTH"
+ : "")
+ }
+
+ return data
+ }
+
+ if (!npm.config.get("long")) return data.path
+
+ return data.path
+ + ":" + (data._id || "")
+ + ":" + (data.realPath !== data.path ? data.realPath : "")
+ + (data.extraneous ? ":EXTRANEOUS" : "")
+ + (data.invalid ? ":INVALID" : "")
}