<commit_before>
////////////////////////////////////// START ///////////////////////////////////////////////////////////////

var gulp = require('gulp');
var plugins = require('gulp-load-plugins')({ lazy: true, camelize: true });
var config = require('./gulp.config')();
var argv = require('yargs').argv;
var fs = require('fs');
var sequence = require("gulp-sequence").use(gulp);

////////////////////////////////////////// Local RUN /////////////////////////////////////////////////////////

var wiredep = require('wiredep');
gulp.task('wiredep', function () {
    var wconfig = { directory: './bower_components/', verbose: true, devDependencies: true };
    return gulp.src(config.index)
        .pipe(wiredep.stream(wconfig))
        .pipe(gulp.dest(config.base));
});

gulp.task('inject', function () {
    var sourcejs = gulp.src(config.sourcejs, { read: false });
    var sourceopt = { name: 'sourcejs', addRootSlash: false };

    var testjs = gulp.src(config.testfixturejs, { read: false });
    var testopt = { name: 'testfixturejs', addRootSlash: false };

    return gulp.src(config.index)
        .pipe(plugins.inject(sourcejs, sourceopt))
        .pipe(plugins.inject(testjs, testopt))
        .pipe(gulp.dest(config.base));
});

gulp.task('serve', ['wiredep','inject'], function () {
  return gulp.src(config.base)
    .pipe(plugins.webserver({
        host: process.env.IP || 'localhost',
        port: process.env.PORT || 8080,
        livereload: true,
        open: true,
		fallback: config.index
    }));
});

gulp.task('heroku', ['wiredep','inject'], function () {
  return gulp.src(config.base)
    .pipe(plugins.webserver({
        host: '0.0.0.0',
        port: process.env.PORT,
        livereload: false,
        open: false,
		fallback: config.index
    }));
});

////////////////////////////////////////// BUILD /////////////////////////////////////////////////////////

var del = require('del');
gulp.task('clean', function (cb) {
    del(config.dist, cb);
});

gulp.task('jsbeautify', function(){
   return gulp.src(config.sourcejs)
   .pipe(gulp.dest(config.srcbase));
});

gulp.task('jslint', ['jsbeautify'], function(){
    return gulp.src(config.sourcejs)
   .pipe(plugins.jsbeautifier())
    .pipe(plugins.jscs({configPath: '.jscsrc', fix: true}))
    .pipe(plugins.jshint())
    .pipe(gulp.dest(config.srcbase));
});

gulp.task('dist-nomin', function(){
   return gulp.src(config.sourcejs)
        .pipe(gulp.dest(config.dist));
});

gulp.task('dist-min', function(){
   return gulp.src(config.sourcejs)
        .pipe(plugins.concat('ngdash.min.js'))
        .pipe(plugins.uglify())
        .pipe(gulp.dest(config.dist));
});

gulp.task('build', function(cb){
   sequence('clean', 'jslint', ['dist-nomin', 'dist-min'], cb);
});

/////////////////////////////////////////// TEST /////////////////////////////////////////////////////////

gulp.task('test', function(){
    return gulp.src('./foo/bar')
    .pipe(plugins.karma({action : 'run', configFile: './karma.conf.js'}));
})

///////////////////////////////////////// RELEASE - PUBLISH //////////////////////////////////////////////

function getReleaseType(){
    var types = ['major','minor','patch'];
    var rel = argv.type || 'minor';
    if(types.indexOf(rel) === -1){
        rel = 'patch'
    }
    return rel.toLowerCase();
}

var bumpOpt = { type: plugins.util.env.type };
var bumpPrompt = { type: 'list', name: 'bump', message: 'What type of bump would you like to do? ', choices: ['patch', 'minor', 'major'] };

gulp.task('bump-version', function () {
  return gulp.src(['./bower.json', './package.json'])
    .pipe(plugins.if(!bumpOpt.type, plugins.prompt.prompt(bumpPrompt, function(res){ bumpOpt.type = res.bump; })))
    .pipe(plugins.bump(bumpOpt).on('error', plugins.util.log))
    .pipe(gulp.dest('./'));
});

gulp.task('commit-changes', function () {
  var version = getPackageJsonVersion();
  return gulp.src(config.base)
    .pipe(plugins.git.commit('[ ' + bumpOpt.type +' ] Bumped version number : ' + version, {args: '-a'}));
});

gulp.task('push-changes', function (cb) {
  plugins.git.push('origin', 'master', cb);
});

function getPackageJsonVersion () {
//We parse the json file instead of using require because require caches multiple calls so the version number won't be updated
return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
};

gulp.task('create-new-tag', function (cb) {
  var version = getPackageJsonVersion();
  plugins.git.tag(version, 'Created Tag for version: ' + version, function (error) {
    if (error) { return cb(error); }
    plugins.git.push('origin', 'master', {args: '--tags'}, cb);
  });
});

gulp.task('release', function (callback) {
    function handleError(error){
        if (error) {
            console.log(error.message);
        } else {
            console.log('RELEASE FINISHED SUCCESSFULLY');
        }
        callback(error);
    }
    sequence('test', 'build', 'bump-version','commit-changes','push-changes','create-new-tag', handleError);
});

gulp.task('push-ci-branch', function (cb) {
  plugins.git.push('heroku', 'master', cb);
});

gulp.task('publish', function(callback) {
    function handleError(error){
        if (error) {
            console.log(error.message);
        } else {
            console.log('RELEASE FINISHED SUCCESSFULLY');
        }
        callback(error);
    }
    sequence('release', 'push-ci-branch', handleError);
});

/////////////////////////////////////////////////////  END //////////////////////////////////////
<commit_msg>removed beautify task<commit_after>
////////////////////////////////////// START ///////////////////////////////////////////////////////////////

var gulp = require('gulp');
var plugins = require('gulp-load-plugins')({ lazy: true, camelize: true });
var config = require('./gulp.config')();
var argv = require('yargs').argv;
var fs = require('fs');
var sequence = require("gulp-sequence").use(gulp);

////////////////////////////////////////// Local RUN /////////////////////////////////////////////////////////

var wiredep = require('wiredep');
gulp.task('wiredep', function () {
    var wconfig = { directory: './bower_components/', verbose: true, devDependencies: true };
    return gulp.src(config.index)
        .pipe(wiredep.stream(wconfig))
        .pipe(gulp.dest(config.base));
});

gulp.task('inject', function () {
    var sourcejs = gulp.src(config.sourcejs, { read: false });
    var sourceopt = { name: 'sourcejs', addRootSlash: false };

    var testjs = gulp.src(config.testfixturejs, { read: false });
    var testopt = { name: 'testfixturejs', addRootSlash: false };

    return gulp.src(config.index)
        .pipe(plugins.inject(sourcejs, sourceopt))
        .pipe(plugins.inject(testjs, testopt))
        .pipe(gulp.dest(config.base));
});

gulp.task('serve', ['wiredep','inject'], function () {
  return gulp.src(config.base)
    .pipe(plugins.webserver({
        host: process.env.IP || 'localhost',
        port: process.env.PORT || 8080,
        livereload: true,
        open: true,
		fallback: config.index
    }));
});

gulp.task('heroku', ['wiredep','inject'], function () {
  return gulp.src(config.base)
    .pipe(plugins.webserver({
        host: '0.0.0.0',
        port: process.env.PORT,
        livereload: false,
        open: false,
		fallback: config.index
    }));
});

////////////////////////////////////////// BUILD /////////////////////////////////////////////////////////

var del = require('del');
gulp.task('clean', function (cb) {
    del(config.dist, cb);
});

gulp.task('jslint', function(){
    return gulp.src(config.sourcejs)
   .pipe(plugins.jsbeautifier())
    .pipe(plugins.jscs({configPath: '.jscsrc', fix: true}))
    .pipe(plugins.jshint())
    .pipe(gulp.dest(config.srcbase));
});

gulp.task('dist-nomin', function(){
   return gulp.src(config.sourcejs)
        .pipe(gulp.dest(config.dist));
});

gulp.task('dist-min', function(){
   return gulp.src(config.sourcejs)
        .pipe(plugins.concat('ngdash.min.js'))
        .pipe(plugins.uglify())
        .pipe(gulp.dest(config.dist));
});

gulp.task('build', function(cb){
   sequence('clean', 'jslint', ['dist-nomin', 'dist-min'], cb);
});

/////////////////////////////////////////// TEST /////////////////////////////////////////////////////////

gulp.task('test', function(){
    return gulp.src('./foo/bar')
    .pipe(plugins.karma({action : 'run', configFile: './karma.conf.js'}));
})

///////////////////////////////////////// RELEASE - PUBLISH //////////////////////////////////////////////

function getReleaseType(){
    var types = ['major','minor','patch'];
    var rel = argv.type || 'minor';
    if(types.indexOf(rel) === -1){
        rel = 'patch'
    }
    return rel.toLowerCase();
}

var bumpOpt = { type: plugins.util.env.type };
var bumpPrompt = { type: 'list', name: 'bump', message: 'What type of bump would you like to do? ', choices: ['patch', 'minor', 'major'] };

gulp.task('bump-version', function () {
  return gulp.src(['./bower.json', './package.json'])
    .pipe(plugins.if(!bumpOpt.type, plugins.prompt.prompt(bumpPrompt, function(res){ bumpOpt.type = res.bump; })))
    .pipe(plugins.bump(bumpOpt).on('error', plugins.util.log))
    .pipe(gulp.dest('./'));
});

gulp.task('commit-changes', function () {
  var version = getPackageJsonVersion();
  return gulp.src(config.base)
    .pipe(plugins.git.commit('[ ' + bumpOpt.type +' ] Bumped version number : ' + version, {args: '-a'}));
});

gulp.task('push-changes', function (cb) {
  plugins.git.push('origin', 'master', cb);
});

function getPackageJsonVersion () {
//We parse the json file instead of using require because require caches multiple calls so the version number won't be updated
return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
};

gulp.task('create-new-tag', function (cb) {
  var version = getPackageJsonVersion();
  plugins.git.tag(version, 'Created Tag for version: ' + version, function (error) {
    if (error) { return cb(error); }
    plugins.git.push('origin', 'master', {args: '--tags'}, cb);
  });
});

gulp.task('release', function (callback) {
    function handleError(error){
        if (error) {
            console.log(error.message);
        } else {
            console.log('RELEASE FINISHED SUCCESSFULLY');
        }
        callback(error);
    }
    sequence('test', 'build', 'bump-version','commit-changes','push-changes','create-new-tag', handleError);
});

gulp.task('push-ci-branch', function (cb) {
  plugins.git.push('heroku', 'master', cb);
});

gulp.task('publish', function(callback) {
    function handleError(error){
        if (error) {
            console.log(error.message);
        } else {
            console.log('RELEASE FINISHED SUCCESSFULLY');
        }
        callback(error);
    }
    sequence('release', 'push-ci-branch', handleError);
});

/////////////////////////////////////////////////////  END //////////////////////////////////////
<|endoftext|>


<commit_before>// Single var pattern of gulp (require) stuff in full effect!!!

var gulp = require("gulp"), // "require" gulp
    jade = require("gulp-jade"), // Jade task
    uncss = require("gulp-uncss"), // Remove unused css selectors
    minifyCSS = require("gulp-minify-css"), // Minify CSS
    concatCss = require("gulp-concat-css"), // Concatenate CSS only
    csslint = require("gulp-csslint"), // Lint CSS
    concat = require("gulp-concat"), // Concatenating stuff(?)
    watch = require("gulp-watch"), // Watch files changes
    imagemin = require('gulp-imagemin'), // Minifying images
    autoprefixer = require('gulp-autoprefixer'), // Vendor prefixes
    connect = require("gulp-connect"); // Livereload server at port 8080

// End single var pattern

// Needed to run grunt tasks through gulp
require("gulp-grunt")(gulp);

/*
 *  ===================================================================
 *  | STORE PREPROCESSOR FILE REFERENCES IN VARIABLES |
 *  ===================================================================
 */
var jadeFiles = ["jade/index.jade", "jade/**/*.jade"], // Jade
    lessFiles = ["css-build/*.less", "css-build/**/*.less"], // LESS
    coffeeFiles = ["coffee/*.coffee"]; // Coffeescript

    /*
     * IGNORE ARRAY
     * ============
     * Selectors NOT to be removed when "gulp uncss" task runs.
     * Try to list them alphabetically and in the following order:
     *
     * 1. Page elements first (<nav>, <aside>, etc.)
     * 2. IDs second
     * 3. Classes third
     */
     ignoreArray = [
       "nav",
       "ol",
       "ul",
       ".all-player-info",
       ".btn",
       ".btn-info",
       ".cycle-slide",
       ".player-info",
       ".player-name",
       ".scroll-nav",
       ".scroll-nav__item",
       ".scroll-nav__link",
       ".scroll-nav__list",
       ".scroll-nav__section",
       ".team-copy-popup"
     ];

/*
 *  ===================================================================
 *  | JADE TASK |
 *  ===================================================================
 */
// Output Jade Files to build "index.html" & send it to "build/"
gulp.task("jade", function () {
  return gulp.src("jade/index.jade")
  .pipe(jade({
    pretty: true
  }))
  .pipe(gulp.dest("build"))
  .pipe(connect.reload());
});

/*
 *  ===================================================================
 *  | CSS BUILD TASK |
 *
 * Running "gulp buildcss" performs the following sequence of tasks...
 *
 * 1. Runs the "gulp less" task that"s passed as a "hint"(*)
 * 2. Concatenate selected .css files listed in "gulp.src"
 * 3. Remove unused CSS
 * 4. Minify CSS
 * 5. Lint CSS
 *
 * (*) gulp "hints" are cool...read more about them at:
 * https://github.com/gulpjs/gulp/blob/master/docs/API.md
 *  ===================================================================
 */
gulp.task("buildcss", ['less'],function () {
  gulp.src(['css-build/bootstrap.css', 'css-build/styles.css'])
  .pipe(concatCss("styles.min.css"))
  .pipe(uncss({
    html: ["build/index.html"],
    ignore: ignoreArray
  }))
  .pipe(autoprefixer({
    browsers: ['last 2 versions'],
    cascade: false
  }))
  .pipe(minifyCSS({
    keepBreaks: true
  }))
  .pipe(gulp.dest("build/css/"))
  .pipe(csslint({
    "important": false,
    "duplicate-background-images": false,
    "ids": false,
    "text-indent": false
  }))
  .pipe(csslint.reporter())
  .pipe(connect.reload())
});

/*
*  ===================================================================
*  | IMAGE MINIFICATION TASK |
*
*  Take all images in "imagemin/" & minify them out to "build/img/"
*  ===================================================================
*/
gulp.task('images', function () {
  return gulp.src('image-min/*')
  .pipe(imagemin({
    progressive: true,
    svgoPlugins: [{removeViewBox: false}]
  }))
  .pipe(gulp.dest('build/img'));
});

/*
 *  ===================================================================
 *  | "gulp-grunt" TASKS...RUN GRUNT TASKS VIA GULP!!!! |
 *  ===================================================================
 */
// Run the "grunt less" task
gulp.task("less", function () {
  gulp.run("grunt-shell");
});

// Run the "grunt jsonlint" task
gulp.task("jsonlint", function () {
  gulp.run("grunt-jsonlint");
});

// Run the "grunt coffee" task
gulp.task("coffee", function () {
  gulp.run("grunt-coffee");
});

// BOWERCOPY TASKS
// Copy over ALL the Bower Components!!!
gulp.task("bowercopy", function () {
  gulp.run("grunt-bowercopy");
});

// Copy over Bootstrap core .css only
gulp.task("bowerbscss", function () {
  gulp.run("grunt-bowercopy:bscss");
});

// Copy over jQuery Cycle2 plugin only
gulp.task("bowercycle", function () {
  gulp.run("grunt-bowercopy:cycle2");
});

// Copy over jQuery v.1.11.1 only
gulp.task("bowerjq", function () {
  gulp.run("grunt-bowercopy:jq");
});

// Copy over scrollNav only
gulp.task("bowerscroll", function () {
  gulp.run("grunt-bowercopy:scroll");
});

// Copy over enquire.js only
gulp.task("boweren", function () {
  gulp.run("grunt-bowercopy:enquire");
});

// Copy over matchMedia.js only
gulp.task("bowermm", function () {
  gulp.run("grunt-bowercopy:matchmedia");
});

// Copy over matchMedia.js only
gulp.task("connect", function () {
  connect.server({
    root: "build/",
    livereload: true
  });
});

/*
 *  ===================================================================
 *  | START WATCH TASK |
 *
 *  Be careful of watching a lot of files because that may eat up
 *  computer memory...at least, it does in Grunt.
 *  ===================================================================
 */

gulp.task('spy', ['connect', 'watch']);
gulp.task("watch", function () {

  /*
   * If either preprocesser files or "build/" files change and the site
   * is currently running in the browser, refresh it in the browser via
   * livereload.
   */
  gulp.watch(jadeFiles, ["jade"]);
  gulp.watch(lessFiles, ["buildcss"]);
  gulp.watch(coffeeFiles, ["coffee"]);
  gulp.watch(["build/index.html", "build/css/*.css", "build/js/*.js"]);
});
<commit_msg>remove old gulp jsonlint task from gulpfile.js]gp<commit_after>// Single var pattern of gulp (require) stuff in full effect!!!

var gulp = require("gulp"), // "require" gulp
    jade = require("gulp-jade"), // Jade task
    uncss = require("gulp-uncss"), // Remove unused css selectors
    minifyCSS = require("gulp-minify-css"), // Minify CSS
    concatCss = require("gulp-concat-css"), // Concatenate CSS only
    csslint = require("gulp-csslint"), // Lint CSS
    concat = require("gulp-concat"), // Concatenating stuff(?)
    watch = require("gulp-watch"), // Watch files changes
    imagemin = require('gulp-imagemin'), // Minifying images
    autoprefixer = require('gulp-autoprefixer'), // Vendor prefixes
    connect = require("gulp-connect"); // Livereload server at port 8080

// End single var pattern

// Needed to run grunt tasks through gulp
require("gulp-grunt")(gulp);

/*
 *  ===================================================================
 *  | STORE PREPROCESSOR FILE REFERENCES IN VARIABLES |
 *  ===================================================================
 */
var jadeFiles = ["jade/index.jade", "jade/**/*.jade"], // Jade
    lessFiles = ["css-build/*.less", "css-build/**/*.less"], // LESS
    coffeeFiles = ["coffee/*.coffee"]; // Coffeescript

    /*
     * IGNORE ARRAY
     * ============
     * Selectors NOT to be removed when "gulp uncss" task runs.
     * Try to list them alphabetically and in the following order:
     *
     * 1. Page elements first (<nav>, <aside>, etc.)
     * 2. IDs second
     * 3. Classes third
     */
     ignoreArray = [
       "nav",
       "ol",
       "ul",
       ".all-player-info",
       ".btn",
       ".btn-info",
       ".cycle-slide",
       ".player-info",
       ".player-name",
       ".scroll-nav",
       ".scroll-nav__item",
       ".scroll-nav__link",
       ".scroll-nav__list",
       ".scroll-nav__section",
       ".team-copy-popup"
     ];

/*
 *  ===================================================================
 *  | JADE TASK |
 *  ===================================================================
 */
// Output Jade Files to build "index.html" & send it to "build/"
gulp.task("jade", function () {
  return gulp.src("jade/index.jade")
  .pipe(jade({
    pretty: true
  }))
  .pipe(gulp.dest("build"))
  .pipe(connect.reload());
});

/*
 *  ===================================================================
 *  | CSS BUILD TASK |
 *
 * Running "gulp buildcss" performs the following sequence of tasks...
 *
 * 1. Runs the "gulp less" task that"s passed as a "hint"(*)
 * 2. Concatenate selected .css files listed in "gulp.src"
 * 3. Remove unused CSS
 * 4. Minify CSS
 * 5. Lint CSS
 *
 * (*) gulp "hints" are cool...read more about them at:
 * https://github.com/gulpjs/gulp/blob/master/docs/API.md
 *  ===================================================================
 */
gulp.task("buildcss", ['less'],function () {
  gulp.src(['css-build/bootstrap.css', 'css-build/styles.css'])
  .pipe(concatCss("styles.min.css"))
  .pipe(uncss({
    html: ["build/index.html"],
    ignore: ignoreArray
  }))
  .pipe(autoprefixer({
    browsers: ['last 2 versions'],
    cascade: false
  }))
  .pipe(minifyCSS({
    keepBreaks: true
  }))
  .pipe(gulp.dest("build/css/"))
  .pipe(csslint({
    "important": false,
    "duplicate-background-images": false,
    "ids": false,
    "text-indent": false
  }))
  .pipe(csslint.reporter())
  .pipe(connect.reload())
});

/*
*  ===================================================================
*  | IMAGE MINIFICATION TASK |
*
*  Take all images in "imagemin/" & minify them out to "build/img/"
*  ===================================================================
*/
gulp.task('images', function () {
  return gulp.src('image-min/*')
  .pipe(imagemin({
    progressive: true,
    svgoPlugins: [{removeViewBox: false}]
  }))
  .pipe(gulp.dest('build/img'));
});

/*
 *  ===================================================================
 *  | "gulp-grunt" TASKS...RUN GRUNT TASKS VIA GULP!!!! |
 *  ===================================================================
 */
// Run the "grunt less" task
gulp.task("less", function () {
  gulp.run("grunt-shell");
});

// Run the "grunt coffee" task
gulp.task("coffee", function () {
  gulp.run("grunt-coffee");
});

// BOWERCOPY TASKS
// Copy over ALL the Bower Components!!!
gulp.task("bowercopy", function () {
  gulp.run("grunt-bowercopy");
});

// Copy over Bootstrap core .css only
gulp.task("bowerbscss", function () {
  gulp.run("grunt-bowercopy:bscss");
});

// Copy over jQuery Cycle2 plugin only
gulp.task("bowercycle", function () {
  gulp.run("grunt-bowercopy:cycle2");
});

// Copy over jQuery v.1.11.1 only
gulp.task("bowerjq", function () {
  gulp.run("grunt-bowercopy:jq");
});

// Copy over scrollNav only
gulp.task("bowerscroll", function () {
  gulp.run("grunt-bowercopy:scroll");
});

// Copy over enquire.js only
gulp.task("boweren", function () {
  gulp.run("grunt-bowercopy:enquire");
});

// Copy over matchMedia.js only
gulp.task("bowermm", function () {
  gulp.run("grunt-bowercopy:matchmedia");
});

// Copy over matchMedia.js only
gulp.task("connect", function () {
  connect.server({
    root: "build/",
    livereload: true
  });
});

/*
 *  ===================================================================
 *  | START WATCH TASK |
 *
 *  Be careful of watching a lot of files because that may eat up
 *  computer memory...at least, it does in Grunt.
 *  ===================================================================
 */

gulp.task('spy', ['connect', 'watch']);
gulp.task("watch", function () {

  /*
   * If either preprocesser files or "build/" files change and the site
   * is currently running in the browser, refresh it in the browser via
   * livereload.
   */
  gulp.watch(jadeFiles, ["jade"]);
  gulp.watch(lessFiles, ["buildcss"]);
  gulp.watch(coffeeFiles, ["coffee"]);
  gulp.watch(["build/index.html", "build/css/*.css", "build/js/*.js"]);
});
<|endoftext|>


<commit_before>'use strict';

const gulp = require('gulp');
const $ = require('gulp-load-plugins')({pattern:['gulp-*']});

gulp.task('js-with-option', () => {
	return gulp.src('src/js/**/*.js')
		.pipe($.plumber())
		.pipe($.babel({presets: [['env', {targets: {ie: 11}}]]}))
		.pipe($.concat('stile-full.min.js'))
		.pipe($.uglify())
		.pipe(gulp.dest('dist/js'));
});

gulp.task('js-without-option', () => {
	return gulp.src(['src/js/basic/*.js', 'src/js/content/*.js'])
		.pipe($.plumber())
		.pipe($.babel({presets: [['env', {targets: {ie: 11}}]]}))
		.pipe($.concat('stile.min.js'))
		.pipe($.uglify())
		.pipe(gulp.dest('dist/js'));
});

gulp.task('js-each', () => {
	return gulp.src('src/js/**/*.js')
		.pipe($.plumber())
		.pipe($.babel({presets: [['env', {targets: {ie: 11}}]]}))
		.pipe($.uglify())
		.pipe($.rename({extname: '.min.js'}))
		.pipe(gulp.dest('dist/js'));
});

gulp.task('js', gulp.parallel('js-with-option', 'js-without-option', 'js-each'));

gulp.task('sass', () => {
	return gulp.src(['src/sass/**/*.scss'], {base: 'src/sass'})
		.pipe($.plumber())
		.pipe($.changed('dist/sass'))
		.pipe(gulp.dest('dist/sass'));
});

gulp.task('watch', () => {
	gulp.watch('src/js/**/*.js', gulp.parallel('js'));
	gulp.watch('src/sass/**/*.scss', gulp.parallel('sass'));
});

gulp.task('build', gulp.parallel('js', 'sass'));

gulp.task('default', gulp.series('build', 'watch'));

// -----------------------------------------------------------------------------

gulp.task('docs-sass', gulp.series('sass', () => {
	return gulp.src('docs/style.scss')
		.pipe($.plumber())
		.pipe($.sourcemaps.init())
		.pipe($.sass({outputStyle: 'compressed'}))
		.pipe($.autoprefixer(['ie >= 11']))
		.pipe($.rename({extname: '.min.css'}))
		.pipe($.sourcemaps.write('.'))
		.pipe(gulp.dest('docs'));
}));

gulp.task('docs-js', gulp.series('js-with-option', () => {
	return gulp.src(['dist/js/stile-full.min.js'])
		.pipe($.plumber())
		.pipe(gulp.dest('docs'));
}));

gulp.task('docs', gulp.series('default', () => {
	gulp.watch('src/js/**/*.js',     gulp.series('docs-js'));
	gulp.watch('src/sass/**/*.scss', gulp.series('docs-sass'));
	gulp.watch('docs/style.scss',    gulp.series('docs-sass'));
}));
<commit_msg>Improve gulpfile<commit_after>'use strict';

const gulp = require('gulp');
const $ = require('gulp-load-plugins')({pattern:['gulp-*']});

gulp.task('js-with-option', () => {
	return gulp.src('src/js/**/*.js')
		.pipe($.plumber())
		.pipe($.babel({presets: [['env', {targets: {ie: 11}}]]}))
		.pipe($.concat('stile-full.min.js'))
		.pipe($.uglify())
		.pipe(gulp.dest('dist/js'));
});

gulp.task('js-without-option', () => {
	return gulp.src(['src/js/basic/*.js', 'src/js/content/*.js'])
		.pipe($.plumber())
		.pipe($.babel({presets: [['env', {targets: {ie: 11}}]]}))
		.pipe($.concat('stile.min.js'))
		.pipe($.uglify())
		.pipe(gulp.dest('dist/js'));
});

gulp.task('js-each', () => {
	return gulp.src('src/js/**/*.js')
		.pipe($.plumber())
		.pipe($.babel({presets: [['env', {targets: {ie: 11}}]]}))
		.pipe($.uglify())
		.pipe($.rename({extname: '.min.js'}))
		.pipe(gulp.dest('dist/js'));
});

gulp.task('js', gulp.parallel('js-with-option', 'js-without-option', 'js-each'));

gulp.task('sass', () => {
	return gulp.src(['src/sass/**/*.scss'], {base: 'src/sass'})
		.pipe($.plumber())
		.pipe($.changed('dist/sass'))
		.pipe(gulp.dest('dist/sass'));
});

gulp.task('watch', () => {
	gulp.watch('src/js/**/*.js', gulp.parallel('js'));
	gulp.watch('src/sass/**/*.scss', gulp.parallel('sass'));
});

gulp.task('build', gulp.parallel('js', 'sass'));

gulp.task('default', gulp.series('build', 'watch'));

// -----------------------------------------------------------------------------

gulp.task('docs-sass', gulp.series('sass', () => {
	return gulp.src('docs/style.scss')
		.pipe($.plumber())
		.pipe($.sourcemaps.init())
		.pipe($.sass({outputStyle: 'compressed'}))
		.pipe($.autoprefixer(['ie >= 11']))
		.pipe($.rename({extname: '.min.css'}))
		.pipe($.sourcemaps.write('.'))
		.pipe(gulp.dest('docs'));
}));

gulp.task('docs-js', gulp.series('js-with-option', () => {
	return gulp.src(['dist/js/stile-full.min.js'])
		.pipe($.plumber())
		.pipe(gulp.dest('docs'));
}));

gulp.task('docs-watch', () => {
	gulp.watch('src/js/**/*.js',     gulp.series('docs-js'));
	gulp.watch('src/sass/**/*.scss', gulp.series('docs-sass'));
	gulp.watch('docs/style.scss',    gulp.series('docs-sass'));
});

gulp.task('docs-build', gulp.parallel('docs-js', 'docs-sass'));

gulp.task('docs-default', gulp.series('docs-build', 'docs-watch'));

gulp.task('docs', gulp.parallel('default', 'docs-default'));
<|endoftext|>


<commit_before>var gulp        = require('gulp');
var gutil       = require('gulp-util');
var source      = require('vinyl-source-stream');
var babelify    = require('babelify');
var watchify    = require('watchify');
var exorcist    = require('exorcist');
var browserify  = require('browserify');
var browserSync = require('browser-sync').create();

// Input file.
watchify.args.debug = true;
var bundler = watchify(browserify('./app/js/app.js', watchify.args));

// Babel transform
bundler.transform(babelify.configure({
    sourceMapRelative: 'app/js'
}));

// On updates recompile
bundler.on('update', bundle);

function bundle() {

    gutil.log('Compiling JS...');

    return bundler.bundle()
        .on('error', function (err) {
            gutil.log(err.message);
            browserSync.notify("Browserify Error!");
            this.emit("end");
        })
        .pipe(exorcist('app/js/dist/bundle.js.map'))
        .pipe(source('bundle.js'))
        .pipe(gulp.dest('./app/js/dist'))
        .pipe(browserSync.stream({once: true}));
}

/**
 * Gulp task alias
 */
gulp.task('bundle', function () {
    return bundle();
});

/**
 * First bundle, then serve from the ./app directory
 */
gulp.task('default', ['bundle'], function () {
    browserSync.init({
        server: "./app"
    });
});<commit_msg>Updated gulpfile.<commit_after>var gulp        = require('gulp');
var gutil       = require('gulp-util');
var source      = require('vinyl-source-stream');
var babelify    = require('babelify');
var watchify    = require('watchify');
var exorcist    = require('exorcist');
var browserify  = require('browserify');
var browserSync = require('browser-sync').create();
var sass        = require('gulp-sass');
var reload      = browserSync.reload;

var src = {
    scss: 'app/scss/*.scss',
    css:  'app/css',
    html: 'app/*.html'
};

// Input file.
watchify.args.debug = true;
var bundler = watchify(browserify('./app/js/app.js', watchify.args));

// Babel transform
bundler.transform(babelify.configure({
    sourceMapRelative: 'app/js'
}));

// On updates recompile
bundler.on('update', bundle);

function bundle() {

    gutil.log('Compiling JS...');

    return bundler.bundle()
        .on('error', function (err) {
            gutil.log(err.message);
            browserSync.notify("Browserify Error!");
            this.emit("end");
        })
        .pipe(exorcist('app/js/dist/bundle.js.map'))
        .pipe(source('bundle.js'))
        .pipe(gulp.dest('./app/js/dist'))
        .pipe(browserSync.stream({once: true}));
}

/**
 * Gulp task alias
 */
gulp.task('bundle', function () {
    return bundle();
});

// Compile sass into CSS
gulp.task('sass', function() {
    return gulp.src(src.scss)
        .pipe(sass())
        .pipe(gulp.dest(src.css))
        .pipe(reload({stream: true}));
});

/**
 * First bundle, then serve from the ./app directory
 */
gulp.task('default', ['bundle', 'sass'], function () {
    browserSync.init({
        server: "./app"
    });

	gulp.watch(src.scss, ['sass']);
    gulp.watch(src.html).on('change', reload);
});

<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp'),
	karma = require('karma').server,
	operation = require('./operationalyzer'),
	jsufon = require('./jsufonify');

var $ = require('gulp-load-plugins')({
  pattern: ['gulp-*']
});

gulp.task('clean-dist', function() {
	return gulp.src('dist', { read: false })
		.pipe($.rimraf());
});

gulp.task('build', ['clean-dist', 'copy'], function() {
	return gulp.src('src/**/*.coffee')
		.pipe($.coffee({bare: true}).on('error', $.util.log))
		.pipe(operation())
		.pipe($.concat('font.json'))
		.pipe(jsufon())
		.pipe(gulp.dest('dist/'));
});

gulp.task('copy', function() {
	return gulp.src('src/**/*.js')
		.pipe(gulp.dest('dist/'));
});

gulp.task('lint', function() {
	return gulp.src(['src/**/*.js'])
		.pipe($.size())
		.pipe($.jshint())
		.pipe($.jshint.reporter('jshint-stylish'))
		.pipe($.jshint.reporter('fail'));
});

gulp.task('test', ['lint', 'build'], function(done) {
	karma.start({
		configFile: __dirname + '/karma.conf.js',
			singleRun: true
		}, done);
});<commit_msg>fix task dependencies<commit_after>'use strict';

var gulp = require('gulp'),
	karma = require('karma').server,
	operation = require('./operationalyzer'),
	jsufon = require('./jsufonify');

var $ = require('gulp-load-plugins')({
  pattern: ['gulp-*']
});

gulp.task('clean-dist', function() {
	return gulp.src('dist', { read: false })
		.pipe($.rimraf());
});

gulp.task('build', ['copy'], function() {
	return gulp.src('src/**/*.coffee')
		.pipe($.coffee({bare: true}).on('error', $.util.log))
		.pipe(operation())
		.pipe($.concat('font.json'))
		.pipe(jsufon())
		.pipe(gulp.dest('dist/'));
});

gulp.task('copy', ['clean-dist'], function() {
	return gulp.src('src/**/*.js')
		.pipe(gulp.dest('dist'));
});

gulp.task('lint', function() {
	return gulp.src(['src/**/*.js'])
		.pipe($.size())
		.pipe($.jshint())
		.pipe($.jshint.reporter('jshint-stylish'))
		.pipe($.jshint.reporter('fail'));
});

gulp.task('test', ['lint', 'build'], function(done) {
	karma.start({
		configFile: __dirname + '/karma.conf.js',
			singleRun: true
		}, done);
});<|endoftext|>


<commit_before>var c   = require( './config/build.json' );
var pkg = require('./package.json');

var spawn  = require('child_process').spawn;
var fs     = require('fs');

var server;

var gulp   = require('gulp');
var es     = require('event-stream');
var through= require('through2');
var gutil  = require('gulp-util');
var clean  = require('gulp-clean');
var jade   = require('gulp-jade');
var aTempl = require('gulp-angular-templatecache');
var rename = require('gulp-rename');
var stylus = require('gulp-stylus');
var concat = require('gulp-concat');
var templt = require('gulp-template');
var walk   = require('walk');
var karma  = require('gulp-karma')({configFile: c.karmaCfg});
var newer  = require('gulp-newer');
var runSeq = require('run-sequence');
var ngmin  = require('gulp-ngmin');
var uglify = require('gulp-uglify');
var tinyLr = require('tiny-lr');
var path   = require('path');
var map    = require('vinyl-map');
var istnbl = require('gulp-istanbul-enforcer');
var csso   = require('gulp-csso');
var rework = require('gulp-rework');
var moveMe = require('rework-move-media');
var imgmin = require('gulp-imagemin');
var jshint = require('jshint').JSHINT;
var Notify = require('node-notifier');
var instWd = require('gulp-protractor').webdriver_update;
var prtrct = require('gulp-protractor').protractor;
var order  = require('gulp-order');
var gzip   = require('gulp-gzip');
var feats  = require('./lib/gulp-featureflags');

var buildDir = c.buildDir;
var complDir = c.compileDir;
var cwd      = __dirname;
var src      = cwd + '/src';
var hintCfg  = c.jsHintCfg;
var fileName = pkg.name + "-" + pkg.version;
var vBuildJs = c.vendor.buildJs.concat(c.vendor.js);
var vComplJs = c.vendor.compileJs.concat(c.vendor.js);
var allAppJs = c.app.js.concat(vBuildJs);
var featsDev = cwd + '/config/flags.dev.json';
var featDist = cwd + '/config/flags.release.json';

var notifier = new Notify({});

function bStyl() {
  return gulp.src(c.app.stylus)
  .pipe(stylus({
      set: ['linenos'],
      use: ['nib'],
      paths: [__dirname + '/public'],
      urlFunc: ['url']
    }))
    .pipe(rework(moveMe()))
    .pipe(csso());
}

// Fix formatting of error messages with newlines
// so that the whole message starts on its own line.
(function () {
  var listeners = gulp.listeners('task_err');
  gulp.removeAllListeners('task_err');

  function formatMultiline(message) {
    if (message.indexOf("\n") !== -1) {
      return ("\n"+message).replace(/\n(?:error[^\s]*\s*)?/ig, "\n   [" + gutil.colors.red('error') + "] ");
    } else {
      return message;
    }
  }

  gulp.on('task_err', function (e) {
    if (e.err && e.err.message) {
      e.err.message = formatMultiline(e.err.message);
    } else if (e.message) {
      e.message = formatMultiline(e.message);
    }
  });

  listeners.forEach(function (listener) {
    gulp.on('task_err', listener);
  });
})();

gulp.task('clean', function () {
  return gulp.src([buildDir, complDir, 'coverage'], {read: false})
    .pipe(clean());
});

gulp.task('assets', function () {
  return es.merge(
      gulp.src(c.app.assets, {base: src}),
      gulp.src(c.vendor.assets, {base: cwd})
    )
    .pipe(newer(buildDir))
    .pipe(imgmin())
    .pipe(gulp.dest(buildDir));
});

gulp.task('jshint', function () {
  var errors = { length : 0 };
  function formatErrors (errors) {
    return errors.length + " total errors. \n" + (Object.keys(errors).map(function (file) {
      if (file == 'length') { return }
      ers = errors[file];
      return file + ": " + ers.length + " errors \n" + ers.map(function (error) {
        return "    l" + error.line + "c" + error.character + ": " + error.evidence + " – " + error.reason;
      }).join("\n");
    }).join("\n"));
  }

  return es.merge(gulp.src(c.app.js), gulp.src(c.app.specs))
    .pipe(through.obj(function (file, enc, next) {
      if (!file.isNull()) {
        if(!jshint(file.contents.toString('utf8'), hintCfg)) {
          errors[file.relative] = jshint.errors;
          errors.length += jshint.errors.length;
        }
      }
      this.push(file);
      next();
    }))
    .pipe(through.obj(function (file, enc, next) {
      if (errors.length) {
        next(new gutil.PluginError('gulp-jshint', formatErrors(errors)));
        this.end();
      } else {
        next();
      }
    }));
});

gulp.task('css', ['assets'], function () {
  return bStyl()
  .pipe(concat(fileName + '.css'))
  .pipe(gulp.dest(buildDir + '/assets/'));
});

gulp.task('specs', ['templates', 'buildJs'], function () {
  var cfg = {};
  if (process.env.TRAVIS) {
    cfg.browsers = ['PhantomJS', 'Firefox'];
  }
  return karma.once(cfg);
});

gulp.task('buildJs', ['jshint'], function () {
  return es.merge(gulp.src(c.app.js)
      .pipe(feats(featsDev, {strict: false, default: true}))
    , gulp.src(vBuildJs, {base: cwd}))
    .pipe(newer(buildDir))
    .pipe(gulp.dest(buildDir));
});

gulp.task('js', ['specs', 'buildJs']);

gulp.task('html', function (cb) {
  var walker = walk.walk(buildDir, { followLinks: false });
  var ctx = {styles:[], scripts:[], compile: false};
  walker.on('file', function (root, stat, next) {
    root = path.relative(buildDir, root);
    if (stat.name == 'angular.js') {
      ctx.scripts.unshift(root + '/' + stat.name);
    } else {
      if (stat.name.match(/\.css$/)) {
        ctx.styles.push(root + '/' + stat.name);
      } else if (stat.name.match(/\.js$/)) {
        ctx.scripts.push(root + '/' + stat.name);
      }
    }
    next();
  });
  walker.on('end', function () {
    gulp.src(c.app.html)
      .pipe(templt(ctx))
      .pipe(gulp.dest(buildDir))
      .on('end', cb);
  });
});

gulp.task('templates', function () {
  var compiled = gulp.src(c.app.jade)
    .pipe(rename(function (path) {
      path.dirname = path.dirname.replace(/^app\/?/, '');
      path.extname = '';
    }))
    .pipe(newer(buildDir + '/templates-app.js'))
    .pipe(jade());
  return es.merge(
      compiled.pipe(newer(buildDir)).pipe(gulp.dest(buildDir)),
      compiled.pipe(aTempl('templates.js', {standalone: true}))
        .pipe(gulp.dest(buildDir + '/app'))
    );
});

gulp.task('build', function (cb) {
  runSeq('clean', ['templates', 'js', 'css', 'assets'], 'html', cb);
});

gulp.task('dist', ['distJs', 'distAssets', 'distHtml']);

gulp.task('distJs', ['buildJs', 'templates'], function () {
  return es.merge(
    gulp.src(vComplJs),
    gulp.src(c.app.js.concat(buildDir + '/app/templates.js'))
      .pipe(ngmin())
      .pipe(feats(featDist, {strict: true, default: false}))
  )
  .pipe(order(['**/angular?(.min).js', '*']))
  .pipe(concat(fileName+'.js'))
  .pipe(gulp.dest(complDir + '/assets'))
  .pipe(uglify({preserveComments: 'some', outSourceMap: true}))
  .pipe(rename(function (path) {
    if (path.extname == '.js') {
      path.extname = '.min.js';
    }
  }))
  .pipe(gulp.dest(complDir + '/assets'));
});

gulp.task('distAssets', ['css', 'assets'], function () {
  return gulp.src([buildDir + '/assets/**/*.*'])
    .pipe(gulp.dest(complDir + '/assets'));
});

gulp.task('distHtml', function () {
  var ctx = {
    styles:['/assets/' + fileName + '.css'],
    scripts:['/assets/' + fileName + '.min.js'],
    compile: true
  };
  return gulp.src(c.app.html)
    .pipe(templt(ctx))
    .pipe(gulp.dest(complDir));
});

gulp.task('testDist', function () {
  return karma.once({
    files: [complDir+"/**/*.min.js"].concat(
      c.test.js, c.app.specs,
      c.test.assets.map(function (pattern) {
        return {
          pattern: pattern, watched: true, included: false, served: true
        };
      })
    ),
    browsers: ['PhantomJS'],
    reporters: ['dots']
  });
});

gulp.task('cacheBust', function (done) {
  var cachebust = new require('gulp-cachebust')();
  gulp.src(complDir + '/assets/**/*.*')
    .pipe(cachebust.resources())
    .pipe(gulp.dest(complDir + '/assets'))
    .on('end', function () {
      gulp.src(complDir + '/**/*.{html,css}')
      .pipe(cachebust.references())
      .pipe(gulp.dest(complDir))
      .on('end', done);
    });
});

gulp.task('compressDist', function () {
  return gulp.src(complDir + "/**/*.*")
  .pipe(gzip())
  .pipe(gulp.dest(complDir));
});

gulp.task('compile', function (cb) {
  runSeq('dist', 'testDist', 'cacheBust', 'compressDist', cb);
});

gulp.task('compileServer', function () {
  if (server) {
    server.close();
  }
  server = require(cwd+'/'+c.app.server).listen(process.env.PORT||8080, complDir);
});

gulp.task('build_', function (cb) {
  runSeq('clean', ['templates', 'buildJs', 'css', 'assets'], 'html', cb);
});

gulp.task('watch', ['build_', 'installWebdriver'], function (cb) {
  server = require(cwd+'/'+c.app.server)
    .listen(process.env.PORT || 8080, buildDir);
  gutil.log("Listening on port " + process.env.PORT || 8080);

  var lr = tinyLr();
  lr.listen(35729);
  gutil.log("LiveReload server started on port 35729");

  gulp.watch(buildDir + "/**/*", function (e) {
    lr.changed({
      body: {
        files: [path.relative(buildDir, e.path)]
      }
    });
  });

  gulp.watch('./src/**/*.styl', ['css']);
  gulp.watch(c.app.jade, ['templates']);
  gulp.watch(c.app.html, ['html']);
  gulp.watch([buildDir + '/**/*.js', buildDir + '/**/*.css'], function (e) {
    if (e.type != 'changed') {
      gulp.run('html');
    }
  });

  gulp.watch(c.e2eSpecs, ['runProtractor']);

  karma.start({ autoWatch: true });

  gulp.watch(allAppJs.concat(featsDev), ['buildJs']);
});

gulp.task('default', ['watch']);

gulp.on('err', function (e) {
  if (!this.tasks['watch'].running) {
    gutil.log("Failure. Terminating.");
    process.exit(1);
  } else {
    notifier.notify({message: "Error in " + e.err.plugin + ": " + e.message }, function (e, t) { });
    gutil.log(gutil.colors.red("Error in build. Continuing execution for `watch` task."));
    console.log('');
    gutil.beep();
  }
});

gulp.task('checkCoverage', ['specs'], function () {
  return gulp.src('.')
    .pipe(istnbl({
      thresholds: c.covReq,
      coverageDirectory : 'coverage',
      rootDirectory : ''
    }));
});

gulp.task('coveralls', ['checkCoverage', 'protractor'], function (done) {
  var ps = spawn(cwd+'/node_modules/coveralls/bin/coveralls.js');
  var coverageDir = cwd + '/coverage/';
  fs.readdir(coverageDir, pickFolder);
  ps.on('exit', function (c) {
    done();
  });
  ps.stdout.on('data', log);
  ps.stderr.on('data', log);

  function pickFolder (err, folders) {
    var folder = folders[0];
    fs.readFile(coverageDir + folder + '/lcov.info', pipeFile);
  }

  function pipeFile (err, data) {
    ps.stdin.write(data);
    ps.stdin.end();
  }

  function log (data) {
    gutil.log(data.toString().replace(/^\n|\n$/g, ''));
  }
});

gulp.task('installWebdriver', function (cb) {
  if (process.env['TRAVIS']) {
    cb();
  } else {
    return instWd(cb);
  }
});

gulp.task('protractor', ['installWebdriver', 'compile', 'compileServer'], function (cb) {
  return gulp.src(c.e2eSpecs)
  .pipe(prtrct({configFile: c.protractorCfg}))
  .on('error', function (e) { cb(e); this.emit('end'); })
  .on('end', function () { server.close(); });
});

gulp.task('runProtractor', function () {
  return gulp.src(c.e2eSpecs)
  .pipe(prtrct({configFile: c.protractorCfg, baseUrl: 'http://localhost:8080'}))
  .on('error', function (e) { this.emit('end', new gutil.PluginError('gulp-jshint', e)); });
});

gulp.task('ci', ['coveralls']);
<commit_msg>copy files because angular templates is broken<commit_after>var c   = require( './config/build.json' );
var pkg = require('./package.json');

var spawn  = require('child_process').spawn;
var fs     = require('fs');

var server;

var gulp   = require('gulp');
var es     = require('event-stream');
var through= require('through2');
var gutil  = require('gulp-util');
var clean  = require('gulp-clean');
var jade   = require('gulp-jade');
var aTempl = require('gulp-angular-templatecache');
var rename = require('gulp-rename');
var stylus = require('gulp-stylus');
var concat = require('gulp-concat');
var templt = require('gulp-template');
var walk   = require('walk');
var karma  = require('gulp-karma')({configFile: c.karmaCfg});
var newer  = require('gulp-newer');
var runSeq = require('run-sequence');
var ngmin  = require('gulp-ngmin');
var uglify = require('gulp-uglify');
var tinyLr = require('tiny-lr');
var path   = require('path');
var map    = require('vinyl-map');
var istnbl = require('gulp-istanbul-enforcer');
var csso   = require('gulp-csso');
var rework = require('gulp-rework');
var moveMe = require('rework-move-media');
var imgmin = require('gulp-imagemin');
var jshint = require('jshint').JSHINT;
var Notify = require('node-notifier');
var instWd = require('gulp-protractor').webdriver_update;
var prtrct = require('gulp-protractor').protractor;
var order  = require('gulp-order');
var gzip   = require('gulp-gzip');
var feats  = require('./lib/gulp-featureflags');

var buildDir = c.buildDir;
var complDir = c.compileDir;
var cwd      = __dirname;
var src      = cwd + '/src';
var hintCfg  = c.jsHintCfg;
var fileName = pkg.name + "-" + pkg.version;
var vBuildJs = c.vendor.buildJs.concat(c.vendor.js);
var vComplJs = c.vendor.compileJs.concat(c.vendor.js);
var allAppJs = c.app.js.concat(vBuildJs);
var featsDev = cwd + '/config/flags.dev.json';
var featDist = cwd + '/config/flags.release.json';

var notifier = new Notify({});

function bStyl() {
  return gulp.src(c.app.stylus)
  .pipe(stylus({
      set: ['linenos'],
      use: ['nib'],
      paths: [__dirname + '/public'],
      urlFunc: ['url']
    }))
    .pipe(rework(moveMe()))
    .pipe(csso());
}

// Fix formatting of error messages with newlines
// so that the whole message starts on its own line.
(function () {
  var listeners = gulp.listeners('task_err');
  gulp.removeAllListeners('task_err');

  function formatMultiline(message) {
    if (message.indexOf("\n") !== -1) {
      return ("\n"+message).replace(/\n(?:error[^\s]*\s*)?/ig, "\n   [" + gutil.colors.red('error') + "] ");
    } else {
      return message;
    }
  }

  gulp.on('task_err', function (e) {
    if (e.err && e.err.message) {
      e.err.message = formatMultiline(e.err.message);
    } else if (e.message) {
      e.message = formatMultiline(e.message);
    }
  });

  listeners.forEach(function (listener) {
    gulp.on('task_err', listener);
  });
})();

gulp.task('clean', function () {
  return gulp.src([buildDir, complDir, 'coverage'], {read: false})
    .pipe(clean());
});

gulp.task('assets', function () {
  return es.merge(
      gulp.src(c.app.assets, {base: src}),
      gulp.src(c.vendor.assets, {base: cwd})
    )
    .pipe(newer(buildDir))
    .pipe(imgmin())
    .pipe(gulp.dest(buildDir));
});

gulp.task('jshint', function () {
  var errors = { length : 0 };
  function formatErrors (errors) {
    return errors.length + " total errors. \n" + (Object.keys(errors).map(function (file) {
      if (file == 'length') { return }
      ers = errors[file];
      return file + ": " + ers.length + " errors \n" + ers.map(function (error) {
        return "    l" + error.line + "c" + error.character + ": " + error.evidence + " – " + error.reason;
      }).join("\n");
    }).join("\n"));
  }

  return es.merge(gulp.src(c.app.js), gulp.src(c.app.specs))
    .pipe(through.obj(function (file, enc, next) {
      if (!file.isNull()) {
        if(!jshint(file.contents.toString('utf8'), hintCfg)) {
          errors[file.relative] = jshint.errors;
          errors.length += jshint.errors.length;
        }
      }
      this.push(file);
      next();
    }))
    .pipe(through.obj(function (file, enc, next) {
      if (errors.length) {
        next(new gutil.PluginError('gulp-jshint', formatErrors(errors)));
        this.end();
      } else {
        next();
      }
    }));
});

gulp.task('css', ['assets'], function () {
  return bStyl()
  .pipe(concat(fileName + '.css'))
  .pipe(gulp.dest(buildDir + '/assets/'));
});

gulp.task('specs', ['templates', 'buildJs'], function () {
  var cfg = {};
  if (process.env.TRAVIS) {
    cfg.browsers = ['PhantomJS', 'Firefox'];
  }
  return karma.once(cfg);
});

gulp.task('buildJs', ['jshint'], function () {
  return es.merge(gulp.src(c.app.js)
      .pipe(feats(featsDev, {strict: false, default: true}))
    , gulp.src(vBuildJs, {base: cwd}))
    .pipe(newer(buildDir))
    .pipe(gulp.dest(buildDir));
});

gulp.task('js', ['specs', 'buildJs']);

gulp.task('html', function (cb) {
  var walker = walk.walk(buildDir, { followLinks: false });
  var ctx = {styles:[], scripts:[], compile: false};
  walker.on('file', function (root, stat, next) {
    root = path.relative(buildDir, root);
    if (stat.name == 'angular.js') {
      ctx.scripts.unshift(root + '/' + stat.name);
    } else {
      if (stat.name.match(/\.css$/)) {
        ctx.styles.push(root + '/' + stat.name);
      } else if (stat.name.match(/\.js$/)) {
        ctx.scripts.push(root + '/' + stat.name);
      }
    }
    next();
  });
  walker.on('end', function () {
    gulp.src(c.app.html)
      .pipe(templt(ctx))
      .pipe(gulp.dest(buildDir))
      .on('end', cb);
  });
});

gulp.task('templates', function () {
  var compiled = gulp.src(c.app.jade)
    .pipe(rename(function (path) {
      path.dirname = path.dirname.replace(/^app\/?/, '');
      path.extname = '';
    }))
    .pipe(newer(buildDir + '/templates-app.js'))
    .pipe(jade());
  return es.merge(
      compiled.pipe(map(function(code) { return code; }))
      .pipe(newer(buildDir))
      .pipe(gulp.dest(buildDir)),
      compiled.pipe(aTempl('templates.js', {standalone: true}))
        .pipe(gulp.dest(buildDir + '/app'))
    );
});

gulp.task('build', function (cb) {
  runSeq('clean', ['templates', 'js', 'css', 'assets'], 'html', cb);
});

gulp.task('dist', ['distJs', 'distAssets', 'distHtml']);

gulp.task('distJs', ['buildJs', 'templates'], function () {
  return es.merge(
    gulp.src(vComplJs),
    gulp.src(c.app.js.concat(buildDir + '/app/templates.js'))
      .pipe(ngmin())
      .pipe(feats(featDist, {strict: true, default: false}))
  )
  .pipe(order(['**/angular?(.min).js', '*']))
  .pipe(concat(fileName+'.js'))
  .pipe(gulp.dest(complDir + '/assets'))
  .pipe(uglify({preserveComments: 'some', outSourceMap: true}))
  .pipe(rename(function (path) {
    if (path.extname == '.js') {
      path.extname = '.min.js';
    }
  }))
  .pipe(gulp.dest(complDir + '/assets'));
});

gulp.task('distAssets', ['css', 'assets'], function () {
  return gulp.src([buildDir + '/assets/**/*.*'])
    .pipe(gulp.dest(complDir + '/assets'));
});

gulp.task('distHtml', function () {
  var ctx = {
    styles:['/assets/' + fileName + '.css'],
    scripts:['/assets/' + fileName + '.min.js'],
    compile: true
  };
  return gulp.src(c.app.html)
    .pipe(templt(ctx))
    .pipe(gulp.dest(complDir));
});

gulp.task('testDist', function () {
  return karma.once({
    files: [complDir+"/**/*.min.js"].concat(
      c.test.js, c.app.specs,
      c.test.assets.map(function (pattern) {
        return {
          pattern: pattern, watched: true, included: false, served: true
        };
      })
    ),
    browsers: ['PhantomJS'],
    reporters: ['dots']
  });
});

gulp.task('cacheBust', function (done) {
  var cachebust = new require('gulp-cachebust')();
  gulp.src(complDir + '/assets/**/*.*')
    .pipe(cachebust.resources())
    .pipe(gulp.dest(complDir + '/assets'))
    .on('end', function () {
      gulp.src(complDir + '/**/*.{html,css}')
      .pipe(cachebust.references())
      .pipe(gulp.dest(complDir))
      .on('end', done);
    });
});

gulp.task('compressDist', function () {
  return gulp.src(complDir + "/**/*.*")
  .pipe(gzip())
  .pipe(gulp.dest(complDir));
});

gulp.task('compile', function (cb) {
  runSeq('dist', 'testDist', 'cacheBust', 'compressDist', cb);
});

gulp.task('compileServer', function () {
  if (server) {
    server.close();
  }
  server = require(cwd+'/'+c.app.server).listen(process.env.PORT||8080, complDir);
});

gulp.task('build_', function (cb) {
  runSeq('clean', ['templates', 'buildJs', 'css', 'assets'], 'html', cb);
});

gulp.task('watch', ['build_', 'installWebdriver'], function (cb) {
  server = require(cwd+'/'+c.app.server)
    .listen(process.env.PORT || 8080, buildDir);
  gutil.log("Listening on port " + process.env.PORT || 8080);

  var lr = tinyLr();
  lr.listen(35729);
  gutil.log("LiveReload server started on port 35729");

  gulp.watch(buildDir + "/**/*", function (e) {
    lr.changed({
      body: {
        files: [path.relative(buildDir, e.path)]
      }
    });
  });

  gulp.watch('./src/**/*.styl', ['css']);
  gulp.watch(c.app.jade, ['templates']);
  gulp.watch(c.app.html, ['html']);
  gulp.watch([buildDir + '/**/*.js', buildDir + '/**/*.css'], function (e) {
    if (e.type != 'changed') {
      gulp.run('html');
    }
  });

  gulp.watch(c.e2eSpecs, ['runProtractor']);

  karma.start({ autoWatch: true });

  gulp.watch(allAppJs.concat(featsDev), ['buildJs']);
});

gulp.task('default', ['watch']);

gulp.on('err', function (e) {
  if (!this.tasks['watch'].running) {
    gutil.log("Failure. Terminating.");
    process.exit(1);
  } else {
    notifier.notify({message: "Error in " + e.err.plugin + ": " + e.message }, function (e, t) { });
    gutil.log(gutil.colors.red("Error in build. Continuing execution for `watch` task."));
    console.log('');
    gutil.beep();
  }
});

gulp.task('checkCoverage', ['specs'], function () {
  return gulp.src('.')
    .pipe(istnbl({
      thresholds: c.covReq,
      coverageDirectory : 'coverage',
      rootDirectory : ''
    }));
});

gulp.task('coveralls', ['checkCoverage', 'protractor'], function (done) {
  var ps = spawn(cwd+'/node_modules/coveralls/bin/coveralls.js');
  var coverageDir = cwd + '/coverage/';
  fs.readdir(coverageDir, pickFolder);
  ps.on('exit', function (c) {
    done();
  });
  ps.stdout.on('data', log);
  ps.stderr.on('data', log);

  function pickFolder (err, folders) {
    var folder = folders[0];
    fs.readFile(coverageDir + folder + '/lcov.info', pipeFile);
  }

  function pipeFile (err, data) {
    ps.stdin.write(data);
    ps.stdin.end();
  }

  function log (data) {
    gutil.log(data.toString().replace(/^\n|\n$/g, ''));
  }
});

gulp.task('installWebdriver', function (cb) {
  if (process.env['TRAVIS']) {
    cb();
  } else {
    return instWd(cb);
  }
});

gulp.task('protractor', ['installWebdriver', 'compile', 'compileServer'], function (cb) {
  return gulp.src(c.e2eSpecs)
  .pipe(prtrct({configFile: c.protractorCfg}))
  .on('error', function (e) { cb(e); this.emit('end'); })
  .on('end', function () { server.close(); });
});

gulp.task('runProtractor', function () {
  return gulp.src(c.e2eSpecs)
  .pipe(prtrct({configFile: c.protractorCfg, baseUrl: 'http://localhost:8080'}))
  .on('error', function (e) { this.emit('end', new gutil.PluginError('gulp-jshint', e)); });
});

gulp.task('ci', ['coveralls']);
<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Jeremy Whitlock
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

'use strict';

var $ = require('gulp-load-plugins')({
  rename: {
    'gulp-jsdoc-to-markdown': 'jsdoc2MD'
  }
});
var browserify = require('browserify');
var buffer = require('vinyl-buffer');
var del = require('del');
var exposify = require('exposify');
var fs = require('fs');
var gulp = require('gulp');
var KarmaServer = require('karma').Server;
var path = require('path');
var runSequence = require('run-sequence');
var source = require('vinyl-source-stream');
var testHelpers = require('./test/helpers');

var httpServer = testHelpers.createServer(require('http'));
var runningAllTests = false;

// Load promises polyfill if necessary
if (typeof Promise === 'undefined') {
  require('native-promise-only');
}

function displayCoverageReport (display) {
  if (display) {
    gulp.src([])
      .pipe($.istanbul.writeReports());
  }
}

gulp.task('browserify', function (cb) {
  function browserifyBuild (isStandalone, useDebug) {
    return new Promise(function (resolve, reject) {
      var b = browserify('./index.js', {
        debug: useDebug,
        standalone: 'JsonRefs'
      });

      if (!isStandalone) {
        // Expose Bower modules so they can be required
        exposify.config = {
          'path-loader': 'PathLoader',
          'traverse': 'traverse'
        };

        b.transform('exposify');
      }

      b.transform('brfs')
        .bundle()
        .pipe(source('json-refs' + (isStandalone ? '-standalone' : '') + (!useDebug ? '-min' : '') + '.js'))
        .pipe($.if(!useDebug, buffer()))
        .pipe($.if(!useDebug, $.uglify()))
        .pipe(gulp.dest('browser/'))
        .on('error', reject)
        .on('end', resolve);
    });
  }

  Promise.resolve()
    // Standalone build with source maps and complete source
    .then(browserifyBuild(true, true))
    // Standalone build minified and without source maps
    .then(browserifyBuild(true, false))
    // Bower build with source maps and complete source
    .then(browserifyBuild(false, true))
    // Bower build minified and without source maps
    .then(browserifyBuild(false, false))
    .then(cb, cb);
});

gulp.task('clean', function (done) {
  del([
    'bower_components',
    'coverage'
  ], done);
});

gulp.task('lint', function () {
  return gulp.src([
      'index.js',
      'test/**/*.js',
      '!test/browser/**/*.js',
      'gulpfile.js'
    ])
    .pipe($.eslint())
    .pipe($.eslint.format('stylish'))
    .pipe($.eslint.failAfterError());
});

gulp.task('test-node', function (cb) {
  function cleanUp () {
    try {
      httpServer.close();

      cb();
    } catch (err) {
      if (err.message.indexOf('Not running') === -1) {
        cb(err);
      }
    }
  }

  Promise.resolve()
    .then(function () {
      httpServer = testHelpers.createServer(require('http')).listen(44444);
    })
    .then(function () {
      return new Promise(function (resolve, reject) {
        gulp.src([
            'index.js',
            'lib/**/*.js'
          ])
          .pipe($.istanbul({includeUntested: true}))
          .pipe($.istanbul.hookRequire()) // Force `require` to return covered files
          .on('finish', function () {
            gulp.src([
              'test/**/test-*.js',
              '!test/browser/test-*.js'
            ])
              .pipe($.mocha({reporter: 'spec'}))
              .on('error', function (err) {
                reject(err);
              })
              .on('end', function () {
                displayCoverageReport(!runningAllTests);

                resolve();
              });
          });
      });
    })
    .then(cleanUp, cleanUp);
});

gulp.task('test-browser', ['browserify'], function (cb) {
  var basePath = './test/browser/';

  function cleanUp () {
    // Clean up just in case
    del.sync([
      basePath + 'json-refs.js',
      basePath + 'json-refs-standalone.js',
      basePath + 'test-browser.js'
    ]);

    try {
      httpServer.close();
    } catch (err) {
      if (err.message.indexOf('Not running') === -1) {
        throw err;
      }
    }
  }

  function finisher (err) {
    cleanUp();

    displayCoverageReport(runningAllTests);

    return err;
  }

  Promise.resolve()
    .then(cleanUp)
    .then(function () {
      // Copy the browser build of json-refs to the test directory
      fs.createReadStream('./browser/json-refs.js')
        .pipe(fs.createWriteStream(basePath + 'json-refs.js'));
      fs.createReadStream('./browser/json-refs-standalone.js')
        .pipe(fs.createWriteStream(basePath + 'json-refs-standalone.js'));

      return new Promise(function (resolve, reject) {
        var b = browserify([
          './test/test-json-refs.js'
        ], {
          debug: true
        });

        b.transform('brfs')
          .bundle()
          .pipe(source('test-browser.js'))
          .pipe(gulp.dest(basePath))
          .on('error', function (err) {
            reject(err);
          })
          .on('end', function () {
            resolve();
        });
      });
    })
    .then(function () {
      httpServer = testHelpers.createServer(require('http')).listen(44444);
    })
    .then(function () {
      return new Promise(function (resolve, reject) {
        new KarmaServer({
          configFile: path.join(__dirname, 'test/browser/karma-bower.conf.js'),
          singleRun: true
        }, function (err) {
          if (err) {
            reject(err);
          } else {
            resolve();
          }
        }).start();
      });
    })
    .then(function () {
      return new Promise(function (resolve, reject) {
        new KarmaServer({
          configFile: path.join(__dirname, 'test/browser/karma-standalone.conf.js'),
          singleRun: true
        }, function (err) {
          if (err) {
            reject(err);
          } else {
            resolve();
          }
        }).start();
      });
    })
    .then(finisher, finisher)
    .then(cb, cb);
});

gulp.task('test', function (cb) {
  runningAllTests = true;

  // Done this way to ensure that test-node runs prior to test-browser.  Since both of those tasks are independent,
  // doing this 'The Gulp Way' isn't feasible.
  runSequence('test-node', 'test-browser', cb);
});

gulp.task('docs', function () {
  return gulp.src([
    './index.js'
  ])
    .pipe($.concat('API.md'))
    .pipe($.jsdoc2MD())
    .pipe(gulp.dest('docs'));
});

gulp.task('default', ['lint', 'test', 'browserify', 'docs']);
<commit_msg>Forgot to remove last use of brfs during test-browserify<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Jeremy Whitlock
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

'use strict';

var $ = require('gulp-load-plugins')({
  rename: {
    'gulp-jsdoc-to-markdown': 'jsdoc2MD'
  }
});
var browserify = require('browserify');
var buffer = require('vinyl-buffer');
var del = require('del');
var exposify = require('exposify');
var fs = require('fs');
var gulp = require('gulp');
var KarmaServer = require('karma').Server;
var path = require('path');
var runSequence = require('run-sequence');
var source = require('vinyl-source-stream');
var testHelpers = require('./test/helpers');

var httpServer = testHelpers.createServer(require('http'));
var runningAllTests = false;

// Load promises polyfill if necessary
if (typeof Promise === 'undefined') {
  require('native-promise-only');
}

function displayCoverageReport (display) {
  if (display) {
    gulp.src([])
      .pipe($.istanbul.writeReports());
  }
}

gulp.task('browserify', function (cb) {
  function browserifyBuild (isStandalone, useDebug) {
    return new Promise(function (resolve, reject) {
      var b = browserify('./index.js', {
        debug: useDebug,
        standalone: 'JsonRefs'
      });

      if (!isStandalone) {
        // Expose Bower modules so they can be required
        exposify.config = {
          'path-loader': 'PathLoader',
          'traverse': 'traverse'
        };

        b.transform('exposify');
      }

      b.bundle()
        .pipe(source('json-refs' + (isStandalone ? '-standalone' : '') + (!useDebug ? '-min' : '') + '.js'))
        .pipe($.if(!useDebug, buffer()))
        .pipe($.if(!useDebug, $.uglify()))
        .pipe(gulp.dest('browser/'))
        .on('error', reject)
        .on('end', resolve);
    });
  }

  Promise.resolve()
    // Standalone build with source maps and complete source
    .then(browserifyBuild(true, true))
    // Standalone build minified and without source maps
    .then(browserifyBuild(true, false))
    // Bower build with source maps and complete source
    .then(browserifyBuild(false, true))
    // Bower build minified and without source maps
    .then(browserifyBuild(false, false))
    .then(cb, cb);
});

gulp.task('clean', function (done) {
  del([
    'bower_components',
    'coverage'
  ], done);
});

gulp.task('lint', function () {
  return gulp.src([
      'index.js',
      'test/**/*.js',
      '!test/browser/**/*.js',
      'gulpfile.js'
    ])
    .pipe($.eslint())
    .pipe($.eslint.format('stylish'))
    .pipe($.eslint.failAfterError());
});

gulp.task('test-node', function (cb) {
  function cleanUp () {
    try {
      httpServer.close();

      cb();
    } catch (err) {
      if (err.message.indexOf('Not running') === -1) {
        cb(err);
      }
    }
  }

  Promise.resolve()
    .then(function () {
      httpServer = testHelpers.createServer(require('http')).listen(44444);
    })
    .then(function () {
      return new Promise(function (resolve, reject) {
        gulp.src([
            'index.js',
            'lib/**/*.js'
          ])
          .pipe($.istanbul({includeUntested: true}))
          .pipe($.istanbul.hookRequire()) // Force `require` to return covered files
          .on('finish', function () {
            gulp.src([
              'test/**/test-*.js',
              '!test/browser/test-*.js'
            ])
              .pipe($.mocha({reporter: 'spec'}))
              .on('error', function (err) {
                reject(err);
              })
              .on('end', function () {
                displayCoverageReport(!runningAllTests);

                resolve();
              });
          });
      });
    })
    .then(cleanUp, cleanUp);
});

gulp.task('test-browser', ['browserify'], function (cb) {
  var basePath = './test/browser/';

  function cleanUp () {
    // Clean up just in case
    del.sync([
      basePath + 'json-refs.js',
      basePath + 'json-refs-standalone.js',
      basePath + 'test-browser.js'
    ]);

    try {
      httpServer.close();
    } catch (err) {
      if (err.message.indexOf('Not running') === -1) {
        throw err;
      }
    }
  }

  function finisher (err) {
    cleanUp();

    displayCoverageReport(runningAllTests);

    return err;
  }

  Promise.resolve()
    .then(cleanUp)
    .then(function () {
      // Copy the browser build of json-refs to the test directory
      fs.createReadStream('./browser/json-refs.js')
        .pipe(fs.createWriteStream(basePath + 'json-refs.js'));
      fs.createReadStream('./browser/json-refs-standalone.js')
        .pipe(fs.createWriteStream(basePath + 'json-refs-standalone.js'));

      return new Promise(function (resolve, reject) {
        var b = browserify([
          './test/test-json-refs.js'
        ], {
          debug: true
        });

        b.transform('brfs')
          .bundle()
          .pipe(source('test-browser.js'))
          .pipe(gulp.dest(basePath))
          .on('error', function (err) {
            reject(err);
          })
          .on('end', function () {
            resolve();
        });
      });
    })
    .then(function () {
      httpServer = testHelpers.createServer(require('http')).listen(44444);
    })
    .then(function () {
      return new Promise(function (resolve, reject) {
        new KarmaServer({
          configFile: path.join(__dirname, 'test/browser/karma-bower.conf.js'),
          singleRun: true
        }, function (err) {
          if (err) {
            reject(err);
          } else {
            resolve();
          }
        }).start();
      });
    })
    .then(function () {
      return new Promise(function (resolve, reject) {
        new KarmaServer({
          configFile: path.join(__dirname, 'test/browser/karma-standalone.conf.js'),
          singleRun: true
        }, function (err) {
          if (err) {
            reject(err);
          } else {
            resolve();
          }
        }).start();
      });
    })
    .then(finisher, finisher)
    .then(cb, cb);
});

gulp.task('test', function (cb) {
  runningAllTests = true;

  // Done this way to ensure that test-node runs prior to test-browser.  Since both of those tasks are independent,
  // doing this 'The Gulp Way' isn't feasible.
  runSequence('test-node', 'test-browser', cb);
});

gulp.task('docs', function () {
  return gulp.src([
    './index.js'
  ])
    .pipe($.concat('API.md'))
    .pipe($.jsdoc2MD())
    .pipe(gulp.dest('docs'));
});

gulp.task('default', ['lint', 'test', 'browserify', 'docs']);
<|endoftext|>


<commit_before>'use strict';

// Requires
// ========

// Node
// ----
// https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
const exec = require('child_process').exec;

// Gulp
// ----
const gulp = require('gulp');
const gulpif = require('gulp-if');
// const ignore
const gutil = require('gulp-util');
const del = require('del');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const browserSync = require('browser-sync').create();

// Pug -> HTML
// -----------
const pug = require('gulp-pug');

// JSX/ES6 -> ES5
// --------------
const browserify = require('browserify');
const babelify = require('babelify');
const envify = require('envify');
const uglifyify = require('uglifyify');
const collapse = require('bundle-collapser/plugin');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const merge = require('merge-stream');
const browserifyInc = require('browserify-incremental');

// SCSS -> CSS
// -----------
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const cssmin = require('gulp-cssmin');

// Image processing
// ----------------
const imagemin = require('gulp-imagemin'); // supports png, jpg, gif, and svg only
const cache = require('gulp-cache');

// JSON processing
// ---------------
const jsoncombine = require('gulp-jsoncombine');

// Appcache creation
// -----------------
const manifest = require('gulp-manifest');

// Configuration Objects
// =====================

// Environmental variables
const isProduction = process.env.NODE_ENV === 'production';
const isGitHubPages = process.env.DEST === 'github';

let ghPages = '';

if (isGitHubPages) {
  ghPages = '.publish/';
}

// Entry points and sources
// ------------------------
const paths = {
  entry: { // entry points
    scripts: [
      'client/scripts/arcademode/main.jsx',
      'client/scripts/public/index.js',
      'client/scripts/public/standalones/ww.js',
      'client/scripts/public/standalones/wwBenchmark.js',
      'client/scripts/public/standalones/sw.js'
    ],
    stylesheets: ['client/stylesheets/style.scss']
  },
  fonts: ['client/fonts/**/*'], // font sources
  images: ['client/images/**/*'], // image sources
  jsons: { // json-related items
    appConfig: ['client/jsons/appconfig.*'],
    fccInterviewSeed: ['client/jsons/seed/**/*'],
    js2jsonScript: ['bin/js2json_challenges.js']
  },
  challengesJs: ['client/scripts/challenges/**/*'],
  scripts: ['client/scripts/**/*'],
  stylesheets: ['client/stylesheets/**/*'],
  vendor: {
    scripts: ['client/scripts/vendor/MathJax.min.js'], // browserify currently imports loop-protect
    stylesheets: ['client/stylesheets/vendor/**/*.css']
  },
  views: ['server/views/*.pug'] // generated for static sites
};

// Gulp Tasks
// ==========

// Build tasks
// -----------
gulp.task('build-font', () =>
  gulp.src(paths.fonts, { base: 'client/fonts' })
    .pipe(gulp.dest(`${ghPages}public/font`)) // no processing: fonts are already optimized
    .pipe(browserSync.reload({ stream: true }))
);

gulp.task('build-img', () => {
  const s1 = gulp.src('client/images/favicon.ico')
    .pipe(isGitHubPages ? gulp.dest(ghPages) : gulp.dest('public/img'));

  const s2 = gulp.src(paths.images)
    .pipe(cache(imagemin([
      imagemin.gifsicle({ interlaced: true }),
      // imagemin.jpegtran({ progressive: true }), // Tuomas: Cannot get this to work, crashes gulp
      imagemin.optipng({ optimizationLevel: 5 })
    ])))
    .pipe(gulp.dest(`${ghPages}public/img`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-json', () => {
  // pass through individual files (currently algo+ds) for individual mode display:
  const s1 = gulp.src(paths.jsons.fccInterviewSeed)
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  // pass through a bundled version for mixed mode display:
  const s2 = gulp.src(paths.jsons.fccInterviewSeed)
    .pipe(jsoncombine('challenges-combined.json', data =>
      new Buffer(JSON.stringify(data))
    ))
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  const appConfigFile = isProduction ? 'client/jsons/appconfig.production.json' : 'client/jsons/appconfig.devel.json';

  const s3 = gulp.src(appConfigFile)
    .pipe(rename('appconfig.json'))
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2, s3);
});

// Builds the arcade-mode json from js challenge files
gulp.task('build-js2json', done => {
  const arcade2json = `bin/js2json_challenges.js\
    --force -f client/scripts/challenges/arcade/*.js -o ${ghPages}public/json/challenges-arcade.json`;
  const rosetta2json = `bin/js2json_challenges.js\
    --force -f client/scripts/challenges/rosettacode/formatted/**/*.js -o ${ghPages}public/json/challenges-rosetta.json`;

  const euler2json = `bin/js2json_challenges.js\
    --force -f client/scripts/challenges/projecteuler/formatted/**/*.js -o ${ghPages}public/json/challenges-euler.json`;

  return Promise.all([arcade2json, rosetta2json, euler2json].map(js2json =>
    new Promise((resolve, reject) => {
      exec(js2json, err => {
        if (err) {
          console.error(`exec error: ${err}`);
          reject(err);
        }
        else resolve();
      });
    })
  ))
  .then(() => {
    done();
  });
});

gulp.task('build-js', () => {
  console.log('gulpfile.js: build-js: Building production js. Takes approximately 60 seconds.');
  console.log('gulpfile.js: build-js: For development, use build-js-inc instead for faster iteration cycles.');
  console.log('gulpfile.js: build-js: Top-level gulp tasks used in development are:');
  console.log('gulpfile.js: build-js: build-dev - includes build-js-inc.');
  console.log('gulpfile.js: build-js: watch-dev - includes build-dev; watches for changes.');
  console.log('gulpfile.js: build-js: watch-sync - includes build-dev; watches for changes and hot reloads with browserSync at port 3000. TODO: fix this task. Currently buggy in that it only hot reloads automatically some of the time and at other times require a complete restart of the gulp task.');
  const s1 = merge(...paths.entry.scripts.map(script =>
    browserify({
      entries: script,
      extensions: ['.jsx'],
      debug: true
    })
      .transform(babelify, { presets: ['env', 'react'] })
      .transform(envify)
      .transform({
        global: true,
        ignore: ['**/node_modules/benchmark/*']
      }, uglifyify)
      .plugin(collapse)
      .bundle()
      .on('error', gutil.log.bind(gutil, 'Browserify error.'))
      .pipe(source(`./${script.split('/')[script.split('/').length - 1]}`))
      .pipe(buffer())
      .pipe(plumber())
      .pipe(rename(path => {
        path.extname = '.bundle.js';
      }))
      .pipe(uglify({ mangle: true }))
      .pipe(gulp.dest(`${ghPages}public/js`))
      .pipe(isGitHubPages ? gulpif('*sw.bundle.js', gulp.dest(ghPages)) : gutil.noop())
      .pipe(browserSync.reload({ stream: true }))
  ));

  // pass through vendor files
  const s2 = gulp.src(paths.vendor.scripts)
    .pipe(gulp.dest(`${ghPages}public/js`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-css', () => {
  const s1 = gulp.src(paths.entry.stylesheets[0]) // only the entry/index sheet, style.scss
    .pipe(plumber())
    .pipe(sass())
    .pipe(autoprefixer())
    .pipe(cssmin())
    .pipe(gulp.dest(`${ghPages}public/css`))
    .pipe(browserSync.reload({ stream: true }));

  // any vendor css files, minify then pass through
  const s2 = gulp.src(paths.vendor.stylesheets, { base: 'client/stylesheets/vendor' })
    .pipe(plumber())
    .pipe(autoprefixer())
    .pipe(cssmin())
    .pipe(rename(path => {
      path.extname = '.min.css';
    }))
    .pipe(gulp.dest(`${ghPages}public/css/vendor`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-view', () =>
  gulp.src(paths.views, { base: 'server/views' })
    .pipe(plumber())
    .pipe(pug({ pretty: true, basedir: 'server/views' }))
    .pipe(isGitHubPages ? gulp.dest(ghPages) : gutil.noop())
    .pipe(browserSync.reload({ stream: true }))
);

// Appcache file creation
// ----------------------
gulp.task('build-appcache', () =>
  gulp.src('public/**/*', { base: 'public' })
    .pipe(manifest({
      hash: true,
      preferOnline: true,
      network: ['*'],
      // fallback:
      filename: 'offline.appcache',
      exclude: 'offline.appcache'
    }))
    .pipe(gulp.dest(`${ghPages}public`))
    .pipe(browserSync.reload({ stream: true }))
);

// DEV-tasks (not used in production)
//-----------------------------------
function handleErrors(...errorArgs) {
  const args = Array.prototype.slice.call(errorArgs);
  notify.onError({
    title: 'Compile Error',
    message: '<%= error.message %>'
  }).apply(this, args);
  this.emit('end'); // Keep gulp from hanging on this task
}

// Incrementally building the js
gulp.task('build-js-inc', () => {
  const s1 = merge(...paths.entry.scripts.map(script => {
    const b = browserify(Object.assign({}, browserifyInc.args,
      {
        entries: script,
        extensions: ['.jsx'],
        debug: true
      }
    ));

    browserifyInc(b, { cacheFile: './browserify-cache.json' });

    return b.transform(babelify, { presets: ['env', 'react'] })
      .bundle()
        .on('error', handleErrors)
        .pipe(source(`./${script.split('/')[script.split('/').length - 1]}`))
        .pipe(buffer())
        .pipe(plumber())
        .pipe(rename(path => {
          path.extname = '.bundle.js';
        }))
        .pipe(gulp.dest('public/js'))
        .pipe(browserSync.reload({ stream: true }));
  }));

  // pass through vendor files
  const s2 = gulp.src(paths.vendor.scripts)
    .pipe(gulp.dest(`${ghPages}public/js`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-appcache-dev', () =>
  gulp.src('public/**/*', { base: 'public' })
    .pipe(manifest({
      hash: true,
      preferOnline: true,
      network: ['*'],
      // fallback:
      filename: 'offline.appcache',
      exclude: 'offline.appcache'
    }))
    .pipe(gulp.dest('public'))
    .pipe(browserSync.reload({ stream: true }))
);

// Cleaners
// --------

// rm -rf public directory
gulp.task('clean:static', () => {
  if (isGitHubPages) {
    return del(['.publish/**/*']);
  }
  return del(['public/**/*']);
});

gulp.task('clear-cache', done => cache.clearAll(done)); // clears img cache

// Bundled tasks
// -------------
gulp.task('build-types',
  gulp.series(
    'build-json',
    'build-js2json',
    gulp.parallel('build-font', 'build-img', 'build-js', 'build-css', 'build-view')
  )
);

gulp.task('build-types-dev',
  gulp.series(
    'build-json',
    'build-js2json',
    gulp.parallel('build-font', 'build-img', 'build-js-inc', 'build-css', 'build-view')
  )
);

gulp.task('build', gulp.series('clean:static', 'build-types', 'build-appcache'));
gulp.task('build-dev', gulp.series('build-types-dev', 'build-appcache-dev'));

gulp.task('watch', gulp.series('build', done => {
  gulp.watch(paths.fonts, gulp.task('build-font'));
  gulp.watch(paths.images, gulp.task('build-img'));
  gulp.watch([...Object.values(paths.jsons)], gulp.task('build-json'));
  gulp.watch(paths.challengesJs, gulp.task('build-js2json'));
  gulp.watch(paths.scripts, gulp.task('build-js'));
  gulp.watch(paths.stylesheets, gulp.task('build-css'));
  done();
}));

gulp.task('watch-dev', gulp.series('build-dev', done => {
  // const jsonFiles = Object.keys(paths.jsons).map(item => paths.jsons[item]);
  gulp.watch(paths.fonts, gulp.task('build-font'));
  gulp.watch(paths.images, gulp.task('build-img'));
  gulp.watch([...Object.values(paths.jsons)], gulp.task('build-json'));
  gulp.watch(paths.challengesJs, gulp.task('build-js2json'));
  gulp.watch(paths.scripts, gulp.task('build-js-inc'));
  gulp.watch(paths.stylesheets, gulp.task('build-css'));
  done();
}));

// Hot-reloading
// -------------
gulp.task('browser-sync', gulp.series('watch-dev', done => {
  browserSync.init({
    proxy: {
      target: 'localhost:8080',
      ws: true // websockets
    },
    ghostMode: true, // sync across all browsers
    reloadDelay: 2000, // give gulp tasks time to reprocess files
    port: 3000 // browserSync port
  }, done);
}));

// GitHub pages deploy
// -------------------

// gulp.task('deploy-gh-pages', gulp.series('build', () =>
//   gulp.src('public/**/*')
//     .pipe(ghPages())
// ));

// Helper tasks
// ------------
/*
gulp.task('bundle', ['build'], () =>
  gulp.src(paths.scripts.map(script =>
    `./public/js/${script.split('/')[script.split('/').length - 1]}`
  ))
    .pipe(concat('bundle.js'))
    .pipe(gulp.dest('public/js'))
);

gulp.task('bundle-dev', ['build-dev'], () =>
  gulp.src(paths.scripts.map(script =>
    `./public/js/${script.split('/')[script.split('/').length - 1]}`
  ))
    .pipe(concat('bundle.js'))
    .pipe(gulp.dest('public/js'))
);
*/
<commit_msg>rearranging the order of how we setup browser-sync and watching the files to that the initial page that loads will be able to connect to browser sync.  Adding a debounce to browser-sync so that it does not reload mmultiple times per build<commit_after>'use strict';

// Requires
// ========

// Node
// ----
// https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
const exec = require('child_process').exec;

// Gulp
// ----
const gulp = require('gulp');
const gulpif = require('gulp-if');
// const ignore
const gutil = require('gulp-util');
const del = require('del');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const browserSync = require('browser-sync').create();

// Pug -> HTML
// -----------
const pug = require('gulp-pug');

// JSX/ES6 -> ES5
// --------------
const browserify = require('browserify');
const babelify = require('babelify');
const envify = require('envify');
const uglifyify = require('uglifyify');
const collapse = require('bundle-collapser/plugin');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const uglify = require('gulp-uglify');
const rename = require('gulp-rename');
const merge = require('merge-stream');
const browserifyInc = require('browserify-incremental');

// SCSS -> CSS
// -----------
const sass = require('gulp-sass');
const autoprefixer = require('gulp-autoprefixer');
const cssmin = require('gulp-cssmin');

// Image processing
// ----------------
const imagemin = require('gulp-imagemin'); // supports png, jpg, gif, and svg only
const cache = require('gulp-cache');

// JSON processing
// ---------------
const jsoncombine = require('gulp-jsoncombine');

// Appcache creation
// -----------------
const manifest = require('gulp-manifest');

// Configuration Objects
// =====================

// Environmental variables
const isProduction = process.env.NODE_ENV === 'production';
const isGitHubPages = process.env.DEST === 'github';

let ghPages = '';

if (isGitHubPages) {
  ghPages = '.publish/';
}

// Entry points and sources
// ------------------------
const paths = {
  entry: { // entry points
    scripts: [
      'client/scripts/arcademode/main.jsx',
      'client/scripts/public/index.js',
      'client/scripts/public/standalones/ww.js',
      'client/scripts/public/standalones/wwBenchmark.js',
      'client/scripts/public/standalones/sw.js'
    ],
    stylesheets: ['client/stylesheets/style.scss']
  },
  fonts: ['client/fonts/**/*'], // font sources
  images: ['client/images/**/*'], // image sources
  jsons: { // json-related items
    appConfig: ['client/jsons/appconfig.*'],
    fccInterviewSeed: ['client/jsons/seed/**/*'],
    js2jsonScript: ['bin/js2json_challenges.js']
  },
  challengesJs: ['client/scripts/challenges/**/*'],
  scripts: ['client/scripts/**/*'],
  stylesheets: ['client/stylesheets/**/*'],
  vendor: {
    scripts: ['client/scripts/vendor/MathJax.min.js'], // browserify currently imports loop-protect
    stylesheets: ['client/stylesheets/vendor/**/*.css']
  },
  views: ['server/views/*.pug'] // generated for static sites
};

// Gulp Tasks
// ==========

// Build tasks
// -----------
gulp.task('build-font', () =>
  gulp.src(paths.fonts, { base: 'client/fonts' })
    .pipe(gulp.dest(`${ghPages}public/font`)) // no processing: fonts are already optimized
    .pipe(browserSync.reload({ stream: true }))
);

gulp.task('build-img', () => {
  const s1 = gulp.src('client/images/favicon.ico')
    .pipe(isGitHubPages ? gulp.dest(ghPages) : gulp.dest('public/img'));

  const s2 = gulp.src(paths.images)
    .pipe(cache(imagemin([
      imagemin.gifsicle({ interlaced: true }),
      // imagemin.jpegtran({ progressive: true }), // Tuomas: Cannot get this to work, crashes gulp
      imagemin.optipng({ optimizationLevel: 5 })
    ])))
    .pipe(gulp.dest(`${ghPages}public/img`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-json', () => {
  // pass through individual files (currently algo+ds) for individual mode display:
  const s1 = gulp.src(paths.jsons.fccInterviewSeed)
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  // pass through a bundled version for mixed mode display:
  const s2 = gulp.src(paths.jsons.fccInterviewSeed)
    .pipe(jsoncombine('challenges-combined.json', data =>
      new Buffer(JSON.stringify(data))
    ))
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  const appConfigFile = isProduction ? 'client/jsons/appconfig.production.json' : 'client/jsons/appconfig.devel.json';

  const s3 = gulp.src(appConfigFile)
    .pipe(rename('appconfig.json'))
    .pipe(gulp.dest(`${ghPages}public/json`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2, s3);
});

// Builds the arcade-mode json from js challenge files
gulp.task('build-js2json', done => {
  const arcade2json = `bin/js2json_challenges.js\
    --force -f client/scripts/challenges/arcade/*.js -o ${ghPages}public/json/challenges-arcade.json`;
  const rosetta2json = `bin/js2json_challenges.js\
    --force -f client/scripts/challenges/rosettacode/formatted/**/*.js -o ${ghPages}public/json/challenges-rosetta.json`;

  const euler2json = `bin/js2json_challenges.js\
    --force -f client/scripts/challenges/projecteuler/formatted/**/*.js -o ${ghPages}public/json/challenges-euler.json`;

  return Promise.all([arcade2json, rosetta2json, euler2json].map(js2json =>
    new Promise((resolve, reject) => {
      exec(js2json, err => {
        if (err) {
          console.error(`exec error: ${err}`);
          reject(err);
        }
        else resolve();
      });
    })
  ))
  .then(() => {
    done();
  });
});

gulp.task('build-js', () => {
  console.log('gulpfile.js: build-js: Building production js. Takes approximately 60 seconds.');
  console.log('gulpfile.js: build-js: For development, use build-js-inc instead for faster iteration cycles.');
  console.log('gulpfile.js: build-js: Top-level gulp tasks used in development are:');
  console.log('gulpfile.js: build-js: build-dev - includes build-js-inc.');
  console.log('gulpfile.js: build-js: watch-dev - includes build-dev; watches for changes.');
  console.log('gulpfile.js: build-js: watch-sync - includes build-dev; watches for changes and hot reloads with browserSync at port 3000. TODO: fix this task. Currently buggy in that it only hot reloads automatically some of the time and at other times require a complete restart of the gulp task.');
  const s1 = merge(...paths.entry.scripts.map(script =>
    browserify({
      entries: script,
      extensions: ['.jsx'],
      debug: true
    })
      .transform(babelify, { presets: ['env', 'react'] })
      .transform(envify)
      .transform({
        global: true,
        ignore: ['**/node_modules/benchmark/*']
      }, uglifyify)
      .plugin(collapse)
      .bundle()
      .on('error', gutil.log.bind(gutil, 'Browserify error.'))
      .pipe(source(`./${script.split('/')[script.split('/').length - 1]}`))
      .pipe(buffer())
      .pipe(plumber())
      .pipe(rename(path => {
        path.extname = '.bundle.js';
      }))
      .pipe(uglify({ mangle: true }))
      .pipe(gulp.dest(`${ghPages}public/js`))
      .pipe(isGitHubPages ? gulpif('*sw.bundle.js', gulp.dest(ghPages)) : gutil.noop())
      .pipe(browserSync.reload({ stream: true }))
  ));

  // pass through vendor files
  const s2 = gulp.src(paths.vendor.scripts)
    .pipe(gulp.dest(`${ghPages}public/js`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-css', () => {
  const s1 = gulp.src(paths.entry.stylesheets[0]) // only the entry/index sheet, style.scss
    .pipe(plumber())
    .pipe(sass())
    .pipe(autoprefixer())
    .pipe(cssmin())
    .pipe(gulp.dest(`${ghPages}public/css`))
    .pipe(browserSync.reload({ stream: true }));

  // any vendor css files, minify then pass through
  const s2 = gulp.src(paths.vendor.stylesheets, { base: 'client/stylesheets/vendor' })
    .pipe(plumber())
    .pipe(autoprefixer())
    .pipe(cssmin())
    .pipe(rename(path => {
      path.extname = '.min.css';
    }))
    .pipe(gulp.dest(`${ghPages}public/css/vendor`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-view', () =>
  gulp.src(paths.views, { base: 'server/views' })
    .pipe(plumber())
    .pipe(pug({ pretty: true, basedir: 'server/views' }))
    .pipe(isGitHubPages ? gulp.dest(ghPages) : gutil.noop())
    .pipe(browserSync.reload({ stream: true }))
);

// Appcache file creation
// ----------------------
gulp.task('build-appcache', () =>
  gulp.src('public/**/*', { base: 'public' })
    .pipe(manifest({
      hash: true,
      preferOnline: true,
      network: ['*'],
      // fallback:
      filename: 'offline.appcache',
      exclude: 'offline.appcache'
    }))
    .pipe(gulp.dest(`${ghPages}public`))
    .pipe(browserSync.reload({ stream: true }))
);

// DEV-tasks (not used in production)
//-----------------------------------
function handleErrors(...errorArgs) {
  const args = Array.prototype.slice.call(errorArgs);
  notify.onError({
    title: 'Compile Error',
    message: '<%= error.message %>'
  }).apply(this, args);
  this.emit('end'); // Keep gulp from hanging on this task
}

// Incrementally building the js
gulp.task('build-js-inc', () => {
  const s1 = merge(...paths.entry.scripts.map(script => {
    const b = browserify(Object.assign({}, browserifyInc.args,
      {
        entries: script,
        extensions: ['.jsx'],
        debug: true
      }
    ));

    browserifyInc(b, { cacheFile: './browserify-cache.json' });

    return b.transform(babelify, { presets: ['env', 'react'] })
      .bundle()
        .on('error', handleErrors)
        .pipe(source(`./${script.split('/')[script.split('/').length - 1]}`))
        .pipe(buffer())
        .pipe(plumber())
        .pipe(rename(path => {
          path.extname = '.bundle.js';
        }))
        .pipe(gulp.dest('public/js'))
        .pipe(browserSync.reload({ stream: true }));
  }));

  // pass through vendor files
  const s2 = gulp.src(paths.vendor.scripts)
    .pipe(gulp.dest(`${ghPages}public/js`))
    .pipe(browserSync.reload({ stream: true }));

  return merge(s1, s2);
});

gulp.task('build-appcache-dev', () =>
  gulp.src('public/**/*', { base: 'public' })
    .pipe(manifest({
      hash: true,
      preferOnline: true,
      network: ['*'],
      // fallback:
      filename: 'offline.appcache',
      exclude: 'offline.appcache'
    }))
    .pipe(gulp.dest('public'))
    .pipe(browserSync.reload({ stream: true }))
);

// Cleaners
// --------

// rm -rf public directory
gulp.task('clean:static', () => {
  if (isGitHubPages) {
    return del(['.publish/**/*']);
  }
  return del(['public/**/*']);
});

gulp.task('clear-cache', done => cache.clearAll(done)); // clears img cache

// Bundled tasks
// -------------
gulp.task('build-types',
  gulp.series(
    'build-json',
    'build-js2json',
    gulp.parallel('build-font', 'build-img', 'build-js', 'build-css', 'build-view')
  )
);

gulp.task('build-types-dev',
  gulp.series(
    'build-json',
    'build-js2json',
    gulp.parallel('build-font', 'build-img', 'build-js-inc', 'build-css', 'build-view')
  )
);

gulp.task('build', gulp.series('clean:static', 'build-types', 'build-appcache'));
gulp.task('build-dev', gulp.series('build-types-dev', 'build-appcache-dev'));

gulp.task('watch', gulp.series('build', done => {
  gulp.watch(paths.fonts, gulp.task('build-font'));
  gulp.watch(paths.images, gulp.task('build-img'));
  gulp.watch([...Object.values(paths.jsons)], gulp.task('build-json'));
  gulp.watch(paths.challengesJs, gulp.task('build-js2json'));
  gulp.watch(paths.scripts, gulp.task('build-js'));
  gulp.watch(paths.stylesheets, gulp.task('build-css'));
  done();
}));

gulp.task('watch-dev', gulp.series('build-dev', done => {
  // const jsonFiles = Object.keys(paths.jsons).map(item => paths.jsons[item]);
  gulp.watch(paths.fonts, gulp.task('build-font'));
  gulp.watch(paths.images, gulp.task('build-img'));
  gulp.watch([...Object.values(paths.jsons)], gulp.task('build-json'));
  gulp.watch(paths.challengesJs, gulp.task('build-js2json'));
  gulp.watch(paths.scripts, gulp.task('build-js-inc'));
  gulp.watch(paths.stylesheets, gulp.task('build-css'));
  done();
}));

// Hot-reloading
// -------------
gulp.task('browser-sync', gulp.series(done => {
  browserSync.init({
    proxy: {
      target: 'localhost:8080',
      ws: true // websockets
    },
    ghostMode: true, // sync across all browsers
    reloadDelay: 1000, // give gulp tasks time to reprocess files
    reloadDebounce: 4000,
    port: 3000 // browserSync port
  }, done)
}, 'watch-dev'));

// GitHub pages deploy
// -------------------

// gulp.task('deploy-gh-pages', gulp.series('build', () =>
//   gulp.src('public/**/*')
//     .pipe(ghPages())
// ));

// Helper tasks
// ------------
/*
gulp.task('bundle', ['build'], () =>
  gulp.src(paths.scripts.map(script =>
    `./public/js/${script.split('/')[script.split('/').length - 1]}`
  ))
    .pipe(concat('bundle.js'))
    .pipe(gulp.dest('public/js'))
);

gulp.task('bundle-dev', ['build-dev'], () =>
  gulp.src(paths.scripts.map(script =>
    `./public/js/${script.split('/')[script.split('/').length - 1]}`
  ))
    .pipe(concat('bundle.js'))
    .pipe(gulp.dest('public/js'))
);
*/
<|endoftext|>