Find file
Fetching contributors…
Cannot retrieve contributors at this time
195 lines (167 sloc) 7.52 KB
/*jslint node: true, regexp: true */
'use strict';
var crypto = require('crypto'),
fs = require('fs'),
path = require('path'),
buildDir = 'www-built',
pagesDir = 'www-ghpages';
module.exports = {
//Builds the JS and CSS into one file each. If you want to do
//dynamic loading of scripts, pass -dynamic to the build, and
//require.js will be used to load scripts.
build: {
flags: {
//Does not print the build output.
'q': 'quiet',
//Uses dynamic loading via require.js instead of building
//all the modules in with almond.
'dynamic': 'dynamic'
run: function (d, v, namedArgs) {
var q = v.require('q');
(q.fcall || () {
//Remove the old dir
if (!namedArgs.dynamic) {
//Copy the directory for output.
v.copyDir('www', buildDir);
//Remove the js dir from the built area, will be
//replaced by an optimized app.js
v.rm(buildDir + '/js');
//Do the CSS optimization
return v.spawn('node', ['tools/r.js', '-o',
'out=' + buildDir + '/css/app.css'], {
useConsole: !namedArgs.quiet
return undefined;
.then(function () {
//JS go time
var optimize = namedArgs.optimize || 'uglify';
if (namedArgs.dynamic) {
//Still use require.js to load the app.js file.
return v.spawn('node', ['tools/r.js', '-o',
'dir=' + buildDir,
'optimize=' + optimize], {
useConsole: !namedArgs.quiet
} else {
//The all-in-one option.
return v.spawn('node', ['tools/r.js', '-o',
'out=' + buildDir + '/js/app.js',
'optimize=' + optimize], {
useConsole: !namedArgs.quiet
.then(function (buildOutput) {
//Remove all the CSS except for the app.css, since it
//inlines all the other ones.
v.getFilteredFileList(buildDir + '/css').forEach(function (path) {
if (!/app\.css$/.test(path)) {
//If almond is in use, it is built into app.js, so need
//to update the script tag to just load app.js instead.
if (!namedArgs.dynamic) {
var indexName = buildDir + '/index.html',
contents =,
scriptRegExp = /(<script[^>]+data-main="[^"]+"[^>]+)(src="[^"]+")([^>]*>\s*<\/script>)/;
contents = contents.replace(scriptRegExp,
function (match, pre, script, post) {
return pre + 'src="js/app.js"' + post;
v.write(indexName, contents);
return buildOutput;
.then(function (buildOutput) {
}, d.reject);
//Runs the build, and generates the appcache manifest
appcache: require('volo-appcache')({
depends: ['build'],
dir: buildDir
//Deploys the code to github pages.
ghdeploy: require('volo-ghdeploy')(buildDir, pagesDir),
//Runs less on the .less files in tools/less to generate the CSS files.
less: {
summary: 'Runs less on the .less files in tools/less to generate the CSS files.',
run: [
'node node_modules/less/bin/lessc tools/less/bootstrap.less www/css/bootstrap.css'
//Run as the result of first setting up this project via a
//"volo create" call. Gets the twitter bootstrap code, and
onCreate: {
run: function (d, v, namedArgs, appName) {
var tempName = 'tempbootstrap',
q = v.require('q'),
amdify = v.require('./commands/amdify'),
jsNameRegExp = /(\w*)\.js$/;
//First replace the name in the package.json with name from
v.write('package.json','package.json').replace(/"name": "[^"]+"/, '"name": "' + appName + '"'));
v.command('add', 'jquery/jquery', 'jquery')
.then(function () {
//Grab the twitter bootstrap and jQuery
return v.command('create', tempName, 'twbs/bootstrap');
.then(function () {
//Move the JS to the right location.
var jsFiles = v.getFilteredFileList(tempName + '/js', /\.js$/, /js[\/\\]tests[\/\\]/),
promises = [];
jsFiles.forEach(function (file) {
//Pull off the name part from bootstrap-name.js pattern.
var match = jsNameRegExp.exec(file),
if (!match) {
name = jsNameRegExp.exec(file)[1];
destName = 'www/js/lib/bootstrap/' + name + '.js';
damd = q.defer();
v.copyFile(file, destName);
//Convert the file to AMD style, [damd, v, {
depends: 'jquery'
}, destName]);
//Wait for all the amdify calls to finish.
return q.all(promises);
.then(function () {
//Copy the images over.
v.copyDir(tempName + '/img', 'www/img');
//Copy the fonts over.
v.copyDir(tempName + '/fonts', 'www/fonts');
//Copy the less files.
v.copyDir(tempName + '/less', 'tools/less');
//Compile the CSS.
return v.command('less').then(function () {
.then(d.resolve, d.reject);