Revision 5aef65a9 deps/npm/lib/install.js
deps/npm/lib/install.js | ||
---|---|---|
61 | 61 |
var npm = require("./npm.js") |
62 | 62 |
, semver = require("semver") |
63 | 63 |
, readJson = require("read-package-json") |
64 |
, readInstalled = require("read-installed") |
|
64 | 65 |
, log = require("npmlog") |
65 | 66 |
, path = require("path") |
66 | 67 |
, fs = require("graceful-fs") |
... | ... | |
77 | 78 |
function cb (er, installed) { |
78 | 79 |
if (er) return cb_(er) |
79 | 80 |
|
80 |
var tree = treeify(installed || [])
|
|
81 |
, pretty = prettify(tree, installed).trim()
|
|
81 |
findPeerInvalid(where, function (er, problem) {
|
|
82 |
if (er) return cb_(er)
|
|
82 | 83 |
|
83 |
if (pretty) console.log(pretty) |
|
84 |
if (er) return cb_(er) |
|
85 |
save(where, installed, tree, pretty, cb_) |
|
84 |
if (problem) { |
|
85 |
var peerInvalidError = new Error("The package " + problem.name + |
|
86 |
" does not satisfy its siblings' peerDependencies requirements!") |
|
87 |
peerInvalidError.code = "EPEERINVALID" |
|
88 |
peerInvalidError.packageName = problem.name |
|
89 |
peerInvalidError.peersDepending = problem.peersDepending |
|
90 |
return cb(peerInvalidError) |
|
91 |
} |
|
92 |
|
|
93 |
var tree = treeify(installed || []) |
|
94 |
, pretty = prettify(tree, installed).trim() |
|
95 |
|
|
96 |
if (pretty) console.log(pretty) |
|
97 |
save(where, installed, tree, pretty, cb_) |
|
98 |
}) |
|
86 | 99 |
} |
87 | 100 |
|
88 | 101 |
// the /path/to/node_modules/.. |
... | ... | |
148 | 161 |
// initial "family" is the name:version of the root, if it's got |
149 | 162 |
// a package.json file. |
150 | 163 |
readJson(path.resolve(where, "package.json"), function (er, data) { |
151 |
if (er && er.code !== "ENOENT") return cb(er) |
|
164 |
if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
|
|
152 | 165 |
if (er) data = null |
153 | 166 |
var context = { family: {} |
154 | 167 |
, ancestors: {} |
... | ... | |
164 | 177 |
}) |
165 | 178 |
} |
166 | 179 |
|
180 |
function findPeerInvalid (where, cb) { |
|
181 |
readInstalled(where, function (er, data) { |
|
182 |
if (er) return cb(er) |
|
183 |
|
|
184 |
cb(null, findPeerInvalid_(data.dependencies, [])) |
|
185 |
}) |
|
186 |
} |
|
187 |
|
|
188 |
function findPeerInvalid_ (packageMap, fpiList) { |
|
189 |
if (fpiList.indexOf(packageMap) !== -1) |
|
190 |
return |
|
191 |
|
|
192 |
fpiList.push(packageMap) |
|
193 |
|
|
194 |
for (var packageName in packageMap) { |
|
195 |
var pkg = packageMap[packageName] |
|
196 |
|
|
197 |
if (pkg.peerInvalid) { |
|
198 |
var peersDepending = {}; |
|
199 |
for (peerName in packageMap) { |
|
200 |
var peer = packageMap[peerName] |
|
201 |
if (peer.peerDependencies && peer.peerDependencies[packageName]) { |
|
202 |
peersDepending[peer.name + "@" + peer.version] = |
|
203 |
peer.peerDependencies[packageName] |
|
204 |
} |
|
205 |
} |
|
206 |
return { name: pkg.name, peersDepending: peersDepending } |
|
207 |
} |
|
208 |
|
|
209 |
if (pkg.dependencies) { |
|
210 |
var invalid = findPeerInvalid_(pkg.dependencies, fpiList) |
|
211 |
if (invalid) |
|
212 |
return invalid |
|
213 |
} |
|
214 |
} |
|
215 |
|
|
216 |
return null |
|
217 |
} |
|
218 |
|
|
167 | 219 |
// reads dependencies for the package at "where". There are several cases, |
168 | 220 |
// depending on our current state and the package's configuration: |
169 | 221 |
// |
... | ... | |
186 | 238 |
if (er) return cb(er) |
187 | 239 |
|
188 | 240 |
if (opts && opts.dev) { |
189 |
if (!data.dependencies) data.dependencies = {};
|
|
241 |
if (!data.dependencies) data.dependencies = {} |
|
190 | 242 |
Object.keys(data.devDependencies || {}).forEach(function (k) { |
191 | 243 |
data.dependencies[k] = data.devDependencies[k] |
192 | 244 |
}) |
... | ... | |
456 | 508 |
return path.resolve(nm, p, "package.json") |
457 | 509 |
}), function (jsonfile, cb) { |
458 | 510 |
readJson(jsonfile, function (er, data) { |
459 |
if (er && er.code !== "ENOENT") return cb(er) |
|
511 |
if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
|
|
460 | 512 |
if (er) return cb(null, []) |
461 | 513 |
return cb(null, [[data.name, data.version]]) |
462 | 514 |
}) |
... | ... | |
536 | 588 |
|
537 | 589 |
if (!context.explicit) fs.readdir(nm, function (er, inst) { |
538 | 590 |
if (er) return alreadyInstalledManually = [] |
591 |
|
|
592 |
// don't even mess with non-package looking things |
|
593 |
inst = inst.filter(function (p) { |
|
594 |
return !p.match(/^[\._-]/) |
|
595 |
}) |
|
596 |
|
|
539 | 597 |
asyncMap(inst, function (pkg, cb) { |
540 | 598 |
readJson(path.resolve(nm, pkg, "package.json"), function (er, d) { |
541 |
if (er && er.code !== "ENOENT") return cb(er) |
|
599 |
if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
|
|
542 | 600 |
// error means it's not a package, most likely. |
543 | 601 |
if (er) return cb(null, []) |
544 | 602 |
|
... | ... | |
657 | 715 |
, parent = context.parent |
658 | 716 |
|
659 | 717 |
readJson(jsonFile, function (er, data) { |
660 |
if (er && er.code !== "ENOENT") return cb(er) |
|
718 |
if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
|
|
661 | 719 |
if (er || data._id === target._id) { |
662 | 720 |
if (er) { |
663 | 721 |
install( path.resolve(npm.globalDir, "..") |
... | ... | |
705 | 763 |
, target._from ] |
706 | 764 |
} |
707 | 765 |
|
766 |
// name => install locations |
|
767 |
var installOnesInProgress = Object.create(null) |
|
768 |
|
|
769 |
function isIncompatibleInstallOneInProgress(target, where) { |
|
770 |
return target.name in installOnesInProgress && |
|
771 |
installOnesInProgress[target.name].indexOf(where) !== -1 |
|
772 |
} |
|
773 |
|
|
708 | 774 |
function installOne_ (target, where, context, cb) { |
709 | 775 |
var nm = path.resolve(where, "node_modules") |
710 | 776 |
, targetFolder = path.resolve(nm, target.name) |
711 |
, prettyWhere = path.relative(process.cwd, where) |
|
777 |
, prettyWhere = path.relative(process.cwd(), where)
|
|
712 | 778 |
, parent = context.parent |
713 | 779 |
|
714 | 780 |
if (prettyWhere === ".") prettyWhere = null |
715 | 781 |
|
782 |
if (isIncompatibleInstallOneInProgress(target, where)) { |
|
783 |
var prettyTarget = path.relative(process.cwd(), targetFolder) |
|
784 |
|
|
785 |
// just call back, with no error. the error will be detected in the |
|
786 |
// final check for peer-invalid dependencies |
|
787 |
return cb() |
|
788 |
} |
|
789 |
|
|
790 |
if (!(target.name in installOnesInProgress)) { |
|
791 |
installOnesInProgress[target.name] = [] |
|
792 |
} |
|
793 |
installOnesInProgress[target.name].push(where) |
|
794 |
var indexOfIOIP = installOnesInProgress[target.name].length - 1 |
|
795 |
|
|
716 | 796 |
chain |
717 | 797 |
( [ [checkEngine, target] |
718 | 798 |
, [checkPlatform, target] |
... | ... | |
720 | 800 |
, [checkGit, targetFolder] |
721 | 801 |
, [write, target, targetFolder, context] ] |
722 | 802 |
, function (er, d) { |
803 |
installOnesInProgress[target.name].splice(indexOfIOIP, 1) |
|
804 |
|
|
723 | 805 |
if (er) return cb(er) |
806 |
|
|
724 | 807 |
d.push(resultList(target, where, parent && parent._id)) |
725 | 808 |
cb(er, d) |
726 | 809 |
} |
... | ... | |
786 | 869 |
list = [list] |
787 | 870 |
} |
788 | 871 |
if (list.length === 1 && list[0] === "any") { |
789 |
return true;
|
|
872 |
return true |
|
790 | 873 |
} |
791 | 874 |
for (var i = 0; i < list.length; ++i) { |
792 | 875 |
tmp = list[i] |
793 | 876 |
if (tmp[0] === '!') { |
794 | 877 |
tmp = tmp.slice(1) |
795 | 878 |
if (tmp === value) { |
796 |
return false;
|
|
879 |
return false |
|
797 | 880 |
} |
798 | 881 |
++blc |
799 | 882 |
} else { |
... | ... | |
933 | 1016 |
|
934 | 1017 |
if (peerDeps.length > 0) { |
935 | 1018 |
actions.push( |
936 |
[ installManyAndBuild, peerDeps, pdTargetFolder, pdContext ]
|
|
1019 |
[ installMany, peerDeps, pdTargetFolder, pdContext ] |
|
937 | 1020 |
) |
938 | 1021 |
} |
939 | 1022 |
|
Also available in: Unified diff