Created
May 15, 2015 06:43
-
-
Save iarna/5350667a2d63a0eca320 to your computer and use it in GitHub Desktop.
Hoisting + CPS example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This the code in the npm multi-stage branch that removes a package directory. | |
function removeDir (pkg, log, next) { | |
var modpath = path.join(path.dirname(pkg.path), '.' + path.basename(pkg.path) + '.MODULES') | |
// Preserve any modules installed in this package, if any | |
fs.rename(path.join(pkg.path, 'node_modules'), modpath, unbuildPackage) | |
function unbuildPackage (renameEr) { | |
npm.commands.unbuild(pkg.path, true, renameEr ? andRemoveEmptyParents(pkg.path) : moveModulesBack) | |
} | |
function andRemoveEmptyParents (path) { | |
return function (er) { | |
if (er) return next(er) | |
removeEmptyParents(pkg.path) | |
} | |
} | |
function moveModulesBack () { | |
fs.readdir(modpath, makeTarget) | |
} | |
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 moveModules (mkdirEr, files) { | |
if (mkdirEr) return next(mkdirEr) | |
asyncMap(files, function (file, done) { | |
var from = path.join(modpath, file) | |
var to = path.join(pkg.path, 'node_modules', file) | |
// we ignore errors here, because they can legitimately happen, for instance, | |
// bundled modules will be in both node_modules folders | |
fs.rename(from, to, function () { done() }) | |
}, cleanup) | |
} | |
function cleanup () { | |
rimraf(modpath, afterCleanup) | |
} | |
function afterCleanup (rimrafEr) { | |
if (rimrafEr) log.warn('finalize', rimrafEr) | |
removeEmptyParents(path.resolve(pkg.path, '..')) | |
} | |
function removeEmptyParents (pkgdir) { | |
fs.rmdir(pkgdir, function (er) { | |
// FIXME: Make sure windows does what we want here | |
if (er && er.code !== 'ENOENT') return next() | |
removeEmptyParents(path.resolve(pkgdir, '..')) | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The FIXME alludes to the fact that Windows doesn't always have the same error codes for the same conditions as Unix-like-OSes. Unfortunately, ENOENT is often replaced by EPERM. =/ This code will likely end up w/ a stat inserted prior to a then conditional rmdir.