Source: apc-abstract/lib/file/copy_dir.js

/**
 * Copy a directory.
 * @function lib.file.copyDir
 * @param {string} src - Directory path to copy from.
 * @param {string} dest - Directory path to copy to.
 * @param {function} callback - Callback when done.
 * @author Taka Okunishi
 *
 */
var path = require('path'),
    copyFile = require('./copy_file'),
    mkdirP = require('./mkdir_p');

exports = module.exports = function (src, dest, callback) {
    if (!callback) callback = new Function;
    var async = require('async');
    exports._readdirRecursive(src, function (err, filenames) {
        if (err) {
            callback(err);
            return;
        }
        async.series(
            filenames
                .map(function (filename) {
                    return {
                        src: path.resolve(src, filename),
                        dest: path.resolve(dest, filename)
                    };
                })
                .map(function (data) {
                    return function (callback) {
                        exports.mkdirP(path.dirname(data.dest), function (err) {
                            if (err) {
                                callback(err);
                            } else {
                                copyFile(data.src, data.dest, function (err) {
                                    callback(err);
                                });
                            }
                        });
                    };
                }),
            function (err) {
                callback(err);
            }
        )
    });
};
exports._readdirRecursive = require('./readdir_recursive');
exports.mkdirP = mkdirP;