123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /**
- * @author Toru Nagashima
- * @copyright 2016 Toru Nagashima. All rights reserved.
- * See LICENSE file in root directory for full license.
- */
- "use strict";
- var fs = require("fs");
- var mkdir = require("mkdirp");
- var Queue = require("./queue");
- /**
- * @param {string} src - A path of the source file.
- * @param {string} dst - A path of the destination file.
- * @param {function[]} transformFactories - Factory functions for transform streams.
- * @param {function} cb - A callback function that called after copied.
- * @returns {void}
- * @private
- */
- function copyBody(src, dst, transformFactories, cb) {
- var reader = fs.createReadStream(src);
- var writer = fs.createWriteStream(dst);
- var streams = [reader];
- /**
- * Clean up.
- * @param {Error|undefined} err - An error or undefined.
- * @returns {void}
- */
- function next(err) {
- try {
- streams.forEach(function (s) {
- s.removeListener("error", next);
- if (typeof s.destroy === "function") {
- s.destroy();
- }
- });
- writer.removeListener("error", next);
- writer.removeListener("finish", next);
- } catch (cleanupErr) {
- cb(err || cleanupErr);
- return;
- }
- cb(err);
- }
- reader.on("error", next);
- writer.on("error", next);
- writer.on("finish", next);
- try {
- transformFactories.reduce(function (input, factory) {
- var t = factory(src);
- t.on("error", next);
- streams.push(t);
- return input.pipe(t);
- }, reader).pipe(writer);
- } catch (err) {
- next(err);
- }
- }
- /**
- * @param {string} src - A path of the source file.
- * @param {string} dst - A path of the destination file.
- * @param {object} options - Options.
- * @param {function[]} options.transformFactories - Factory functions for transform streams.
- * @param {boolean} options.preserve - The flag to copy attributes.
- * @param {boolean} options.update - The flag to disallow overwriting.
- * @param {function} cb - A callback function that called after copied.
- * @returns {void}
- * @private
- */
- module.exports = function copy(src, dst, _ref, cb) {
- var transformFactories = _ref.transformFactories;
- var preserve = _ref.preserve;
- var update = _ref.update;
- var q = new Queue();
- var stat = null;
- q.push(function (next) {
- return fs.stat(src, function (err, result) {
- if (err) {
- cb(err);
- } else {
- stat = result;
- next();
- }
- });
- });
- if (update) {
- q.push(function (next) {
- return fs.stat(dst, function (err, dstStat) {
- if (!err && dstStat.mtime.getTime() > stat.mtime.getTime()) {
- // Don't overwrite because the file on destination is newer than
- // the source file.
- cb(null);
- } else {
- next();
- }
- });
- });
- }
- q.push(function (next) {
- if (stat.isDirectory()) {
- mkdir(dst, function (err) {
- if (err) {
- cb(err);
- } else {
- next();
- }
- });
- } else {
- copyBody(src, dst, transformFactories, function (err) {
- if (err) {
- cb(err);
- } else {
- next();
- }
- });
- }
- });
- q.push(function (next) {
- return fs.chmod(dst, stat.mode, function (err) {
- if (err) {
- cb(err);
- } else {
- next();
- }
- });
- });
- if (preserve) {
- q.push(function (next) {
- return fs.chown(dst, stat.uid, stat.gid, function (err) {
- if (err) {
- cb(err);
- } else {
- next();
- }
- });
- });
- q.push(function (next) {
- return fs.utimes(dst, stat.atime, stat.mtime, function (err) {
- if (err) {
- cb(err);
- } else {
- next();
- }
- });
- });
- }
- q.push(function (next) {
- next();
- cb(null);
- });
- };
|