mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-19 06:07:59 -04:00
Continue refactoring
This commit is contained in:
@@ -35,43 +35,60 @@ var fs = require('mz/fs')
|
||||
* - symlink bins
|
||||
*/
|
||||
|
||||
module.exports = function install (ctx, pkg, modules, options) {
|
||||
debug('installing ' + pkg)
|
||||
|
||||
var keypath = (options && options.keypath || [])
|
||||
var pkgSpec = npa(pkg) // { raw, name, scope, type, spec, rawSpec }
|
||||
var pkgData // { name, version, ... }
|
||||
var fullname // 'lodash@4.0.0'
|
||||
var dist // { shasum, tarball }
|
||||
var log = ctx.log(pkgSpec) // function
|
||||
module.exports = function install (ctx, pkgSpec, modules, options) {
|
||||
debug('installing ' + pkgSpec)
|
||||
if (!ctx.fetches) ctx.fetches = {}
|
||||
|
||||
var paths = {
|
||||
modules: modules,
|
||||
store: join(ctx.root, 'node_modules', '.store'),
|
||||
tmp: join(ctx.root, 'node_modules', '.tmp', getUuid()),
|
||||
target: undefined // store + '/lodash@4.0.0'
|
||||
var pkg = {
|
||||
// Preliminary spec data
|
||||
// => { raw, name, scope, type, spec, rawSpec }
|
||||
spec: npa(pkgSpec),
|
||||
|
||||
// Dependency path to the current package
|
||||
// => ['babel-core@6.4.5', 'babylon@6.4.5', 'babel-runtime@5.8.35']
|
||||
keypath: (options && options.keypath || []),
|
||||
|
||||
// Full name of package => 'lodash@4.0.0'
|
||||
fullname: undefined,
|
||||
|
||||
// Distribution data from resolve() => { shasum, tarball }
|
||||
dist: undefined,
|
||||
|
||||
// package.json data as retrieved from resolve() => { name, version, ... }
|
||||
data: undefined
|
||||
}
|
||||
|
||||
return fs.stat(join(modules, pkgSpec.name, 'package.json'))
|
||||
var paths = {
|
||||
modules: modules, // './node_modules'
|
||||
|
||||
// Final destination
|
||||
store: join(ctx.root, 'node_modules', '.store'),
|
||||
|
||||
// Temporary destination while building
|
||||
tmp: join(ctx.root, 'node_modules', '.tmp', getUuid()),
|
||||
|
||||
// Final destination => store + '/lodash@4.0.0'
|
||||
target: undefined
|
||||
}
|
||||
|
||||
var log = ctx.log(pkg.spec) // function
|
||||
|
||||
return fs.stat(join(modules, pkg.spec.name, 'package.json'))
|
||||
.catch(err => {
|
||||
if (err.code !== 'ENOENT') throw err
|
||||
return resolve(pkgSpec)
|
||||
return resolve(pkg.spec)
|
||||
.then(set)
|
||||
.then(_ => log('resolved', pkgData))
|
||||
.then(_ => log('resolved', pkg.data))
|
||||
.then(_ => fs.stat(join(paths.target, 'package.json'))) // todo: verify version?
|
||||
.catch(err => {
|
||||
if (err.code !== 'ENOENT') throw err
|
||||
var isCircular = keypath.indexOf(fullname) > -1
|
||||
if (isCircular) {
|
||||
return Promise.resolve()
|
||||
} else {
|
||||
return memoize(ctx.fetches, fullname,
|
||||
_ => doFetch(ctx, paths, dist, pkgData, keypath.concat(fullname), log))
|
||||
}
|
||||
return isCircular(pkg)
|
||||
? Promise.resolve()
|
||||
: memoize(ctx.fetches, pkg.fullname,
|
||||
_ => doFetch(ctx, paths, pkg, log))
|
||||
})
|
||||
.then(_ => mkdirp(paths.modules))
|
||||
.then(_ => symlinkToModules(paths.target, pkgSpec, paths.modules))
|
||||
.then(_ => symlinkToModules(paths.target, pkg.spec, paths.modules))
|
||||
})
|
||||
.then(_ => log('done'))
|
||||
.catch(err => {
|
||||
@@ -81,15 +98,15 @@ module.exports = function install (ctx, pkg, modules, options) {
|
||||
|
||||
// set metadata as fetched from resolve()
|
||||
function set (res) {
|
||||
pkgData = res
|
||||
fullname = '' + res.name.replace('/', '!') + '@' + res.version
|
||||
paths.target = join(paths.store, fullname)
|
||||
dist = res.dist
|
||||
pkg.data = res
|
||||
pkg.fullname = '' + res.name.replace('/', '!') + '@' + res.version
|
||||
pkg.dist = res.dist
|
||||
paths.target = join(paths.store, pkg.fullname)
|
||||
}
|
||||
}
|
||||
|
||||
// perform a fetch to `.store/lodash@4.0.0` (paths.target)
|
||||
function doFetch (ctx, paths, dist, pkgData, keypath, log) {
|
||||
function doFetch (ctx, paths, pkg, log) {
|
||||
var installAll = require('./install_multiple')
|
||||
|
||||
return Promise.resolve()
|
||||
@@ -98,14 +115,14 @@ function doFetch (ctx, paths, dist, pkgData, keypath, log) {
|
||||
.then(_ => log('downloading'))
|
||||
.then(_ => mkdirp(paths.store))
|
||||
.then(_ => mkdirp(paths.tmp))
|
||||
.then(_ => fetch(paths.tmp, dist.tarball, dist.shasum, log))
|
||||
.then(_ => fetch(paths.tmp, pkg.dist.tarball, pkg.dist.shasum, log))
|
||||
.then(_ => linkBins(paths.modules, paths.tmp, paths.target))
|
||||
.then(_ => log('dependencies'))
|
||||
.then(_ => installAll(ctx,
|
||||
pkgData.dependencies,
|
||||
pkg.data.dependencies,
|
||||
join(paths.tmp, 'node_modules'),
|
||||
{ keypath: keypath }))
|
||||
.then(_ => symlinkSelf(paths.tmp, pkgData, keypath.length - 1))
|
||||
{ keypath: pkg.keypath.concat([ pkg.fullname ]) }))
|
||||
.then(_ => symlinkSelf(paths.tmp, pkg.data, pkg.keypath.length))
|
||||
.then(_ => fs.unlink(paths.target))
|
||||
.then(_ => fs.rename(paths.tmp, paths.target))
|
||||
}
|
||||
@@ -154,3 +171,11 @@ function symlinkToModules (target, pkg, modules) {
|
||||
|
||||
return relSymlink(target, join(modules, pkg.name))
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the current package is a circular dependency.
|
||||
*/
|
||||
|
||||
function isCircular (pkg) {
|
||||
return pkg.keypath.indexOf(pkg.fullname) > -1
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user