diff options
Diffstat (limited to 'deps/npm/lib/install.js')
-rw-r--r-- | deps/npm/lib/install.js | 153 |
1 files changed, 9 insertions, 144 deletions
diff --git a/deps/npm/lib/install.js b/deps/npm/lib/install.js index 9270303a6..f0604a9ce 100644 --- a/deps/npm/lib/install.js +++ b/deps/npm/lib/install.js @@ -73,6 +73,7 @@ var npm = require("./npm.js") , lifecycle = require("./utils/lifecycle.js") , archy = require("archy") , isGitUrl = require("./utils/is-git-url.js") + , npmInstallChecks = require("npm-install-checks") function install (args, cb_) { var hasArguments = !!args.length @@ -842,12 +843,16 @@ function installOne_ (target, where, context, cb) { } installOnesInProgress[target.name].push(where) var indexOfIOIP = installOnesInProgress[target.name].length - 1 + , force = npm.config.get("force") + , nodeVersion = npm.config.get("node-version") + , strict = npm.config.get("engine-strict") + , c = npmInstallChecks chain - ( [ [checkEngine, target] - , [checkPlatform, target] - , [checkCycle, target, context.ancestors] - , [checkGit, targetFolder] + ( [ [c.checkEngine, target, npm.version, nodeVersion, force, strict] + , [c.checkPlatform, target, force] + , [c.checkCycle, target, context.ancestors] + , [c.checkGit, targetFolder] , [write, target, targetFolder, context] ] , function (er, d) { installOnesInProgress[target.name].splice(indexOfIOIP, 1) @@ -860,146 +865,6 @@ function installOne_ (target, where, context, cb) { ) } -function checkEngine (target, cb) { - var npmv = npm.version - , force = npm.config.get("force") - , nodev = force ? null : npm.config.get("node-version") - , strict = npm.config.get("engine-strict") || target.engineStrict - , eng = target.engines - if (!eng) return cb() - if (nodev && eng.node && !semver.satisfies(nodev, eng.node) - || eng.npm && !semver.satisfies(npmv, eng.npm)) { - if (strict) { - var er = new Error("Unsupported") - er.code = "ENOTSUP" - er.required = eng - er.pkgid = target._id - return cb(er) - } else { - log.warn( "engine", "%s: wanted: %j (current: %j)" - , target._id, eng, {node: nodev, npm: npm.version} ) - } - } - return cb() -} - -function checkPlatform (target, cb) { - var platform = process.platform - , arch = process.arch - , osOk = true - , cpuOk = true - , force = npm.config.get("force") - - if (force) { - return cb() - } - - if (target.os) { - osOk = checkList(platform, target.os) - } - if (target.cpu) { - cpuOk = checkList(arch, target.cpu) - } - if (!osOk || !cpuOk) { - var er = new Error("Unsupported") - er.code = "EBADPLATFORM" - er.os = target.os || ['any'] - er.cpu = target.cpu || ['any'] - er.pkgid = target._id - return cb(er) - } - return cb() -} - -function checkList (value, list) { - var tmp - , match = false - , blc = 0 - if (typeof list === "string") { - list = [list] - } - if (list.length === 1 && list[0] === "any") { - return true - } - for (var i = 0; i < list.length; ++i) { - tmp = list[i] - if (tmp[0] === '!') { - tmp = tmp.slice(1) - if (tmp === value) { - return false - } - ++blc - } else { - match = match || tmp === value - } - } - return match || blc === list.length -} - -function checkCycle (target, ancestors, cb) { - // there are some very rare and pathological edge-cases where - // a cycle can cause npm to try to install a never-ending tree - // of stuff. - // Simplest: - // - // A -> B -> A' -> B' -> A -> B -> A' -> B' -> A -> ... - // - // Solution: Simply flat-out refuse to install any name@version - // that is already in the prototype tree of the ancestors object. - // A more correct, but more complex, solution would be to symlink - // the deeper thing into the new location. - // Will do that if anyone whines about this irl. - // - // Note: `npm install foo` inside of the `foo` package will abort - // earlier if `--force` is not set. However, if it IS set, then - // we need to still fail here, but just skip the first level. Of - // course, it'll still fail eventually if it's a true cycle, and - // leave things in an undefined state, but that's what is to be - // expected when `--force` is used. That is why getPrototypeOf - // is used *twice* here: to skip the first level of repetition. - - var p = Object.getPrototypeOf(Object.getPrototypeOf(ancestors)) - , name = target.name - , version = target.version - while (p && p !== Object.prototype && p[name] !== version) { - p = Object.getPrototypeOf(p) - } - if (p[name] !== version) return cb() - - var er = new Error("Unresolvable cycle detected") - var tree = [target._id, JSON.parse(JSON.stringify(ancestors))] - , t = Object.getPrototypeOf(ancestors) - while (t && t !== Object.prototype) { - if (t === p) t.THIS_IS_P = true - tree.push(JSON.parse(JSON.stringify(t))) - t = Object.getPrototypeOf(t) - } - log.verbose("unresolvable dependency tree", tree) - er.pkgid = target._id - er.code = "ECYCLE" - return cb(er) -} - -function checkGit (folder, cb) { - // if it's a git repo then don't touch it! - fs.lstat(folder, function (er, s) { - if (er || !s.isDirectory()) return cb() - else checkGit_(folder, cb) - }) -} - -function checkGit_ (folder, cb) { - fs.stat(path.resolve(folder, ".git"), function (er, s) { - if (!er && s.isDirectory()) { - var e = new Error("Appears to be a git repo or submodule.") - e.path = folder - e.code = "EISGIT" - return cb(e) - } - cb() - }) -} - function write (target, targetFolder, context, cb_) { var up = npm.config.get("unsafe-perm") , user = up ? null : npm.config.get("user") |