Skip to content
This repository was archived by the owner on May 2, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions bin/closure-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var parser = require('nomnom');

var deps = require('../lib/deps');
var build = require('../lib/build');
var serve = require('../lib/serve');

parser.options({
loglevel: {
Expand Down Expand Up @@ -82,6 +83,22 @@ parser.command('build')
});
}).help('Build with Closure Compiler');

parser.command('serve')
.option('config', {
position: 1,
required: true,
help: 'Path to JSON config file'
})
.callback(function(opts) {
var configFile = opts.config;
serve(configFile, function(err) {
if (err) {
log.error('closure-util', err.message);
process.exit(1);
}
});
}).help('Start the development server');

var options = parser.parse();

/**
Expand Down
49 changes: 39 additions & 10 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ var async = require('async');
var fse = require('fs-extra');
var log = require('npmlog');

var buildconfig = require('./buildconfig');
var configfile = require('./configfile');
var closure = require('./index');
var config = require('./config');

Expand All @@ -20,9 +20,37 @@ log.level = config.get('log_level');
* @param {function(Error, Object)} callback Called with the build
* configuration object or any error.
*/
function _readConfig(configFile, callback) {
function readConfig(configFile, callback) {
log.info('closure-util', 'Reading build config');
buildconfig.readConfig(configFile, callback);
configfile.readConfig(configFile, callback);
}


/**
* Assert that a provided config object is valid.
* @param {Object} config Build configuration object.
* @param {function(Error, Object)} callback Called with the configuration
* object or any error.
*/
function assertValidConfig(config, callback) {
process.nextTick(function() {
if (!config.lib) {
config.lib = config.src;
}
if (!Array.isArray(config.lib)) {
callback(new Error('Config "lib" must be an array'));
return;
}
if (typeof config.compile !== 'object') {
callback(new Error('Config "compile" must be an object'));
return;
}
if (config.jvm && !Array.isArray(config.jvm)) {
callback(new Error('Config "jvm" must be an array'));
return;
}
callback(null, config);
});
}


Expand All @@ -32,7 +60,7 @@ function _readConfig(configFile, callback) {
* @param {function(Error, Array.<string>)} callback Called with a
* list of paths or any error.
*/
function _getDependencies(config, callback) {
function getDependencies(config, callback) {
log.info('closure-util', 'Getting Closure dependencies');
var options = {
lib: config.lib || config.src,
Expand All @@ -55,7 +83,7 @@ function _getDependencies(config, callback) {
* @param {function(Error, string)} callback Called with the compiled output
* or any error.
*/
function _compile(config, paths, callback) {
function compile(config, paths, callback) {
log.info('closure-util', 'Compiling ' + paths.length + ' sources');
var options = {
compile: config.compile,
Expand All @@ -73,7 +101,7 @@ function _compile(config, paths, callback) {
* @param {string} code The code to write to the output file.
* @param {function(Error)} callback Called with the error if any.
*/
function _writeOutput(outputFile, code, callback) {
function writeOutput(outputFile, code, callback) {
log.info('closure-util', 'Writing compiled code to ' + outputFile);
fse.outputFile(outputFile, code, callback);
}
Expand All @@ -90,10 +118,11 @@ function _writeOutput(outputFile, code, callback) {
*/
module.exports = function(configFile, outputFile, callback) {
async.waterfall([
_readConfig.bind(null, configFile),
_getDependencies,
_compile,
_writeOutput.bind(null, outputFile)
readConfig.bind(null, configFile),
assertValidConfig,
getDependencies,
compile,
writeOutput.bind(null, outputFile)
], function(err) {
if (err) {
callback(err);
Expand Down
26 changes: 0 additions & 26 deletions lib/buildconfig.js → lib/configfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,6 @@ var config = require('./config');
log.level = config.get('log_level');


/**
* Assert that a provided config object is valid.
* @param {Object} config Build configuration object.
*/
function assertValidConfig(config) {
if (!config.lib) {
config.lib = config.src;
}
if (!Array.isArray(config.lib)) {
throw new Error('Config "lib" must be an array');
}
if (typeof config.compile !== 'object') {
throw new Error('Config "compile" must be an object');
}
if (config.jvm && !Array.isArray(config.jvm)) {
throw new Error('Config "jvm" must be an array');
}
}


/**
* Read the build configuration file.
* @param {string} configPath Path to config file.
Expand All @@ -52,12 +32,6 @@ exports.readConfig = function(configPath, callback) {
err2.message));
return;
}
try {
assertValidConfig(config);
} catch (err3) {
callback(err3);
return;
}
callback(null, config);
});
};
113 changes: 113 additions & 0 deletions lib/serve.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
var async = require('async');
var log = require('npmlog');

var config = require('./config');
var configfile = require('./configfile');
var manager = require('./manager');
var server = require('./server');


/**
* Configurable log level.
* @type {string}
*/
log.level = config.get('log_level');


/**
* Read the build configuration file.
* @param {string} configFile Config file.
* @param {function(Error, Object)} callback Called with the build
* configuration object or any error.
*/
function readConfig(configFile, callback) {
log.info('closure-util', 'Reading build config');
configfile.readConfig(configFile, callback);
}


/**
* Assert that a provided config object is valid.
* @param {Object} config Build configuration object.
* @param {function(Error, Object)} callback Called with the configuration
* object or any error.
*/
function assertValidConfig(config, callback) {
process.nextTick(function() {
if (!config.lib) {
config.lib = config.src;
}
if (!Array.isArray(config.lib)) {
callback(new Error('Config "lib" must be an array'));
return;
}
callback(null, config);
});
}


/**
* Create a development server.
* @param {Object} config The configuration object.
* @param {function(Error, closure.Server)} callback Callback.
*/
function createServer(config, callback) {
var srv;
var mgr = new manager.Manager({
lib: config.lib
});
mgr.on('error', function(err) {
if (server) {
log.error('serve', err.message);
} else {
callback(err);
}
});
mgr.on('ready', function() {
srv = new server.Server({
manager: mgr
});
callback(null, config, srv);
});
}


/**
* @param {Object} config The configuration object.
* @param {closure.Server} server The server.
* @param {function(Error)} callback Callback with an error, if any.
*/
function listen(config, server, callback) {
var port = config.serve && config.serve.port ?
config.serve.port : 3000;
server.listen(port, function() {
log.info('closure-util', 'Listening on http://localhost:' +
port + '/ (Ctrl+C to stop)');
});
server.on('error', function(err) {
log.error('serve', 'Server failed to start: ' + err.message);
callback(err);
});
callback(null);
}


/**
* @param {string} configFile Config file path.
* @param {function(Error)} callback Called when the compilation is
* finished or when any error occured.
*/
module.exports = function(configFile, callback) {
async.waterfall([
readConfig.bind(null, configFile),
assertValidConfig,
createServer,
listen
], function(err) {
if (err) {
callback(err);
} else {
callback(null);
}
});
};
13 changes: 10 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,28 @@ Available configuration options (see `default-config.json` for default values):

## CLI

The `closure-util` command line utility provides commands for updating (or installing) specific versions of the Closure Compiler and Closure Library for use with your project, and a command for building your project using the Closure Compiler.
The `closure-util` command line utility provides `update` commands for updating (or installing) specific versions of the Closure Compiler and Closure Library for use with your project, a `build` command for building your project using the Closure Compiler, and a `serve` command for starting a development server for your project.

* `closure-util update` - Update both the Compiler and Library.
* `closure-util update-compiler` - Update the Compiler.
* `closure-util update-library` - Update the Library.
* `closure-util build` - Build a JavaScript application.
* `closure-util serve` - Start a development server.
* `closure-util --help` - Display command usage and options.

See the [configuration](#configuration) section above for information on how to configure URLs for specific versions of the Compiler or Library. The `closure-util` utility will look for this configuration when executing one of the `update`, `update-compiler` or `update-library` commands.

This is how the `build` command is used:

closure-util build build.json app.min.js
closure-util build config.json app.min.js

where `build.json` is a build config file and `app.min.js` in the output file including the compiled code. As an example for a build config file see the [`build-config.json`](test/fixtures/build-config.json) file used in the `closure-util` tests.
where `config.json` is a build config file and `app.min.js` in the output file including the compiled code. As an example for a build config file see the [`config.json`](test/fixtures/config.json) file used in the `closure-util` tests. The config file should include a `"lib"` and a `"compile"` sections.

This is how the `serve` command is used:

closure-util serve config.json

where `config.json` is a config file. You can look at the [`config.json`](test/fixtures/config.json) again. For the `serve` command the config file should include a `"lib"` and a `"serve"` sections.

## Development

Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/build-config.json → test/fixtures/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,8 @@
"warning_level": "VERBOSE",
"output_wrapper": "(function(){%output%})();",
"use_types_for_optimization": true
},
"serve": {
"port": 3001
}
}
2 changes: 1 addition & 1 deletion test/spec/build.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('build', function() {
// this test runs the compiler, increase the timeout value
this.timeout(30000);
var outputFile = temp.path({suffix: '.js'});
var configFile = path.join(fixtures, 'build-config.json');
var configFile = path.join(fixtures, 'config.json');
build(configFile, outputFile, function(err) {
assert.isNull(err);
fs.exists(outputFile, function(exists) {
Expand Down