diff --git a/package.json b/package.json index 1a5019c0fb..cf4de3382e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "install": "node tasks/install.js", "postinstall": "closure-util update", "start": "node tasks/serve.js", - "test": "node tasks/test.js" + "test": "node tasks/test.js", + "debug-server": "node tasks/serve-lib.js" }, "main": "dist/ol.js", "repository": { @@ -25,7 +26,7 @@ }, "dependencies": { "async": "0.9.0", - "closure-util": "1.4.0", + "closure-util": "1.5.0", "fs-extra": "0.12.0", "glob": "5.0.3", "graceful-fs": "3.0.2", diff --git a/tasks/.jshintrc b/tasks/.jshintrc index 501497c0b4..3c2c4aa041 100644 --- a/tasks/.jshintrc +++ b/tasks/.jshintrc @@ -12,6 +12,7 @@ "globals": { "Buffer": false, "__dirname": false, + "__filename": false, "exports": true, "module": false, "process": false, diff --git a/tasks/serve-lib.js b/tasks/serve-lib.js new file mode 100644 index 0000000000..8e7d76627b --- /dev/null +++ b/tasks/serve-lib.js @@ -0,0 +1,113 @@ +/** + * This task starts a dev server that provides a script loader for the + * OpenLayers library. + */ + +var path = require('path'); +var url = require('url'); + +var closure = require('closure-util'); +var nomnom = require('nomnom'); + +var log = closure.log; +var name = path.basename(__filename, '.js'); + +/** + * Create a debug server for the OpenLayers and Closure Library sources. + * @param {function(Error, closure.Server)} callback Callback. + */ +var createServer = exports.createServer = function(callback) { + var server; + var manager = new closure.Manager({ + lib: [ + 'src/**/*.js', + 'build/ol.ext/*.js', + ] + }); + manager.on('error', function(err) { + if (server) { + log.error('serve', err.message); + } else { + callback(err); + } + }); + manager.on('ready', function() { + server = new closure.Server({ + manager: manager, + loader: '/loader.js' + }); + callback(null, server); + }); +}; + +/** + * Try listening for incoming connections on a range of ports. + * @param {number} min Minimum port to try. + * @param {number} max Maximum port to try. + * @param {http.Server} server The server. + * @param {function(Error)} callback Callback called with any error. + */ +function listen(min, max, server, callback) { + function _listen(port) { + server.once('error', function(err) { + if (err.code === 'EADDRINUSE') { + log.warn(name, 'Port %d in use, trying next one', port); + ++port; + if (port < max) { + _listen(port); + } else { + callback(new Error('Could not find an open port')); + } + } else { + callback(err); + } + }); + server.listen(port); + } + server.once('listening', function() { + callback(null); + }); + _listen(min); +} + +/** + * If running this module directly start the server. + */ +if (require.main === module) { + var options = nomnom.options({ + port: { + abbr: 'p', + default: 3000, + help: 'Port for incoming connections (will try additional ports if used)', + metavar: 'PORT' + }, + loglevel: { + abbr: 'l', + choices: ['silly', 'verbose', 'info', 'warn', 'error'], + default: 'info', + help: 'Log level', + metavar: 'LEVEL' + } + }).parse(); + + /** @type {string} */ + log.level = options.loglevel; + + log.info(name, 'Parsing dependencies.'); + createServer(function(err, server) { + if (err) { + log.error(name, 'Parsing failed'); + log.error(name, err.message); + process.exit(1); + } + listen(options.port, options.port + 4, server, function(err) { + if (err) { + log.error(name, 'Server failed to start: ' + err.message); + process.exit(1); + } + log.info(name, 'Debug server running http://localhost:' + + server.address().port + '/loader.js (Ctrl+C to stop)'); + }); + }); + +} diff --git a/tasks/test.js b/tasks/test.js index e644dea235..aecda4c744 100644 --- a/tasks/test.js +++ b/tasks/test.js @@ -31,8 +31,11 @@ function listen(min, max, server, callback) { callback(err); } }); - server.listen(port, '127.0.0.1', callback); + server.listen(port, '127.0.0.1'); } + server.once('listening', function() { + callback(null); + }); _listen(min); }