UNPKG

gorillajs

Version:

A smart development environment designed to easily install and neatly manage web applications. Gorilla JS frees you from the repetitive daily tasks like apps installation, database management, creation of virtual environment, server configuration… And it

244 lines (215 loc) • 6.04 kB
// imported from ncp (this is temporary, will rewrite) var fs = require('graceful-fs') var path = require('path') var utimes = require('../util/utimes') function ncp (source, dest, options, callback) { if (!callback) { callback = options options = {} } var basePath = process.cwd() var currentPath = path.resolve(basePath, source) var targetPath = path.resolve(basePath, dest) var filter = options.filter var transform = options.transform var clobber = options.clobber !== false var dereference = options.dereference var preserveTimestamps = options.preserveTimestamps === true var errs = null var started = 0 var finished = 0 var running = 0 // this is pretty useless now that we're using graceful-fs // consider removing var limit = options.limit || 512 startCopy(currentPath) function startCopy (source) { started++ if (filter) { if (filter instanceof RegExp) { if (!filter.test(source)) { return doneOne(true) } } else if (typeof filter === 'function') { if (!filter(source)) { return doneOne(true) } } } return getStats(source) } function getStats (source) { var stat = dereference ? fs.stat : fs.lstat if (running >= limit) { return setImmediate(function () { getStats(source) }) } running++ stat(source, function (err, stats) { if (err) return onError(err) // We need to get the mode from the stats object and preserve it. var item = { name: source, mode: stats.mode, mtime: stats.mtime, // modified time atime: stats.atime, // access time stats: stats // temporary } if (stats.isDirectory()) { return onDir(item) } else if (stats.isFile() || stats.isCharacterDevice() || stats.isBlockDevice()) { return onFile(item) } else if (stats.isSymbolicLink()) { // Symlinks don't really need to know about the mode. return onLink(source) } }) } function onFile (file) { var target = file.name.replace(currentPath, targetPath) isWritable(target, function (writable) { if (writable) { copyFile(file, target) } else { if (clobber) { rmFile(target, function () { copyFile(file, target) }) } else { doneOne() } } }) } function copyFile (file, target) { var readStream = fs.createReadStream(file.name) var writeStream = fs.createWriteStream(target, { mode: file.mode }) readStream.on('error', onError) writeStream.on('error', onError) if (transform) { transform(readStream, writeStream, file) } else { writeStream.on('open', function () { readStream.pipe(writeStream) }) } writeStream.once('finish', function () { fs.chmod(target, file.mode, function (err) { if (err) return onError(err) if (preserveTimestamps) { utimes.utimesMillis(target, file.atime, file.mtime, function (err) { if (err) return onError(err) return doneOne() }) } else { doneOne() } }) }) } function rmFile (file, done) { fs.unlink(file, function (err) { if (err) return onError(err) return done() }) } function onDir (dir) { var target = dir.name.replace(currentPath, targetPath) isWritable(target, function (writable) { if (writable) { return mkDir(dir, target) } copyDir(dir.name) }) } function mkDir (dir, target) { fs.mkdir(target, dir.mode, function (err) { if (err) return onError(err) // despite setting mode in fs.mkdir, doesn't seem to work // so we set it here. fs.chmod(target, dir.mode, function (err) { if (err) return onError(err) copyDir(dir.name) }) }) } function copyDir (dir) { fs.readdir(dir, function (err, items) { if (err) return onError(err) items.forEach(function (item) { startCopy(path.join(dir, item)) }) return doneOne() }) } function onLink (link) { var target = link.replace(currentPath, targetPath) fs.readlink(link, function (err, resolvedPath) { if (err) return onError(err) checkLink(resolvedPath, target) }) } function checkLink (resolvedPath, target) { if (dereference) { resolvedPath = path.resolve(basePath, resolvedPath) } isWritable(target, function (writable) { if (writable) { return makeLink(resolvedPath, target) } fs.readlink(target, function (err, targetDest) { if (err) return onError(err) if (dereference) { targetDest = path.resolve(basePath, targetDest) } if (targetDest === resolvedPath) { return doneOne() } return rmFile(target, function () { makeLink(resolvedPath, target) }) }) }) } function makeLink (linkPath, target) { fs.symlink(linkPath, target, function (err) { if (err) return onError(err) return doneOne() }) } function isWritable (path, done) { fs.lstat(path, function (err) { if (err) { if (err.code === 'ENOENT') return done(true) return done(false) } return done(false) }) } function onError (err) { if (options.stopOnError) { return callback(err) } else if (!errs && options.errs) { errs = fs.createWriteStream(options.errs) } else if (!errs) { errs = [] } if (typeof errs.write === 'undefined') { errs.push(err) } else { errs.write(err.stack + '\n\n') } return doneOne() } function doneOne (skipped) { if (!skipped) running-- finished++ if ((started === finished) && (running === 0)) { if (callback !== undefined) { return errs ? callback(errs) : callback(null) } } } } module.exports = ncp