UNPKG

syrup

Version:

A collection of common UI utilities and libraries leveraged by AI2.

292 lines (269 loc) 11.2 kB
'use strict'; var cb = require('gulp-cache-breaker'); var fs = require('fs'); var autoprefixer = require('gulp-autoprefixer'); var browserify = require('browserify'); var uglify = require('gulp-uglify'); var less = require('gulp-less'); var del = require('del'); var gutil = require('gulp-util'); var gif = require('gulp-if'); var jshint = require('gulp-jshint'); var sourcemaps = require('gulp-sourcemaps'); var buffer = require('vinyl-buffer'); var source = require('vinyl-source-stream'); var karma = require('karma'); var pesto = require('pesto'); var stylish = require('jshint-stylish'); var util = require('util'); var path = require('path'); var replace = require('gulp-replace'); var stringify = require('stringify'); var server = require('../server'); var merge = require('../merge'); var defaultPaths = require('./default-paths'); module.exports = { /** * Registers default gulp tasks. * * @param {object} gulp The gulp library. * @param {object} options Optional object definining configuration * parameters. * @param {object} options.compressJs If true javascript will be minified. Defaults * to true. * @param {object} options.sourceMaps Enables javascript source maps. Defaults to * true. * @param {object} options.compressCss If true styles will be compressed. Defaults to * true. * @param {string} options.jsOut Sets the name of the javascript file produced * by the javascript build step. Defaults to * "app.js". * @param {object} configParameters Optional map of configuration keys. If set each * key is searched for in the html contents of the * application and replaced with the corresponding * value. * @param {object} paths Optional object defining paths relevant to the * project. If not specified the defaults are used. * @param {string} paths.base The base directory of your project where the * gulpfile itself lives. Defaults to * process.cwd(). * @param {string} paths.src Path to the application's source files. * @param {string} paths.html Path to the project's HTML files. * @param {string} paths.jshint Path to javascript files which should be linted * using jshint. * @param {string} paths.js Path to javascript files to be bundled using * browserify. * @param {string} paths.less Path to the project's less files. * @param {string} paths.assets Path to the project's assets. * @param {string} paths.fonts Path to the project's fonts. * @param {string} paths.build Path to the project's build directory where the * final output should be placed. * @param {string} paths.tmp Path where temporary files should be put. * @param {string} paths.watch Path to the files which should be watched for * changes while the griddle serve is running and * trigger a rebuild as changes occur. * @param {string} paths.unitTests Path to the project's unit tests. These files * are browserified to paths.tmp prior to execution * @param {string} paths.unitTestConfig Path to the project's karma configuration file. * @param {string} paths.integrationTestConfig Path to the project's pesto / protractor * configuration file. * @returns {undefined} */ init: function(gulp, options, configParameters, paths) { // Produce paths by merging any user specified paths with the defaults. paths = merge(defaultPaths, paths); if(options.silent === true) { gutil.log = gutil.noop; } if(!gulp || typeof gulp.task !== 'function') { throw 'Invalid gulp instance'; } if(!paths || typeof paths !== 'object') { throw 'Invalid paths'; } /** * Removes all build artifacts. */ gulp.task('clean', function(cb) { gutil.log(util.format('Removing artifacts from %s', gutil.colors.magenta(paths.build))); var targets = [ paths.build ]; if(paths.tmp) { targets.push(paths.tmp); } return del(targets, { force: true }, cb); }); /** * Compiles less files to css. */ gulp.task('less', function() { gutil.log(util.format('Compiling %s to %s', gutil.colors.magenta(paths.less), gutil.colors.magenta(paths.build))); return gulp.src(paths.less) .pipe(less({ compress: options.compressCss !== false })) .pipe(autoprefixer('last 2 versions')) .pipe(gulp.dest(paths.build)); }); /** * Lints javascript */ gulp.task('jslint', function() { gutil.log(util.format('Linting %s', gutil.colors.magenta(paths.jshint))); return gulp.src(paths.jshint) .pipe(jshint(path.resolve(__dirname, '../.jshintrc'))) .pipe(jshint.reporter(stylish)); }); /** * Bundles, compresses and produces sourcemaps for javascript. */ gulp.task('js', function() { var jsPath = path.resolve(paths.base, paths.js); gutil.log( util.format( 'Compiling %s to %s', gutil.colors.magenta(jsPath), gutil.colors.magenta(path.resolve(paths.build, options.jsOut || 'app.js')) ) ); if (fs.existsSync(jsPath)) { var bundler = browserify({ entries: [jsPath], debug: true, transform: stringify({ extensions: ['.html'], minify: true }) }); return bundler.bundle() .pipe(source(options.jsOut || 'app.js')) .pipe(buffer()) .pipe(gif(options.sourcemap !== false, sourcemaps.init({loadMaps: true}))) .pipe(gif(options.compressJs !== false, uglify())) .pipe(gif(options.sourcemap !== false, sourcemaps.write('./'))) .pipe(gulp.dest(paths.build)); } else { gutil.log( util.format( 'No js files found at %s to bundle', gutil.colors.magenta(jsPath) ) ); } }); /** * Copies static assets. */ gulp.task('assets', function() { gutil.log( util.format( 'Copying %s to %s', gutil.colors.magenta(paths.assets), gutil.colors.magenta(paths.build) ) ); return gulp.src(paths.assets, { base: paths.src }) .pipe(gulp.dest(paths.build)); }); /** * Copies all html files to the build directory. */ gulp.task('html', [ 'js', 'less', 'assets' ], function() { gutil.log(util.format('Copying %s to %s', gutil.colors.magenta(paths.html), gutil.colors.magenta(paths.build))); return gulp.src(paths.html) .pipe(cb(paths.build)) .pipe(gulp.dest(paths.build)); }); /** * Bundles all unit tests into a single file for testing. */ gulp.task('browserify-unit-tests', function() { return gulp.src(paths.unitTests, { read: false }) .pipe(browserify()) .pipe(gulp.dest(paths.tmp)); }); /** * Run project unit tests using Karma. */ gulp.task('run-unit-tests', ['browserify-unit-tests'], function(done) { karma.server.start({ // Karma needs an absolute path to the configuration file so attempt to resolve configFile: path.resolve(paths.base, paths.base, paths.unitTestConfig), singleRun: true }, done); }); /** * Run integration tests using Pesto */ gulp.task('run-integration-tests', function(done) { // We don't need to build since griddle does it for us. server.start({ base: paths.base, serve: paths.build }).then( function() { pesto(paths.integrationTestConfig).then(function(passed) { server.stop().then(function() { if(passed) { done(); } else { done(false); } }); }); } ); }); /** * Combined test task which executes both the unit and integration tests */ gulp.task('test', ['run-unit-tests', 'run-integration-tests']); /** * Task for starting a griddle + express based HTTP server. */ gulp.task('start-server', function(done) { var opts = { base: paths.base, serve: paths.build }; if(paths.watch) { opts.watch = paths.watch; } server.start(opts).then( function(event) { gutil.log('Server listening: ' + gutil.colors.magenta(event.data)); done(); }, function(e) { gutil.log(gutil.colors.red(e)); done(); } ); }); /** * Sets configuration data. */ gulp.task('set-config', ['html'], function() { if(configParameters) { gutil.log('Replacing configuration parameters in index html with those provided.'); var configKeys = Object.getOwnPropertyNames(configParameters || {}); var reConfigKeys = new RegExp('(?:' + configKeys.join('|') + ')', 'g') return gulp.src(path.resolve(paths.build, path.basename(paths.html))) .pipe(replace(reConfigKeys, function(key) { return configParameters[key] || ''; })) .pipe(gulp.dest(paths.build)); } else { gutil.log('No configuration parameters provided.'); } }); /** * Watches specific files and rebuilds only the changed component(s). */ gulp.task('watch', ['build'], function() { gulp.watch(config.paths.js, ['jslint', 'js', 'html', 'set-config']); gulp.watch(config.paths.allLess, ['less', 'html', 'set-config']); gulp.watch(config.paths.assets, ['assets', 'html', 'set-config']); gulp.watch(config.paths.html, ['html', 'set-config']); }); /** * Combined build task. This bundles up all required UI resources. */ gulp.task('build', ['assets', 'jslint', 'js', 'less', 'html', 'set-config']); /** * Default task. Gets executed when gulp is called without arguments. */ gulp.task('default', ['build']); } };