mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.1 KiB
101 lines
3.1 KiB
'use strict'
|
|
|
|
const BB = require('bluebird')
|
|
|
|
const fs = BB.promisifyAll(require('graceful-fs'))
|
|
const gentlyRm = BB.promisify(require('../../utils/gently-rm.js'))
|
|
const log = require('npmlog')
|
|
const mkdirp = BB.promisify(require('mkdirp'))
|
|
const moduleName = require('../../utils/module-name.js')
|
|
const moduleStagingPath = require('../module-staging-path.js')
|
|
const move = BB.promisify(require('../../utils/move.js'))
|
|
const npa = require('npm-package-arg')
|
|
const npm = require('../../npm.js')
|
|
const packageId = require('../../utils/package-id.js')
|
|
const pacote = require('pacote')
|
|
const pacoteOpts = require('../../config/pacote')
|
|
const path = require('path')
|
|
|
|
module.exports = extract
|
|
function extract (staging, pkg, log) {
|
|
log.silly('extract', packageId(pkg))
|
|
const up = npm.config.get('unsafe-perm')
|
|
const user = up ? null : npm.config.get('user')
|
|
const group = up ? null : npm.config.get('group')
|
|
const extractTo = moduleStagingPath(staging, pkg)
|
|
const opts = pacoteOpts({
|
|
uid: user,
|
|
gid: group,
|
|
integrity: pkg.package._integrity
|
|
})
|
|
return pacote.extract(
|
|
pkg.package._resolved
|
|
? npa.resolve(pkg.package.name, pkg.package._resolved)
|
|
: pkg.package._requested,
|
|
extractTo,
|
|
opts
|
|
).then(() => {
|
|
if (pkg.package.bundleDependencies) {
|
|
return readBundled(pkg, staging, extractTo)
|
|
}
|
|
}).then(() => {
|
|
return gentlyRm(path.join(extractTo, 'node_modules'))
|
|
})
|
|
}
|
|
|
|
function readBundled (pkg, staging, extractTo) {
|
|
return BB.map(pkg.children, (child) => {
|
|
if (child.error) {
|
|
throw child.error
|
|
} else {
|
|
return stageBundledModule(pkg, child, staging, extractTo)
|
|
}
|
|
}, {concurrency: 10})
|
|
}
|
|
|
|
function getTree (pkg) {
|
|
while (pkg.parent) pkg = pkg.parent
|
|
return pkg
|
|
}
|
|
|
|
function warn (pkg, code, msg) {
|
|
const tree = getTree(pkg)
|
|
const err = new Error(msg)
|
|
err.code = code
|
|
tree.warnings.push(err)
|
|
}
|
|
|
|
function stageBundledModule (bundler, child, staging, parentPath) {
|
|
const stageFrom = path.join(parentPath, 'node_modules', child.package.name)
|
|
const stageTo = moduleStagingPath(staging, child)
|
|
|
|
return BB.map(child.children, (child) => {
|
|
if (child.error) {
|
|
throw child.error
|
|
} else {
|
|
return stageBundledModule(bundler, child, staging, stageFrom)
|
|
}
|
|
}).then(() => {
|
|
return finishModule(bundler, child, stageTo, stageFrom)
|
|
})
|
|
}
|
|
|
|
function finishModule (bundler, child, stageTo, stageFrom) {
|
|
// If we were the one's who bundled this module…
|
|
if (child.fromBundle === bundler) {
|
|
return mkdirp(path.dirname(stageTo)).then(() => {
|
|
return move(stageFrom, stageTo)
|
|
})
|
|
} else {
|
|
return fs.statAsync(stageFrom).then(() => {
|
|
const bundlerId = packageId(bundler)
|
|
if (!getTree(bundler).warnings.some((w) => {
|
|
return w.code === 'EBUNDLEOVERRIDE'
|
|
})) {
|
|
warn(bundler, 'EBUNDLEOVERRIDE', `${bundlerId} had bundled packages that do not match the required version(s). They have been replaced with non-bundled versions.`)
|
|
}
|
|
log.verbose('bundle', `EBUNDLEOVERRIDE: Replacing ${bundlerId}'s bundled version of ${moduleName(child)} with ${packageId(child)}.`)
|
|
return gentlyRm(stageFrom)
|
|
}, () => {})
|
|
}
|
|
}
|
|
|