summaryrefslogtreecommitdiff
path: root/deps/npm/lib/install/action
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/lib/install/action')
-rw-r--r--deps/npm/lib/install/action/extract.js163
-rw-r--r--deps/npm/lib/install/action/fetch.js31
-rw-r--r--deps/npm/lib/install/action/finalize.js131
-rw-r--r--deps/npm/lib/install/action/global-install.js2
-rw-r--r--deps/npm/lib/install/action/refresh-package-json.js38
-rw-r--r--deps/npm/lib/install/action/update-linked.js16
6 files changed, 190 insertions, 191 deletions
diff --git a/deps/npm/lib/install/action/extract.js b/deps/npm/lib/install/action/extract.js
index fd9562c184..7839177850 100644
--- a/deps/npm/lib/install/action/extract.js
+++ b/deps/npm/lib/install/action/extract.js
@@ -1,67 +1,56 @@
'use strict'
-var path = require('path')
-var iferr = require('iferr')
-var asyncMap = require('slide').asyncMap
-var fs = require('graceful-fs')
-var mkdirp = require('mkdirp')
-var move = require('../../utils/move.js')
-var gentlyRm = require('../../utils/gently-rm.js')
-var updatePackageJson = require('../update-package-json')
-var npm = require('../../npm.js')
-var moduleName = require('../../utils/module-name.js')
-var packageId = require('../../utils/package-id.js')
-var cache = require('../../cache.js')
-var moduleStagingPath = require('../module-staging-path.js')
-var readPackageJson = require('read-package-json')
-module.exports = function (staging, pkg, log, next) {
- log.silly('extract', packageId(pkg))
- var up = npm.config.get('unsafe-perm')
- var user = up ? null : npm.config.get('user')
- var group = up ? null : npm.config.get('group')
- var extractTo = moduleStagingPath(staging, pkg)
- cache.unpack(pkg.package.name, pkg.package.version, extractTo, null, null, user, group,
- andUpdatePackageJson(pkg, staging, extractTo,
- andStageBundledChildren(pkg, staging, extractTo, log,
- andRemoveExtraneousBundles(extractTo, next))))
-}
-
-function andUpdatePackageJson (pkg, staging, extractTo, next) {
- return iferr(next, function () {
- readPackageJson(path.join(extractTo, 'package.json'), false, function (err, metadata) {
- if (!err) {
- // Copy _ keys (internal to npm) and any missing keys from the possibly incomplete
- // registry metadata over to the full package metadata read off of disk.
- Object.keys(pkg.package).forEach(function (key) {
- if (key[0] === '_' || !(key in metadata)) metadata[key] = pkg.package[key]
- })
- metadata.name = pkg.package.name // things go wrong if these don't match
- pkg.package = metadata
- }
- updatePackageJson(pkg, extractTo, next)
- })
- })
-}
+const BB = require('bluebird')
-function andStageBundledChildren (pkg, staging, extractTo, log, next) {
- return iferr(next, function () {
- if (!pkg.package.bundleDependencies) return next()
+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')
- asyncMap(pkg.children, andStageBundledModule(pkg, staging, extractTo), next)
+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
})
-}
-
-function andRemoveExtraneousBundles (extractTo, next) {
- return iferr(next, function () {
- gentlyRm(path.join(extractTo, 'node_modules'), next)
+ 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 andStageBundledModule (bundler, staging, parentPath) {
- return function (child, next) {
- if (child.error) return next(child.error)
- stageBundledModule(bundler, child, staging, parentPath, next)
- }
+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) {
@@ -70,47 +59,43 @@ function getTree (pkg) {
}
function warn (pkg, code, msg) {
- var tree = getTree(pkg)
- var err = new Error(msg)
+ const tree = getTree(pkg)
+ const err = new Error(msg)
err.code = code
tree.warnings.push(err)
}
-function stageBundledModule (bundler, child, staging, parentPath, next) {
- var stageFrom = path.join(parentPath, 'node_modules', child.package.name)
- var stageTo = moduleStagingPath(staging, child)
-
- return asyncMap(child.children, andStageBundledModule(bundler, staging, stageFrom), iferr(next, finishModule))
+function stageBundledModule (bundler, child, staging, parentPath) {
+ const stageFrom = path.join(parentPath, 'node_modules', child.package.name)
+ const stageTo = moduleStagingPath(staging, child)
- function finishModule () {
- // If we were the one's who bundled this module…
- if (child.fromBundle === bundler) {
- return moveModule()
+ return BB.map(child.children, (child) => {
+ if (child.error) {
+ throw child.error
} else {
- return checkForReplacement()
+ return stageBundledModule(bundler, child, staging, stageFrom)
}
- }
-
- function moveModule () {
- return mkdirp(path.dirname(stageTo), iferr(next, function () {
- return move(stageFrom, stageTo, iferr(next, updateMovedPackageJson))
- }))
- }
+ }).then(() => {
+ return finishModule(bundler, child, stageTo, stageFrom)
+ })
+}
- function checkForReplacement () {
- return fs.stat(stageFrom, function (notExists, exists) {
- if (exists) {
- warn(bundler, 'EBUNDLEOVERRIDE', 'In ' + packageId(bundler) +
- ' replacing bundled version of ' + moduleName(child) +
- ' with ' + packageId(child))
- return gentlyRm(stageFrom, next)
- } else {
- return next()
- }
+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)
})
- }
-
- function updateMovedPackageJson () {
- updatePackageJson(child, stageTo, next)
+ } 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)
+ }, () => {})
}
}
diff --git a/deps/npm/lib/install/action/fetch.js b/deps/npm/lib/install/action/fetch.js
index 0e9146a0d5..474e00b05c 100644
--- a/deps/npm/lib/install/action/fetch.js
+++ b/deps/npm/lib/install/action/fetch.js
@@ -1,29 +1,12 @@
'use strict'
-// var cache = require('../../cache.js')
-// var packageId = require('../../utils/package-id.js')
-// var moduleName = require('../../utils/module-name.js')
-module.exports = function (staging, pkg, log, next) {
- next()
-/*
-// FIXME: Unnecessary as long as we have to have the tarball to resolve all deps, which
-// is progressively seeming to be likely for the indefinite future.
-// ALSO fails for local deps specified with relative URLs outside of the top level.
+const packageId = require('../../utils/package-id.js')
+const pacote = require('pacote')
+const pacoteOpts = require('../../config/pacote')
- var name = moduleName(pkg)
- var version
- switch (pkg.package._requested.type) {
- case 'version':
- case 'range':
- version = pkg.package.version
- break
- case 'hosted':
- name = name + '@' + pkg.package._requested.spec
- break
- default:
- name = pkg.package._requested.raw
- }
+module.exports = fetch
+function fetch (staging, pkg, log, next) {
log.silly('fetch', packageId(pkg))
- cache.add(name, version, pkg.parent.path, false, next)
-*/
+ const opts = pacoteOpts({integrity: pkg.package._integrity})
+ pacote.prefetch(pkg.package._requested, opts).then(() => next(), next)
}
diff --git a/deps/npm/lib/install/action/finalize.js b/deps/npm/lib/install/action/finalize.js
index 03a71f4cc0..1e86475710 100644
--- a/deps/npm/lib/install/action/finalize.js
+++ b/deps/npm/lib/install/action/finalize.js
@@ -1,85 +1,94 @@
'use strict'
-var path = require('path')
-var rimraf = require('rimraf')
-var fs = require('graceful-fs')
-var mkdirp = require('mkdirp')
-var asyncMap = require('slide').asyncMap
-var move = require('../../utils/move.js')
-var gentlyRm = require('../../utils/gently-rm')
-var moduleStagingPath = require('../module-staging-path.js')
+const path = require('path')
+const fs = require('graceful-fs')
+const Bluebird = require('bluebird')
+const rimraf = Bluebird.promisify(require('rimraf'))
+const mkdirp = Bluebird.promisify(require('mkdirp'))
+const lstat = Bluebird.promisify(fs.lstat)
+const readdir = Bluebird.promisify(fs.readdir)
+const symlink = Bluebird.promisify(fs.symlink)
+const gentlyRm = require('../../utils/gently-rm')
+const moduleStagingPath = require('../module-staging-path.js')
+const move = require('move-concurrently')
+const moveOpts = {fs: fs, Promise: Bluebird, maxConcurrency: 4}
+const getRequested = require('../get-requested.js')
-module.exports = function (staging, pkg, log, next) {
- log.silly('finalize', pkg.path)
+module.exports = function (staging, pkg, log) {
+ log.silly('finalize', pkg.realpath)
- var extractedTo = moduleStagingPath(staging, pkg)
+ const extractedTo = moduleStagingPath(staging, pkg)
- var delpath = path.join(path.dirname(pkg.path), '.' + path.basename(pkg.path) + '.DELETE')
+ const delpath = path.join(path.dirname(pkg.realpath), '.' + path.basename(pkg.realpath) + '.DELETE')
+ let movedDestAway = false
- mkdirp(path.resolve(pkg.path, '..'), whenParentExists)
-
- function whenParentExists (mkdirEr) {
- if (mkdirEr) return next(mkdirEr)
- // We stat first, because we can't rely on ENOTEMPTY from Windows.
- // Windows, by contrast, gives the generic EPERM of a folder already exists.
- fs.lstat(pkg.path, destStatted)
- }
-
- function destStatted (doesNotExist) {
- if (doesNotExist) {
- move(extractedTo, pkg.path, whenMoved)
- } else {
- moveAway()
- }
- }
-
- function whenMoved (moveEr) {
- if (!moveEr) return next()
- if (moveEr.code !== 'ENOTEMPTY' && moveEr.code !== 'EEXIST') return next(moveEr)
- moveAway()
+ const requested = pkg.package._requested || getRequested(pkg)
+ if (requested.type === 'directory') {
+ return makeParentPath(pkg.path)
+ .then(() => symlink(pkg.realpath, pkg.path, 'junction'))
+ .catch((ex) => {
+ return rimraf(pkg.path).then(() => symlink(pkg.realpath, pkg.path, 'junction'))
+ })
+ } else {
+ return makeParentPath(pkg.realpath)
+ .then(moveStagingToDestination)
+ .then(restoreOldNodeModules)
+ .catch((err) => {
+ if (movedDestAway) {
+ return rimraf(pkg.realpath).then(moveOldDestinationBack).then(() => {
+ throw err
+ })
+ } else {
+ throw err
+ }
+ })
+ .then(() => rimraf(delpath))
}
- function moveAway () {
- move(pkg.path, delpath, whenOldMovedAway)
+ function makeParentPath (dir) {
+ return mkdirp(path.dirname(dir))
}
- function whenOldMovedAway (moveEr) {
- if (moveEr) return next(moveEr)
- move(extractedTo, pkg.path, whenConflictMoved)
+ function moveStagingToDestination () {
+ return destinationIsClear()
+ .then(actuallyMoveStaging)
+ .catch(() => moveOldDestinationAway().then(actuallyMoveStaging))
}
- function whenConflictMoved (moveEr) {
- // if we got an error we'll try to put back the original module back,
- // succeed or fail though we want the original error that caused this
- if (moveEr) return move(delpath, pkg.path, function () { next(moveEr) })
- fs.readdir(path.join(delpath, 'node_modules'), makeTarget)
+ function destinationIsClear () {
+ return lstat(pkg.realpath).then(() => {
+ throw new Error('destination exists')
+ }, () => {})
}
- function makeTarget (readdirEr, files) {
- if (readdirEr) return cleanup()
- if (!files.length) return cleanup()
- mkdirp(path.join(pkg.path, 'node_modules'), function (mkdirEr) { moveModules(mkdirEr, files) })
+ function actuallyMoveStaging () {
+ return move(extractedTo, pkg.realpath, moveOpts)
}
- function moveModules (mkdirEr, files) {
- if (mkdirEr) return next(mkdirEr)
- asyncMap(files, function (file, done) {
- var from = path.join(delpath, 'node_modules', file)
- var to = path.join(pkg.path, 'node_modules', file)
- move(from, to, done)
- }, cleanup)
+ function moveOldDestinationAway () {
+ return rimraf(delpath).then(() => {
+ return move(pkg.realpath, delpath, moveOpts)
+ }).then(() => { movedDestAway = true })
}
- function cleanup (moveEr) {
- if (moveEr) return next(moveEr)
- rimraf(delpath, afterCleanup)
+ function moveOldDestinationBack () {
+ return move(delpath, pkg.realpath, moveOpts).then(() => { movedDestAway = false })
}
- function afterCleanup (rimrafEr) {
- if (rimrafEr) log.warn('finalize', rimrafEr)
- next()
+ function restoreOldNodeModules () {
+ if (!movedDestAway) return
+ return readdir(path.join(delpath, 'node_modules')).catch(() => []).then((modules) => {
+ if (!modules.length) return
+ return mkdirp(path.join(pkg.realpath, 'node_modules')).then(() => Bluebird.map(modules, (file) => {
+ const from = path.join(delpath, 'node_modules', file)
+ const to = path.join(pkg.realpath, 'node_modules', file)
+ return move(from, to, moveOpts)
+ }))
+ })
}
}
module.exports.rollback = function (top, staging, pkg, next) {
- gentlyRm(pkg.path, false, top, next)
+ const requested = pkg.package._requested || getRequested(pkg)
+ if (requested.type === 'directory') return next()
+ gentlyRm(pkg.realpath, false, top, next)
}
diff --git a/deps/npm/lib/install/action/global-install.js b/deps/npm/lib/install/action/global-install.js
index e4fd8d11d1..bdc121b693 100644
--- a/deps/npm/lib/install/action/global-install.js
+++ b/deps/npm/lib/install/action/global-install.js
@@ -8,7 +8,7 @@ module.exports = function (staging, pkg, log, next) {
log.silly('global-install', packageId(pkg))
var globalRoot = path.resolve(npm.globalDir, '..')
npm.config.set('global', true)
- var install = new Installer(globalRoot, false, [pkg.package.name + '@' + pkg.package._requested.spec])
+ var install = new Installer(globalRoot, false, [pkg.package.name + '@' + pkg.package._requested.fetchSpec])
install.link = false
install.run(function () {
npm.config.set('global', false)
diff --git a/deps/npm/lib/install/action/refresh-package-json.js b/deps/npm/lib/install/action/refresh-package-json.js
new file mode 100644
index 0000000000..337be0caf2
--- /dev/null
+++ b/deps/npm/lib/install/action/refresh-package-json.js
@@ -0,0 +1,38 @@
+'use strict'
+const path = require('path')
+const Bluebird = require('bluebird')
+const readJson = Bluebird.promisify(require('read-package-json'))
+const updatePackageJson = Bluebird.promisify(require('../update-package-json'))
+const getRequested = require('../get-requested.js')
+
+module.exports = function (staging, pkg, log) {
+ log.silly('refresh-package-json', pkg.realpath)
+
+ return readJson(path.join(pkg.path, 'package.json'), false).then((metadata) => {
+ Object.keys(pkg.package).forEach(function (key) {
+ if (key !== '_injectedFromShrinkwrap' && !isEmpty(pkg.package[key])) {
+ metadata[key] = pkg.package[key]
+ if (key === '_resolved' && metadata[key] == null && pkg.package._injectedFromShrinkwrap) {
+ metadata[key] = pkg.package._injectedFromShrinkwrap.resolved
+ }
+ }
+ })
+ // These two sneak in and it's awful
+ delete metadata.readme
+ delete metadata.readmeFilename
+
+ pkg.package = metadata
+ }).catch(() => 'ignore').then(() => {
+ const requested = pkg.package._requested || getRequested(pkg)
+ if (requested.type !== 'directory') {
+ return updatePackageJson(pkg, pkg.path)
+ }
+ })
+}
+
+function isEmpty (value) {
+ if (value == null) return true
+ if (Array.isArray(value)) return !value.length
+ if (typeof value === 'object') return !Object.keys(value).length
+ return false
+}
diff --git a/deps/npm/lib/install/action/update-linked.js b/deps/npm/lib/install/action/update-linked.js
deleted file mode 100644
index 0babe10fdf..0000000000
--- a/deps/npm/lib/install/action/update-linked.js
+++ /dev/null
@@ -1,16 +0,0 @@
-'use strict'
-var path = require('path')
-
-function getTop (pkg) {
- if (pkg.target && pkg.target.parent) return getTop(pkg.target.parent)
- if (pkg.parent) return getTop(pkg.parent)
- return pkg.path
-}
-
-module.exports = function (staging, pkg, log, next) {
- if (pkg.package.version !== pkg.oldPkg.package.version) {
- log.warn('update-linked', path.relative(getTop(pkg), pkg.path), 'needs updating to', pkg.package.version,
- 'from', pkg.oldPkg.package.version, "but we can't, as it's a symlink")
- }
- next()
-}