Files
openlayers/tasks/build.js
2014-04-29 09:53:06 -06:00

164 lines
3.9 KiB
JavaScript

/**
* This task builds OpenLayers with the Closure Compiler.
*/
var fs = require('fs');
var path = require('path');
var async = require('async');
var closure = require('closure-util');
var fse = require('fs-extra');
var nomnom = require('nomnom');
var generateExports = require('./generate-exports');
var log = closure.log;
var root = path.join(__dirname, '..');
/**
* Assert that a provided config object is valid.
* @param {Object} config Build configuration object.
* @param {function(Error)} callback Called with an error if config is invalid.
*/
function assertValidConfig(config, callback) {
process.nextTick(function() {
if (!Array.isArray(config.exports)) {
callback(new Error('Config missing "exports" array'));
return;
}
if (typeof config.compile !== 'object') {
callback(new Error('Config missing "compile" object'));
return;
}
callback(null);
});
}
/**
* Read the build configuration file.
* @param {string} configPath Path to config file.
* @param {function(Error, Object)} callback Callback.
*/
function readConfig(configPath, callback) {
fs.readFile(configPath, function(err, data) {
if (err) {
if (err.code === 'ENOENT') {
err = new Error('Unable to find config file: ' + configPath);
}
callback(err);
return;
}
var config;
try {
config = JSON.parse(String(data));
} catch (err2) {
callback(new Error('Trouble parsing config as JSON: ' + err2.message));
return;
}
callback(null, config);
});
}
/**
* Get the list of sources sorted in dependency order.
* @param {function(Error, Array.<string>)} callback Called with a list of paths
* or any error.
*/
function getDependencies(callback) {
log.info('ol', 'Parsing dependencies');
closure.getDependencies({lib: ['src/**/*.js']}, function(err, paths) {
if (err) {
callback(err);
return;
}
paths.push(path.join(root, 'build', 'exports.js'));
callback(null, paths);
});
}
/**
* Run the compiler.
* @param {Object} options Options for Closure Compiler.
* @param {Array.<string>} paths List of paths to source files.
* @param {function(Error, string)} callback Called with the compiled output or
* any error.
*/
function build(options, paths, callback) {
log.info('ol', 'Compiling ' + paths.length + ' sources');
options.js = paths;
closure.compile(options, callback);
}
/**
* Generate a build of the library.
* @param {Object} config Build configuration object. Must have an "exports"
* array and a "compile" object with options for the compiler.
* @param {function(Error, string)} callback Called with the compiled source
* or any error.
*/
function main(config, callback) {
async.waterfall([
assertValidConfig.bind(null, config),
generateExports.bind(null, config.exports),
getDependencies,
build.bind(null, config.compile)
], callback);
}
/**
* If running this module directly, read the config file and call the main
* function.
*/
if (require.main === module) {
var options = nomnom.options({
config: {
position: 0,
required: true,
help: 'Path to JSON config file'
},
output: {
position: 1,
required: true,
help: 'Output file path'
},
loglevel: {
abbr: 'l',
choices: ['silly', 'verbose', 'info', 'warn', 'error'],
default: 'info',
help: 'Log level',
metavar: 'LEVEL'
}
}).parse();
/**
* Set the log level.
* @type {string}
*/
log.level = options.loglevel;
// read the config, run the main function, and write the output file
async.waterfall([
readConfig.bind(null, options.config),
main,
fse.outputFile.bind(fse, options.output)
], function(err) {
if (err) {
log.error(err.message);
process.exit(1);
} else {
process.exit(0);
}
});
}
/**
* Export main function.
*/
module.exports = main;