<commit_before>var FS = require('fs'),
    SYS = require('sys'),
    Q = require('qq'),
    bemUtil = require('./util'),
    PATH = require('./path'),
    INHERIT = require('inherit'),

    /**
     * Returns tech class for tech module path
     * @param {String} path  path to tech module
     * @returns {Tech}
     */
    getTechClass = exports.getTechClass = function(path) {
        var tech = require(path),
            TechClass = Tech;

        if(tech.Tech) return tech.Tech;
        if(tech.baseTechPath) TechClass = getTechClass(tech.baseTechPath);
        else if (tech.techModule || tech.bemBuild || tech.bemCreate) TechClass = LegacyTech;

        return INHERIT(TechClass, tech);
    },

    /**
     * Returns tech object for tech module
     * @param {String} path  tech module absolute path
     * @param {String} name  tech name
     * @returns {Tech}
     */
    createTech = exports.createTech = function(path, name) {
        path = require.resolve(path);
        return new (getTechClass(path))(name, path);
    },

    Tech = exports.Tech = INHERIT({

        /**
         * @class Base tech class
         * @constructs
         * @private
         * @param {Object} name  tech name
         * @param {Object} path  tech module absolute path
         */
        __constructor: function(name, path) {
            this.techName = name;
            this.techPath = path;
        },

        /**
         * Sets context to use in tech modules
         * @public
         * @param {Context} ctx  context
         */
        setContext: function(ctx) {
            this.context = ctx;
            return this;
        },

        /**
         * Returns context
         * @public
         * @returns {Context}
         */
        getContext: function() {
            return this.context;
        },

        /**
         * Implementation of 'bem create block | elem | mod' commands
         * @public
         * @param {String}  prefix  path prefix of object to create
         * @param {Object}  vars    variables to use in template
         * @param {Boolean} force   force creation flag
         */
        create: function(prefix, vars, force) {
            var _this = this;
            return Q.step(
                function() {
                    return _this.getCreateResults(prefix, vars);
                },
                function(res) {
                    return _this.storeCreateResults(prefix, res, force);
                }
            );
        },

        /**
         * Returns create result for one suffix
         * @protected
         * @param {String} path    full path of object to create
         * @param {String} suffix  suffix of object to create
         * @param {Object} vars    variables to use in template
         * @returns {String}
         */
        getCreateResult: function(path, suffix, vars) {
            return '';
        },

        /**
         * Returns create result for all suffixes
         * @protected
         * @param {String}  prefix  path prefix of object to create
         * @param {Object}  vars    variables to use in template
         * @returns {Object}
         */
        getCreateResults: function(prefix, vars) {
            var _this = this,
                res = {};

            this.getSuffixes().forEach(function(suffix) {
                res[suffix] = _this.getCreateResult(_this.getPath(prefix, suffix), suffix, vars);
            });

            return Q.shallow(res);
        },

        /**
         * Stores result of object creation for one suffix
         * @protected
         * @param {String}  path    full path of object to create
         * @param {String}  suffix  suffix of object to create
         * @param {Object}  res     result of object creation
         * @param {Boolean} force   force creation flag
         */
        storeCreateResult: function(path, suffix, res, force) {
            return Q.step(
                function() {
                    return bemUtil.isFileP(path);
                },
                function(exists) {
                    if(exists && !force) {
                        // TODO: bad idea to output error to console directly
                        SYS.error("Already exists '" + path + "'");
                        return;
                    }
                    return bemUtil.writeFile(path, res);
                }
            );
        },

        /**
         * Stores results of object creation
         * @protected
         * @param {String}  prefix  path prefix of object to create
         * @param {Object}  res     result of object creation
         * @param {Boolean} force   force creation flag
         */
        storeCreateResults: function(prefix, res, force) {
            var _this = this,
                done;

            this.getSuffixes().forEach(function(suffix) {
                done = Q.wait(done, _this.storeCreateResult(_this.getPath(prefix, suffix), suffix, res[suffix], force));
            });

            return done;
        },

        /**
         * Reads and returns content of object with specified prefix
         * for specified suffix
         * @protected
         * @param {String} path    full path of object to read
         * @param {String} suffix  suffix of object to read
         * @returns {String}
         */
        readContent: function(path, suffix) {
            if(bemUtil.isFile(path)) {
                return FS.readFileSync(path, 'utf8');
            }
            return '';
        },

        /**
         * Reads and returns content of object with specified prefix
         * @param {String}  prefix  path prefix of object to read content of
         * @returns {Object}
         */
        readAllContent: function(prefix) {
            var _this = this,
                res = {};

            this.getSuffixes().forEach(function(suffix) {
                res[suffix] = _this.readContent(_this.getPath(prefix, suffix), suffix);
            });

            return res;
        },

        /**
         * Implementation of 'bem create build' command
         * @public
         * @param {Array}  prefixes    prefixes to build
         * @param {String} outputDir   dir to output result to
         * @param {String} outputName  name prefix of output
         */
        build: function(prefixes, outputDir, outputName) {
            var _this = this;
            return Q.step(
                function() {
                    return _this.getBuildResults(prefixes, outputDir, outputName);
                },
                function(res) {
                    return _this.storeBuildResults(PATH.join(outputDir, outputName), res);
                }
            );
        },

        /**
         * Filters prefixes with attached suffixes and returns
         * array of paths to aggregate during build process
         * @protected
         * @param {Array} prefixes
         * @param {Array} suffixes
         * @return {Array}
         */
        filterPrefixes: function(prefixes, suffixes) {
            var _this = this,
                res = {};

            prefixes.forEach(function(prefix) {
                suffixes.forEach(function(suffix) {
                    var path = _this.getPath(prefix, suffix);
                    res[path] = bemUtil.isExists(path);
                });
            });

            return Q.when(Q.shallow(res), function(res) {
                var paths = [];
                for(var path in res) {
                    if(res[path]) paths.push(path);
                }
                return paths;
            });
        },

        /**
         * Returns build result chunk
         * @protected
         * @param {String} relPath  relative path to source object
         * @param {String} path     path to source object
         * @param {String} suffix   suffix of source object
         * @returns {String}
         */
        getBuildResultChunk: function(relPath, path, suffix) {
            return relPath + '\n';
        },

        /**
         * Builds and returns result of build of specified prefixes
         * for specified suffix
         * @protected
         * @param {Array} prefixes     prfixes to build
         * @param {String} suffix      suffix to build result for
         * @param {String} outputDir   output dir name for build result
         * @param {String} outputName  output name of build result
         */
        getBuildResult: function(prefixes, suffix, outputDir, outputName) {
            var _this = this;
            return Q.when(this.filterPrefixes(prefixes, [suffix]), function(paths) {
                return Q.shallow(paths.map(function(path) {
                    return _this.getBuildResultChunk(
                        PATH.relative(outputDir, path), path, suffix);
                }));
            });
        },

        /**
         * Builds and returns result of build of specified prefixes
         * @protected
         * @param {Array} prefixes     prfixes to build
         * @param {String} outputDir   output dir name for build result
         * @param {String} outputName  output name of build result
         * @return {Object}
         */
        getBuildResults: function(prefixes, outputDir, outputName) {
            var _this = this,
                res = {};

            this.getSuffixes().forEach(function(suffix) {
                res[suffix] = _this.getBuildResult(prefixes, suffix, outputDir, outputName);
            });

            return Q.shallow(res);
        },

        /**
         * Stores result of build for specified suffix
         * @protected
         * @param {String} path    path of object to store
         * @param {String} suffix  suffix of object to store
         * @param {String} res     result of build for specified suffix
         */
        storeBuildResult: function(path, suffix, res) {
            return bemUtil.writeFile(path, res);
        },

        /**
         * Stores results of build
         * @protected
         * @param {String} prefix  prefix of object to build
         * @param {String} res     result of build
         */
        storeBuildResults: function(prefix, res) {
            var _this = this,
                done;

            this.getSuffixes().forEach(function(suffix) {
                done = Q.wait(done, _this.storeBuildResult(_this.getPath(prefix, suffix), suffix, res[suffix]));
            });

            return done;
        },

        /**
         * Returns true if suffix mathes one of tech suffixes
         * @public
         * @param {String} suffix
         * @returns {Boolean}
         */
        matchSuffix: function(suffix) {
            (suffix.substr(0, 1) == '.') && (suffix = suffix.substr(1));
            return this.getSuffixes().indexOf(suffix) >= 0;
        },

        /**
         * Returns all tech suffixes
         * @public
         * @returns {Array}
         */
        getSuffixes: function() {
            return [this.getTechName()];
        },

        /**
         * Returns path by prefix and suffix
         * @public
         * @param {String} prefix
         * @param {String} suffix
         * @returns {String}
         */
        getPath: function(prefix, suffix) {
            suffix = suffix || this.getTechName();
            return [prefix, suffix].join('.');
        },

        /**
         * Returns tech name
         * @public
         * @returns {String}
         */
        getTechName: function() {
            if(this.techName) return this.techName;
            return bemUtil.stripModuleExt(PATH.basename(this.getTechPath()));
        },

        /**
         * Returns tech module absolute path
         * @public
         * @returns {String}
         */
        getTechPath: function() {
            return this.techPath;
        },

        /**
         * Returns tech module relative path
         * @public
         * @param   {String} from  path to calculate relative path from
         * @returns {String}
         */
        getTechRelativePath: function(from) {
            from = PATH.join(from || '.', '/');
            var absPath = this.getTechPath(),
                techPath = PATH.relative(PATH.join(__dirname, '../../'), absPath);

            // tech from 'bem' module
            if(!/^[\.\/]/.test(techPath) && /^.*?\/lib/.test(techPath)) {
                techPath = techPath.replace(/^.*?\//, 'bem/');
            } else {
                // look for tech into node_modules and NODE_PATH env variable
                var shortestPath = PATH.relative(from, absPath);
                shortestPath = shortestPath.split('/');
                module.paths.concat(bemUtil.getNodePaths()).forEach(function(reqPath) {
                    var relPath = PATH.relative(PATH.join(reqPath, '/'), absPath);
                    if(!/^\./.test(relPath)) {
                        relPath = relPath.split('/');
                        if(relPath.length < shortestPath.length) {
                            shortestPath = relPath;
                        }
                    }
                });

                techPath = Array.prototype.join.call(shortestPath, '/');
                if(!/^\./.test(techPath)) techPath = './' + techPath;
            }

            techPath = bemUtil.stripModuleExt(techPath);

            // NOTE: default tech, need to return empty path for it
            if(techPath == bemUtil.getBemTechPath('default')) return '';
            return techPath;
        }

    }, {

        /**
         * Sets context to use in tech modules
         * @static
         * @public
         * @param {Context} ctx  context
         */
        setContext: function(ctx) {
            Tech.prototype.context = ctx;
            require('./legacy-tech').Tech.setContext(ctx);
        }

    }),

    LegacyTech = INHERIT(Tech, {

        /**
         * @class Legacy tech modules wrapper class
         * @constructs
         * @private
         * @param {Object} name  tech name
         * @param {Object} path  tech module absolute path
         */
        __constructor: function(name, path) {
            this.techObj = new (require('./legacy-tech').Tech)(path, name);
            this.__base(name, path);
        },

        create: function(prefix, vars, force) {
            this.techObj.bemCreate(prefix, vars, force);
        },

        readAllContent: function(prefix) {
            var res = {};
            res[this.getTechName()] = this.techObj.getFileContent(prefix);
            return res;
        },

        build: function(prefixes, outputDir, outputName) {
            this.techObj.bemBuild(prefixes, outputDir, outputName);
            return this;
        },

        getTechName: function() {
            return this.techObj.getTechName();
        }

    });
<commit_msg>Remove `return this` from `LegacyTech().build()`<commit_after>var FS = require('fs'),
    SYS = require('sys'),
    Q = require('qq'),
    bemUtil = require('./util'),
    PATH = require('./path'),
    INHERIT = require('inherit'),

    /**
     * Returns tech class for tech module path
     * @param {String} path  path to tech module
     * @returns {Tech}
     */
    getTechClass = exports.getTechClass = function(path) {
        var tech = require(path),
            TechClass = Tech;

        if(tech.Tech) return tech.Tech;
        if(tech.baseTechPath) TechClass = getTechClass(tech.baseTechPath);
        else if (tech.techModule || tech.bemBuild || tech.bemCreate) TechClass = LegacyTech;

        return INHERIT(TechClass, tech);
    },

    /**
     * Returns tech object for tech module
     * @param {String} path  tech module absolute path
     * @param {String} name  tech name
     * @returns {Tech}
     */
    createTech = exports.createTech = function(path, name) {
        path = require.resolve(path);
        return new (getTechClass(path))(name, path);
    },

    Tech = exports.Tech = INHERIT({

        /**
         * @class Base tech class
         * @constructs
         * @private
         * @param {Object} name  tech name
         * @param {Object} path  tech module absolute path
         */
        __constructor: function(name, path) {
            this.techName = name;
            this.techPath = path;
        },

        /**
         * Sets context to use in tech modules
         * @public
         * @param {Context} ctx  context
         */
        setContext: function(ctx) {
            this.context = ctx;
            return this;
        },

        /**
         * Returns context
         * @public
         * @returns {Context}
         */
        getContext: function() {
            return this.context;
        },

        /**
         * Implementation of 'bem create block | elem | mod' commands
         * @public
         * @param {String}  prefix  path prefix of object to create
         * @param {Object}  vars    variables to use in template
         * @param {Boolean} force   force creation flag
         */
        create: function(prefix, vars, force) {
            var _this = this;
            return Q.step(
                function() {
                    return _this.getCreateResults(prefix, vars);
                },
                function(res) {
                    return _this.storeCreateResults(prefix, res, force);
                }
            );
        },

        /**
         * Returns create result for one suffix
         * @protected
         * @param {String} path    full path of object to create
         * @param {String} suffix  suffix of object to create
         * @param {Object} vars    variables to use in template
         * @returns {String}
         */
        getCreateResult: function(path, suffix, vars) {
            return '';
        },

        /**
         * Returns create result for all suffixes
         * @protected
         * @param {String}  prefix  path prefix of object to create
         * @param {Object}  vars    variables to use in template
         * @returns {Object}
         */
        getCreateResults: function(prefix, vars) {
            var _this = this,
                res = {};

            this.getSuffixes().forEach(function(suffix) {
                res[suffix] = _this.getCreateResult(_this.getPath(prefix, suffix), suffix, vars);
            });

            return Q.shallow(res);
        },

        /**
         * Stores result of object creation for one suffix
         * @protected
         * @param {String}  path    full path of object to create
         * @param {String}  suffix  suffix of object to create
         * @param {Object}  res     result of object creation
         * @param {Boolean} force   force creation flag
         */
        storeCreateResult: function(path, suffix, res, force) {
            return Q.step(
                function() {
                    return bemUtil.isFileP(path);
                },
                function(exists) {
                    if(exists && !force) {
                        // TODO: bad idea to output error to console directly
                        SYS.error("Already exists '" + path + "'");
                        return;
                    }
                    return bemUtil.writeFile(path, res);
                }
            );
        },

        /**
         * Stores results of object creation
         * @protected
         * @param {String}  prefix  path prefix of object to create
         * @param {Object}  res     result of object creation
         * @param {Boolean} force   force creation flag
         */
        storeCreateResults: function(prefix, res, force) {
            var _this = this,
                done;

            this.getSuffixes().forEach(function(suffix) {
                done = Q.wait(done, _this.storeCreateResult(_this.getPath(prefix, suffix), suffix, res[suffix], force));
            });

            return done;
        },

        /**
         * Reads and returns content of object with specified prefix
         * for specified suffix
         * @protected
         * @param {String} path    full path of object to read
         * @param {String} suffix  suffix of object to read
         * @returns {String}
         */
        readContent: function(path, suffix) {
            if(bemUtil.isFile(path)) {
                return FS.readFileSync(path, 'utf8');
            }
            return '';
        },

        /**
         * Reads and returns content of object with specified prefix
         * @param {String}  prefix  path prefix of object to read content of
         * @returns {Object}
         */
        readAllContent: function(prefix) {
            var _this = this,
                res = {};

            this.getSuffixes().forEach(function(suffix) {
                res[suffix] = _this.readContent(_this.getPath(prefix, suffix), suffix);
            });

            return res;
        },

        /**
         * Implementation of 'bem create build' command
         * @public
         * @param {Array}  prefixes    prefixes to build
         * @param {String} outputDir   dir to output result to
         * @param {String} outputName  name prefix of output
         */
        build: function(prefixes, outputDir, outputName) {
            var _this = this;
            return Q.step(
                function() {
                    return _this.getBuildResults(prefixes, outputDir, outputName);
                },
                function(res) {
                    return _this.storeBuildResults(PATH.join(outputDir, outputName), res);
                }
            );
        },

        /**
         * Filters prefixes with attached suffixes and returns
         * array of paths to aggregate during build process
         * @protected
         * @param {Array} prefixes
         * @param {Array} suffixes
         * @return {Array}
         */
        filterPrefixes: function(prefixes, suffixes) {
            var _this = this,
                res = {};

            prefixes.forEach(function(prefix) {
                suffixes.forEach(function(suffix) {
                    var path = _this.getPath(prefix, suffix);
                    res[path] = bemUtil.isExists(path);
                });
            });

            return Q.when(Q.shallow(res), function(res) {
                var paths = [];
                for(var path in res) {
                    if(res[path]) paths.push(path);
                }
                return paths;
            });
        },

        /**
         * Returns build result chunk
         * @protected
         * @param {String} relPath  relative path to source object
         * @param {String} path     path to source object
         * @param {String} suffix   suffix of source object
         * @returns {String}
         */
        getBuildResultChunk: function(relPath, path, suffix) {
            return relPath + '\n';
        },

        /**
         * Builds and returns result of build of specified prefixes
         * for specified suffix
         * @protected
         * @param {Array} prefixes     prfixes to build
         * @param {String} suffix      suffix to build result for
         * @param {String} outputDir   output dir name for build result
         * @param {String} outputName  output name of build result
         */
        getBuildResult: function(prefixes, suffix, outputDir, outputName) {
            var _this = this;
            return Q.when(this.filterPrefixes(prefixes, [suffix]), function(paths) {
                return Q.shallow(paths.map(function(path) {
                    return _this.getBuildResultChunk(
                        PATH.relative(outputDir, path), path, suffix);
                }));
            });
        },

        /**
         * Builds and returns result of build of specified prefixes
         * @protected
         * @param {Array} prefixes     prfixes to build
         * @param {String} outputDir   output dir name for build result
         * @param {String} outputName  output name of build result
         * @return {Object}
         */
        getBuildResults: function(prefixes, outputDir, outputName) {
            var _this = this,
                res = {};

            this.getSuffixes().forEach(function(suffix) {
                res[suffix] = _this.getBuildResult(prefixes, suffix, outputDir, outputName);
            });

            return Q.shallow(res);
        },

        /**
         * Stores result of build for specified suffix
         * @protected
         * @param {String} path    path of object to store
         * @param {String} suffix  suffix of object to store
         * @param {String} res     result of build for specified suffix
         */
        storeBuildResult: function(path, suffix, res) {
            return bemUtil.writeFile(path, res);
        },

        /**
         * Stores results of build
         * @protected
         * @param {String} prefix  prefix of object to build
         * @param {String} res     result of build
         */
        storeBuildResults: function(prefix, res) {
            var _this = this,
                done;

            this.getSuffixes().forEach(function(suffix) {
                done = Q.wait(done, _this.storeBuildResult(_this.getPath(prefix, suffix), suffix, res[suffix]));
            });

            return done;
        },

        /**
         * Returns true if suffix mathes one of tech suffixes
         * @public
         * @param {String} suffix
         * @returns {Boolean}
         */
        matchSuffix: function(suffix) {
            (suffix.substr(0, 1) == '.') && (suffix = suffix.substr(1));
            return this.getSuffixes().indexOf(suffix) >= 0;
        },

        /**
         * Returns all tech suffixes
         * @public
         * @returns {Array}
         */
        getSuffixes: function() {
            return [this.getTechName()];
        },

        /**
         * Returns path by prefix and suffix
         * @public
         * @param {String} prefix
         * @param {String} suffix
         * @returns {String}
         */
        getPath: function(prefix, suffix) {
            suffix = suffix || this.getTechName();
            return [prefix, suffix].join('.');
        },

        /**
         * Returns tech name
         * @public
         * @returns {String}
         */
        getTechName: function() {
            if(this.techName) return this.techName;
            return bemUtil.stripModuleExt(PATH.basename(this.getTechPath()));
        },

        /**
         * Returns tech module absolute path
         * @public
         * @returns {String}
         */
        getTechPath: function() {
            return this.techPath;
        },

        /**
         * Returns tech module relative path
         * @public
         * @param   {String} from  path to calculate relative path from
         * @returns {String}
         */
        getTechRelativePath: function(from) {
            from = PATH.join(from || '.', '/');
            var absPath = this.getTechPath(),
                techPath = PATH.relative(PATH.join(__dirname, '../../'), absPath);

            // tech from 'bem' module
            if(!/^[\.\/]/.test(techPath) && /^.*?\/lib/.test(techPath)) {
                techPath = techPath.replace(/^.*?\//, 'bem/');
            } else {
                // look for tech into node_modules and NODE_PATH env variable
                var shortestPath = PATH.relative(from, absPath);
                shortestPath = shortestPath.split('/');
                module.paths.concat(bemUtil.getNodePaths()).forEach(function(reqPath) {
                    var relPath = PATH.relative(PATH.join(reqPath, '/'), absPath);
                    if(!/^\./.test(relPath)) {
                        relPath = relPath.split('/');
                        if(relPath.length < shortestPath.length) {
                            shortestPath = relPath;
                        }
                    }
                });

                techPath = Array.prototype.join.call(shortestPath, '/');
                if(!/^\./.test(techPath)) techPath = './' + techPath;
            }

            techPath = bemUtil.stripModuleExt(techPath);

            // NOTE: default tech, need to return empty path for it
            if(techPath == bemUtil.getBemTechPath('default')) return '';
            return techPath;
        }

    }, {

        /**
         * Sets context to use in tech modules
         * @static
         * @public
         * @param {Context} ctx  context
         */
        setContext: function(ctx) {
            Tech.prototype.context = ctx;
            require('./legacy-tech').Tech.setContext(ctx);
        }

    }),

    LegacyTech = INHERIT(Tech, {

        /**
         * @class Legacy tech modules wrapper class
         * @constructs
         * @private
         * @param {Object} name  tech name
         * @param {Object} path  tech module absolute path
         */
        __constructor: function(name, path) {
            this.techObj = new (require('./legacy-tech').Tech)(path, name);
            this.__base(name, path);
        },

        create: function(prefix, vars, force) {
            this.techObj.bemCreate(prefix, vars, force);
        },

        readAllContent: function(prefix) {
            var res = {};
            res[this.getTechName()] = this.techObj.getFileContent(prefix);
            return res;
        },

        build: function(prefixes, outputDir, outputName) {
            this.techObj.bemBuild(prefixes, outputDir, outputName);
        },

        getTechName: function() {
            return this.techObj.getTechName();
        }

    });
<|endoftext|>


<commit_before>var gulp = require('gulp');
var karma = require('karma').server;
var watch = require('gulp-watch');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var image = require('gulp-image');
var compass = require('gulp-compass');
var minifyCSS = require('gulp-minify-css');
var mocha = require('gulp-mocha');
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var rename = require('gulp-rename');
var runSequence = require('run-sequence');
var preprocess = require('gulp-preprocess');
var istanbul = require('gulp-istanbul');
var coveralls = require('gulp-coveralls');
var plumber = require('gulp-plumber');

var paths = {
  src: {
    bower: './client/app/src/bower_components',
    js: './client/app/src/js',
    scss: './client/app/src/scss',
    img: './client/app/src/img',
    views: './client/app/src/views'
  },
  dist: {
    js: './client/app/dist/js',
    css: './client/app/dist/css',
    img: './client/app/dist/img',
    views: './client/app/dist/views'
  },
  server: './server',
  spec: './spec',
  jade: './server/views/_partials',
  serverSpec: __dirname + '/spec/server/**/*.js',
  karmaConf: __dirname + '/spec/karma.conf.js'
};

var handleError = function(err) {
  console.log(err.toString());
  this.emit('end');
};

var jsFiles = [
  paths.src.bower + '/angular/angular.js',
  paths.src.bower + '/angular-ui-router/release/angular-ui-router.js',
  paths.src.js + '/app.js',
  paths.src.js + '/controllers/*.js',
  paths.src.js + '/directives/*.js',
  paths.src.js + '/services/*.js'
];

// Keep track of own JS files for linting
var jsFilesForLint = [
  paths.src.js + '/**/*.js',
  paths.server + '/**/*.js',
  paths.spec + '/**/*.js'
];

var jadeFiles = [paths.jade + '/*.jade'];

/**
 * envConfig, envConfigDevelopment, and envConfigProduction are used to configure builds
 * with the proper environment. Arguments are passed into the preprocess
 * task to insert variables into files. For example, the base href needs
 * to be dynamically set based on the environment.
 */
var envConfig;

var envConfigDevelopment = {
  BASE_HREF: 'localhost:3000'
};

var envConfigProduction = {
  BASE_HREF: 'archivr-dev.herokuapp.com'
};

gulp.task('javascript', function() {
  gulp.src(jsFiles)
  .pipe(concat('app.min.js'))
  // .pipe(uglify({
  //   beautify: true
  // }))
  .on('error', handleError)
  .pipe(gulp.dest(paths.dist.js));
});

/**
 * Run JSHint
 */
gulp.task('lint', function() {
  return gulp.src(jsFilesForLint)
    .pipe(jshint())
    .pipe(jshint.reporter(stylish))
    // Error out if any warnings appear
    .pipe(jshint.reporter('fail'));
});

gulp.task('image', function() {
   gulp.src(paths.src.img + '/**/*')
    .pipe(image())
    .on('error', handleError)
    .pipe(gulp.dest(paths.dist.img));
});

gulp.task('moveViews', function() {
  gulp.src(paths.src.views + '/**/*')
    .pipe(gulp.dest(paths.dist.views));
});

gulp.task('compass', function() {
  gulp.src(paths.src.scss + '/*.scss')
    .pipe(compass({
      css: paths.dist.css,
      sass: paths.src.scss,
      image: paths.dist.img,
      require: ['breakpoint']
    }))
    .on('error', handleError)
    .pipe(minifyCSS())
    .pipe(concat('app.css'))
    .pipe(gulp.dest(paths.dist.css));
});

gulp.task('processEnv', function() {
  gulp.src(jadeFiles)
    .pipe(preprocess({context: envConfig}))
    .pipe(gulp.dest(paths.jade + '/dist'));
});

// Run testing suite: lint, karma (client-side) and mocha (server-side)
gulp.task('test', function(callback) {
  /**
   * Use `runSequence` to call tasks synchronously, otherwise
   * messages from both will be potentially interleaved.
   */
  runSequence('lint', 'karma', 'mocha', callback);
});

gulp.task('karma', function (done) {
  return karma.start({
    configFile: paths.karmaConf,
    singleRun: true
  }, done);
});

/**
 * mocha
 * =====
 * Runs the mocha tests. Because gulp-mocha is stupid, this task must be
 * forcibly exited using `process.exit()`. As such, **no other tasks will
 * successfully be reached after this task.** Do whatever hair-brained
 * workarounds are necessary to not have any tasks be dependent on this one.
 */

var handleMochaError = function (err) {
  console.log('Mocha encountered an error, exiting with status 1');
  console.log('Error:', err.message);
  process.exit(1);
};

gulp.task('mocha', function (cb) {
  var mochaErr;
  // Track src files that should be covered
  gulp.src(['./server/**/*.js'])
    .pipe(istanbul({ includeUntested: true })) // Covering files
    .pipe(istanbul.hookRequire()) // Force `require` to return covered files
    .on('finish', function() {
      // Specify server specs
      gulp.src(paths.serverSpec, {read: false})
        .pipe(plumber())
        .pipe(mocha({
          reporter: 'spec',
          timeout: 20000
        }))
        /**
         * Keep track of latest error on Mocha. Because a failed test counts
         * as an error, the process should not be exited until end of tests.
         */
        .on('error', function(err) {
          /**
           * This intermediate log is useful for when mocha crashes (as opposed
           * to a test failing). Can be commented out if needed.
           */
          console.error('ERROR:', err.message);
          console.error('Stack:', err.stack);
          mochaErr = err;
        })
        // Write reports to Istanbul
        .pipe(istanbul.writeReports())
        /**
         * The methods below are a hack to get gulp to exit after mocha tests
         * finish. Without them, `gulp mocha` doesn't exit and Travis
         * never finishes running the tests.
         */
        .on('end', function () {
          if (mochaErr) return handleMochaError(mochaErr);
          // Force mocha to exit, because gulp-mocha is stupid.
          process.exit();
        });
    });
});

/**
 * coveralls
 * =========
 * Sends code coverage data to Coveralls.
 */
gulp.task('coveralls', function () {
  if (!process.env.CI) return;
  return gulp.src([
    './coverage/client/lcov.info',
    './coverage/lcov.info'
  ])
    .pipe(concat('lcov.info'))
    .pipe(coveralls)
  return gulp.src('./coverage/lcov.info')
    .pipe(coveralls());
});

gulp.task('testy', function () {
  // return gulp.src([
  //   './coverage/client/lcov.info',
  //   './coverage/lcov.info'
  // ])
  //   .pipe(concat('combined.info'))
  //   .pipe(gulp.dest('./coverage'))
  return gulp.src('./coverage/combined.info')
  .pipe(coveralls());
});

gulp.task('watch', function() {
  gulp.watch(paths.src.img + '/**/*', ['image']);
  gulp.watch(paths.src.scss + '/**/*.scss', ['compass']);
  gulp.watch(paths.src.js + '/**/*.js', ['lint', 'javascript']);
  gulp.watch(paths.src.views + '/**/*', ['moveViews']);
});

/**
 * build is the entry-point to build out app artifacts for deployment. Runs
 * sub-task based on environment.
 */
gulp.task('build', function() {
  var env = process.env.NODE_ENV || 'development';
  gulp.start('build-' + env);
});

/**
 * build-development and build-production tasks are to build out the app with different
 * configurations. Preprocessing is necessary to insert the appropriate
 * base href into the Jade partials.
 */
gulp.task('build-development', function() {
  envConfig = envConfigDevelopment;
  gulp.start('compass', 'image', 'moveViews', 'lint', 'javascript', 'processEnv');
});

gulp.task('build-production', function() {
  envConfig = envConfigProduction;
  gulp.start('compass', 'image', 'moveViews', 'lint', 'javascript', 'processEnv');
});

gulp.task('default', ['build-development', 'watch']);
<commit_msg>finishing touches<commit_after>var gulp = require('gulp');
var karma = require('karma').server;
var watch = require('gulp-watch');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var image = require('gulp-image');
var compass = require('gulp-compass');
var minifyCSS = require('gulp-minify-css');
var mocha = require('gulp-mocha');
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var rename = require('gulp-rename');
var runSequence = require('run-sequence');
var preprocess = require('gulp-preprocess');
var istanbul = require('gulp-istanbul');
var coveralls = require('gulp-coveralls');
var plumber = require('gulp-plumber');

var paths = {
  src: {
    bower: './client/app/src/bower_components',
    js: './client/app/src/js',
    scss: './client/app/src/scss',
    img: './client/app/src/img',
    views: './client/app/src/views'
  },
  dist: {
    js: './client/app/dist/js',
    css: './client/app/dist/css',
    img: './client/app/dist/img',
    views: './client/app/dist/views'
  },
  server: './server',
  spec: './spec',
  jade: './server/views/_partials',
  serverSpec: __dirname + '/spec/server/**/*.js',
  karmaConf: __dirname + '/spec/karma.conf.js'
};

var handleError = function(err) {
  console.log(err.toString());
  this.emit('end');
};

var jsFiles = [
  paths.src.bower + '/angular/angular.js',
  paths.src.bower + '/angular-ui-router/release/angular-ui-router.js',
  paths.src.js + '/app.js',
  paths.src.js + '/controllers/*.js',
  paths.src.js + '/directives/*.js',
  paths.src.js + '/services/*.js'
];

// Keep track of own JS files for linting
var jsFilesForLint = [
  paths.src.js + '/**/*.js',
  paths.server + '/**/*.js',
  paths.spec + '/**/*.js'
];

var jadeFiles = [paths.jade + '/*.jade'];

/**
 * envConfig, envConfigDevelopment, and envConfigProduction are used to configure builds
 * with the proper environment. Arguments are passed into the preprocess
 * task to insert variables into files. For example, the base href needs
 * to be dynamically set based on the environment.
 */
var envConfig;

var envConfigDevelopment = {
  BASE_HREF: 'localhost:3000'
};

var envConfigProduction = {
  BASE_HREF: 'archivr-dev.herokuapp.com'
};

gulp.task('javascript', function() {
  gulp.src(jsFiles)
  .pipe(concat('app.min.js'))
  // .pipe(uglify({
  //   beautify: true
  // }))
  .on('error', handleError)
  .pipe(gulp.dest(paths.dist.js));
});

/**
 * Run JSHint
 */
gulp.task('lint', function() {
  return gulp.src(jsFilesForLint)
    .pipe(jshint())
    .pipe(jshint.reporter(stylish))
    // Error out if any warnings appear
    .pipe(jshint.reporter('fail'));
});

gulp.task('image', function() {
   gulp.src(paths.src.img + '/**/*')
    .pipe(image())
    .on('error', handleError)
    .pipe(gulp.dest(paths.dist.img));
});

gulp.task('moveViews', function() {
  gulp.src(paths.src.views + '/**/*')
    .pipe(gulp.dest(paths.dist.views));
});

gulp.task('compass', function() {
  gulp.src(paths.src.scss + '/*.scss')
    .pipe(compass({
      css: paths.dist.css,
      sass: paths.src.scss,
      image: paths.dist.img,
      require: ['breakpoint']
    }))
    .on('error', handleError)
    .pipe(minifyCSS())
    .pipe(concat('app.css'))
    .pipe(gulp.dest(paths.dist.css));
});

gulp.task('processEnv', function() {
  gulp.src(jadeFiles)
    .pipe(preprocess({context: envConfig}))
    .pipe(gulp.dest(paths.jade + '/dist'));
});

// Run testing suite: lint, karma (client-side) and mocha (server-side)
gulp.task('test', function(callback) {
  /**
   * Use `runSequence` to call tasks synchronously, otherwise
   * messages from both will be potentially interleaved.
   */
  runSequence('lint', 'karma', 'mocha', callback);
});

gulp.task('karma', function (done) {
  return karma.start({
    configFile: paths.karmaConf,
    singleRun: true
  }, done);
});

/**
 * mocha
 * =====
 * Runs the mocha tests. Because gulp-mocha is stupid, this task must be
 * forcibly exited using `process.exit()`. As such, **no other tasks will
 * successfully be reached after this task.** Do whatever hair-brained
 * workarounds are necessary to not have any tasks be dependent on this one.
 */

var handleMochaError = function (err) {
  console.log('Mocha encountered an error, exiting with status 1');
  console.log('Error:', err.message);
  process.exit(1);
};

gulp.task('mocha', function (cb) {
  var mochaErr;
  // Track src files that should be covered
  gulp.src(['./server/**/*.js'])
    .pipe(istanbul({ includeUntested: true })) // Covering files
    .pipe(istanbul.hookRequire()) // Force `require` to return covered files
    .on('finish', function() {
      // Specify server specs
      gulp.src(paths.serverSpec, {read: false})
        .pipe(plumber())
        .pipe(mocha({
          reporter: 'spec',
          timeout: 20000
        }))
        /**
         * Keep track of latest error on Mocha. Because a failed test counts
         * as an error, the process should not be exited until end of tests.
         */
        .on('error', function(err) {
          /**
           * This intermediate log is useful for when mocha crashes (as opposed
           * to a test failing). Can be commented out if needed.
           */
          console.error('ERROR:', err.message);
          console.error('Stack:', err.stack);
          mochaErr = err;
        })
        // Write reports to Istanbul
        .pipe(istanbul.writeReports())
        /**
         * The methods below are a hack to get gulp to exit after mocha tests
         * finish. Without them, `gulp mocha` doesn't exit and Travis
         * never finishes running the tests.
         */
        .on('end', function () {
          if (mochaErr) return handleMochaError(mochaErr);
          // Force mocha to exit, because gulp-mocha is stupid.
          process.exit();
        });
    });
});

/**
 * coveralls
 * =========
 * Sends code coverage data to Coveralls.
 */
gulp.task('coveralls', function () {
  // if (!process.env.CI) return;
  return gulp
    .src([
      './coverage/client/lcovTest/lcov.info',
      './coverage/lcov.info'
    ])
    .pipe(concat('lcov.info'))
    .pipe(coveralls());
  // return gulp.src('./coverage/lcov.info')
  //   .pipe(coveralls());
});

gulp.task('testy', function () {
  // return gulp.src([
  //   './coverage/client/lcov.info',
  //   './coverage/lcov.info'
  // ])
  //   .pipe(concat('combined.info'))
  //   .pipe(gulp.dest('./coverage'))
  return gulp.src('./coverage/combined.info')
  .pipe(coveralls());
});

gulp.task('watch', function() {
  gulp.watch(paths.src.img + '/**/*', ['image']);
  gulp.watch(paths.src.scss + '/**/*.scss', ['compass']);
  gulp.watch(paths.src.js + '/**/*.js', ['lint', 'javascript']);
  gulp.watch(paths.src.views + '/**/*', ['moveViews']);
});

/**
 * build is the entry-point to build out app artifacts for deployment. Runs
 * sub-task based on environment.
 */
gulp.task('build', function() {
  var env = process.env.NODE_ENV || 'development';
  gulp.start('build-' + env);
});

/**
 * build-development and build-production tasks are to build out the app with different
 * configurations. Preprocessing is necessary to insert the appropriate
 * base href into the Jade partials.
 */
gulp.task('build-development', function() {
  envConfig = envConfigDevelopment;
  gulp.start('compass', 'image', 'moveViews', 'lint', 'javascript', 'processEnv');
});

gulp.task('build-production', function() {
  envConfig = envConfigProduction;
  gulp.start('compass', 'image', 'moveViews', 'lint', 'javascript', 'processEnv');
});

gulp.task('default', ['build-development', 'watch']);
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    cleanhtml = require('gulp-cleanhtml'),
    csslint = require('gulp-csslint'),
    htmlhint = require('gulp-htmlhint'),
    jshint = require('gulp-jshint'),
    notify = require('gulp-notify'),
    plumber = require('gulp-plumber'),
    size = require('gulp-size'),
    uncss = require('gulp-uncss'),
    w3cjs = require('gulp-w3cjs'),
    gulputil = require('gulp-util'),
    stylestats = require('gulp-stylestats-report'),
    clean = require('gulp-clean'),
    cssValidation = require('gulp-css-validator');

var fs = require('fs'),
    mkdirp = require('mkdirp'),
    runSequence = require('run-sequence');

var reportsDir = './reports/json'

    //Individual Tasks

gulp.task('markymark', function() {
  var jsonReporter = function (file) {
    if (file && file.htmlhint) {
      fs.writeFileSync(reportsDir + '/htmlhint-' + file.path.split('/').pop().replace(/\.[^\.]+$/, '') + '.json', JSON.stringify(file.htmlhint, null, 2));
    }
  };

  return gulp.src('build/*.html')
    .pipe(plumber())
    .pipe(htmlhint())
    .pipe(htmlhint.reporter(jsonReporter))
    .pipe(notify("The Funky Bunch has hinted."));
});

gulp.task('wildstyle', function() {
  mkdirp(reportsDir);

  var jsonReporter = function (file) {
    if (file && file.csslint) {
      fs.writeFileSync(reportsDir + '/csshint-' + file.path.split('/').pop().replace(/\.[^\.]+$/, '') + '.json', JSON.stringify(file.csslint, null, 2));
    }
  };

  return gulp.src('build/css/*.css')
    .pipe(plumber())
    .pipe(csslint())
    .pipe(csslint.reporter(jsonReporter))
    .pipe(notify("All right, all right, all right! CSS busted"));
});

gulp.task('stylestats', function() {
  return gulp.src('build/css/*.css')
    .pipe(stylestats({reportDir: './reports/json'}))
    .pipe(notify("stylestats report generated."));
});

gulp.task('css-validation', function() {
  return gulp.src('build/css/*.css')
    .pipe(cssValidation({
      allowHacks: true
    }));
});

gulp.task('validation', function() {
  return gulp.src('build/*.html')
    .pipe(w3cjs())
    .pipe(notify("Validation Complete!"));
});

gulp.task('uncss', function() {
  return gulp.src('build/css/*.css')
    .pipe(plumber())
    .pipe(uncss({
      html: ['build/index.html']
    }))
    .pipe(gulp.dest('build/linted/css'))
    .pipe(notify('Removed unused styles'));
});

gulp.task('cleanhtml', function() {
  return gulp.src('build/*.html')
    .pipe(plumber())
    .pipe(cleanhtml())
    .pipe(gulp.dest('build/linted'))
    .pipe(notify('Cleaned up html'));
});

gulp.task('size', function() {
  return gulp.src('build')
    .pipe(size(showFiles));
});

gulp.task('jshint', function() {
  var jsonReporter = function (results, data, s2) {
    var filename = results[0].file.split('/').pop().replace(/\.[^\.]+$/, '');
    var output = {
      results: results,
      data: data
    };

    fs.writeFileSync(reportsDir + '/jshint-' + filename + '.json', JSON.stringify(output, null, 2));
  };

  return gulp.src('build/js/*.js')
    .pipe(jshint('build/js/.jshintrc'))
    .pipe(jshint.reporter(jsonReporter))
    .pipe(notify('JS has been hinted'));
});

gulp.task('clean-reports', function () {
  return gulp.src('./reports/json')
    .pipe(clean());
});

gulp.task('reports-index', function (cb) {
  var reports = fs.readdirSync('./reports/json/');
  var output = {
    css: [],
    stylestats: [],
    html: [],
    js: []
  };

  for (var i = reports.length - 1; i >= 0; i--) {
    if (/^csshint/.test(reports[i])) output.css.push(reports[i]);
    if (/^jshint/.test(reports[i])) output.js.push(reports[i]);
    if (/^htmlhint/.test(reports[i])) output.html.push(reports[i]);
    if (/^stylestats/.test(reports[i])) output.stylestats.push(reports[i]);
  };

  fs.writeFileSync(reportsDir + '/index.json', JSON.stringify(output, null, 2));

  cb();
});

gulp.task('generate-reports', function (cb) {
  runSequence('clean-reports', 'css-validation', ['jshint', 'wildstyle', 'markymark', 'stylestats'], 'reports-index', cb);
});
<commit_msg>removed validation from reports<commit_after>var gulp = require('gulp'),
    cleanhtml = require('gulp-cleanhtml'),
    csslint = require('gulp-csslint'),
    htmlhint = require('gulp-htmlhint'),
    jshint = require('gulp-jshint'),
    notify = require('gulp-notify'),
    plumber = require('gulp-plumber'),
    size = require('gulp-size'),
    uncss = require('gulp-uncss'),
    w3cjs = require('gulp-w3cjs'),
    gulputil = require('gulp-util'),
    stylestats = require('gulp-stylestats-report'),
    clean = require('gulp-clean'),
    cssValidation = require('gulp-css-validator');

var fs = require('fs'),
    mkdirp = require('mkdirp'),
    runSequence = require('run-sequence');

var reportsDir = './reports/json'

    //Individual Tasks

gulp.task('markymark', function() {
  var jsonReporter = function (file) {
    if (file && file.htmlhint) {
      fs.writeFileSync(reportsDir + '/htmlhint-' + file.path.split('/').pop().replace(/\.[^\.]+$/, '') + '.json', JSON.stringify(file.htmlhint, null, 2));
    }
  };

  return gulp.src('build/*.html')
    .pipe(plumber())
    .pipe(htmlhint())
    .pipe(htmlhint.reporter(jsonReporter))
    .pipe(notify("The Funky Bunch has hinted."));
});

gulp.task('wildstyle', function() {
  mkdirp(reportsDir);

  var jsonReporter = function (file) {
    if (file && file.csslint) {
      fs.writeFileSync(reportsDir + '/csshint-' + file.path.split('/').pop().replace(/\.[^\.]+$/, '') + '.json', JSON.stringify(file.csslint, null, 2));
    }
  };

  return gulp.src('build/css/*.css')
    .pipe(plumber())
    .pipe(csslint())
    .pipe(csslint.reporter(jsonReporter))
    .pipe(notify("All right, all right, all right! CSS busted"));
});

gulp.task('stylestats', function() {
  return gulp.src('build/css/*.css')
    .pipe(stylestats({reportDir: './reports/json'}))
    .pipe(notify("stylestats report generated."));
});

gulp.task('css-validation', function() {
  return gulp.src('build/css/*.css')
    .pipe(cssValidation({
      allowHacks: true
    }));
});

gulp.task('validation', function() {
  return gulp.src('build/*.html')
    .pipe(w3cjs())
    .pipe(notify("Validation Complete!"));
});

gulp.task('uncss', function() {
  return gulp.src('build/css/*.css')
    .pipe(plumber())
    .pipe(uncss({
      html: ['build/index.html']
    }))
    .pipe(gulp.dest('build/linted/css'))
    .pipe(notify('Removed unused styles'));
});

gulp.task('cleanhtml', function() {
  return gulp.src('build/*.html')
    .pipe(plumber())
    .pipe(cleanhtml())
    .pipe(gulp.dest('build/linted'))
    .pipe(notify('Cleaned up html'));
});

gulp.task('size', function() {
  return gulp.src('build')
    .pipe(size(showFiles));
});

gulp.task('jshint', function() {
  var jsonReporter = function (results, data, s2) {
    var filename = results[0].file.split('/').pop().replace(/\.[^\.]+$/, '');
    var output = {
      results: results,
      data: data
    };

    fs.writeFileSync(reportsDir + '/jshint-' + filename + '.json', JSON.stringify(output, null, 2));
  };

  return gulp.src('build/js/*.js')
    .pipe(jshint('build/js/.jshintrc'))
    .pipe(jshint.reporter(jsonReporter))
    .pipe(notify('JS has been hinted'));
});

gulp.task('clean-reports', function () {
  return gulp.src('./reports/json')
    .pipe(clean());
});

gulp.task('reports-index', function (cb) {
  var reports = fs.readdirSync('./reports/json/');
  var output = {
    css: [],
    stylestats: [],
    html: [],
    js: []
  };

  for (var i = reports.length - 1; i >= 0; i--) {
    if (/^csshint/.test(reports[i])) output.css.push(reports[i]);
    if (/^jshint/.test(reports[i])) output.js.push(reports[i]);
    if (/^htmlhint/.test(reports[i])) output.html.push(reports[i]);
    if (/^stylestats/.test(reports[i])) output.stylestats.push(reports[i]);
  };

  fs.writeFileSync(reportsDir + '/index.json', JSON.stringify(output, null, 2));

  cb();
});

gulp.task('generate-reports', function (cb) {
  runSequence('clean-reports', ['jshint', 'wildstyle', 'markymark', 'stylestats'], 'reports-index', cb);
});
<|endoftext|>


<commit_before><commit_msg>added basic tasks<commit_after>var gulp            = require('gulp');
var plumber         = require('gulp-plumber');
var rename          = require('gulp-rename');
var autoprefixer    = require('gulp-autoprefixer');
var concat          = require('gulp-concat');
var uglify          = require('gulp-uglify');
var cache           = require('gulp-cache');
var minifycss       = require('gulp-minify-css');
var sass            = require('gulp-sass');

gulp.task('styles', function(){
  gulp.src(['scss/**/*.scss'])
    .pipe(plumber({
      errorHandler: function (error) {
        console.log(error.message);
        this.emit('end');
    }}))
    .pipe(sass())
    .pipe(autoprefixer('last 10 versions'))
    .pipe(gulp.dest('css/'))
    .pipe(rename({suffix: '.min'}))
    .pipe(minifycss())
    .pipe(gulp.dest('css/'))
});

gulp.task('scripts', function(){
  return gulp.src(['js/vendors/*.js', 'js/*.js'])
    .pipe(plumber({
      errorHandler: function (error) {
        console.log(error.message);
        this.emit('end');
    }}))
    .pipe(concat('template.js'))
    .pipe(gulp.dest('js/'))
    .pipe(rename({suffix: '.min'}))
    .pipe(uglify())
    .pipe(gulp.dest('js/'))
});

gulp.task('build', ['styles', 'scripts']);

gulp.task('default', ['build', 'browser-sync'], function(){
  gulp.watch("scss/**/*.scss", ['styles']);
  gulp.watch("js/**/*.js", ['scripts']);
});<|endoftext|>


<commit_before>// Karma configuration
// Generated on Wed Mar 19 2014 12:48:17 GMT+1100 (AUS Eastern Daylight Time)

module.exports = function (config) {
    config.set({

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '../../../',

        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: [ 'jasmine' ],

        // list of files / patterns to load in the browser
        files: [
            'bower_components/jquery/dist/jquery.js',
            'bower_components/angular/angular.js',
            'bower_components/angular-route/angular-route.js',
            'bower_components/angular-mocks/angular-mocks.js',
            'bower_components/bootstrap/dist/js/bootstrap.js',
            'bower_components/jquery-ui/jquery-ui.js',
            'bower_components/angular-ui/build/angular-ui.js',
            'bower_components/angular-ui-utils/ui-utils.js',
            'external/OpenLayers2/OpenLayers.js',
            'bower_components/proj4/dist/proj4.js',
            'node_modules/openlayers/dist/ol-debug.js',
            'src/main/js/map services/*.js',
            'src/main/js/config/*.js',
            'src/main/js/core/core.js',
            'src/main/js/core/*.js',
            'src/main/js/vendor/*.js',
            'src/main/js/ui/components/**/*.js',
            'src/main/js/toolkit-templates.js',
            'src/main/js/ui/components/components.js',
            'src/main/js/ui/ui-directives.js',
            'http://maps.google.com/maps/api/js?.js&libraries=places',
            'src/test/js/**/*.js'],

        // list of files to exclude
        exclude: [
            'src/test/js/karma*.js'
        ],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            'src/main/js/**/*.js': [ 'coverage' ]
        },
        coverageReporter: {
            type: 'lcov', // lcov or lcovonly are required for generating lcov.info files
            dir: 'coverage/'
        },

        reporters: [ 'progress', 'coverage'],

        htmlReporter: {
            outputDir: 'target/karma-reports'
        },

        // web server port
        port: 9876,

        // enable / disable colors in the output (reporters and logs)
        colors: true,

        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_DEBUG,

        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,

        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: [ 'PhantomJS' ],

        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: false,

        plugins: [ 'karma-jasmine',
            'karma-phantomjs-launcher',
            'karma-chrome-launcher',
            'karma-firefox-launcher',
            'karma-ie-launcher',
            'karma-html-reporter',
            'karma-coverage']

    });
};
<commit_msg>Add karma coveralls reporter<commit_after>// Karma configuration
// Generated on Wed Mar 19 2014 12:48:17 GMT+1100 (AUS Eastern Daylight Time)

module.exports = function (config) {
    config.set({

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '../../../',

        // frameworks to use
        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
        frameworks: [ 'jasmine' ],

        // list of files / patterns to load in the browser
        files: [
            'bower_components/jquery/dist/jquery.js',
            'bower_components/angular/angular.js',
            'bower_components/angular-route/angular-route.js',
            'bower_components/angular-mocks/angular-mocks.js',
            'bower_components/bootstrap/dist/js/bootstrap.js',
            'bower_components/jquery-ui/jquery-ui.js',
            'bower_components/angular-ui/build/angular-ui.js',
            'bower_components/angular-ui-utils/ui-utils.js',
            'external/OpenLayers2/OpenLayers.js',
            'bower_components/proj4/dist/proj4.js',
            'node_modules/openlayers/dist/ol-debug.js',
            'src/main/js/map services/*.js',
            'src/main/js/config/*.js',
            'src/main/js/core/core.js',
            'src/main/js/core/*.js',
            'src/main/js/vendor/*.js',
            'src/main/js/ui/components/**/*.js',
            'src/main/js/toolkit-templates.js',
            'src/main/js/ui/components/components.js',
            'src/main/js/ui/ui-directives.js',
            'http://maps.google.com/maps/api/js?.js&libraries=places',
            'src/test/js/**/*.js'],

        // list of files to exclude
        exclude: [
            'src/test/js/karma*.js'
        ],

        // preprocess matching files before serving them to the browser
        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
        preprocessors: {
            'src/main/js/**/*.js': [ 'coverage' ]
        },
        coverageReporter: {
            type: 'lcov', // lcov or lcovonly are required for generating lcov.info files
            dir: 'coverage/'
        },

        reporters: [ 'progress', 'coverage', 'coveralls'],

        htmlReporter: {
            outputDir: 'target/karma-reports'
        },

        // web server port
        port: 9876,

        // enable / disable colors in the output (reporters and logs)
        colors: true,

        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_DEBUG,

        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,

        // start these browsers
        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
        browsers: [ 'PhantomJS' ],

        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: false,

        plugins: [ 'karma-jasmine',
            'karma-phantomjs-launcher',
            'karma-chrome-launcher',
            'karma-firefox-launcher',
            'karma-ie-launcher',
            'karma-html-reporter',
            'karma-coverage']

    });
};
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    nib = require('nib'),
    stylus = require('gulp-stylus'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat'),
    browserify = require('browserify'),
    source = require('vinyl-source-stream'),
    streamify = require('gulp-streamify'),
    bistre = require('bistre'),
    nodemon = require('gulp-nodemon'),
    rename = require('gulp-rename'),
    // imagemin = require('gulp-imagemin'),
    pngcrush = require('imagemin-pngcrush');

var paths = {
  fonts: ['./assets/fonts/*'],
  styles: ['./assets/styles/*.styl'],
  images: ['./assets/images/*'],
  misc: ['./assets/misc/*'],
  scripts: {
    browserify: ["./assets/scripts/*.js"],
    vendor: ["./assets/scripts/vendor/*.js"]
  }
};

gulp.task('watch', function(){
  gulp.watch(paths.fonts, ['fonts']);
  gulp.watch(paths.styles, ['styles']);
  gulp.watch(paths.scripts.browserify, ['browserify']);
  gulp.watch(paths.scripts.vendor, ['concat']);
});

gulp.task('styles', function () {
  gulp.src('./assets/styles/index.styl')
    .pipe(stylus({use: [nib()]}))
    .pipe(gulp.dest('static/css/'))
});

gulp.task('browserify', function () {
  browserify("./assets/scripts/index.js")
    .bundle()
    .pipe(source('index.js'))
    .pipe(gulp.dest('static/js/'))
    .pipe(rename('index.min.js'))
    .pipe(streamify(uglify()))
    .pipe(gulp.dest('static/js/'));
});

gulp.task('concat', function () {
  gulp.src(paths.scripts.vendor)
    .pipe(uglify())
    .pipe(concat('vendor.min.js'))
    .pipe(gulp.dest('static/js/'))
});

gulp.task('fonts', function(){
  gulp.src(paths.fonts)
  .pipe(gulp.dest('static/fonts'));
})

gulp.task('images', function(){
  gulp.src(paths.images)
    // .pipe(imagemin({
    //     progressive: true,
    //     svgoPlugins: [{removeViewBox: false}],
    //     use: [pngcrush()]
    // }))
    .pipe(gulp.dest('static/images'));
})

gulp.task('misc', function(){
  gulp.src(paths.misc)
    .pipe(gulp.dest('static/misc'));
})

gulp.task('nodemon', function() {
  process.env.NODE_ENV = 'dev';
  nodemon({
    script: 'server.js',
    ext: 'hbs js',
    ignore: [
      'assets/',
      'facets/*/test/',
      'node_modules/',
      'static/',
      'test/',
    ],
    stdout: false,
  })
    .on('readable', function () {
      this.stdout
        .pipe(bistre({time: true}))
        .pipe(process.stdout);
      this.stderr
        .pipe(bistre({time: true}))
        .pipe(process.stderr);
    });
});

gulp.task('build', ['fonts', 'images', 'misc', 'styles', 'browserify', 'concat']);
gulp.task('dev', ['build', 'nodemon', 'watch']);
gulp.task('default', ['build']);
<commit_msg>trigger gulp watch for frontend template changes<commit_after>var gulp = require('gulp'),
    nib = require('nib'),
    stylus = require('gulp-stylus'),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat'),
    browserify = require('browserify'),
    source = require('vinyl-source-stream'),
    streamify = require('gulp-streamify'),
    bistre = require('bistre'),
    nodemon = require('gulp-nodemon'),
    rename = require('gulp-rename'),
    // imagemin = require('gulp-imagemin'),
    pngcrush = require('imagemin-pngcrush');

var paths = {
  fonts: ['./assets/fonts/*'],
  styles: ['./assets/styles/*.styl'],
  images: ['./assets/images/*'],
  misc: ['./assets/misc/*'],
  scripts: {
    browserify: ["./assets/scripts/*.js"],
    vendor: ["./assets/scripts/vendor/*.js"]
  },
  templates: ['./assets/templates/*.hbs']
};

gulp.task('watch', function(){
  gulp.watch(paths.fonts, ['fonts']);
  gulp.watch(paths.styles, ['styles']);
  gulp.watch(paths.scripts.browserify, ['browserify']);
  gulp.watch(paths.templates, ['browserify']);
  gulp.watch(paths.scripts.vendor, ['concat']);
});

gulp.task('styles', function () {
  gulp.src('./assets/styles/index.styl')
    .pipe(stylus({use: [nib()]}))
    .pipe(gulp.dest('static/css/'))
});

gulp.task('browserify', function () {
  browserify("./assets/scripts/index.js")
    .bundle()
    .pipe(source('index.js'))
    .pipe(gulp.dest('static/js/'))
    .pipe(rename('index.min.js'))
    .pipe(streamify(uglify()))
    .pipe(gulp.dest('static/js/'));
});

gulp.task('concat', function () {
  gulp.src(paths.scripts.vendor)
    .pipe(uglify())
    .pipe(concat('vendor.min.js'))
    .pipe(gulp.dest('static/js/'))
});

gulp.task('fonts', function(){
  gulp.src(paths.fonts)
  .pipe(gulp.dest('static/fonts'));
})

gulp.task('images', function(){
  gulp.src(paths.images)
    // .pipe(imagemin({
    //     progressive: true,
    //     svgoPlugins: [{removeViewBox: false}],
    //     use: [pngcrush()]
    // }))
    .pipe(gulp.dest('static/images'));
})

gulp.task('misc', function(){
  gulp.src(paths.misc)
    .pipe(gulp.dest('static/misc'));
})

gulp.task('nodemon', function() {
  process.env.NODE_ENV = 'dev';
  nodemon({
    script: 'server.js',
    ext: 'hbs js',
    ignore: [
      'assets/',
      'facets/*/test/',
      'node_modules/',
      'static/',
      'test/',
    ],
    stdout: false,
  })
    .on('readable', function () {
      this.stdout
        .pipe(bistre({time: true}))
        .pipe(process.stdout);
      this.stderr
        .pipe(bistre({time: true}))
        .pipe(process.stderr);
    });
});

gulp.task('build', ['fonts', 'images', 'misc', 'styles', 'browserify', 'concat']);
gulp.task('dev', ['build', 'nodemon', 'watch']);
gulp.task('default', ['build']);
<|endoftext|>


<commit_before>const promisify = require('promisify-node')
const fs = promisify('fs');
const path = require('path');
const url = require('url');
const isThere = require('is-there');
const co = require('co');
const mkdirp = require('mkdirp');
const helper = require('./helper');
const merge = require('deepmerge');

const browserSync = require('browser-sync').create();
const del = require('del');
const cssnext = require('postcss-cssnext');

const gulp = require('gulp');
const $ = require('gulp-load-plugins')();

const minimist = require('minimist');
const options = {
  string: ['input'],
  boolean: 'all',
  alias: {
    i: 'input',
    a: 'all'
  },
  default: {
    input: 'myanmar'
  }
};
const argv = minimist(process.argv.slice(2), options);

const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');

const footer = require('./bower_components/ftc-footer');

const config = require('./config.json');

const demoList = require('./demos/src/demo-list.json');
// If argv.a exists, you are building all in `demoList`. Otherwise a single project.
const names = argv.a ? demoList : [argv.i];
// Browser-syn use `index.html` for argv.a or single individual projects' name
const index = argv.a ? 'index.html' : `${argv.i}.html`;

const prodSetting = {
  "analytics": true,
  "production": true
};

const tmpDir = '.tmp';

process.env.NODE_ENV = 'dev';
// change NODE_ENV between tasks.
gulp.task('prod', function(done) {
  process.env.NODE_ENV = 'prod';
  done();
});

gulp.task('dev', function(done) {
  process.env.NODE_ENV = 'dev';
  done();
});

gulp.task('html', () => {
  return co(function *() {

    if (!isThere(tmpDir)) {
      mkdirp.sync(tmpDir);
    }

    const data = yield Promise.all(names.map(name => {
      const file = path.resolve(process.cwd(), `data/${name}.json`);
      return helper.readJson(file);
    }));

    const renderResults = yield Promise.all(data.map(datum => {
      const template = 'index.html';
      console.log(`Using data file ${datum.name}.json`);

      const context = merge({
        footer: footer
      }, datum.content);

      if (process.env.NODE_ENV === 'prod') {
        Object.assign(context, prodSetting);
      }

      return helper.render(template, context, datum.name);
    }));

    yield Promise.all(renderResults.map(result => {
      return fs.writeFile(`${tmpDir}/${result.name}.html`, result.content, 'utf8');
    }));

  // If argv.a passed, you are building all projects. Let's generate an index page listing them all.
    if (argv.a) {
    // Data is nested under `content` field. Unwrap it.
      const demoData = data.map(d => {
        return d.content
      });

      const demoResult = yield helper.render('demo.html', {demos: demoData});

      yield fs.writeFile(`${tmpDir}/index.html`, demoResult, 'utf8');
    }
  })
  .then(function(){
    browserSync.reload('*.html');
  }, function(err) {
    console.error(err.stack);
  });
});

gulp.task('styles', function styles() {
  const DEST = `${tmpDir}/styles`;

  return gulp.src('client/scss/main.scss')
    .pipe($.changed(DEST))
    .pipe($.plumber())
    .pipe($.sourcemaps.init({loadMaps:true}))
    .pipe($.sass({
      outputStyle: 'expanded',
      precision: 10,
      includePaths: ['bower_components']
    }).on('error', $.sass.logError))
    .pipe($.postcss([
      cssnext({
        features: {
          colorRgba: false
        }
      })
    ]))
    .pipe($.if(process.env.NODE_ENV === 'prod', $.cssnano()))
    .pipe($.size({
      gzip: true,
      showFiles: true
    }))
    .pipe($.sourcemaps.write('./'))
    .pipe(gulp.dest(DEST))
    .pipe(browserSync.stream({once:true}));
});

gulp.task('eslint', () => {
  return gulp.src('client/js/*.js')
    .pipe($.eslint())
    .pipe($.eslint.format())
    .pipe($.eslint.failAfterError());
});

gulp.task('webpack', function(done) {
  if (process.env.NODE_ENV === 'prod') {
    webpackConfig.plugins.push(new webpack.optimize.UglifyJsPlugin())
  }
  webpack(webpackConfig, function(err, stats) {
    if (err) throw new $.util.PluginError('webpack', err);
    $.util.log('[webpack]', stats.toString({
      colors: $.util.colors.supportsColor,
      chunks: false,
      hash: false,
      version: false
    }))
    browserSync.reload('main.js');
    done();
  });
});

gulp.task('wpwatch', () => {
  return Promise.resolve(webpackConfig.watch = true);
});

gulp.task('serve',
  gulp.series('wpwatch',
    gulp.parallel(
      'html', 'styles', 'webpack',

      function serve() {
      browserSync.init({
        server: {
          baseDir: [tmpDir, 'custom', 'public'],
          index: index,
          routes: {
            '/bower_components': 'bower_components'
          }
        },
        files: 'custom/**/*.{css,js,csv}'
      });

      gulp.watch(['views/**/**/*.html', 'data/*.json'], gulp.parallel('html'));
      gulp.watch('client/scss/**/**/*.scss', gulp.parallel('styles'));
    })
  )
);

gulp.task('custom', () => {
  const SRC = `custom/**/${projectName}.{js,css}`;
  const DEST = '.tmp';
  console.log('Copy custom js and css files to:', DEST);

  return gulp.src(SRC)
    .pipe(gulp.dest(DEST));
});

// gulp-prefix cannot prefix `source` of `<picture>`.
gulp.task('prefix', () => {
  return gulp.src('.tmp/index.html')
    .pipe($.cheerio(function($, file) {
      $('picture source').each(function() {
        var source = $(this);
        var srcset = source.attr('srcset')
        if (srcset) {
          srcset = srcset.split(',').map(function(href) {
            return url.resolve(config.urlPrefix, href.trim());
          }).join(', ');
          source.attr('srcset', srcset);
        }
      });
    }))
    .pipe($.htmlmin({
      removeComments: true,
      collapseWhitespace: true,
      removeAttributeQuotes: true,
      minifyJS: true,
      minifyCSS: true
    }))
    .pipe($.size({
      gzip: true,
      showFiles: true
    }))
    .pipe(gulp.dest('dist'));
})

gulp.task('smoosh', gulp.series('custom', function smoosh () {
  return gulp.src('.tmp/*.html')
    .pipe($.smoosher({
      ignoreFilesNotFound: true
    }))
    .pipe(gulp.dest('dist'));
}));

gulp.task('extras', function () {
  return gulp.src('data/csv/*.csv', {
    dot: true
  })
  .pipe(gulp.dest('dist'));
});

gulp.task('clean', function() {
  return del(['.tmp', 'dist']).then(()=>{
    console.log('.tmp and dist deleted');
  });
});

gulp.task('build', gulp.series('prod', 'clean', gulp.parallel('html', 'styles', 'webpack', 'extras'), 'smoosh'));

/**********deploy***********/
gulp.task('images', function () {
  const imgDir = argv.a ? '**' : argv.i;
  const destDir = argv.a ? '' : argv.i;
  const SRC = `./public/images/${imgDir}/*.{svg,png,jpg,jpeg,gif}`;
  const DEST = path.resolve(__dirname, `${config.assets}/images/${destDir}`);

  console.log(`Copying images ${SRC} to: ${DEST}`);

  return gulp.src(SRC)
    .pipe($.imagemin({
      progressive: true,
      interlaced: true,
      svgoPlugins: [{cleanupIDs: false}],
      verbose: true
    }))
    .pipe(gulp.dest(DEST));
});

gulp.task('deploy:html', function() {
  const DEST = path.resolve(__dirname, config.html)

  console.log(`Deploying built html file to: ${DEST}`);

  return gulp.src('dist/*.html')
    .pipe(gulp.dest(DEST));
});

gulp.task('deploy',
  gulp.series('build',
    gulp.parallel(
      'images',
      'deploy:html'
    )
  )
);
/**************/

gulp.task('demo:copy', () => {
  const dest = path.resolve(__dirname, config.assets, path.basename(__dirname));
  console.log(`Copying assets to ${dest}`);

  return gulp.src(['tmp/**/*', 'custom/**/*.{js,css}'])
    .pipe(gulp.dest(dest));
});

gulp.task(gulp.series('clean', gulp.parallel('html', 'styles', 'webpack', 'images', 'extras')));<commit_msg>fix custom task file path<commit_after>const promisify = require('promisify-node')
const fs = promisify('fs');
const path = require('path');
const url = require('url');
const isThere = require('is-there');
const co = require('co');
const mkdirp = require('mkdirp');
const helper = require('./helper');
const merge = require('deepmerge');

const browserSync = require('browser-sync').create();
const del = require('del');
const cssnext = require('postcss-cssnext');

const gulp = require('gulp');
const $ = require('gulp-load-plugins')();

const minimist = require('minimist');
const options = {
  string: ['input'],
  boolean: 'all',
  alias: {
    i: 'input',
    a: 'all'
  },
  default: {
    input: 'myanmar'
  }
};
const argv = minimist(process.argv.slice(2), options);

const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');

const footer = require('./bower_components/ftc-footer');

const config = require('./config.json');

const demoList = require('./demos/src/demo-list.json');
// If argv.a exists, you are building all in `demoList`. Otherwise a single project.
const names = argv.a ? demoList : [argv.i];
// Browser-syn use `index.html` for argv.a or single individual projects' name
const index = argv.a ? 'index.html' : `${argv.i}.html`;

const prodSetting = {
  "analytics": true,
  "production": true
};

const tmpDir = '.tmp';

process.env.NODE_ENV = 'dev';
// change NODE_ENV between tasks.
gulp.task('prod', function(done) {
  process.env.NODE_ENV = 'prod';
  done();
});

gulp.task('dev', function(done) {
  process.env.NODE_ENV = 'dev';
  done();
});

gulp.task('html', () => {
  return co(function *() {

    if (!isThere(tmpDir)) {
      mkdirp.sync(tmpDir);
    }

    const data = yield Promise.all(names.map(name => {
      const file = path.resolve(process.cwd(), `data/${name}.json`);
      return helper.readJson(file);
    }));

    const renderResults = yield Promise.all(data.map(datum => {
      const template = 'index.html';
      console.log(`Using data file ${datum.name}.json`);

      const context = merge({
        footer: footer
      }, datum.content);

      if (process.env.NODE_ENV === 'prod') {
        Object.assign(context, prodSetting);
      }

      return helper.render(template, context, datum.name);
    }));

    yield Promise.all(renderResults.map(result => {
      return fs.writeFile(`${tmpDir}/${result.name}.html`, result.content, 'utf8');
    }));

  // If argv.a passed, you are building all projects. Let's generate an index page listing them all.
    if (argv.a) {
    // Data is nested under `content` field. Unwrap it.
      const demoData = data.map(d => {
        return d.content
      });

      const demoResult = yield helper.render('demo.html', {demos: demoData});

      yield fs.writeFile(`${tmpDir}/index.html`, demoResult, 'utf8');
    }
  })
  .then(function(){
    browserSync.reload('*.html');
  }, function(err) {
    console.error(err.stack);
  });
});

gulp.task('styles', function styles() {
  const DEST = `${tmpDir}/styles`;

  return gulp.src('client/scss/main.scss')
    .pipe($.changed(DEST))
    .pipe($.plumber())
    .pipe($.sourcemaps.init({loadMaps:true}))
    .pipe($.sass({
      outputStyle: 'expanded',
      precision: 10,
      includePaths: ['bower_components']
    }).on('error', $.sass.logError))
    .pipe($.postcss([
      cssnext({
        features: {
          colorRgba: false
        }
      })
    ]))
    .pipe($.if(process.env.NODE_ENV === 'prod', $.cssnano()))
    .pipe($.size({
      gzip: true,
      showFiles: true
    }))
    .pipe($.sourcemaps.write('./'))
    .pipe(gulp.dest(DEST))
    .pipe(browserSync.stream({once:true}));
});

gulp.task('eslint', () => {
  return gulp.src('client/js/*.js')
    .pipe($.eslint())
    .pipe($.eslint.format())
    .pipe($.eslint.failAfterError());
});

gulp.task('webpack', function(done) {
  if (process.env.NODE_ENV === 'prod') {
    webpackConfig.plugins.push(new webpack.optimize.UglifyJsPlugin())
  }
  webpack(webpackConfig, function(err, stats) {
    if (err) throw new $.util.PluginError('webpack', err);
    $.util.log('[webpack]', stats.toString({
      colors: $.util.colors.supportsColor,
      chunks: false,
      hash: false,
      version: false
    }))
    browserSync.reload('main.js');
    done();
  });
});

gulp.task('wpwatch', () => {
  return Promise.resolve(webpackConfig.watch = true);
});

gulp.task('serve',
  gulp.series('wpwatch',
    gulp.parallel(
      'html', 'styles', 'webpack',

      function serve() {
      browserSync.init({
        server: {
          baseDir: [tmpDir, 'custom', 'public'],
          index: index,
          routes: {
            '/bower_components': 'bower_components'
          }
        },
        files: 'custom/**/*.{css,js,csv}'
      });

      gulp.watch(['views/**/**/*.html', 'data/*.json'], gulp.parallel('html'));
      gulp.watch('client/scss/**/**/*.scss', gulp.parallel('styles'));
    })
  )
);

gulp.task('custom', () => {
  const customFile = argv.a ? '*' : argv.i
  const SRC = `custom/**/${customFile}.{js,css}`;
  const DEST = '.tmp';
  console.log('Copy custom js and css files to:', DEST);

  return gulp.src(SRC)
    .pipe(gulp.dest(DEST));
});

// gulp-prefix cannot prefix `source` of `<picture>`.
gulp.task('prefix', () => {
  return gulp.src('.tmp/index.html')
    .pipe($.cheerio(function($, file) {
      $('picture source').each(function() {
        var source = $(this);
        var srcset = source.attr('srcset')
        if (srcset) {
          srcset = srcset.split(',').map(function(href) {
            return url.resolve(config.urlPrefix, href.trim());
          }).join(', ');
          source.attr('srcset', srcset);
        }
      });
    }))
    .pipe($.htmlmin({
      removeComments: true,
      collapseWhitespace: true,
      removeAttributeQuotes: true,
      minifyJS: true,
      minifyCSS: true
    }))
    .pipe($.size({
      gzip: true,
      showFiles: true
    }))
    .pipe(gulp.dest('dist'));
})

gulp.task('smoosh', gulp.series('custom', function smoosh () {
  return gulp.src('.tmp/*.html')
    .pipe($.smoosher({
      ignoreFilesNotFound: true
    }))
    .pipe(gulp.dest('dist'));
}));

gulp.task('extras', function () {
  return gulp.src('data/csv/*.csv', {
    dot: true
  })
  .pipe(gulp.dest('dist'));
});

gulp.task('clean', function() {
  return del(['.tmp', 'dist']).then(()=>{
    console.log('.tmp and dist deleted');
  });
});

gulp.task('build', gulp.series('prod', 'clean', gulp.parallel('html', 'styles', 'webpack', 'extras'), 'smoosh'));

/**********deploy***********/
gulp.task('images', function () {
  const imgDir = argv.a ? '**' : argv.i;
  const destDir = argv.a ? '' : argv.i;
  const SRC = `./public/images/${imgDir}/*.{svg,png,jpg,jpeg,gif}`;
  const DEST = path.resolve(__dirname, `${config.assets}/images/${destDir}`);

  console.log(`Copying images ${SRC} to: ${DEST}`);

  return gulp.src(SRC)
    .pipe($.imagemin({
      progressive: true,
      interlaced: true,
      svgoPlugins: [{cleanupIDs: false}],
      verbose: true
    }))
    .pipe(gulp.dest(DEST));
});

gulp.task('deploy:html', function() {
  const DEST = path.resolve(__dirname, config.html)

  console.log(`Deploying built html file to: ${DEST}`);

  return gulp.src('dist/*.html')
    .pipe(gulp.dest(DEST));
});

gulp.task('deploy',
  gulp.series('build',
    gulp.parallel(
      'images',
      'deploy:html'
    )
  )
);
/**************/

gulp.task('demo:copy', () => {
  const dest = path.resolve(__dirname, config.assets, path.basename(__dirname));
  console.log(`Copying assets to ${dest}`);

  return gulp.src(['tmp/**/*', 'custom/**/*.{js,css}'])
    .pipe(gulp.dest(dest));
});

gulp.task(gulp.series('clean', gulp.parallel('html', 'styles', 'webpack', 'images', 'extras')));<|endoftext|>


<commit_before>import { mockAppContext } from '@mindhive/di/test'

const runInFiber = (func) =>
  (done) => {
    func.future()().resolve((err) => {
      done(err)
    })
  }

export const mockServerContext = (testModules, testFunc) =>
  runInFiber(mockAppContext(testModules, testFunc))
<commit_msg>Rename<commit_after>import { mockAppContext } from '@mindhive/di/test'

const inFiberTestRunner = (func) =>
  (done) => {
    func.future()().resolve((err) => {
      done(err)
    })
  }

export const mockServerContext = (testModules, testFunc) =>
  inFiberTestRunner(mockAppContext(testModules, testFunc))
<|endoftext|>


<commit_before>const fs = require("fs");
const pkg = require('./package.json');
const gulp = require('gulp');
const $ = require('gulp-load-plugins')({lazy:true });
const tsProject = require('tsproject');
const eventStream = require('event-stream');

gulp.task('clean', function clean(done) {
  const del = require('del');
  del.sync(['dist'], { force: true });
  done();
});

gulp.task('typescript', function typescript(done) {
  const stream = tsProject.src('src/tsconfig.json').pipe(gulp.dest('dist/temp'));
  stream.on('finish', done);
});

gulp.task('typescript.integrations', gulp.series('typescript', function typescriptIntegrations(done) {
  const stream = tsProject.src('src/integrations/tsconfig.json').pipe(gulp.dest('dist/temp'));
  stream.on('finish', done);
}));

gulp.task('typescript.node', function typescriptNode(done) {
  const stream = tsProject.src('src/tsconfig.node.json').pipe(gulp.dest('dist/temp'));
  stream.on('finish', done);
});

gulp.task('typescript.universal', function typescriptUniversal(done) {
  const stream = tsProject.src('src/tsconfig.universal.json').pipe(gulp.dest('dist/temp'));
  stream.on('finish', done);
});

gulp.task('exceptionless.umd', gulp.series('typescript.integrations', function exceptionlessUmd() {
  return gulp.src('dist/temp/src/exceptionless.js')
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.wrapUmd({
      exports: 'exports',
      globalName: 'exceptionless',
      namespace: 'exceptionless',
      deps: ['TraceKit'],
      template: fs.readFileSync('./umd.template.jst', 'utf8')
    }))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist/temp'));
}));

gulp.task('exceptionless.universal.umd', gulp.series('typescript.universal', function universalUmd() {
  return gulp.src('dist/temp/src/exceptionless.universal.js')
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.wrapUmd({
      exports: 'exports',
      globalName: 'exceptionless',
      namespace: 'exceptionless',
      deps: ['TraceKit'],
      template: fs.readFileSync('./umd.template.jst', 'utf8')
    }))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist/temp'));
}));

gulp.task('exceptionless', gulp.series('exceptionless.umd', function exceptionless() {
  gulp.src('dist/temp/src/exceptionless.d.ts')
    .pipe(gulp.dest('dist'));
  const integrations = [
    'dist/temp/src/integrations/angular.js'
  ];

  gulp.src(integrations)
    .pipe(gulp.dest('dist/integrations'));

  const files = [
    'node_modules/tracekit/tracekit.js',
    'dist/temp/exceptionless.js'
  ];

  gulp.src(files)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.concat('exceptionless.js'))
    .pipe($.replace('exceptionless-js/1.0.0.0', 'exceptionless-js/' + pkg.version))
    .pipe($.replace('var TraceKit = require("TraceKit");\n', ''))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'));

  return gulp.src(files)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.concat('exceptionless.min.js'))
    .pipe($.replace('exceptionless-js/1.0.0.0', 'exceptionless-js/' + pkg.version))
    .pipe($.replace('var TraceKit = require("TraceKit");\n', ''))
    .pipe($.uglify({ output: { beautify: false } }))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'));
}));

gulp.task('exceptionless.node', gulp.series('typescript.node', function node() {
  const files = [
    'dist/temp/src/exceptionless.node.js',
    'dist/temp/src/submitSync.js'
  ];

  return gulp.src(files)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.replace('exceptionless-js/1.0.0.0', 'exceptionless-node/' + pkg.version))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'));
}));

gulp.task('exceptionless.universal', gulp.series('exceptionless.universal.umd', function universal() {
  const files = [
    'node_modules/tracekit/tracekit.js',
    'dist/temp/exceptionless.universal.js'
  ];

  // NOTE: This is really hacky to replace require statements based on order..... but we need to ensure they are excluded for requirejs.
  gulp.src(files)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.concat('exceptionless.universal.js'))
    .pipe($.replace('exceptionless-js/1.0.0.0', 'exceptionless-universal-js/' + pkg.version))
    .pipe($.replace('var TraceKit = require("TraceKit");', 'if (typeof process !== \'undefined\') {'))
    .pipe($.replace('var url = require("url");', 'var url = require("url");\n}'))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'));

  return gulp.src(files)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.concat('exceptionless.universal.min.js'))
    .pipe($.replace('exceptionless-js/1.0.0.0', 'exceptionless-universal-js/' + pkg.version))
    .pipe($.replace('var TraceKit = require("TraceKit");', 'if (require && typeof process !== \'undefined\') {'))
    .pipe($.replace('var url = require("url");', 'var url = require("url");\n}'))
    .pipe($.uglify({ output: { beautify: false } }))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'));
}));

gulp.task('lint', function lint() {
  return gulp.src(['src/**/*.ts'])
    .pipe($.tslint({ formatter: 'verbose' }))
    .pipe($.tslint.report());
});

gulp.task('build', gulp.series('clean', 'lint', 'exceptionless', 'exceptionless.node', 'exceptionless.universal'));

gulp.task('watch', gulp.series('build', function watch() {
  return gulp.watch('src/**/*.ts', gulp.series('build'));
}));

gulp.task('typescript.test', function test(done) {
  const stream = tsProject.src('src/tsconfig.test.json').pipe(gulp.dest('dist/temp'));
  stream.on('finish', done);
});

gulp.task('exceptionless.test.umd', gulp.series('typescript.test', function testUmd(done) {
  var wrap = function(filename){
    return gulp.src(filename)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.wrapUmd({
      exports: 'exports',
      globalName: 'exceptionless',
      namespace: 'exceptionless'
    }))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist/temp'));
  };

  eventStream.merge(
    wrap('dist/temp/src/exceptionless-nodespec.js'),
    wrap('dist/temp/src/exceptionless-browserspec.js'));

  done();
}));

gulp.task('test-node', gulp.series('exceptionless.test.umd', function testNode() {
  return gulp.src('dist/temp/exceptionless-nodespec.js', { read: false })
    .pipe($.mocha({
      require: ['source-map-support/register'],
      timeout: 5000
    }))
    .once('end', function () {
      process.exit();
    });
}));

gulp.task('test-browser', gulp.series('exceptionless.test.umd', function testBrowser(){
  return gulp
    .src('testrunner.html')
    .pipe($.mochaPhantomjs());
}));

// test-node calls process.exit(), so run browser tests before node tests
gulp.task('test', gulp.series('test-browser', 'test-node'));

gulp.task('format', function format() {
  return gulp.src(['src/**/*.ts'])
    .pipe($.exec('node_modules/typescript-formatter/bin/tsfmt -r <%= file.path %>'))
    .pipe($.exec.reporter());
});

gulp.task('default', gulp.series('watch', 'test'));
<commit_msg>Fixed unit tests not exiting...<commit_after>const fs = require("fs");
const pkg = require('./package.json');
const gulp = require('gulp');
const $ = require('gulp-load-plugins')({lazy:true });
const tsProject = require('tsproject');
const eventStream = require('event-stream');

gulp.task('clean', function clean(done) {
  const del = require('del');
  del.sync(['dist'], { force: true });
  done();
});

gulp.task('typescript', function typescript(done) {
  const stream = tsProject.src('src/tsconfig.json').pipe(gulp.dest('dist/temp'));
  stream.on('finish', done);
});

gulp.task('typescript.integrations', gulp.series('typescript', function typescriptIntegrations(done) {
  const stream = tsProject.src('src/integrations/tsconfig.json').pipe(gulp.dest('dist/temp'));
  stream.on('finish', done);
}));

gulp.task('typescript.node', function typescriptNode(done) {
  const stream = tsProject.src('src/tsconfig.node.json').pipe(gulp.dest('dist/temp'));
  stream.on('finish', done);
});

gulp.task('typescript.universal', function typescriptUniversal(done) {
  const stream = tsProject.src('src/tsconfig.universal.json').pipe(gulp.dest('dist/temp'));
  stream.on('finish', done);
});

gulp.task('exceptionless.umd', gulp.series('typescript.integrations', function exceptionlessUmd() {
  return gulp.src('dist/temp/src/exceptionless.js')
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.wrapUmd({
      exports: 'exports',
      globalName: 'exceptionless',
      namespace: 'exceptionless',
      deps: ['TraceKit'],
      template: fs.readFileSync('./umd.template.jst', 'utf8')
    }))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist/temp'));
}));

gulp.task('exceptionless.universal.umd', gulp.series('typescript.universal', function universalUmd() {
  return gulp.src('dist/temp/src/exceptionless.universal.js')
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.wrapUmd({
      exports: 'exports',
      globalName: 'exceptionless',
      namespace: 'exceptionless',
      deps: ['TraceKit'],
      template: fs.readFileSync('./umd.template.jst', 'utf8')
    }))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist/temp'));
}));

gulp.task('exceptionless', gulp.series('exceptionless.umd', function exceptionless() {
  gulp.src('dist/temp/src/exceptionless.d.ts')
    .pipe(gulp.dest('dist'));
  const integrations = [
    'dist/temp/src/integrations/angular.js'
  ];

  gulp.src(integrations)
    .pipe(gulp.dest('dist/integrations'));

  const files = [
    'node_modules/tracekit/tracekit.js',
    'dist/temp/exceptionless.js'
  ];

  gulp.src(files)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.concat('exceptionless.js'))
    .pipe($.replace('exceptionless-js/1.0.0.0', 'exceptionless-js/' + pkg.version))
    .pipe($.replace('var TraceKit = require("TraceKit");\n', ''))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'));

  return gulp.src(files)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.concat('exceptionless.min.js'))
    .pipe($.replace('exceptionless-js/1.0.0.0', 'exceptionless-js/' + pkg.version))
    .pipe($.replace('var TraceKit = require("TraceKit");\n', ''))
    .pipe($.uglify({ output: { beautify: false } }))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'));
}));

gulp.task('exceptionless.node', gulp.series('typescript.node', function node() {
  const files = [
    'dist/temp/src/exceptionless.node.js',
    'dist/temp/src/submitSync.js'
  ];

  return gulp.src(files)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.replace('exceptionless-js/1.0.0.0', 'exceptionless-node/' + pkg.version))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'));
}));

gulp.task('exceptionless.universal', gulp.series('exceptionless.universal.umd', function universal() {
  const files = [
    'node_modules/tracekit/tracekit.js',
    'dist/temp/exceptionless.universal.js'
  ];

  // NOTE: This is really hacky to replace require statements based on order..... but we need to ensure they are excluded for requirejs.
  gulp.src(files)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.concat('exceptionless.universal.js'))
    .pipe($.replace('exceptionless-js/1.0.0.0', 'exceptionless-universal-js/' + pkg.version))
    .pipe($.replace('var TraceKit = require("TraceKit");', 'if (typeof process !== \'undefined\') {'))
    .pipe($.replace('var url = require("url");', 'var url = require("url");\n}'))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'));

  return gulp.src(files)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.concat('exceptionless.universal.min.js'))
    .pipe($.replace('exceptionless-js/1.0.0.0', 'exceptionless-universal-js/' + pkg.version))
    .pipe($.replace('var TraceKit = require("TraceKit");', 'if (require && typeof process !== \'undefined\') {'))
    .pipe($.replace('var url = require("url");', 'var url = require("url");\n}'))
    .pipe($.uglify({ output: { beautify: false } }))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist'));
}));

gulp.task('lint', function lint() {
  return gulp.src(['src/**/*.ts'])
    .pipe($.tslint({ formatter: 'verbose' }))
    .pipe($.tslint.report());
});

gulp.task('build', gulp.series('clean', 'lint', 'exceptionless', 'exceptionless.node', 'exceptionless.universal'));

gulp.task('watch', gulp.series('build', function watch() {
  return gulp.watch('src/**/*.ts', gulp.series('build'));
}));

gulp.task('typescript.test', function test(done) {
  const stream = tsProject.src('src/tsconfig.test.json').pipe(gulp.dest('dist/temp'));
  stream.on('finish', done);
});

gulp.task('exceptionless.test.umd', gulp.series('typescript.test', function testUmd(done) {
  var wrap = function(filename){
    return gulp.src(filename)
    .pipe($.sourcemaps.init({ loadMaps: true }))
    .pipe($.wrapUmd({
      exports: 'exports',
      globalName: 'exceptionless',
      namespace: 'exceptionless'
    }))
    .pipe($.sourcemaps.write('.'))
    .pipe(gulp.dest('dist/temp'));
  };

  eventStream.merge(
    wrap('dist/temp/src/exceptionless-nodespec.js'),
    wrap('dist/temp/src/exceptionless-browserspec.js'));

  done();
}));

gulp.task('test-node', gulp.series('exceptionless.test.umd', function testNode() {
  return gulp.src('dist/temp/exceptionless-nodespec.js', { read: false })
    .pipe($.mocha({
      require: ['source-map-support/register'],
      timeout: 5000,
      exit: true
    }));
}));

gulp.task('test-browser', gulp.series('exceptionless.test.umd', function testBrowser(){
  return gulp
    .src('testrunner.html')
    .pipe($.mochaPhantomjs());
}));

gulp.task('test', gulp.series('test-browser', 'test-node'));

gulp.task('format', function format() {
  return gulp.src(['src/**/*.ts'])
    .pipe($.exec('node_modules/typescript-formatter/bin/tsfmt -r <%= file.path %>'))
    .pipe($.exec.reporter());
});

gulp.task('default', gulp.series('watch', 'test'));
<|endoftext|>