Source: apc-abstract-heir/task/worker/inherit_templates.js

/**
 * Inherit templates from prototype.
 * @function CI.worker.inheritTemplates
 * @param {object} config - Work configuration.
 * @param {string} config.pattern - Source filename pattern. Relative to prototype base dir.Glob.
 * @param {string} [config.destDir=apeman.current.basedir()] - Destination directory name.
 * @param {string} config.ignore - Ignore  filename pattern. Glob.
 * @param {function} callback - Callback when done.
 * @author Taka Okunishi
 *
 */
var path = require('path'),
    apeman = require('apeman'),
    file = require('../../lib/file'),
    debug = require('./_prototype')._debug,
    relativeSymlink = file.relativeSymlink,
    forceUnlink = file.forceUnlink,
    mkdirP = file.mkdirP,
    fs = require('fs'),
    matchesGlob = file.matchesGlob;
module.exports = function (config, callback) {
    var async = require('async');

    var prototype = apeman.current.getPrototype(),
        prototypeBase = prototype.basedir(),
        src = [].concat(config.pattern || []).map(function (pattern) {
            return path.resolve(prototypeBase, pattern);
        }),
        destDir = path.resolve(config.destDir || apeman.current.basedir()),
        ignore = [].concat(config.ignore || []).map(function (ignore) {
            return path.resolve(prototypeBase, ignore);
        });


    file.expandGlob(src, function (err, filenames) {
        if (err) {
            callback(err);
            return;
        }
        async.series(
            filenames
                .filter(function (filename) {
                    if (!ignore) return true;
                    for (var i = 0; i < ignore.length; i++) {
                        var hit = matchesGlob(filename, ignore[i]);
                        if (hit) return false;
                    }
                    return true;
                })
                .map(function (src) {
                    var dest = path.resolve(destDir, path.relative(prototypeBase, src));
                    return function (callback) {
                        fs.exists(dest, function (exists) {
                            if (exists) {
                                callback();
                                return;
                            }
                            mkdirP(path.dirname(dest), function (err) {
                                if (err) {
                                    callback(err);
                                    return;
                                }
                                relativeSymlink(src, dest, function (err) {
                                    if (!err) {
                                        debug.didCreateLink(dest, src);
                                    }
                                    callback(err);
                                });
                            })
                        });
                    }
                }),
            function (err) {
                callback(err);
            }
        );
    });
};