Files
xen-orchestra/gulpfile.js
2014-11-14 09:50:11 +01:00

409 lines
9.2 KiB
JavaScript

// Julien Fontanet gulpfile.js
//
// https://gist.github.com/julien-f/4af9f3865513efeff6ab
'use strict';
//====================================================================
var gulp = require('gulp');
// All plugins are loaded (on demand) by gulp-load-plugins.
var $ = require('gulp-load-plugins')();
//====================================================================
var DIST_DIR = __dirname +'/dist';
var SRC_DIR = __dirname +'/app';
// Bower directory is read from its configuration.
var BOWER_DIR = (function () {
var cfg;
try
{
cfg = JSON.parse(require('fs').readFileSync(__dirname +'/.bowerrc'));
}
catch (error)
{
cfg = {};
}
cfg.cwd || (cfg.cwd = __dirname);
cfg.directory || (cfg.directory = 'bower_components');
return cfg.cwd +'/'+ cfg.directory;
})();
var PRODUCTION = process.argv.indexOf('--production') !== -1;
// Port to use for the livereload server.
//
// It must be available and if possible unique to not conflict with other projects.
// http://www.random.org/integers/?num=1&min=1024&max=65535&col=1&base=10&format=plain&rnd=new
var LIVERELOAD_PORT = 46417;
// Port to use for the embedded web server.
//
// Set to 0 to choose a random port at each run.
var SERVER_PORT = LIVERELOAD_PORT + 1;
// Address the server should bind to.
//
// - `'localhost'` to make it accessible from this host only
// - `null` to make it accessible for the whole network
var SERVER_ADDR = 'localhost';
//--------------------------------------------------------------------
// Browserify plugin for gulp.js which uses watchify in development
// mode.
function browserify(path, opts) {
opts || (opts = {});
var bundler = require('browserify')({
basedir: SRC_DIR,
debug: !PRODUCTION,
entries: [path],
extensions: opts.extensions,
standalone: opts.standalone,
// Required by Watchify.
cache: {},
packageCache: {},
fullPaths: true,
});
if (opts.transforms)
{
[].concat(opts.transforms).forEach(function addTransform(transform) {
if (transform instanceof Array) {
bundler.transform.apply(bundler, transform);
} else {
bundler.transform(transform);
}
});
}
if (!PRODUCTION) {
bundler = require('watchify')(bundler);
}
// Append the extension if necessary.
if (!/\.js$/.test(path))
{
path += '.js';
}
// Absolute path.
path = require('path').resolve(path);
var proxy = $.plumber().pipe(new (require('stream').PassThrough)({
objectMode: true,
}));
var write;
function bundle() {
bundler.bundle(function onBundleComplete(err, buf) {
if (err) {
proxy.emit('error', err);
return;
}
write(new (require('vinyl'))({
base: opts.base,
path: path,
contents: buf,
}));
});
}
if (PRODUCTION) {
write = proxy.end.bind(proxy);
} else {
write = proxy.write.bind(proxy);
bundler.on('update', bundle);
}
bundle();
return proxy;
}
// Combine multiple streams together and can be handled as a single
// stream.
var combine = function () {
// `event-stream` is required only when necessary to maximize
// performance.
combine = require('event-stream').pipe;
return combine.apply(this, arguments);
};
// Merge multiple readable streams into a single one.
var merge = function () {
// `event-stream` is required only when necessary to maximize
// performance.
merge = require('event-stream').merge;
return merge.apply(this, arguments);
};
// Create a noop duplex stream.
var noop = function () {
var PassThrough = require('stream').PassThrough;
noop = function () {
return new PassThrough({
objectMode: true
});
};
return noop.apply(this, arguments);
};
// Similar to `gulp.src()` but the pattern is relative to `SRC_DIR`
// and files are automatically watched when not in production mode.
var src = (function () {
if (PRODUCTION)
{
return function src(pattern) {
return gulp.src(pattern, {
base: SRC_DIR,
cwd: SRC_DIR,
});
};
}
// gulp-plumber prevents streams from disconnecting when errors.
// See: https://gist.github.com/floatdrop/8269868#file-thoughts-md
return function src(pattern) {
return combine(
gulp.src(pattern, {
base: SRC_DIR,
cwd: SRC_DIR,
}),
$.watch(pattern, {
base: SRC_DIR,
cwd: SRC_DIR,
}),
$.plumber()
);
};
})();
// Similar to `gulp.dest()` but the output directory is relative to
// `DIST_DIR` and default to `./`, and files are automatically live-
// reloaded when not in production mode.
var dest = (function () {
var resolvePath = require('path').resolve;
function resolve(path) {
if (path) {
return resolvePath(DIST_DIR, path);
}
return DIST_DIR;
}
if (PRODUCTION)
{
return function dest(path) {
return gulp.dest(resolve(path));
};
}
return function dest(path) {
return combine(
gulp.dest(resolve(path)),
$.livereload(LIVERELOAD_PORT)
);
};
})();
//====================================================================
gulp.task('buildPages', function buildPages() {
return src('index.jade')
.pipe($.jade())
.pipe(PRODUCTION ? noop() : $.embedlr({ port: LIVERELOAD_PORT }))
.pipe(dest())
;
});
gulp.task('buildScripts', [
'installBowerComponents',
], function buildScripts() {
return browserify('./app', {
// Extensions (other than “.js” and “.json”) to use.
extensions: [
'.coffee',
'.jade',
],
// Name of the UMD module to generate.
//standalone: 'foo',
transforms: [
[{ global: true }, 'browserify-shim'],
// require('template.jade')
[{ global: true }, 'browserify-plain-jade'],
// require('module.coffee')
'coffeeify',
// require('module-installed-via-bower')
//'debowerify',
// require('module-exposing-AMD interface')
//'deamdify',
// require('file.{html,css}')
//'partialify',
],
})
// Annotate the code before minification (for Angular.js)
.pipe(PRODUCTION ? $.ngAnnotate({
add: true,
'single_quotes': true,
}) : noop())
.pipe(PRODUCTION ? $.uglify() : noop())
.pipe(dest())
;
});
gulp.task('buildStyles', [
'installBowerComponents',
], function buildStyles() {
return src('styles/main.scss')
.pipe($.sass({
includePaths: [
BOWER_DIR,
],
}))
.pipe($.autoprefixer([
'last 1 version',
'> 1%',
]))
.pipe(PRODUCTION ? $.csso() : noop())
.pipe(dest())
;
});
gulp.task('copyAssets', [
'installBowerComponents',
], function copyAssets() {
var imgStream;
if (PRODUCTION) {
var imgFilter = $.filter('**/*.{gif,jpg,jpeg,png,svg}');
imgStream = combine(
imgFilter,
$.imagemin({
progressive: true,
}),
imgFilter.restore()
);
} else {
imgStream = noop();
}
return src('{favicon.ico,images/**/*}')
.pipe(imgStream)
.pipe(dest())
;
});
gulp.task('installBowerComponents', function installBowerComponents(done) {
require('bower').commands.install()
.on('error', done)
.on('end', function () {
done();
})
;
});
//--------------------------------------------------------------------
gulp.task('checkPages', function () {
// TODO: Handle Jade.
return gulp.src(SRC_DIR +'/**/*.html')
.pipe($.htmlhint({
'doctype-first': false, // Incorrect for partials.
'img-alt-require': true,
}))
.pipe($.htmlhint.reporter())
;
});
gulp.task('checkScripts', function checkScripts() {
return merge(
// Disable for now due to issues with gulp-coffeelint.
//gulp.src(SRC_DIR +'/**/*.coffee')
// .pipe($.coffeelint())
// .pipe($.coffeelint.reporter()),
gulp.src(SRC_DIR +'/**/*.js')
.pipe($.jsvalidate())
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish'))
);
});
gulp.task('checkScripts', function checkScripts() {
return gulp.src(SRC_DIR +'/**/*.js')
.pipe($.jsvalidate())
.pipe($.jshint())
.pipe($.jshint.reporter('jshint-stylish'))
;
});
//--------------------------------------------------------------------
gulp.task('build', [
'buildPages',
'buildScripts',
'buildStyles',
'copyAssets',
]);
gulp.task('check', [
'checkPages',
'checkScripts',
]);
gulp.task('clean', function clean(done) {
require('rimraf')(DIST_DIR, done);
});
gulp.task('distclean', ['clean'], function distclean(done) {
require('rimraf')(BOWER_DIR, done);
});
gulp.task('test', function test() {
return gulp.src(SRC_DIR +'/**/*.spec.js')
.pipe($.mocha({
reporter: 'spec'
}))
;
});
gulp.task('server', function server(done) {
require('connect')()
.use(require('serve-static')(DIST_DIR))
.listen(SERVER_PORT, SERVER_ADDR, function serverOnListen() {
var address = this.address();
var port = address.port;
address = address.address;
// Correctly handle IPv6 addresses.
if (address.indexOf(':') !== -1) {
address = '['+ address +']';
}
console.log('Listening on http://'+ address +':'+ port);
})
.on('close', function serverOnClose() {
done();
})
;
});
//------------------------------------------------------------------------------
gulp.task('default', ['build']);