<commit_before>var path = require('path');
var PassThrough = require('stream').PassThrough;
var _ = require('underscore');
var gulp = require('gulp');
var gulpif = require('gulp-if');
var gutil = require('gulp-util');
var s3 = require('gulp-s3');
var gzip = require('gulp-gzip');
var less = require('gulp-less');
var cssmin = require('gulp-minify-css');
var webpack = require('gulp-webpack');
var plumber = require('gulp-plumber');
var merge = require('merge-stream');
var sourcemaps = require('gulp-sourcemaps');
var sitemap = require('gulp-sitemap');
var jscs = require('gulp-jscs');
var jshint = require('gulp-jshint');
var autoprefixer = require('gulp-autoprefixer');
var rename = require('gulp-rename');

var IndexFileStream = require('./lib/gulp-index-file-stream');
var webpackConfig = require('./webpack.config');
var config = require('./lib/config');
var travis = require('./lib/travis');
var server = require('./test/browser/server');
var indexStaticWatcher = require('./lib/index-static-watcher').create();

var MINIMAL_BUILD_TASKS = [
  'copy-static-files',
  'less',
  'webpack'
];

var BUILD_TASKS = MINIMAL_BUILD_TASKS.concat([
  'sitemap'
]);

var LINT_DIRS = [
    '*.js',
    'lib/**/*.js',
    'test/**/*.js',
    // Google analytics contains code from GA's snippet, which
    // is intentionally uglified and obfuscated and crap.
    '!lib/googleanalytics.js',
    // TODO let's figure out how to let our linters handle the test suite: delete the line below when we're ready
    '!test/**/*.js'
];

var LESS_FILES = './less/**/*.less';

function onError(err) {
  gutil.log(gutil.colors.red(err));
  gutil.beep();
  this.emit('end');
}

function handleError() {
  return plumber({
    errorHandler: onError
  });
}

function createIndexFileStream() {
  var stream = new PassThrough({ objectMode: true });
  var meta = {};
  var execSync = require('child_process').execSync;

  try {
    meta['git-rev'] = execSync('git rev-parse HEAD', {
      cwd: __dirname,
      encoding: 'utf8'
    }).slice(0, 40);
  } catch (e) {}

  indexStaticWatcher.build(function(err, indexStatic) {
    if (err) {
      return stream.emit('error', err);
    }
    new IndexFileStream(indexStatic, {
      meta: meta
    }).on('error', function(err) {
      stream.emit('error', err);
    }).pipe(stream);
  });

  return stream;
}

gulp.task('sitemap', ['generate-index-files'], function() {
  gulp.src('dist/**/*.html')
    .pipe(sitemap({
      siteUrl: config.ORIGIN
    }))
    .pipe(gulp.dest('./dist'));
});

gulp.task('copy-static-files', [
  'copy-test-dirs',
  'copy-images',
  'copy-bootstrap',
  'copy-webmaker-app-icons',
]);

gulp.task('copy-test-dirs', function() {
  return merge(
    gulp.src('test/browser/static/**', {
      base: './test/browser/static'
    }),
    gulp.src('node_modules/mocha/mocha.*', {
      base: './node_modules/mocha'
    })
  ).pipe(gulp.dest('./dist/test'));
});

gulp.task('copy-images', function () {
  return gulp.src('img/**', {
    base: '.'
  }).pipe(gulp.dest('./dist'));
});

gulp.task('copy-webmaker-app-icons', function () {
  return gulp.src(['node_modules/webmaker-app-icons/css/**', 'node_modules/webmaker-app-icons/fonts/**'], {
    base: 'node_modules/webmaker-app-icons'
  }).pipe(gulp.dest('./dist/vendor/webmaker-app-icons'));
});

gulp.task('copy-bootstrap', function () {
  return gulp.src(['node_modules/bootstrap/dist/css/**', 'node_modules/bootstrap/dist/fonts/**'], {
    base: 'node_modules/bootstrap/dist'
  }).pipe(gulp.dest('./dist/vendor/bootstrap'));
});

gulp.task('less', function() {
  return gulp.src('./less/index.less')
    .pipe(handleError())
    .pipe(sourcemaps.init())
    .pipe(less({
      paths: [path.join(__dirname, 'less')],
      filename: 'styles.css'
    }))
    .pipe(gulpif(process.env.LESS_AUTOPREFIXER != 'off', autoprefixer({
      browsers: ['last 2 versions'],
      cascade: false,
      remove: true
    })))
    .pipe(gulpif(process.env.NODE_ENV === 'production', cssmin()))
    .pipe(rename('styles.css'))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('./dist'));
});

gulp.task('webpack', function() {
  return gulp.src(webpackConfig.entry.app)
    .pipe(webpack(webpackConfig))
    .pipe(gulp.dest('./dist'));
});

gulp.task('smoketest', BUILD_TASKS.concat([
  'test-react-warnings'
]), function() {
  gutil.log(gutil.colors.green.bold('Yay, smoke test passes!'));
});

gulp.task('test-react-warnings', function() {
  var oldWarn = console.warn;
  var warnings = 0;

  console.warn = function(message) {
    warnings++;
    gutil.log(gutil.colors.red.bold(message));
  };

  return createIndexFileStream()
    .on('end', function() {
      console.warn = oldWarn;
      if (warnings) {
        this.emit('error', new Error('At least one warning was logged.'));
      }
    })
    .on('data', function() {
      // Drain the stream. We don't actually need to do anything with
      // the data, we just want to make sure no warnings are logged while
      // the stream's data is being generated.
    });
});

gulp.task('generate-index-files', function() {
  return createIndexFileStream().pipe(gulp.dest('./dist'));
});

gulp.task('jshint', function() {
  return gulp.src(LINT_DIRS)
      .pipe(jshint({ lookup: 'node_modules/mofo-style/linters/.jshintrc' }))
      .pipe(jshint.reporter('default'));
});

gulp.task('jscs', function () {
  // jscs doesn't play nice with *.jsx files so we're avoiding lib/*.jsx
  return gulp.src(LINT_DIRS)
      .pipe(jscs({ configPath: 'node_modules/mofo-style/linters/.jscsrc' }));
});

gulp.task('lint-test', ['jscs', 'jshint']);

gulp.task('default', BUILD_TASKS);

gulp.task('watch-webpack', function() {
  return gulp.src(webpackConfig.entry.app)
    .pipe(webpack(_.extend({
      watch: true
    }, webpackConfig)))
    .pipe(gulp.dest('./dist'));
});

gulp.task('watch-static-files', function() {
  gulp.watch('img/**', ['copy-images']);
  gulp.watch('test/browser/static/**', ['copy-test-dirs']);
});

gulp.task('watch', _.without(BUILD_TASKS, 'webpack'), function() {
  require('./lib/developer-help')();

  gulp.start('watch-webpack', 'watch-static-files');

  indexStaticWatcher.watch(200, function() {
    createIndexFileStream()
      .on('error', function(err) {
        gutil.log('Error rebuilding index HTML files.');
        gutil.log(gutil.colors.red.bold(err.stack));
      })
      .on('end', function() {
        gutil.log('Index HTML files rebuilt.');
      })
      .pipe(gulp.dest('./dist'));
  });

  gulp.watch(LESS_FILES, ['less']);
  gulp.watch([
    'gulpfile.js',
    'package.json',
    'webpack.config.js'
  ], function(event) {
    var filename = path.basename(event.path);
    gutil.log(gutil.colors.red.bold(filename + ' was ' + event.type + '.'));
    gutil.log(gutil.colors.red.bold('Please restart the watch process ' +
                                    'with "npm start".'));
    process.exit(0);
  });

  server.create().listen(config.DEV_SERVER_PORT, function() {
    gutil.log('Development server listening at ' +
              gutil.colors.green.bold(config.ORIGIN) + '.');
  });
});

gulp.task('travis-after-success', function(cb) {
  var env = travis.getS3Env();

  if (env === null) {
    gutil.log('Current build does not need to be pushed to S3.');
    return;
  }

  require('child_process')
    .spawn(process.execPath, [process.argv[1], 's3'], {
      env: _.extend({}, process.env, env),
      stdio: 'inherit'
    }).on('close', function(code) {
      if (code !== 0) {
        gutil.log(gutil.colors.red.bold('Error deploying to S3!'));
        cb(new Error('gulp s3 failed with exit code ' + code));
      } else {
        gutil.log('Site deployed to S3.');
        cb(null);
      }
    });
});

gulp.task('s3', BUILD_TASKS, function() {
  var key = process.env.AWS_ACCESS_KEY;
  var secret = process.env.AWS_SECRET_KEY;

  gutil.log('NODE_ENV is ' + process.env.NODE_ENV + '.');

  if (!key || !secret) {
    throw new Error('Please set AWS_ACCESS_KEY and AWS_SECRET_KEY ' +
    'in your environment.');
  }

  // WARNING: Even if deploying to S3 fails, no errors will be raised.
  // https://github.com/nkostelnik/gulp-s3/issues/47

  return gulp.src('./dist/**')
    .pipe(gzip())
    .pipe(s3({
      key: key,
      secret: secret,
      bucket: process.env.AWS_BUCKET || 'teach.mofostaging.net',
      region: process.env.AWS_REGION || 'us-east-1'
    }, {
      gzippedOnly: true,
      headers: {
        'Cache-Control': 'max-age=600, public'
      }
    }));
});

if (process.env.NODE_ENV === 'production') {
  gulp.task('postinstall', MINIMAL_BUILD_TASKS);
} else {
  gulp.task('postinstall');
}

module.exports.LESS_FILES = LESS_FILES;
<commit_msg>fix lint errors<commit_after>var path = require('path');
var PassThrough = require('stream').PassThrough;
var _ = require('underscore');
var gulp = require('gulp');
var gulpif = require('gulp-if');
var gutil = require('gulp-util');
var s3 = require('gulp-s3');
var gzip = require('gulp-gzip');
var less = require('gulp-less');
var cssmin = require('gulp-minify-css');
var webpack = require('gulp-webpack');
var plumber = require('gulp-plumber');
var merge = require('merge-stream');
var sourcemaps = require('gulp-sourcemaps');
var sitemap = require('gulp-sitemap');
var jscs = require('gulp-jscs');
var jshint = require('gulp-jshint');
var autoprefixer = require('gulp-autoprefixer');
var rename = require('gulp-rename');

var IndexFileStream = require('./lib/gulp-index-file-stream');
var webpackConfig = require('./webpack.config');
var config = require('./lib/config');
var travis = require('./lib/travis');
var server = require('./test/browser/server');
var indexStaticWatcher = require('./lib/index-static-watcher').create();

var MINIMAL_BUILD_TASKS = [
  'copy-static-files',
  'less',
  'webpack'
];

var BUILD_TASKS = MINIMAL_BUILD_TASKS.concat([
  'sitemap'
]);

var LINT_DIRS = [
    '*.js',
    'lib/**/*.js',
    'test/**/*.js',
    // Google analytics contains code from GA's snippet, which
    // is intentionally uglified and obfuscated and crap.
    '!lib/googleanalytics.js',
    // TODO let's figure out how to let our linters handle the test suite: delete the line below when we're ready
    '!test/**/*.js'
];

var LESS_FILES = './less/**/*.less';

function onError(err) {
  gutil.log(gutil.colors.red(err));
  gutil.beep();
  this.emit('end');
}

function handleError() {
  return plumber({
    errorHandler: onError
  });
}

function createIndexFileStream() {
  var stream = new PassThrough({ objectMode: true });
  var meta = {};
  var execSync = require('child_process').execSync;

  try {
    meta['git-rev'] = execSync('git rev-parse HEAD', {
      cwd: __dirname,
      encoding: 'utf8'
    }).slice(0, 40);
  } catch (e) {}

  indexStaticWatcher.build(function(err, indexStatic) {
    if (err) {
      return stream.emit('error', err);
    }
    new IndexFileStream(indexStatic, {
      meta: meta
    }).on('error', function(err) {
      stream.emit('error', err);
    }).pipe(stream);
  });

  return stream;
}

gulp.task('sitemap', ['generate-index-files'], function() {
  gulp.src('dist/**/*.html')
    .pipe(sitemap({
      siteUrl: config.ORIGIN
    }))
    .pipe(gulp.dest('./dist'));
});

gulp.task('copy-static-files', [
  'copy-test-dirs',
  'copy-images',
  'copy-bootstrap',
  'copy-webmaker-app-icons'
]);

gulp.task('copy-test-dirs', function() {
  return merge(
    gulp.src('test/browser/static/**', {
      base: './test/browser/static'
    }),
    gulp.src('node_modules/mocha/mocha.*', {
      base: './node_modules/mocha'
    })
  ).pipe(gulp.dest('./dist/test'));
});

gulp.task('copy-images', function () {
  return gulp.src('img/**', {
    base: '.'
  }).pipe(gulp.dest('./dist'));
});

gulp.task('copy-webmaker-app-icons', function () {
  return gulp.src(['node_modules/webmaker-app-icons/css/**', 'node_modules/webmaker-app-icons/fonts/**'], {
    base: 'node_modules/webmaker-app-icons'
  }).pipe(gulp.dest('./dist/vendor/webmaker-app-icons'));
});

gulp.task('copy-bootstrap', function () {
  return gulp.src(['node_modules/bootstrap/dist/css/**', 'node_modules/bootstrap/dist/fonts/**'], {
    base: 'node_modules/bootstrap/dist'
  }).pipe(gulp.dest('./dist/vendor/bootstrap'));
});

gulp.task('less', function() {
  return gulp.src('./less/index.less')
    .pipe(handleError())
    .pipe(sourcemaps.init())
    .pipe(less({
      paths: [path.join(__dirname, 'less')],
      filename: 'styles.css'
    }))
    .pipe(gulpif(process.env.LESS_AUTOPREFIXER != 'off', autoprefixer({
      browsers: ['last 2 versions'],
      cascade: false,
      remove: true
    })))
    .pipe(gulpif(process.env.NODE_ENV === 'production', cssmin()))
    .pipe(rename('styles.css'))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('./dist'));
});

gulp.task('webpack', function() {
  return gulp.src(webpackConfig.entry.app)
    .pipe(webpack(webpackConfig))
    .pipe(gulp.dest('./dist'));
});

gulp.task('smoketest', BUILD_TASKS.concat([
  'test-react-warnings'
]), function() {
  gutil.log(gutil.colors.green.bold('Yay, smoke test passes!'));
});

gulp.task('test-react-warnings', function() {
  var oldWarn = console.warn;
  var warnings = 0;

  console.warn = function(message) {
    warnings++;
    gutil.log(gutil.colors.red.bold(message));
  };

  return createIndexFileStream()
    .on('end', function() {
      console.warn = oldWarn;
      if (warnings) {
        this.emit('error', new Error('At least one warning was logged.'));
      }
    })
    .on('data', function() {
      // Drain the stream. We don't actually need to do anything with
      // the data, we just want to make sure no warnings are logged while
      // the stream's data is being generated.
    });
});

gulp.task('generate-index-files', function() {
  return createIndexFileStream().pipe(gulp.dest('./dist'));
});

gulp.task('jshint', function() {
  return gulp.src(LINT_DIRS)
      .pipe(jshint({ lookup: 'node_modules/mofo-style/linters/.jshintrc' }))
      .pipe(jshint.reporter('default'));
});

gulp.task('jscs', function () {
  // jscs doesn't play nice with *.jsx files so we're avoiding lib/*.jsx
  return gulp.src(LINT_DIRS)
      .pipe(jscs({ configPath: 'node_modules/mofo-style/linters/.jscsrc' }));
});

gulp.task('lint-test', ['jscs', 'jshint']);

gulp.task('default', BUILD_TASKS);

gulp.task('watch-webpack', function() {
  return gulp.src(webpackConfig.entry.app)
    .pipe(webpack(_.extend({
      watch: true
    }, webpackConfig)))
    .pipe(gulp.dest('./dist'));
});

gulp.task('watch-static-files', function() {
  gulp.watch('img/**', ['copy-images']);
  gulp.watch('test/browser/static/**', ['copy-test-dirs']);
});

gulp.task('watch', _.without(BUILD_TASKS, 'webpack'), function() {
  require('./lib/developer-help')();

  gulp.start('watch-webpack', 'watch-static-files');

  indexStaticWatcher.watch(200, function() {
    createIndexFileStream()
      .on('error', function(err) {
        gutil.log('Error rebuilding index HTML files.');
        gutil.log(gutil.colors.red.bold(err.stack));
      })
      .on('end', function() {
        gutil.log('Index HTML files rebuilt.');
      })
      .pipe(gulp.dest('./dist'));
  });

  gulp.watch(LESS_FILES, ['less']);
  gulp.watch([
    'gulpfile.js',
    'package.json',
    'webpack.config.js'
  ], function(event) {
    var filename = path.basename(event.path);
    gutil.log(gutil.colors.red.bold(filename + ' was ' + event.type + '.'));
    gutil.log(gutil.colors.red.bold('Please restart the watch process ' +
                                    'with "npm start".'));
    process.exit(0);
  });

  server.create().listen(config.DEV_SERVER_PORT, function() {
    gutil.log('Development server listening at ' +
              gutil.colors.green.bold(config.ORIGIN) + '.');
  });
});

gulp.task('travis-after-success', function(cb) {
  var env = travis.getS3Env();

  if (env === null) {
    gutil.log('Current build does not need to be pushed to S3.');
    return;
  }

  require('child_process')
    .spawn(process.execPath, [process.argv[1], 's3'], {
      env: _.extend({}, process.env, env),
      stdio: 'inherit'
    }).on('close', function(code) {
      if (code !== 0) {
        gutil.log(gutil.colors.red.bold('Error deploying to S3!'));
        cb(new Error('gulp s3 failed with exit code ' + code));
      } else {
        gutil.log('Site deployed to S3.');
        cb(null);
      }
    });
});

gulp.task('s3', BUILD_TASKS, function() {
  var key = process.env.AWS_ACCESS_KEY;
  var secret = process.env.AWS_SECRET_KEY;

  gutil.log('NODE_ENV is ' + process.env.NODE_ENV + '.');

  if (!key || !secret) {
    throw new Error('Please set AWS_ACCESS_KEY and AWS_SECRET_KEY ' +
    'in your environment.');
  }

  // WARNING: Even if deploying to S3 fails, no errors will be raised.
  // https://github.com/nkostelnik/gulp-s3/issues/47

  return gulp.src('./dist/**')
    .pipe(gzip())
    .pipe(s3({
      key: key,
      secret: secret,
      bucket: process.env.AWS_BUCKET || 'teach.mofostaging.net',
      region: process.env.AWS_REGION || 'us-east-1'
    }, {
      gzippedOnly: true,
      headers: {
        'Cache-Control': 'max-age=600, public'
      }
    }));
});

if (process.env.NODE_ENV === 'production') {
  gulp.task('postinstall', MINIMAL_BUILD_TASKS);
} else {
  gulp.task('postinstall');
}

module.exports.LESS_FILES = LESS_FILES;
<|endoftext|>


<commit_before>var gulp = require('gulp');
var dust = require('dustjs-linkedin/lib/server');
var compile = require('gulp-dust');
var render = require('gulp-dust-render');
var concat = require('gulp-concat');
var insert = require('gulp-insert');
var beautify = require('gulp-beautify');
var rename = require('gulp-rename');
var sq = require('streamqueue');
var fs = require('fs');

dust.isDebug = true;
dust.debugLevel = 'DEBUG';

//gulp.task('code', function () {
//
//});

gulp.task('plugin', function() {
    /*
     * Create a runtime environment to interrogate CodeGeneratorRequests from
     * the compiler.
     */
    var schema = require('src/compile/schema');
    var dust = require('dustjs-helpers');
    require('dist/decode');     // Add precompiled templates.
    require('compile/helpers'); // Add helpers to `dust` global.

    function name(file) { return 'plugin'; }
    return gulp.src('src/template/decode/struct/reader.dust')
        .pipe(compile(name))
        .pipe(render(name, schema))
        .pipe(beautify({ indentSize : 4 }))
        .pipe(rename('struct'))
        .pipe(gulp.dest('plugin'));
});

gulp.task('encode', function () {
    // grep for "//" type comments and issue error
    var stream = /*sq*/({ objectMode: true });
    stream.queue(gulp.src('src/template/encode/**/*.dust'));
    stream.queue(gulp.src('src/template/offset/*.dust', { base : 'src/template' }));
    return stream.done()
        .pipe(compile())
        .pipe(concat('encode.js'))
        .pipe(insert.prepend('exports.dust = require("dustjs-linkedin");var dust = exports.dust;'))
        .pipe(gulp.dest('dist'));
});

gulp.task('decode', function () {
    // grep for "//" type comments and issue error
    var stream = sq({ objectMode: true });
    stream.queue(gulp.src('src/template/decode/**/*.dust'));
    stream.queue(gulp.src('src/template/offset/*.dust', { base : 'src/template' }));
    return stream.done()
        .pipe(compile())
        .pipe(concat('decode.js'))
        .pipe(insert.prepend('var dust = require("dustjs-linkedin/lib/server");'))
        .pipe(gulp.dest('dist'));
});
<commit_msg>Export modules and add watching<commit_after>var gulp = require('gulp');
var sq = require('streamqueue');

var compile = require('gulp-dust');
var concat = require('gulp-concat');
var insert = require('gulp-insert');
var jshint = require('gulp-jshint');
var rename = require('gulp-rename');

gulp.task('watch', function () {
    gulp.watch('./src/**/*.js', ['base']);
    gulp.watch([
        './src/template/decode/**/*.dust',
        './src/template/helpers.js'
    ], ['reader']);
    gulp.watch([
        './src/template/encode/**/*.dust',
        './src/template/helpers.js'
    ], ['builder']);
});

gulp.task('base', function () {
    return gulp.src('./src/**/*.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
});

gulp.task('reader', ['base'], function () {
    // grep for "//" type comments and issue error
    var stream = sq({ objectMode: true });
    stream.queue(gulp.src('./src/template/decode/**/*.dust'));
    stream.queue(gulp.src('./src/template/offset/*.dust', { base : './src/template' }));
    return stream.done()
        .pipe(rename({ extname: "" }))
        .pipe(compile())
        .pipe(concat('reader.js'))
        .pipe(insert.prepend('var dust = require("dustjs-linkedin/lib/server");'))
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(gulp.dest('precompile'));
});

gulp.task('builder', ['base'], function () {
    // grep for "//" type comments and issue error
    var stream = sq({ objectMode: true });
    stream.queue(gulp.src('./src/template/encode/**/*.dust'));
    stream.queue(gulp.src('./src/template/offset/*.dust', { base : './src/template' }));
    return stream.done()
        .pipe(rename({ extname: "" }))
        .pipe(compile())
        .pipe(concat('builder.js'))
        .pipe(insert.prepend('var dust = require("dustjs-linkedin/lib/server");'))
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(gulp.dest('precompile'));
});
<|endoftext|>


<commit_before><commit_msg>fixed docs gulp task breaking default gulp tasks<commit_after><|endoftext|>


<commit_before><commit_msg>add --debug flag for gulp integration<commit_after><|endoftext|>


<commit_before><commit_msg>Upgrade machine to 1.1.0<commit_after><|endoftext|>


<commit_before><commit_msg>Modify package to include symlinked folders more than one level deep in package<commit_after><|endoftext|>


<commit_before>'use strict';
// Импортируем необходимые плагины в проект
var gulp = require('gulp'),
    bower = require('gulp-bower'),
    watch = require('gulp-watch'),
    prefixer = require('gulp-autoprefixer'),
    uglify = require('gulp-uglify'),
    sass = require('gulp-sass'),
    sourcemaps = require('gulp-sourcemaps'),
    rigger = require('gulp-rigger'),
    cssmin = require('gulp-clean-css'),
    imagemin = require('gulp-imagemin'),
    pngquant = require('imagemin-pngquant'),
    rimraf = require('rimraf'),
    browserSync = require("browser-sync"),
    filter = require('gulp-filter'),
    reload = browserSync.reload;

// Прописываем объект содержащий все необходимые пути
var path = {
    build: { // Тут мы укажем куда складывать готовые после сборки файлы
        html: 'web/',
        js: 'web/js/',
        css: 'web/css/',
        img: 'web/images/',
        fonts: 'web/fonts/',
        libs: 'web/libs/'
    },

    src: { // Пути откуда брать исходники
        html: 'src/*.html', // Синтаксис src/*.html говорит gulp что мы хотим взять все файлы с расширением .html
        js: 'src/js/common.js',// В скриптах нам понадобятся только common файл
        style: 'src/sass/style.scss', // В стилях берем два файла style и media
        media: 'src/sass/media.scss',
        img: 'src/images/**/*.*', // Синтаксис images/**/*.* означает - взять все файлы всех расширений из папки и из вложенных каталогов
        fonts: 'src/fonts/**/*.*',
        libs: './bower_components/'
    },

    watch: { // Тут мы укажем, за изменением каких файлов мы хотим наблюдать
        html: 'src/**/*.html',
        js: 'src/js/**/*.js',
        style: 'src/sass/**/*.scss',
        img: 'src/images/**/*.*',
        fonts: 'src/fonts/**/*.*'
    },
    clean: './web'
};

// Переменная с настройками dev сервера
var config = {
    server: {
        baseDir: "./web"
    },
    tunnel: false,
    host: 'localhost',
    port: 9000,
    logPrefix: "lucas"
};

// Таск для сборки .html
gulp.task('html:build', function () {
    gulp.src(path.src.html) // Выберем файлы по нужному пути
        .pipe(rigger()) // Прогоним через rigger
        .pipe(gulp.dest(path.build.html)) // Выплюнем их в папку build
        .pipe(reload({stream: true})); // И перезагрузим наш сервер для обновлений
});

// Таск для сборки common.js
gulp.task('js:build', function () {
    gulp.src(path.src.js) // Найдем наш common файл
        .pipe(rigger()) // Прогоним через rigger
        // .pipe(sourcemaps.init()) // Инициализируем sourcemap
        // .pipe(uglify().on('error', function(e){
        //     console.log(e); // При возникновении ошибки покажет где проблема
        // })) // Сожмем наш js
       .pipe(sourcemaps.write()) // Пропишем карты
        .pipe(gulp.dest(path.build.js)) // Выплюнем готовый файл в build
        .pipe(reload({stream: true})); // И перезагрузим сервер
});

// Таск для сборки .scss файлов
gulp.task('style:build', function () {
    // Кусок для файла style
    gulp.src(path.src.style) // Выберем наш style.scss
        // .pipe(sourcemaps.init()) // То же самое что и с js
        .pipe(sass({
            outputStyle: 'expanded'
        })) // Скомпилируем
        .pipe(prefixer()) // Добавим вендорные префиксы
        // .pipe(cssmin()) // Сожмем
        // .pipe(sourcemaps.write())
        .pipe(gulp.dest(path.build.css)) // И в build
        .pipe(reload({stream: true}));

    // Кусок для файла media
    gulp.src(path.src.media) // Выберем наш media.scss
        // .pipe(sourcemaps.init()) // То же самое что и с js
        .pipe(sass({
            outputStyle: 'expanded'
        })) // Скомпилируем
        .pipe(prefixer()) // Добавим вендорные префиксы
        // .pipe(cssmin()) // Сожмем
        // .pipe(sourcemaps.write())
        .pipe(gulp.dest(path.build.css)) // И в build
        .pipe(reload({stream: true}));
});

// Таск для переваривания картинок
gulp.task('image:build', function () {
    gulp.src(path.src.img) // Выберем наши картинки
        .pipe(gulp.dest(path.build.img)) // И бросим в build
        .pipe(reload({stream: true}));
});

// Таск десантирования шрифтов
gulp.task('fonts:build', function() {
    gulp.src(path.src.fonts)
        .pipe(gulp.dest(path.build.fonts))
});

// Таск на просмотр изменения файлов
gulp.task('watch', function(){
    watch([path.watch.html], function(event, cb) { // Посмотрели html
        gulp.start('html:build'); // Выплюнули в билд
    });
    watch([path.watch.style], function(event, cb) { // Посмотрели стили
        gulp.start('style:build'); // Выплюнули в билд
    });
    watch([path.watch.js], function(event, cb) { // Посмотрели скрипты
        gulp.start('js:build'); // Выплюнули в билд
    });
    watch([path.watch.img], function(event, cb) { // Посмотрели картинки
        gulp.start('image:build'); // Выплюнули в билд
    });
    watch([path.watch.fonts], function(event, cb) { // Посмотрели шрифты
        gulp.start('fonts:build'); // Выплюнули в билд
    });
});

// Таск запуска локального сервера с livereload
gulp.task('webserver', function () {
    browserSync(config);
});

// Таск очистки
gulp.task('clean', function (cb) {
    rimraf(path.clean, cb);
});

// Таск сборки сторонних библиотек через bower
gulp.task('bower', function() {
    return bower();
});

// Фильтруем библиотеки и вынимаем только нужные файлы
gulp.task('filter', function() {
    // Настраиваем фильтры для файлов
    const jsFilter = filter(['*.js', '!src/vendor'], {restore: true, passthrough: false});
    const cssFilter = filter(['*.css', '!src/vendor'], {restore: true, passthrough: false});

    // Для нормальных плагинов отработает этот кусок кода
    const stream = gulp.src([
        'bower_components/**/*.min.*',
        'bower_components/**/fonts/*',
        'bower_components/**/*.css',
        '!bower_components/**/*.map'
    ])
    // Фильтруем содержимое на наличие js и css
    .pipe(jsFilter)
    .pipe(cssFilter)
    // run them through a plugin
    .pipe(gulp.dest('dist'));

    // Вываливаем в билд
    jsFilter.restore.pipe(gulp.dest('web/libs/'));

    return stream;
});

// Таск "Сделать хорошо"
gulp.task('build', [
    'html:build',
    'js:build',
    'style:build',
    'fonts:build',
    'image:build'
]);

// Дефолтный таск старта
gulp.task('default', ['bower', 'build', 'webserver', 'watch']);
<commit_msg>del img plugins<commit_after>'use strict';
// Импортируем необходимые плагины в проект
var gulp = require('gulp'),
    bower = require('gulp-bower'),
    watch = require('gulp-watch'),
    prefixer = require('gulp-autoprefixer'),
    uglify = require('gulp-uglify'),
    sass = require('gulp-sass'),
    sourcemaps = require('gulp-sourcemaps'),
    rigger = require('gulp-rigger'),
    cssmin = require('gulp-clean-css'),
    rimraf = require('rimraf'),
    browserSync = require("browser-sync"),
    filter = require('gulp-filter'),
    reload = browserSync.reload;

// Прописываем объект содержащий все необходимые пути
var path = {
    build: { // Тут мы укажем куда складывать готовые после сборки файлы
        html: 'web/',
        js: 'web/js/',
        css: 'web/css/',
        img: 'web/images/',
        fonts: 'web/fonts/',
        libs: 'web/libs/'
    },

    src: { // Пути откуда брать исходники
        html: 'src/*.html', // Синтаксис src/*.html говорит gulp что мы хотим взять все файлы с расширением .html
        js: 'src/js/common.js',// В скриптах нам понадобятся только common файл
        style: 'src/sass/style.scss', // В стилях берем два файла style и media
        media: 'src/sass/media.scss',
        img: 'src/images/**/*.*', // Синтаксис images/**/*.* означает - взять все файлы всех расширений из папки и из вложенных каталогов
        fonts: 'src/fonts/**/*.*',
        libs: './bower_components/'
    },

    watch: { // Тут мы укажем, за изменением каких файлов мы хотим наблюдать
        html: 'src/**/*.html',
        js: 'src/js/**/*.js',
        style: 'src/sass/**/*.scss',
        img: 'src/images/**/*.*',
        fonts: 'src/fonts/**/*.*'
    },
    clean: './web'
};

// Переменная с настройками dev сервера
var config = {
    server: {
        baseDir: "./web"
    },
    tunnel: false,
    host: 'localhost',
    port: 9000,
    logPrefix: "lucas"
};

// Таск для сборки .html
gulp.task('html:build', function () {
    gulp.src(path.src.html) // Выберем файлы по нужному пути
        .pipe(rigger()) // Прогоним через rigger
        .pipe(gulp.dest(path.build.html)) // Выплюнем их в папку build
        .pipe(reload({stream: true})); // И перезагрузим наш сервер для обновлений
});

// Таск для сборки common.js
gulp.task('js:build', function () {
    gulp.src(path.src.js) // Найдем наш common файл
        .pipe(rigger()) // Прогоним через rigger
        // .pipe(sourcemaps.init()) // Инициализируем sourcemap
        // .pipe(uglify().on('error', function(e){
        //     console.log(e); // При возникновении ошибки покажет где проблема
        // })) // Сожмем наш js
       .pipe(sourcemaps.write()) // Пропишем карты
        .pipe(gulp.dest(path.build.js)) // Выплюнем готовый файл в build
        .pipe(reload({stream: true})); // И перезагрузим сервер
});

// Таск для сборки .scss файлов
gulp.task('style:build', function () {
    // Кусок для файла style
    gulp.src(path.src.style) // Выберем наш style.scss
        // .pipe(sourcemaps.init()) // То же самое что и с js
        .pipe(sass({
            outputStyle: 'expanded'
        })) // Скомпилируем
        .pipe(prefixer()) // Добавим вендорные префиксы
        // .pipe(cssmin()) // Сожмем
        // .pipe(sourcemaps.write())
        .pipe(gulp.dest(path.build.css)) // И в build
        .pipe(reload({stream: true}));

    // Кусок для файла media
    gulp.src(path.src.media) // Выберем наш media.scss
        // .pipe(sourcemaps.init()) // То же самое что и с js
        .pipe(sass({
            outputStyle: 'expanded'
        })) // Скомпилируем
        .pipe(prefixer()) // Добавим вендорные префиксы
        // .pipe(cssmin()) // Сожмем
        // .pipe(sourcemaps.write())
        .pipe(gulp.dest(path.build.css)) // И в build
        .pipe(reload({stream: true}));
});

// Таск для переваривания картинок
gulp.task('image:build', function () {
    gulp.src(path.src.img) // Выберем наши картинки
        .pipe(gulp.dest(path.build.img)) // И бросим в build
        .pipe(reload({stream: true}));
});

// Таск десантирования шрифтов
gulp.task('fonts:build', function() {
    gulp.src(path.src.fonts)
        .pipe(gulp.dest(path.build.fonts))
});

// Таск на просмотр изменения файлов
gulp.task('watch', function(){
    watch([path.watch.html], function(event, cb) { // Посмотрели html
        gulp.start('html:build'); // Выплюнули в билд
    });
    watch([path.watch.style], function(event, cb) { // Посмотрели стили
        gulp.start('style:build'); // Выплюнули в билд
    });
    watch([path.watch.js], function(event, cb) { // Посмотрели скрипты
        gulp.start('js:build'); // Выплюнули в билд
    });
    watch([path.watch.img], function(event, cb) { // Посмотрели картинки
        gulp.start('image:build'); // Выплюнули в билд
    });
    watch([path.watch.fonts], function(event, cb) { // Посмотрели шрифты
        gulp.start('fonts:build'); // Выплюнули в билд
    });
});

// Таск запуска локального сервера с livereload
gulp.task('webserver', function () {
    browserSync(config);
});

// Таск очистки
gulp.task('clean', function (cb) {
    rimraf(path.clean, cb);
});

// Таск сборки сторонних библиотек через bower
gulp.task('bower', function() {
    return bower();
});

// Фильтруем библиотеки и вынимаем только нужные файлы
gulp.task('filter', function() {
    // Настраиваем фильтры для файлов
    const jsFilter = filter(['*.js', '!src/vendor'], {restore: true, passthrough: false});
    const cssFilter = filter(['*.css', '!src/vendor'], {restore: true, passthrough: false});

    // Для нормальных плагинов отработает этот кусок кода
    const stream = gulp.src([
        'bower_components/**/*.min.*',
        'bower_components/**/fonts/*',
        'bower_components/**/*.css',
        '!bower_components/**/*.map'
    ])
    // Фильтруем содержимое на наличие js и css
    .pipe(jsFilter)
    .pipe(cssFilter)
    // run them through a plugin
    .pipe(gulp.dest('dist'));

    // Вываливаем в билд
    jsFilter.restore.pipe(gulp.dest('web/libs/'));

    return stream;
});

// Таск "Сделать хорошо"
gulp.task('build', [
    'html:build',
    'js:build',
    'style:build',
    'fonts:build',
    'image:build'
]);

// Дефолтный таск старта
gulp.task('default', ['bower', 'build', 'webserver', 'watch']);
<|endoftext|>


<commit_before><commit_msg>gulp heroku task<commit_after><|endoftext|>


<commit_before>var gulp = require('gulp');
var webserver = require('gulp-webserver');

var config = require('./gulp/config');
var clean = require('./gulp/clean');
var downloadLocales = require('./gulp/download-locales');
var locale = require('./gulp/locale');
var template = require('./gulp/template');
var browserify = require('./gulp/browserify');
var less = require('./gulp/less');
var cache = require('./gulp/cache');
var publish = require('./gulp/publish');

var jshint = require('./gulp/jshint');
var jscs = require('./gulp/jscs');
var unit = require('./gulp/unit');

// Config
gulp.task('config', config);

// Build
gulp.task('clean', ['config'], clean);
gulp.task('download-locales', ['clean'], downloadLocales);
gulp.task('locale', ['download-locales'], locale);
gulp.task('template', ['config', 'clean'], template);

var browserifyMain = browserify('./lib/index.js', './build/index.js');
var browserifyPublish = browserify('./publish/index.js', './build/publish-assets/index.js')

gulp.task('less', ['clean'], less);
gulp.task('browserify', ['clean', 'locale'], browserifyMain);
gulp.task('browserify-publish', ['clean', 'locale', 'publish'], browserifyPublish);
gulp.task('publish', ['less', 'locale'], publish);
gulp.task('build', [
    'less',
    'browserify',
    'browserify-publish',
    'publish',
    'template'
], cache);

gulp.task('re-locale', ['clean'], locale);
gulp.task('re-browserify', ['clean', 're-locale'], browserifyMain);
gulp.task('re-browserify-publish', ['clean', 're-locale', 're-publish'], browserifyPublish);
gulp.task('re-publish', ['less', 're-locale'], publish);
gulp.task('re-build', [
    'less',
    're-browserify',
    're-browserify-publish',
    're-publish',
    'template'
], cache);

// Test
gulp.task('jshint', jshint);
gulp.task('jscs', jscs);
gulp.task('lint', ['jshint', 'jscs']);
gulp.task('unit', ['re-build'], unit);
gulp.task('test', ['lint', 'unit']);

// Watch
gulp.task('watch', ['build'], function () {
    gulp.watch([
        './{blocks,components,lib,static,views,publish}/**/*.{js,json,less,html}',
        './locale/en_US/*.json',
        './config/*.env',
        '.env'
    ],['re-build']);
});

// Serve + Watch
gulp.task('dev', ['watch'], function() {
  return gulp.src('build')
    .pipe(webserver({
        port: 8080,
        livereload: false,
        fallback: 'index.html'
    }));
});
<commit_msg>Fixes #900:  Development server can't be accessed from local network<commit_after>var gulp = require('gulp');
var webserver = require('gulp-webserver');

var config = require('./gulp/config');
var clean = require('./gulp/clean');
var downloadLocales = require('./gulp/download-locales');
var locale = require('./gulp/locale');
var template = require('./gulp/template');
var browserify = require('./gulp/browserify');
var less = require('./gulp/less');
var cache = require('./gulp/cache');
var publish = require('./gulp/publish');

var jshint = require('./gulp/jshint');
var jscs = require('./gulp/jscs');
var unit = require('./gulp/unit');

// Config
gulp.task('config', config);

// Build
gulp.task('clean', ['config'], clean);
gulp.task('download-locales', ['clean'], downloadLocales);
gulp.task('locale', ['download-locales'], locale);
gulp.task('template', ['config', 'clean'], template);

var browserifyMain = browserify('./lib/index.js', './build/index.js');
var browserifyPublish = browserify('./publish/index.js', './build/publish-assets/index.js')

gulp.task('less', ['clean'], less);
gulp.task('browserify', ['clean', 'locale'], browserifyMain);
gulp.task('browserify-publish', ['clean', 'locale', 'publish'], browserifyPublish);
gulp.task('publish', ['less', 'locale'], publish);
gulp.task('build', [
    'less',
    'browserify',
    'browserify-publish',
    'publish',
    'template'
], cache);

gulp.task('re-locale', ['clean'], locale);
gulp.task('re-browserify', ['clean', 're-locale'], browserifyMain);
gulp.task('re-browserify-publish', ['clean', 're-locale', 're-publish'], browserifyPublish);
gulp.task('re-publish', ['less', 're-locale'], publish);
gulp.task('re-build', [
    'less',
    're-browserify',
    're-browserify-publish',
    're-publish',
    'template'
], cache);

// Test
gulp.task('jshint', jshint);
gulp.task('jscs', jscs);
gulp.task('lint', ['jshint', 'jscs']);
gulp.task('unit', ['re-build'], unit);
gulp.task('test', ['lint', 'unit']);

// Watch
gulp.task('watch', ['build'], function () {
    gulp.watch([
        './{blocks,components,lib,static,views,publish}/**/*.{js,json,less,html}',
        './locale/en_US/*.json',
        './config/*.env',
        '.env'
    ],['re-build']);
});

// Serve + Watch
gulp.task('dev', ['watch'], function() {
  return gulp.src('build')
    .pipe(webserver({
        host: '0.0.0.0',
        port: 8080,
        livereload: false,
        fallback: 'index.html'
    }));
});
<|endoftext|>


<commit_before>'use strict';

// =============================
// ------ Import Plugins -------
// =============================

var gulp      = require('gulp');
var $         = require('gulp-load-plugins')();
var mmq       = require('gulp-merge-media-queries');

var autoprefixer = require('autoprefixer');
var runSequence  = require('run-sequence');
var browserSync  = require('browser-sync').create();
var attrSorter   = require('posthtml-attrs-sorter');
var del          = require('del');
var reload       = browserSync.reload;

// =============================
// -------- Functions ----------
// =============================

// Error handler for gulp-plumber
function errorHandler(err) {
    $.util.log([ (err.name + ' in ' + err.plugin).bold.red, '', err.message, '' ].join('\n'));

    this.emit('end');
}

function correctNumber(number) {
    return number < 10 ? '0' + number : number;
}

// Return timestamp
function getDateTime() {
    var now = new Date();
    var year = now.getFullYear();
    var month = correctNumber(now.getMonth() + 1);
    var day = correctNumber(now.getDate());
    var hours = correctNumber(now.getHours());
    var minutes = correctNumber(now.getMinutes());
    return year + '-' + month + '-' + day + '-' + hours + minutes;
};

// =============================
// ------- Add var path --------
// =============================

var path = {

    build: {
        html:   'web/',
        js:     'web/js/',
        css:    'web/css/',
        img:    'web/images/',
        fonts:  'web/fonts/',
        libs:   'web/libs/'
    },

    src: {
        html:   'src/*.html',                 // Синтаксис src/*.html говорит gulp что мы хотим взять все файлы с расширением .html
        js:     'src/js/common.js',
        style:  'src/sass/style.scss',
        img:    'src/images/**/*.*',           // Синтаксис images/**/*.* означает - взять все файлы всех расширений из папки и из вложенных каталогов
        fonts:  'src/fonts/**/*.*',
        libs:   './bower_components/'
    },

    watch: {
        html:   'src/**/*.html',
        js:     'src/js/**/*.js',
        style:  'src/sass/**/*.scss',
        img:    'src/images/**/*.*',
        fonts:  'src/fonts/**/*.*'
    },

    clean:      './web'
};

// =============================
// ---- Add plugins options ----
// =============================

var option = {

    browserSync: {
        server: './web',
        tunnel: false,
        open: false,
        host: 'localhost',
        port: 9000,
        logPrefix: "lucas"
    },

    plumber: {
        errorHandler: errorHandler
    },

    sass: {
        outputStyle: 'expanded'
    },

    postcss: [
        autoprefixer({
            cascade: true
        }),
    ],

    posthtml: {
        plugins: [
            attrSorter({
                order: [
                    'class',
                    'id',
                    'name',
                    'data',
                    'ng',
                    'src',
                    'for',
                    'type',
                    'href',
                    'values',
                    'title',
                    'alt',
                    'role',
                    'aria',
                    'tabindex'
                ]
            })
        ],
        options: {}
    },

    mmq: {
        log: true,
        use_external: true
    },

    csscomb: 'csscomb.json',

}

// =============================
// --------- Sub tasks ---------
// =============================

gulp.task('clean', function (cb) {
    return del(path.clean, cb);
});

gulp.task('serve', function () {
    return browserSync.init(option.browserSync);
});

gulp.task('bower', function() {
    return $.bower();
});

// =============================
// ------- Build tasks ---------
// =============================

gulp.task('build:html', function () {
    return gulp.src(path.src.html)
        .pipe($.plumber(option.plumber))
        .pipe($.rigger())
        .pipe($.posthtml(option.posthtml.plugins, option.posthtml.options))
        .pipe(gulp.dest(path.build.html));
});

gulp.task('build:js', function () {
    return gulp.src(path.src.js)
        .pipe($.plumber(option.plumber))
        .pipe($.rigger())
        .pipe(gulp.dest(path.build.js));
});

gulp.task('build:css', function (cb) {
    return gulp.src(path.src.style)
        .pipe($.plumber(option.plumber))
        .pipe($.sourcemaps.init())
        .pipe($.sass(option.sass))
        .pipe($.postcss(option.postcss))
        .pipe(mmq(option.mmq))
        .pipe($.csscomb(option.csscomb))
        .pipe($.sourcemaps.write('.'))
        .pipe(gulp.dest(path.build.css));
});

gulp.task('build:media', function () {
    gulp.src(path.build.css + '*.responsive.css')
        .pipe($.plumber(option.plumber))
        .pipe($.sourcemaps.init())
        .pipe($.rename({basename: 'media'}))
        .pipe($.sourcemaps.write('.'))
        .pipe(gulp.dest(path.build.css));

    return del(path.build.css + '*.responsive.css');
});

gulp.task('build:img', function () {
    return gulp.src(path.src.img)
        .pipe($.plumber(option.plumber))
        .pipe(gulp.dest(path.build.img));
});

gulp.task('build:fonts', function() {
    return gulp.src(path.src.fonts, {read: false})
        .pipe($.plumber(option.plumber))
        .pipe(gulp.dest(path.build.fonts));
});

gulp.task('build:zip', function() {
    var datetime = '-' + getDateTime();
    var zipName = 'web' + datetime + '.zip';

    return gulp.src('web/**/*.*')
        .pipe($.zip(zipName))
        .pipe(gulp.dest('dist'));
});

// =============================
// ------- Watch task ----------
// =============================

gulp.task('watch', function(){
    $.watch([path.watch.html], function(event, cb) {
        return runSequence('build:html', reload);
    });

    $.watch([path.watch.style], function(event, cb) {
        return runSequence('build:css', 'build:media', reload);
    });

    $.watch([path.watch.js], function(event, cb) {
        return runSequence('build:js', reload);
    });

    $.watch([path.watch.img], function(event, cb) {
        return runSequence('build:img', reload);
    });

    $.watch([path.watch.fonts], function(event, cb) {
        return runSequence('build:fonts', reload);
    });
});

// =============================
// -------- Main task ----------
// =============================

gulp.task('build:style', function (cb) {
    return runSequence(
        'build:css',
        'build:media'
    );
});

gulp.task('build', [
    'build:html',
    'build:style',
    'build:js',
    'build:img',
    'build:fonts'
]);

gulp.task('vendor', function (cb) {
    return runSequence(
        'bower',
        'filter',
        cb
    );
});

gulp.task('zip', function (cb) {
    return runSequence(
        'build',
        'build:zip',
        cb
    );
});

gulp.task('dev', [
    'build',
    'watch',
    'serve'
]);

// Default task
gulp.task('default', ['dev']);

// TODO: Разобрать таск и переписать
// Фильтруем библиотеки и вынимаем только нужные файлы
gulp.task('filter', function() {
    // Настраиваем фильтры для файлов
    const jsFilter = $.filter(['*.js', '!src/vendor'], {restore: true, passthrough: false});
    const cssFilter = $.filter(['*.css', '!src/vendor'], {restore: true, passthrough: false});

    // Для нормальных плагинов отработает этот кусок кода
    const stream = gulp.src([
        'bower_components/**/*.min.*',
        'bower_components/**/fonts/*',
        'bower_components/**/*.css',
        '!bower_components/**/*.map'
    ])

    // Фильтруем содержимое на наличие js и css
    .pipe(jsFilter)
    .pipe(cssFilter)
    // run them through a plugin
    .pipe(gulp.dest('dist'));

    // Вываливаем в билд
    jsFilter.restore.pipe(gulp.dest(path.build.libs));

    return stream;
});
<commit_msg>small fix style task<commit_after>'use strict';

// =============================
// ------ Import Plugins -------
// =============================

var gulp      = require('gulp');
var $         = require('gulp-load-plugins')();
var mmq       = require('gulp-merge-media-queries');

var autoprefixer = require('autoprefixer');
var runSequence  = require('run-sequence');
var browserSync  = require('browser-sync').create();
var attrSorter   = require('posthtml-attrs-sorter');
var del          = require('del');
var reload       = browserSync.reload;

// =============================
// -------- Functions ----------
// =============================

// Error handler for gulp-plumber
function errorHandler(err) {
    $.util.log([ (err.name + ' in ' + err.plugin).bold.red, '', err.message, '' ].join('\n'));

    this.emit('end');
}

function correctNumber(number) {
    return number < 10 ? '0' + number : number;
}

// Return timestamp
function getDateTime() {
    var now = new Date();
    var year = now.getFullYear();
    var month = correctNumber(now.getMonth() + 1);
    var day = correctNumber(now.getDate());
    var hours = correctNumber(now.getHours());
    var minutes = correctNumber(now.getMinutes());
    return year + '-' + month + '-' + day + '-' + hours + minutes;
};

// =============================
// ------- Add var path --------
// =============================

var path = {

    build: {
        html:   'web/',
        js:     'web/js/',
        css:    'web/css/',
        img:    'web/images/',
        fonts:  'web/fonts/',
        libs:   'web/libs/'
    },

    src: {
        html:   'src/*.html',                 // Синтаксис src/*.html говорит gulp что мы хотим взять все файлы с расширением .html
        js:     'src/js/common.js',
        style:  'src/sass/style.scss',
        img:    'src/images/**/*.*',           // Синтаксис images/**/*.* означает - взять все файлы всех расширений из папки и из вложенных каталогов
        fonts:  'src/fonts/**/*.*',
        libs:   './bower_components/'
    },

    watch: {
        html:   'src/**/*.html',
        js:     'src/js/**/*.js',
        style:  'src/sass/**/*.scss',
        img:    'src/images/**/*.*',
        fonts:  'src/fonts/**/*.*'
    },

    clean:      './web'
};

// =============================
// ---- Add plugins options ----
// =============================

var option = {

    browserSync: {
        server: './web',
        tunnel: false,
        open: false,
        host: 'localhost',
        port: 9000,
        logPrefix: "lucas"
    },

    plumber: {
        errorHandler: errorHandler
    },

    sass: {
        outputStyle: 'expanded'
    },

    postcss: [
        autoprefixer({
            cascade: true
        }),
    ],

    posthtml: {
        plugins: [
            attrSorter({
                order: [
                    'class',
                    'id',
                    'name',
                    'data',
                    'ng',
                    'src',
                    'for',
                    'type',
                    'href',
                    'values',
                    'title',
                    'alt',
                    'role',
                    'aria',
                    'tabindex'
                ]
            })
        ],
        options: {}
    },

    mmq: {
        log: true,
        use_external: true
    },

    csscomb: 'csscomb.json',

}

// =============================
// --------- Sub tasks ---------
// =============================

gulp.task('clean', function (cb) {
    return del(path.clean, cb);
});

gulp.task('serve', function () {
    return browserSync.init(option.browserSync);
});

gulp.task('bower', function() {
    return $.bower();
});

// =============================
// ------- Build tasks ---------
// =============================

gulp.task('build:html', function () {
    return gulp.src(path.src.html)
        .pipe($.plumber(option.plumber))
        .pipe($.rigger())
        .pipe($.posthtml(option.posthtml.plugins, option.posthtml.options))
        .pipe(gulp.dest(path.build.html));
});

gulp.task('build:js', function () {
    return gulp.src(path.src.js)
        .pipe($.plumber(option.plumber))
        .pipe($.rigger())
        .pipe(gulp.dest(path.build.js));
});

gulp.task('build:css', function (cb) {
    return gulp.src(path.src.style)
        .pipe($.plumber(option.plumber))
        .pipe($.sourcemaps.init())
        .pipe($.sass(option.sass))
        .pipe($.postcss(option.postcss))
        .pipe(mmq(option.mmq))
        .pipe($.csscomb(option.csscomb))
        .pipe($.sourcemaps.write('.'))
        .pipe(gulp.dest(path.build.css));
});

gulp.task('build:media', function () {
    gulp.src(path.build.css + '*.responsive.css')
        .pipe($.plumber(option.plumber))
        .pipe($.sourcemaps.init())
        .pipe($.rename({basename: 'media'}))
        .pipe($.sourcemaps.write('.'))
        .pipe(gulp.dest(path.build.css));

    return del(path.build.css + '*.responsive.css');
});

gulp.task('build:img', function () {
    return gulp.src(path.src.img)
        .pipe($.plumber(option.plumber))
        .pipe(gulp.dest(path.build.img));
});

gulp.task('build:fonts', function() {
    return gulp.src(path.src.fonts, {read: false})
        .pipe($.plumber(option.plumber))
        .pipe(gulp.dest(path.build.fonts));
});

gulp.task('build:zip', function() {
    var datetime = '-' + getDateTime();
    var zipName = 'web' + datetime + '.zip';

    return gulp.src('web/**/*.*')
        .pipe($.zip(zipName))
        .pipe(gulp.dest('dist'));
});

// =============================
// ------- Watch task ----------
// =============================

gulp.task('watch', function(){
    $.watch([path.watch.html], function(event, cb) {
        return runSequence('build:html', reload);
    });

    $.watch([path.watch.style], function(event, cb) {
        return runSequence('build:css', 'build:media', reload);
    });

    $.watch([path.watch.js], function(event, cb) {
        return runSequence('build:js', reload);
    });

    $.watch([path.watch.img], function(event, cb) {
        return runSequence('build:img', reload);
    });

    $.watch([path.watch.fonts], function(event, cb) {
        return runSequence('build:fonts', reload);
    });
});

// =============================
// -------- Main task ----------
// =============================

gulp.task('build:style', function (cb) {
    return runSequence(
        'build:css',
        'build:media',
        cb
    );
});

gulp.task('build', [
    'build:html',
    'build:style',
    'build:js',
    'build:img',
    'build:fonts'
]);

gulp.task('vendor', function (cb) {
    return runSequence(
        'bower',
        'filter',
        cb
    );
});

gulp.task('zip', function (cb) {
    return runSequence(
        'build',
        'build:zip',
        cb
    );
});

gulp.task('dev', [
    'build',
    'watch',
    'serve'
]);

// Default task
gulp.task('default', ['dev']);

// TODO: Разобрать таск и переписать
// Фильтруем библиотеки и вынимаем только нужные файлы
gulp.task('filter', function() {
    // Настраиваем фильтры для файлов
    const jsFilter = $.filter(['*.js', '!src/vendor'], {restore: true, passthrough: false});
    const cssFilter = $.filter(['*.css', '!src/vendor'], {restore: true, passthrough: false});

    // Для нормальных плагинов отработает этот кусок кода
    const stream = gulp.src([
        'bower_components/**/*.min.*',
        'bower_components/**/fonts/*',
        'bower_components/**/*.css',
        '!bower_components/**/*.map'
    ])

    // Фильтруем содержимое на наличие js и css
    .pipe(jsFilter)
    .pipe(cssFilter)
    // run them through a plugin
    .pipe(gulp.dest('dist'));

    // Вываливаем в билд
    jsFilter.restore.pipe(gulp.dest(path.build.libs));

    return stream;
});
<|endoftext|>


<commit_before><commit_msg>fix: making sure that console prints errors during documentation errors<commit_after><|endoftext|>


<commit_before>// Load gulp and global config
var gulp      = require('gulp');
var debug     = require('gulp-debug');
var config    = require('./config.json');
var options   = require('minimist')(process.argv.slice(2));
var gulpif    = require('gulp-if');

// Load modules to run tasks from files
var requireDir   = require('require-dir');
var tasks        = requireDir('./tasks');
var runSequence  = require('run-sequence');

// Build website with development assets and run server with live reloading
gulp.task('default', function(callback) {
  runSequence(
    'clean',
    ['css', 'img', 'copy'],
    'server',
    callback
  );
});

// Build website, either with development or minified assets depending on flag
gulp.task('build', function(callback) {
  runSequence(
    'clean',
    ['css', 'img', 'copy'],
    callback
  );
});
<commit_msg>rename build task to prod<commit_after>// Load gulp and global config
var gulp      = require('gulp');
var debug     = require('gulp-debug');
var config    = require('./config.json');
var options   = require('minimist')(process.argv.slice(2));
var gulpif    = require('gulp-if');

// Load modules to run tasks from files
var requireDir   = require('require-dir');
var tasks        = requireDir('./tasks');
var runSequence  = require('run-sequence');

// Build website with development assets and run server with live reloading
gulp.task('default', function(callback) {
  runSequence(
    'clean',
    ['css', 'img', 'copy'],
    'server',
    callback
  );
});

// Build production ready website, either with development or minified assets depending on flag
gulp.task('prod', function(callback) {
  runSequence(
    'clean',
    ['css', 'img', 'copy'],
    callback
  );
});
<|endoftext|>


<commit_before>var gulp = require('gulp');
var browserify = require('gulp-browserify');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify')
var rename = require('gulp-rename');
var connect = require('gulp-connect');
var less = require('gulp-less');
var clean = require('gulp-clean');
var jshint = require('gulp-jshint');
var gzip = require('gulp-gzip');
var template = require('gulp-template');
var watch = require('gulp-watch');
var path = require('path');
var combineCSS = require('combine-css');
var gulpif = require('gulp-if');
var gutil = require('gulp-util');
var handlebars = require('gulp-handlebars');
// var styl = require('gulp-styl');
// var refresh = require('gulp-livereload');
// var lr = require('tiny-lr');
// var server = lr();
var header = require('gulp-header');
var hbsfy = require("hbsfy").configure({
  extensions: ["handlebars"]
});

var useJsHint = false;
var destRoot = __dirname + "/devel";
var devMode = true;

gulp.task('connect', connect.server({
  root: destRoot,
  port: 8000,
  // livereload: true,
  // open: {
  //   browser: 'chrome' // if not working OS X browser: 'Google Chrome'
  // }
}));

gulp.task('cleancss', function(){
  gulp.src(destRoot + '/css', {read: false})
      .pipe(clean())
})

gulp.task('less', function(){
  gulp.src([
    "css/polis_main.less",
    ])
      .pipe(less())
      .pipe(concat("polis.css"))
      .pipe(gulp.dest(destRoot + '/css'))
});

gulp.task('fontawesome', function() {
  gulp.src('bower_components/font-awesome/font/**/*')
    .pipe(gulp.dest(destRoot + "/font"));
});
gulp.task('index', function() {
  var s = gulp.src('index.html');
  if (devMode) {
    s = s.pipe(template({
      basepath: '',
      d3Filename: 'd3.js',
    }))
  } else {
    s = s.pipe(template({
      basepath: 'https://s3.amazonaws.com/www.polis.io',
      d3Filename: 'd3.min.js',
    }));
  }
  return s.pipe(gulp.dest(destRoot));
});

gulp.task('templates', function(){
  gulp.src(['js/templates/*.hbs', 'js/templates/*.handlebars'])
    .pipe(handlebars({
      outputType: 'node',
      wrapped: true,
    }))
    .pipe(gulp.dest('js/tmpl'));
});

gulp.task('jshint', function(){
  gulp.src('js/**/*.js')
      .pipe(gulpif(useJsHint, jshint(

      {
         // reporter: 'jslint',
          curly: true, // require if,else blocks to have {}
          eqeqeq: true,
          trailing: true, // no trailing whitespace allowed
          // immed: true,
          // latedef: true,
          // newcap: true,
          // noarg: true,
          // sub: true,
          // undef: true,
        //  unused: true,
          quotmark: "double",
         // plusplus: true, // no ++ or --
        //  nonew: true,
          noarg: true, // no arguments.caller and arguments.callee (allow for optimizations)
          newcap: true, // constructors must be capitalized
        //  latedef: "nofunc",
         // indent: 2,
          immed: true,
//          forin: true, require hasOwnProperty checks
          boss: true,
//          debug: true, // uncomment temporarily when you want to allow debugger; statements.
          // browser: true,
          es3: true,
          globals: {
            d3: true,
            jQuery: true,
            console: true,
            require: true,
            define: true,
            requirejs: true,
            describe: true,
            expect: true,
            module: true,
            // it: true
          },
          // relax: eventually we should get rid of these
            //expr: true,
           // loopfunc: true,
            //shadow: true,
        }
        )))
      .pipe(jshint.reporter('default'))
})

gulp.task('scripts', ['templates', 'jshint'], function() {
  // Single entry point to browserify
  var s = gulp.src('js/main.js')
      .pipe(browserify({
        insertGlobals : true,
        debug : false, //!gulp.env.production
        // transform: ['hbsfy'],
        shim : {
          //TODO 'handlebars': 'templates/helpers/handlebarsWithHelpers', //this one has polis custom template helpers
          handlebars: {
            path : 'bower_components/handlebars/handlebars.runtime.js', //original handlebars
            exports: 'Handlebars',
          },
          originalbackbone: {
            path: 'bower_components/backbone/backbone', // backbone before modifications
            depends: { jquery: '$', underscore: '_' },
            exports: 'Backbone',
          },
          backbone: {
            path: 'js/net/backbonePolis', // polis-specific backbone modifications
            depends: { originalbackbone: "Backbone" },
            exports: "Backbone",
          },
          underscore: {
            path: 'bower_components/underscore/underscore',
            exports: '_',
          },
          thorax: {
            path: 'bower_components/thorax/thorax',
            depends: { handlebars: 'Handlebars', backbone: 'Backbone' },
            exports: 'Thorax',
          },
          bootstrap_alert: {  //all bootstrap files need to be added to the dependency array of js/main.js
            path: 'bower_components/bootstrap/js/alert',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_tab: {
            path : 'bower_components/bootstrap/js/tab',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_popover: {
            path: 'bower_components/bootstrap/js/popover',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_collapse: {
            path: 'bower_components/bootstrap/js/collapse',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_dropdown: {
            path: 'bower_components/bootstrap/js/dropdown',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_affix: {
            path: 'bower_components/bootstrap/js/affix',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          d3tooltips: {
            path: 'bower_components/d3-tip/index',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_tooltip: {
            path: 'bower_components/bootstrap/js/tooltip',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_button: {
            path: 'bower_components/bootstrap/js/button',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_transition: {
            path: 'bower_components/bootstrap/js/transition',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          VisView: {
            path: 'js/lib/VisView',
            depends: { d3tooltips: 'foo' }, // added to d3 object as d3.tip
            exports: 'VisView',
          },
        },
      }))
      .pipe(concat('polis.js'))
  // TODO      .pipe(header("copyright Polis... (except that libs are mixed in)
      if (!devMode) {
        s = s
          .pipe(uglify())
          .pipe(gzip())
      }
      s = s.pipe(rename('polis.js'));
      return s.pipe(gulp.dest(destRoot + "/js"));
});

// for big infrequently changing scripts that we don't want to concatenate
// on each dev build.
gulp.task("scriptsOther", function() {

  var files = [];
  if (devMode) {
    files.push('bower_components/d3/d3.js');
  } else {
    files.push('bower_components/d3/d3.min.js');
  }
  var s = gulp.src(files);
  if (!devMode) {
    s = s
      .pipe(uglify())
      .pipe(gzip())
      .pipe(rename(function (path) {
        // path.dirname += "/ciao";
        // path.basename += "-goodbye";
        // path.extname = ".md"

        // remove .gz extension
        var ext = path.extname;
        path.extname = ext.substr(0, ext.length- ".gz".length);
      }));
  }
  return s.pipe(gulp.dest(destRoot + "/js"));
});

gulp.task("configureForProduction", function() {
  destRoot = "./dist";
  devMode = false;
});

gulp.task('common', [
  "scriptsOther",
  "scripts",
  "less",
  "fontawesome",
  "index",
  ], function() {
    // if (devMode) {
    //   connect.reload();
    // }
});

gulp.task('dev', [
  "common",
  ], function(){
});

gulp.task('dist', [
  "configureForProduction",
  "common",
  ], function(){
});

gulp.task("watchForDev", [
  "connect",
  ], function() {
    gulp.watch([
      "js/**",
      "!js/tmpl/**", // These are genterated, so don't watch!
      "css/**",
      "*.html",
    ], function(e) {
      console.log("watch saw: " + e.path + " " + e.type);
      gulp.run("dev");
    });
});

gulp.task('default', [
  "watchForDev",
  ], function() {
});

<commit_msg>gulp run dev task immediately<commit_after>var gulp = require('gulp');
var browserify = require('gulp-browserify');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify')
var rename = require('gulp-rename');
var connect = require('gulp-connect');
var less = require('gulp-less');
var clean = require('gulp-clean');
var jshint = require('gulp-jshint');
var gzip = require('gulp-gzip');
var template = require('gulp-template');
var watch = require('gulp-watch');
var path = require('path');
var combineCSS = require('combine-css');
var gulpif = require('gulp-if');
var gutil = require('gulp-util');
var handlebars = require('gulp-handlebars');
// var styl = require('gulp-styl');
// var refresh = require('gulp-livereload');
// var lr = require('tiny-lr');
// var server = lr();
var header = require('gulp-header');
var hbsfy = require("hbsfy").configure({
  extensions: ["handlebars"]
});

var useJsHint = false;
var destRoot = __dirname + "/devel";
var devMode = true;

gulp.task('connect', connect.server({
  root: destRoot,
  port: 8000,
  // livereload: true,
  // open: {
  //   browser: 'chrome' // if not working OS X browser: 'Google Chrome'
  // }
}));

gulp.task('cleancss', function(){
  gulp.src(destRoot + '/css', {read: false})
      .pipe(clean())
})

gulp.task('less', function(){
  gulp.src([
    "css/polis_main.less",
    ])
      .pipe(less())
      .pipe(concat("polis.css"))
      .pipe(gulp.dest(destRoot + '/css'))
});

gulp.task('fontawesome', function() {
  gulp.src('bower_components/font-awesome/font/**/*')
    .pipe(gulp.dest(destRoot + "/font"));
});
gulp.task('index', function() {
  var s = gulp.src('index.html');
  if (devMode) {
    s = s.pipe(template({
      basepath: '',
      d3Filename: 'd3.js',
    }))
  } else {
    s = s.pipe(template({
      basepath: 'https://s3.amazonaws.com/www.polis.io',
      d3Filename: 'd3.min.js',
    }));
  }
  return s.pipe(gulp.dest(destRoot));
});

gulp.task('templates', function(){
  gulp.src(['js/templates/*.hbs', 'js/templates/*.handlebars'])
    .pipe(handlebars({
      outputType: 'node',
      wrapped: true,
    }))
    .pipe(gulp.dest('js/tmpl'));
});

gulp.task('jshint', function(){
  gulp.src('js/**/*.js')
      .pipe(gulpif(useJsHint, jshint(

      {
         // reporter: 'jslint',
          curly: true, // require if,else blocks to have {}
          eqeqeq: true,
          trailing: true, // no trailing whitespace allowed
          // immed: true,
          // latedef: true,
          // newcap: true,
          // noarg: true,
          // sub: true,
          // undef: true,
        //  unused: true,
          quotmark: "double",
         // plusplus: true, // no ++ or --
        //  nonew: true,
          noarg: true, // no arguments.caller and arguments.callee (allow for optimizations)
          newcap: true, // constructors must be capitalized
        //  latedef: "nofunc",
         // indent: 2,
          immed: true,
//          forin: true, require hasOwnProperty checks
          boss: true,
//          debug: true, // uncomment temporarily when you want to allow debugger; statements.
          // browser: true,
          es3: true,
          globals: {
            d3: true,
            jQuery: true,
            console: true,
            require: true,
            define: true,
            requirejs: true,
            describe: true,
            expect: true,
            module: true,
            // it: true
          },
          // relax: eventually we should get rid of these
            //expr: true,
           // loopfunc: true,
            //shadow: true,
        }
        )))
      .pipe(jshint.reporter('default'))
})

gulp.task('scripts', ['templates', 'jshint'], function() {
  // Single entry point to browserify
  var s = gulp.src('js/main.js')
      .pipe(browserify({
        insertGlobals : true,
        debug : false, //!gulp.env.production
        // transform: ['hbsfy'],
        shim : {
          //TODO 'handlebars': 'templates/helpers/handlebarsWithHelpers', //this one has polis custom template helpers
          handlebars: {
            path : 'bower_components/handlebars/handlebars.runtime.js', //original handlebars
            exports: 'Handlebars',
          },
          originalbackbone: {
            path: 'bower_components/backbone/backbone', // backbone before modifications
            depends: { jquery: '$', underscore: '_' },
            exports: 'Backbone',
          },
          backbone: {
            path: 'js/net/backbonePolis', // polis-specific backbone modifications
            depends: { originalbackbone: "Backbone" },
            exports: "Backbone",
          },
          underscore: {
            path: 'bower_components/underscore/underscore',
            exports: '_',
          },
          thorax: {
            path: 'bower_components/thorax/thorax',
            depends: { handlebars: 'Handlebars', backbone: 'Backbone' },
            exports: 'Thorax',
          },
          bootstrap_alert: {  //all bootstrap files need to be added to the dependency array of js/main.js
            path: 'bower_components/bootstrap/js/alert',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_tab: {
            path : 'bower_components/bootstrap/js/tab',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_popover: {
            path: 'bower_components/bootstrap/js/popover',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_collapse: {
            path: 'bower_components/bootstrap/js/collapse',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_dropdown: {
            path: 'bower_components/bootstrap/js/dropdown',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_affix: {
            path: 'bower_components/bootstrap/js/affix',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          d3tooltips: {
            path: 'bower_components/d3-tip/index',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_tooltip: {
            path: 'bower_components/bootstrap/js/tooltip',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_button: {
            path: 'bower_components/bootstrap/js/button',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          bootstrap_transition: {
            path: 'bower_components/bootstrap/js/transition',
            depends: { jquery: "jQuery" },
            exports: null,
          },
          VisView: {
            path: 'js/lib/VisView',
            depends: { d3tooltips: 'foo' }, // added to d3 object as d3.tip
            exports: 'VisView',
          },
        },
      }))
      .pipe(concat('polis.js'))
  // TODO      .pipe(header("copyright Polis... (except that libs are mixed in)
      if (!devMode) {
        s = s
          .pipe(uglify())
          .pipe(gzip())
      }
      s = s.pipe(rename('polis.js'));
      return s.pipe(gulp.dest(destRoot + "/js"));
});

// for big infrequently changing scripts that we don't want to concatenate
// on each dev build.
gulp.task("scriptsOther", function() {

  var files = [];
  if (devMode) {
    files.push('bower_components/d3/d3.js');
  } else {
    files.push('bower_components/d3/d3.min.js');
  }
  var s = gulp.src(files);
  if (!devMode) {
    s = s
      .pipe(uglify())
      .pipe(gzip())
      .pipe(rename(function (path) {
        // path.dirname += "/ciao";
        // path.basename += "-goodbye";
        // path.extname = ".md"

        // remove .gz extension
        var ext = path.extname;
        path.extname = ext.substr(0, ext.length- ".gz".length);
      }));
  }
  return s.pipe(gulp.dest(destRoot + "/js"));
});

gulp.task("configureForProduction", function() {
  destRoot = "./dist";
  devMode = false;
});

gulp.task('common', [
  "scriptsOther",
  "scripts",
  "less",
  "fontawesome",
  "index",
  ], function() {
    // if (devMode) {
    //   connect.reload();
    // }
});

gulp.task('dev', [
  "common",
  ], function(){
});

gulp.task('dist', [
  "configureForProduction",
  "common",
  ], function(){
});

gulp.task("watchForDev", [
  "connect",
  ], function() {
    gulp.watch([
      "js/**",
      "!js/tmpl/**", // These are genterated, so don't watch!
      "css/**",
      "*.html",
    ], function(e) {
      console.log("watch saw: " + e.path + " " + e.type);
      gulp.run("dev");
    });
});

gulp.task('default', [
  "dev",
  "watchForDev",
  ], function() {
});

<|endoftext|>


<commit_before><commit_msg>document push<commit_after><|endoftext|>


<commit_before><commit_msg>Firebase-Twitter auth implementation: minor fix<commit_after><|endoftext|>


<commit_before><commit_msg>starting<commit_after><|endoftext|>


<commit_before>var Dashboard = React.createClass({
    getInitialState: function() {
        return {page: "dashboard", query: "", error: null, selected: null, loading: false, willUpdate: true,
                animateOnUpdate: false, sortRowsLabel: null, sortRowsAscending: null}
    },
    /*
     * For large dashboards, maintaining a websocket/socket.io connection for each row is expensive. Instead,
     * we use the shouldComponentUpdate method to do an intelligent update. If a query has not yet been
     * submitted, we return the default value of true. If a query *has* been submitted, then at the bottom of
     * the submitQuery method, a timer is executed that sets the value of shouldComponentUpdate to true
     * every second, so the entire component will only be updated then.
     */
    shouldComponentUpdate: function(nextState, nextProps) {
        if (this.state.query == null) { return true; }
        if (this.state.willUpdate) {
            this.setState({willUpdate: false});
            return true;
        }
        return false;
    },
    /*
     * Here we use React's immutable updates to give it some hints on how to update the full DOM
     */
    updateFromRepublish: function(newdata) {
        var self = this;
        _.each(_.values(newdata), function(obj) {
            if (obj.Readings == null) { return; }
            if (self.state.data[obj.uuid] == null) { return; }
            self.setState(React.addons.update(self.state, {
                data: makeProp(obj.uuid, {
                    latestValue: {$set : obj.Readings[obj.Readings.length-1][1] },
                    latestTime:  {$set : moment.unix(obj.Readings[obj.Readings.length-1][0]) }
                })
            }));
        });
    },
    componentDidMount: function() {
        this.submitQuery({});
    },
    /*
     * When a query is submitted we submit it to the archiver, and render any error that we receive.
     * If there is no error, then we set our internal state to a mapping of UUID -> timeseries object.
     * Each timeseries object contains the top level keys Metadata, Properties, Path, uuid and Readings
     */
    submitQuery: function(e) {
        // fetch metadata query
        var query = this.refs.queryInput.getValue();
        this.setState({query: query, error: null, loading: true});
        var self = this;
        run_query(query,
            function(data) {
                var newstate = {};
                _.each(data, function(obj) {
                    newstate[obj.uuid] = obj;
                });
                self.setState({data: newstate, loading: false});
            },
            function(xhr,status,err) {
                self.setState({error: xhr.responseText, loading:false});
                console.error(xhr.responseText);
            }
        );

        // fetch most recent data point query
        run_dataquery(query,
            function(data) {
                var newstate = self.state.data;
                _.each(data, function(obj) {
                    if (obj.Readings == null) { return; }
                    newstate[obj.uuid].latestValue = obj.Readings[obj.Readings.length-1][1];
                    newstate[obj.uuid].latestTime = moment.unix(obj.Readings[obj.Readings.length-1][0]);
                });
                self.setState({data: newstate, loading: false});
            },
            function(xhr,status,err) {
                self.setState({error: xhr.responseText, loading:false});
                console.error(xhr.responseText);
            }
        );

        // set up realtime data updates
        console.log("subscribe", query);
        var socket = io.connect();
        socket.emit('new subscribe', query);
        socket.on(query, function(data) {
            if (self.isMounted()) {
                self.updateFromRepublish(data);
            }
        });
        this.setState({socket: socket});
        setInterval(function () {
            self.setState({willUpdate: true});
        }, 250);
    },
    showDetail: function(point) {
        this.setState({selected: point});
    },
    toggleAnimateOnUpdate: function(e) {
        this.setState({animateOnUpdate: e.target.checked});
    },
    sortRows: function(label) {
        console.log("sort by", label);
        this.setState({sortRowsLabel: label});
        if (this.state.sortRowsAscending == null) {
            this.setState({sortRowsAscending: false});
        } else if (!this.state.sortRowsAscending) {
            this.setState({sortRowsAscending: true});
        } else {
            this.setState({sortRowsAscending: null});
        }
    },
    render: function() {
        var self = this;

        // render error if one occurs during any query
        var error = ();
        if (this.state.error != null) {
            error = (
                <Panel header="Query Error" bsStyle="danger">
                    {this.state.error}
                </Panel>
            );
        }

        // set up the point detail pane on the right
        var detail = ();
        if (this.state.selected != null) {
           detail =  <PointDetail {...this.state.selected} />
        }

        // create the rows resulting from the points
        // thresholds is built off of the global threshold/color values
        var rows = _.map(this.state.data, function(point) {
            return (
                <PointRow key={point.uuid} thresholds={_.sortBy(this.props.valueLink.value, function(o) { return -o.time})} onClick={this.showDetail.bind(this, point)} {...point} />
            )
        }, this);

        if (this.state.sortRowsLabel != null) {
            rows = _.sortBy(rows, function(r) {
                switch (self.state.sortRowsLabel) {
                case "Path":
                    return r.props.Path == null ? -Number.MIN_VALUE : r.props.Path
                case "Value":
                    return r.props.latestValue == null ? -Number.MIN_VALUE : r.props.latestValue
                case "Time":
                    return r.props.latestTime == null ? -Number.MIN_VALUE : r.props.latestTime
                }
            });
            if (!this.state.sortRowsAscending) {
                rows.reverse();
            }
        }

       //

       //

       //        <Input type='checkbox' label='Flash on Update' ref="animateOnUpdate" onChange={this.toggleAnimateOnUpdate} />
       //

       //

        return (

                        <Input
                            type='text'
                            placeholder="where clause"
                            ref="queryInput"
                            hasFeedback
                        />

                        <Button onClick={this.submitQuery} disabled={this.state.loading} bsStyle='success'>
                            {this.state.loading ? "Loading..." : "Query"}
                        </Button>

                {error}

                        <ListGroup>
                            <ListGroupItem>

                                    Path

                                    Latest Value

                                    Latest Time

                            </ListGroupItem>
                            {rows}
                        </ListGroup>

                        {detail}

        );
    }
});

var PointRow = React.createClass({
    getInitialState: function() {
        return {loading: false}
    },
    goToPlot: function() {
        console.log("get permalink for", this.props.uuid);
        var self = this;
        this.setState({loading: true});
        get_permalink(this.props.uuid,
            function(url) {
                console.log(url);
                self.setState({loading: false});
                window.open(url, '_blank');
            },
            function(xhr) {
            }
        );
    },
    render: function() {
        //console.log("props", this.props);
        var color = 'danger';
        if (this.props.latestTime != null) {
            var difference = moment().diff(this.props.latestTime, 'seconds');
            _.each(this.props.thresholds, function(t) {
                if (difference < t.time) {
                    color = t.color;
                }
            });
        }
        return (
        <ListGroupItem href="#" onClick={this.props.onClick} bsStyle={color}>

                        {this.props.Path}

                        {this.props.latestValue}

                        {this.props.latestTime == null ? null : this.props.latestTime.format("dddd, MMMM Do YYYY, h:mm:ss a")}

                        {this.props.latestTime == null ? null : this.props.latestTime.from(moment()) }

                        <Button onClick={this.goToPlot}
                                bsStyle="info"
                                disabled={this.state.loading}>
                            {this.state.loading ? "Fetching" : "Plot"}
                        </Button>

        </ListGroupItem>
        );
    }
});

var PointDetail = React.createClass({
    render: function() {
        return (

Detail

{JSON.stringify(this.props, null, 2) }

        );
    }
});
<commit_msg>more edge case<commit_after>var Dashboard = React.createClass({
    getInitialState: function() {
        return {page: "dashboard", query: "", error: null, selected: null, loading: false, willUpdate: true,
                animateOnUpdate: false, sortRowsLabel: null, sortRowsAscending: null}
    },
    /*
     * For large dashboards, maintaining a websocket/socket.io connection for each row is expensive. Instead,
     * we use the shouldComponentUpdate method to do an intelligent update. If a query has not yet been
     * submitted, we return the default value of true. If a query *has* been submitted, then at the bottom of
     * the submitQuery method, a timer is executed that sets the value of shouldComponentUpdate to true
     * every second, so the entire component will only be updated then.
     */
    shouldComponentUpdate: function(nextState, nextProps) {
        if (this.state.query == null) { return true; }
        if (this.state.willUpdate) {
            this.setState({willUpdate: false});
            return true;
        }
        return false;
    },
    /*
     * Here we use React's immutable updates to give it some hints on how to update the full DOM
     */
    updateFromRepublish: function(newdata) {
        var self = this;
        _.each(_.values(newdata), function(obj) {
            if (obj.Readings == null) { return; }
            if (self.state.data[obj.uuid] == null) { return; }
            self.setState(React.addons.update(self.state, {
                data: makeProp(obj.uuid, {
                    latestValue: {$set : obj.Readings[obj.Readings.length-1][1] },
                    latestTime:  {$set : moment.unix(obj.Readings[obj.Readings.length-1][0]) }
                })
            }));
        });
    },
    componentDidMount: function() {
        this.submitQuery({});
    },
    /*
     * When a query is submitted we submit it to the archiver, and render any error that we receive.
     * If there is no error, then we set our internal state to a mapping of UUID -> timeseries object.
     * Each timeseries object contains the top level keys Metadata, Properties, Path, uuid and Readings
     */
    submitQuery: function(e) {
        // fetch metadata query
        var query = this.refs.queryInput.getValue();
        this.setState({query: query, error: null, loading: true});
        var self = this;
        run_query(query,
            function(data) {
                var newstate = {};
                _.each(data, function(obj) {
                    newstate[obj.uuid] = obj;
                });
                self.setState({data: newstate, loading: false});
            },
            function(xhr,status,err) {
                self.setState({error: xhr.responseText, loading:false});
                console.error(xhr.responseText);
            }
        );

        // fetch most recent data point query
        run_dataquery(query,
            function(data) {
                var newstate = self.state.data;
                _.each(data, function(obj) {
                    if (obj.Readings == null) { return; }
                    if (newstate[obj.uuid] == null) { return; }
                    newstate[obj.uuid].latestValue = obj.Readings[obj.Readings.length-1][1];
                    newstate[obj.uuid].latestTime = moment.unix(obj.Readings[obj.Readings.length-1][0]);
                });
                self.setState({data: newstate, loading: false});
            },
            function(xhr,status,err) {
                self.setState({error: xhr.responseText, loading:false});
                console.error(xhr.responseText);
            }
        );

        // set up realtime data updates
        console.log("subscribe", query);
        var socket = io.connect();
        socket.emit('new subscribe', query);
        socket.on(query, function(data) {
            if (self.isMounted()) {
                self.updateFromRepublish(data);
            }
        });
        this.setState({socket: socket});
        setInterval(function () {
            self.setState({willUpdate: true});
        }, 250);
    },
    showDetail: function(point) {
        this.setState({selected: point});
    },
    toggleAnimateOnUpdate: function(e) {
        this.setState({animateOnUpdate: e.target.checked});
    },
    sortRows: function(label) {
        console.log("sort by", label);
        this.setState({sortRowsLabel: label});
        if (this.state.sortRowsAscending == null) {
            this.setState({sortRowsAscending: false});
        } else if (!this.state.sortRowsAscending) {
            this.setState({sortRowsAscending: true});
        } else {
            this.setState({sortRowsAscending: null});
        }
    },
    render: function() {
        var self = this;

        // render error if one occurs during any query
        var error = ();
        if (this.state.error != null) {
            error = (
                <Panel header="Query Error" bsStyle="danger">
                    {this.state.error}
                </Panel>
            );
        }

        // set up the point detail pane on the right
        var detail = ();
        if (this.state.selected != null) {
           detail =  <PointDetail {...this.state.selected} />
        }

        // create the rows resulting from the points
        // thresholds is built off of the global threshold/color values
        var rows = _.map(this.state.data, function(point) {
            return (
                <PointRow key={point.uuid} thresholds={_.sortBy(this.props.valueLink.value, function(o) { return -o.time})} onClick={this.showDetail.bind(this, point)} {...point} />
            )
        }, this);

        if (this.state.sortRowsLabel != null) {
            rows = _.sortBy(rows, function(r) {
                switch (self.state.sortRowsLabel) {
                case "Path":
                    return r.props.Path == null ? -Number.MIN_VALUE : r.props.Path
                case "Value":
                    return r.props.latestValue == null ? -Number.MIN_VALUE : r.props.latestValue
                case "Time":
                    return r.props.latestTime == null ? -Number.MIN_VALUE : r.props.latestTime
                }
            });
            if (!this.state.sortRowsAscending) {
                rows.reverse();
            }
        }

       //

       //

       //        <Input type='checkbox' label='Flash on Update' ref="animateOnUpdate" onChange={this.toggleAnimateOnUpdate} />
       //

       //

        return (

                        <Input
                            type='text'
                            placeholder="where clause"
                            ref="queryInput"
                            hasFeedback
                        />

                        <Button onClick={this.submitQuery} disabled={this.state.loading} bsStyle='success'>
                            {this.state.loading ? "Loading..." : "Query"}
                        </Button>

                {error}

                        <ListGroup>
                            <ListGroupItem>

                                    Path

                                    Latest Value

                                    Latest Time

                            </ListGroupItem>
                            {rows}
                        </ListGroup>

                        {detail}

        );
    }
});

var PointRow = React.createClass({
    getInitialState: function() {
        return {loading: false}
    },
    goToPlot: function() {
        console.log("get permalink for", this.props.uuid);
        var self = this;
        this.setState({loading: true});
        get_permalink(this.props.uuid,
            function(url) {
                console.log(url);
                self.setState({loading: false});
                window.open(url, '_blank');
            },
            function(xhr) {
            }
        );
    },
    render: function() {
        //console.log("props", this.props);
        var color = 'danger';
        if (this.props.latestTime != null) {
            var difference = moment().diff(this.props.latestTime, 'seconds');
            _.each(this.props.thresholds, function(t) {
                if (difference < t.time) {
                    color = t.color;
                }
            });
        }
        return (
        <ListGroupItem href="#" onClick={this.props.onClick} bsStyle={color}>

                        {this.props.Path}

                        {this.props.latestValue}

                        {this.props.latestTime == null ? null : this.props.latestTime.format("dddd, MMMM Do YYYY, h:mm:ss a")}

                        {this.props.latestTime == null ? null : this.props.latestTime.from(moment()) }

                        <Button onClick={this.goToPlot}
                                bsStyle="info"
                                disabled={this.state.loading}>
                            {this.state.loading ? "Fetching" : "Plot"}
                        </Button>

        </ListGroupItem>
        );
    }
});

var PointDetail = React.createClass({
    render: function() {
        return (

Detail

{JSON.stringify(this.props, null, 2) }

        );
    }
});
<|endoftext|>


<commit_before><commit_msg>fix formatting<commit_after><|endoftext|>


<commit_before>// 引入gulp
var gulp = require('gulp'),

// 引入组件
    pkg = require('./package.json'), // 读取package.json文件信息
    header = require('gulp-header'),
    banner = ['/*!',
              '* 上网设备检测及处理',
              '* 版本：v<%= pkg.version %>',
              '* 原创：吴育民',
              '* 网站：www.089858.com',
              '* 使用说明：https://github.com/wuyumin/whatdevice',
              '*/',
              ''].join('\n'),
    rename = require('gulp-rename'),
    uglify = require('gulp-uglify');

// 定义一个scripts任务(可以自定义任务名称)
gulp.task('scripts', function() {
    return gulp.src('whatdevice.js')
           .pipe(uglify())
           .pipe(header(banner, { pkg : pkg } ))
           .pipe(rename('whatdevice.min.js'))
           .pipe(gulp.dest('./'));
});

// 定义默认任务
gulp.task('default',['scripts']);

// gulp.task(name[, deps], fn) 定义任务  name：任务名称 deps：依赖任务名称 fn：回调函数
// gulp.src(globs[, options]) 执行任务处理的文件  globs：处理的文件路径(字符串或者字符串数组)
// gulp.dest(path[, options]) 处理完后文件生成路径<commit_msg>优化gulpfile<commit_after>// 引入gulp
var gulp = require('gulp'),

// 引入组件
    pkg = require('./package.json'), // 读取package.json文件信息
    header = require('gulp-header'),
    banner = ['/*!',
              '* 上网设备检测及处理',
              '* 版本：v<%= pkg.version %>',
              '* 原创：吴育民',
              '* 网站：www.089858.com',
              '* 使用说明：https://github.com/wuyumin/whatdevice',
              '*/',
              ''].join('\n'),
    rename = require('gulp-rename'),
    uglify = require('gulp-uglify');

// 定义一个scripts任务(可以自定义任务名称)
gulp.task('scripts', function() {
    console.log('压缩JS...');
    return gulp.src('whatdevice.js')
           .pipe(uglify())
           .pipe(header(banner, { pkg : pkg } ))
           .pipe(rename({suffix:'.min'}))
           .pipe(gulp.dest('./'));
});

// 定义默认任务
gulp.task('default',['scripts']);

// gulp.task(name[, deps], fn) 定义任务  name：任务名称 deps：依赖任务名称 fn：回调函数
// gulp.src(globs[, options]) 执行任务处理的文件  globs：处理的文件路径(字符串或者字符串数组)
// gulp.dest(path[, options]) 处理完后文件生成路径<|endoftext|>


<commit_before><commit_msg>fix less path<commit_after><|endoftext|>


<commit_before><commit_msg>Cleanup duplicated content<commit_after><|endoftext|>


<commit_before><commit_msg>remove db credentials<commit_after><|endoftext|>


<commit_before><commit_msg>Min: pug watch > remove warning<commit_after><|endoftext|>


<commit_before>// include gulp
var gulp = require('gulp');

// include plug-ins
var jshint = require('gulp-jshint');
var gulpif = require('gulp-if');
var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
 var gutil = require('gulp-util');
// JS hint task
gulp.task('jshint', function() {
  gulp.src('./lib/*/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('default'));
});

//
gulp.task('build', function(){
  gulp.src(['./lib/helpers/*'])
    .pipe(gulpif(/[.]coffee$/, coffee())).on('error', gutil.log)
    .pipe(concat('app.js'))
    .pipe(gulp.dest('./dest'));
});<commit_msg>Add the gulpfile<commit_after>// include gulp
var gulp = require('gulp');

// include plug-ins
var jshint = require('gulp-jshint');
var gulpif = require('gulp-if');
var coffee = require('gulp-coffee');
var concat = require('gulp-concat');
var gutil = require('gulp-util');
var stylish = require('jshint-stylish');
var coffeelint = require('gulp-coffeelint');

// JS hint task
gulp.task('jshint', function() {
  //Js linting.
  gulp.src('./lib/*/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter(stylish));
  //Coffee linting
  gulp.src('./lib/*/*.coffee')
        .pipe(coffeelint())
        .pipe(coffeelint.reporter());
});

//Build all the javascripts file.
gulp.task('build', function(){
  //Build the js file for the browser.
  gulp.src(['./lib/helpers/*'])
    .pipe(gulpif(/[.]coffee$/, coffee())).on('error', gutil.log)
    .pipe(concat('app.js'))
    .pipe(gulp.dest('./dist/browser/'));
  // Build the node sources.
  gulp.src(['./lib/helpers/*'])
    .pipe(gulp.dest('./dist/node/helpers/'));
});<|endoftext|>