diff --git a/.gitignore b/.gitignore index 5501ffa..c3b31c6 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,6 @@ test/**/out.nex test/**/test.nex test/**/tmp test/**/node_modules +test/**/*.map src diff --git a/bin/nexe b/bin/nexe index 946daff..03c36b9 100755 --- a/bin/nexe +++ b/bin/nexe @@ -1,96 +1,109 @@ #!/usr/bin/env node var path = require('path'), - fs = require('fs'), - nexe = require('../lib'), - _log = require("../lib/log"), - cli = require('yargs'). + fs = require('fs'), + nexe = require('../lib'), + _log = require("../lib/log"), + cli = require('yargs'). usage('Usage: $0 -i [sources] -o [binary]'). options('i', { - demand: true, - alias: 'input', - desc: 'The entry javascript files', - default: process.cwd() + demand: true, + alias: 'input', + desc: 'The entry javascript files', + default: process.cwd() }). options('o', { - demand: true, - alias: 'output', - desc: 'The output binary', - default: "out.nex" + demand: true, + alias: 'output', + desc: 'The output binary', + default: "out.nex" }). options('r', { - alias: 'runtime', - default: 'latest', - description: 'The node.js runtime to use' + alias: 'runtime', + default: 'latest', + description: 'The node.js runtime to use' }). options('t', { - alias: 'temp', - default: './tmp/nexe', - description: 'The path to store node.js sources' + alias: 'temp', + default: './tmp/nexe', + description: 'The path to store node.js sources' }). options('f', { - alias: 'flags', - description: 'Don\'t parse node and v8 flags, pass through app flags', - default: false + alias: 'flags', + description: 'Don\'t parse node and v8 flags, pass through app flags', + default: false }). +options('d', { + alias: 'debug', + default: false, + description: 'generate and use source maps, large file size' +}). +options('j', { + alias: 'jsFlags', + default: false, + description: 'v8 flags for runtime' +}) options('v', { - alias: 'version', - description: 'Display version number' + alias: 'version', + description: 'Display version number' }). options('p', { - alias: 'python', - description: 'Set path of python to use.', - default: 'python' + alias: 'python', + description: 'Set path of python to use.', + default: 'python' }). options('F', { - alias: 'framework', - description: 'Set the framework to use', - default: 'nodejs' + alias: 'framework', + description: 'Set the framework to use', + default: 'nodejs' }); var argv = cli.argv; -if(argv.h || argv.help) { - cli.showHelp(); - process.exit(); +if (argv.h || argv.help) { + cli.showHelp(); + process.exit(); } else if (argv.v || argv.version) { - var pkginfo = require('../package.json'); - console.log(pkginfo.version); - process.exit(); + var pkginfo = require('../package.json'); + console.log(pkginfo.version); + process.exit(); } /** * TODO: Support network shares? **/ function toAbsolute(pt) { - if(pt.substr(0, 1) == "/") return pt; - if(pt.substr(1, 3) == ":/") return pt; // for windows "c:/" - return path.join(process.cwd(), pt); + if (pt.substr(0, 1) == "/") return pt; // for *nix "/" + if (pt.substr(0, 2) == "\\\\") return pt; // for windows "\\" + if (pt.substr(1, 3) == ":/") return pt; // for windows "c:/" + + // otheerwise... + return path.join(process.cwd(), pt); } -if(fs.lstatSync(argv.i).isDirectory()) { - opts = nexe.package(path.join(argv.i, "package.json"), argv); - nexe.compile(opts, function(error) { - if(error) { - return console.log(error.message); - } - }); +if (fs.lstatSync(argv.i).isDirectory()) { + opts = nexe.package(path.join(argv.i, "package.json"), argv); + nexe.compile(opts, function(error) { + if (error) { + return console.log(error.message); + } + }); } else { - /** - * Call the core - **/ - nexe.compile({ - input : require.resolve(toAbsolute(argv.i)), - output : toAbsolute(argv.o), - flags : argv.f, - nodeVersion : argv.r, - python : argv.python, - nodeTempDir : toAbsolute(argv.t), - framework : argv.F - }, - function(error) { - if(error) { - return console.log(error.message); - } - } - ); + /** + * Call the core + **/ + nexe.compile({ + input: require.resolve(toAbsolute(argv.i)), + output: toAbsolute(argv.o), + flags: argv.f, + nodeVersion: argv.r, + python: argv.python, + nodeTempDir: toAbsolute(argv.t), + framework: argv.F + }, + function(error) { + if (error) { + return console.log(error.message); + } + } + ); } diff --git a/lib/bundle.js b/lib/bundle.js index 3134eb7..a520b8f 100644 --- a/lib/bundle.js +++ b/lib/bundle.js @@ -23,65 +23,61 @@ * **/ -var mdeps = require("module-deps"), - path = require("path"), - spawn = require('child_process').spawn, - fs = require("fs"), - async = require("async"), - browserify = require('browserify'), - builtins = require("builtins"), - _log = require("./log"); +'use strict'; + +let exorcist = require('exorcist'), + browserify = require('browserify'), + path = require("path"), + spawn = require('child_process').spawn, + insertGlobals = require('insert-module-globals'), + fs = require("fs"), + async = require("async"), + builtins = require("builtins"), + _log = require("./log"); /** * User browserify to create a "packed" file. * - * @param {String} input - input file - * @param {String} nc - node compiler dir - * @param {Function} complete - next function to call (async) + * @param {string} input - input file + * @param {string} nc - node compiler dir + * @param {array} options - nexe options + * @param {function} complete - next function to call (async) **/ -function bundle (input, nc, complete) { - var bundlePath = path.join(nc, "lib", "nexe.js"); - var ws = fs.createWriteStream(bundlePath); - var browserifyExec; +function bundle(input, nc, options, complete) { + const bundlePath = path.join(nc, "lib", "nexe.js"); + const mapfile = options.output+'.map'; + let ws = fs.createWriteStream(bundlePath); - var browserifyLocations = [ // TODO: Do this programattically. - 'This is to ignore the 0 location.', - path.join(__dirname, '../', 'node_modules/browserify/bin/cmd.js'), - path.join(__dirname, '../../', 'node_modules/browserify/bin/cmd.js'), - path.join(__dirname, '../../../', 'node_modules/browserify/bin/cmd.js'), - path.join(__dirname, '../../../../', 'node_modules/browserify/bin/cmd.js') - ] - for(var i = 0; i !== (browserifyLocations.length-1); i++) { - if(fs.existsSync(browserifyLocations[i])) { - browserifyExec = browserifyLocations[i]; - _log('found browserify in', browserifyExec); - break; + const igv = '__filename,__dirname'; + let insertGlobalVars = {}, + wantedGlobalVars = igv.split(','); + + // parse insertGlobalVars. + Object.keys(insertGlobals.vars).forEach(function (x) { + if (wantedGlobalVars.indexOf(x) === -1) { + insertGlobalVars[x] = undefined; } - } - - var proc = spawn('node', [browserifyExec, '--node', input ]); - - proc.stdout.pipe(ws); - - proc.on('error', function(err) { - console.error(err.toString('ascii')); - _log('error', 'Failed to invoke browserify'); - process.exit(1); - }) - - proc.stderr.on('data', function(data) { - console.error(data.toString('ascii')); - if(!fs.existsSync(input)) { - _log('error', 'Your input file doesn\'t exist!'); - } - _log('error', 'Browserify failed to launch'); - process.exit(1); }); - proc.on('close', function(code) { - _log("Browserify finished"); - }) + + _log('executing browserify via API'); + let bproc = browserify([], { + debug: options.debug, + commondir: false, + builtins: false, + insertGlobalVars: insertGlobalVars, + detectGlobals: true, + browserField: false + }).add(input) + + if(options.debug) { + bproc.require(require.resolve('source-map-support')) + } + + let bprocbun = bproc.bundle() // bundle + .pipe(exorcist(mapfile, mapfile, './')) // generate source maps. + .pipe(ws) // pipe to file ws.on('error', function(err) { console.log(err); @@ -95,7 +91,7 @@ function bundle (input, nc, complete) { // write the source modified to nexe.js fs.writeFile(bundlePath, source, 'utf8', function(err) { - if(err) { + if (err) { _log('error', 'failed to save source'); process.exit(1); } diff --git a/lib/embed.js b/lib/embed.js index ce715f6..aa55d52 100644 --- a/lib/embed.js +++ b/lib/embed.js @@ -23,11 +23,17 @@ * **/ +'use strict'; + var path = require("path"), - fs = require("fs"); + fs = require("fs"); /** - * TODO: Optimize this code. (more like document it so I understand it better.) + * Embed files. + * + * @param {array} resourceFiles - array of files to embed. + * @param {string} resourceRoot - root of resources. + * @param {function} compelte - callback **/ function embed(resourceFiles, resourceRoot, complete) { function encode(filePath) { @@ -52,11 +58,10 @@ function embed(resourceFiles, resourceRoot, complete) { complete(null, buffer); } -var accessor = function (key) { +var accessor = function(key) { if (embeddedFiles.hasOwnProperty(key)) { return new Buffer(embeddedFiles[key], 'base64'); - } - else { + } else { //file was not embedded, throw err. throw new Error('Embedded file not found'); } diff --git a/lib/exe.js b/lib/exe.js index de0056f..49640d5 100644 --- a/lib/exe.js +++ b/lib/exe.js @@ -22,25 +22,28 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * **/ -var async = require("async"), - outcome = require("outcome"), - mkdirp = require("mkdirp"), - request = require("request"), - gunzip = require("gunzip-maybe"), - path = require("path"), - fs = require("fs"), - tarstream = require('tar-stream'), - colors = require('colors'), - ncp = require("ncp").ncp, - ProgressBar = require("progress"), - child_process = require("child_process"), - glob = require("glob"), - bundle = require("./bundle"), - embed = require("./embed"), - os = require("os"), - _log = require("./log"), - _monkeypatch = require("./monkeypatch"), - spawn = child_process.spawn; + +'use strict'; + +var async = require("async"), + outcome = require("outcome"), + mkdirp = require("mkdirp"), + request = require("request"), + gunzip = require("gunzip-maybe"), + path = require("path"), + fs = require("fs"), + tarstream = require('tar-stream'), + colors = require('colors'), + ncp = require("ncp").ncp, + ProgressBar = require("progress"), + child_process = require("child_process"), + glob = require("glob"), + bundle = require("./bundle"), + embed = require("./embed"), + os = require("os"), + _log = require("./log"), + _monkeypatch = require("./monkeypatch"), + spawn = child_process.spawn; var isWin = /^win/.test(process.platform); var isPy; @@ -48,236 +51,231 @@ var framework; var version; var option_list = [ - "python", - "input", - "output", - "nodeTempDir", - "flags", - "framework", + "python", + "debug", + "input", + "output", + "nodeTempDir", + "flags", + "framework", "nodeConfigureArgs", "nodeMakeArgs", - "nodeVersion" + "nodeVersion" ] /** * Compiliation process. */ -exports.compile = function (options, complete) { +exports.compile = function(options, complete) { - var nodeCompiler, nexeEntryPath; + var nodeCompiler, nexeEntryPath; - async.waterfall([ - /** - *check relevant options - */ - function checkOpts (next) { - /* failsafe */ - if(options === undefined) { - _log("error", "no options given to .compile()"); - process.exit() - } + async.waterfall([ + /** + *check relevant options + */ + function checkOpts(next) { + /* failsafe */ + if (options === undefined) { + _log("error", "no options given to .compile()"); + process.exit() + } - /* option_list.forEach(function(v) { - if(options[v] === undefined) { - _log("error", "option "+v+" was empty") - process.exit(); - } - }); */ + /** + * Have we been given a custom flag for python executable? + **/ + if (options.python !== 'python' && options.python !== "" && options.python !== undefined) { + if (isWin) { + isPy = options.python.replace(/\//gm, "\\"); // use windows file paths, batch is sensitive. + } else { + isPy = options.python; + } - /** - * Have we been given a custom flag for python executable? - **/ - if(options.python!=='python' && options.python!=="" - && options.python!==undefined) { - if(isWin) { - isPy=options.python.replace(/\//gm, "\\"); // use windows file paths, batch is sensitive. - } else { - isPy=options.python; - } + _log("set python as " + isPy); + } else { + isPy = "python"; + } - _log("set python as "+isPy); - } else { - isPy="python"; - } + // remove dots + options.framework = options.framework.replace(/\./g, ""); - // remove dots - options.framework = options.framework.replace(/\./g, ""); + // set outter-scope framework variable. + framework = options.framework; + _log("framework => " + framework); - // set outter-scope framework variable. - framework = options.framework; - _log("framework => "+framework); + version = options.nodeVersion; // better framework vc - version = options.nodeVersion; // better framework vc + // check iojs version + if (framework === "iojs" && version === "latest") { + _log("fetching iojs versions"); + mkdirp(options.nodeTempDir); // make temp dir, probably repetive. - // check iojs version - if (framework === "iojs" && version === "latest" ) { - _log("fetching iojs versions"); - mkdirp(options.nodeTempDir); // make temp dir, probably repetive. + // create write stream so we have control over events + var output = fs.createWriteStream(path.join(options.nodeTempDir, + "iojs-versions.json")); - // create write stream so we have control over events - var output = fs.createWriteStream(path.join(options.nodeTempDir, - "iojs-versions.json")); + request.get("https://iojs.org/dist/index.json") + .pipe(output); - request.get("https://iojs.org/dist/index.json") - .pipe(output); + output.on('close', function() { + _log("done"); + var f = fs.readFileSync(path.join(options.nodeTempDir, + "iojs-versions.json")); + f = JSON.parse(f); + version = f[0].version.replace("v", ""); - output.on('close', function() { - _log("done"); - var f = fs.readFileSync(path.join(options.nodeTempDir, - "iojs-versions.json")); - f = JSON.parse(f); - version = f[0].version.replace("v", ""); + _log("iojs latest => " + version); - _log("iojs latest => "+version); + // continue down along the async road + next(); + }); + } else { + next(); + } + }, - // continue down along the async road - next(); - }); - } else { - next(); - } - }, + /** + * first download node + */ + function downloadNode(next) { + _downloadNode(version, options.nodeTempDir, options.nodeConfigureArgs, options.nodeMakeArgs, next); + }, - /** - * first download node - */ - function downloadNode (next) { - _downloadNode(version, options.nodeTempDir, options.nodeConfigureArgs, options.nodeMakeArgs, next); - }, + /** + * bundle the application into one script + */ - /** - * bundle the application into one script - */ + function combineProject(nc, next) { + nodeCompiler = nc; + _log("bundle %s", options.input); + bundle(options.input, nodeCompiler.dir, options, next); + }, - function combineProject (nc, next) { - nodeCompiler = nc; - _log("bundle %s", options.input); - bundle(options.input, nodeCompiler.dir, next); - }, + function embedResources(next) { + _log("embedResources %s", options.resourceFiles); + embed(options.resourceFiles, options.resourceRoot, next); + }, - function embedResources(next) { - _log("embedResources %s", options.resourceFiles); - embed(options.resourceFiles, options.resourceRoot, next); - }, + function writeResources(resources, next) { + let resourcePath = path.join(nodeCompiler.dir, "lib", "nexeres.js"); + _log("resource -> %s", resourcePath); - function writeResources (resources, next) { - resourcePath = path.join(nodeCompiler.dir, "lib", "nexeres.js"); - _log("resource -> %s", resourcePath); + fs.writeFile(resourcePath, resources, next); + }, - fs.writeFile(resourcePath, resources, next); - }, + /** + * monkeypatch some files so that the nexe.js file is loaded when the app runs + */ - /** - * monkeypatch some files so that the nexe.js file is loaded when the app runs - */ + function monkeyPatchNodeConfig(next) { + _monkeyPatchNodeConfig(nodeCompiler, next); + }, - function monkeyPatchNodeConfig (next) { - _monkeyPatchNodeConfig(nodeCompiler, next); - }, + /** + * monkeypatch node.cc to prevent v8 and node from processing CLI flags + */ + function monkeyPatchNodeCc(next) { + if (options.flags) { + _monkeyPatchMainCc(nodeCompiler, next); + } else { + next(); + } + }, - /** - * monkeypatch node.cc to prevent v8 and node from processing CLI flags - */ - function monkeyPatchNodeCc (next) { - if (options.flags) { - _monkeyPatchMainCc(nodeCompiler, next); - } else { - next(); - } - }, - - function monkeyPatchv8FlagsCc (next) { - if(options.jsFlags) { + function monkeyPatchv8FlagsCc(next) { + if (options.jsFlags) { return _monkeyPatchv8FlagsCc(nodeCompiler, options, next); } return next(); }, - /** - * monkeypatch child_process.js so nexejs knows when it is a forked process - */ - function monkeyPatchChildProc(next) { - _monkeyPatchChildProcess(nodeCompiler, next); - }, + /** + * monkeypatch child_process.js so nexejs knows when it is a forked process + */ + function monkeyPatchChildProc(next) { + _monkeyPatchChildProcess(nodeCompiler, next); + }, - /** - * If an old compiled executable exists in the Release directory, delete it. - * This lets us see if the build failed by checking the existence of this file later. - */ + /** + * If an old compiled executable exists in the Release directory, delete it. + * This lets us see if the build failed by checking the existence of this file later. + */ - function cleanUpOldExecutable (next) { - fs.unlink(nodeCompiler.releasePath, function (err) { - if (err) { - if (err.code === "ENOENT") { - next(); - } else { - throw err; - } - } else { - next(); - } - }); - }, + function cleanUpOldExecutable(next) { + fs.unlink(nodeCompiler.releasePath, function(err) { + if (err) { + if (err.code === "ENOENT") { + next(); + } else { + throw err; + } + } else { + next(); + } + }); + }, - /** - * compile the node application - */ + /** + * compile the node application + */ - function makeExecutable (next) { - if(isWin) { - _log("vcbuild [make stage]"); - } else { - _log("make"); - } - nodeCompiler.make(next); - }, + function makeExecutable(next) { + if (isWin) { + _log("vcbuild [make stage]"); + } else { + _log("make"); + } + nodeCompiler.make(next); + }, - /** - * we create the output directory if needed - */ + /** + * we create the output directory if needed + */ - function makeOutputDirectory (next) { - mkdirp(path.dirname(options.output), function(){ next(); }); - }, + function makeOutputDirectory(next) { + mkdirp(path.dirname(options.output), function() { + next(); + }); + }, - /** - * Verify that the executable was compiled successfully - */ + /** + * Verify that the executable was compiled successfully + */ - function checkThatExecutableExists (next) { - fs.exists(nodeCompiler.releasePath, function (exists) { - if (!exists) { - _log("error", - "The release executable has not been generated. " + - "This indicates a failure in the build process. " + - "There is likely additional information above." - ); - process.exit(1); - } else { - next(); - } - }); - }, + function checkThatExecutableExists(next) { + fs.exists(nodeCompiler.releasePath, function(exists) { + if (!exists) { + _log("error", + "The release executable has not been generated. " + + "This indicates a failure in the build process. " + + "There is likely additional information above." + ); + process.exit(1); + } else { + next(); + } + }); + }, - /** - * Copy the compilied binary to the output specified. - */ + /** + * Copy the compilied binary to the output specified. + */ - function copyBinaryToOutput (next) { - _log("cp %s %s", nodeCompiler.releasePath, options.output); - ncp(nodeCompiler.releasePath, options.output, function (err) { - if (err) { - _log("error", "Couldn't copy binary."); - throw err; // dump raw error object - } - _log('copied'); + function copyBinaryToOutput(next) { + _log("cp %s %s", nodeCompiler.releasePath, options.output); + ncp(nodeCompiler.releasePath, options.output, function(err) { + if (err) { + _log("error", "Couldn't copy binary."); + throw err; // dump raw error object + } + _log('copied'); - next(); - }); - } - ], complete); + next(); + }); + } + ], complete); } /** @@ -289,88 +287,92 @@ exports.compile = function (options, complete) { */ function _downloadNode(version, directory, nodeConfigureArgs, nodeMakeArgs, complete) { - var nodeFileDir = path.resolve(path.join(directory, framework, version)), // fixes #107, was process.cwd(), + rest. - nodeFilePath = path.resolve(path.join(nodeFileDir, framework + "-" + version + ".tar.gz")); + var nodeFileDir = path.resolve(path.join(directory, framework, version)), // fixes #107, was process.cwd(), + rest. + nodeFilePath = path.resolve(path.join(nodeFileDir, framework + "-" + version + ".tar.gz")); - // might already be downloaded, and unzipped - if (_getNodeCompiler(nodeFileDir, nodeConfigureArgs, nodeMakeArgs, complete)) { - return; - } + // might already be downloaded, and unzipped + if (_getNodeCompiler(nodeFileDir, nodeConfigureArgs, nodeMakeArgs, complete)) { + return; + } - async.waterfall([ + async.waterfall([ - /** - * first make the directory where the zip file will live - */ + /** + * first make the directory where the zip file will live + */ - function makeDirectory (next) { - mkdirp.sync(path.dirname(nodeFilePath)); - next(); - }, + function makeDirectory(next) { + mkdirp.sync(path.dirname(nodeFilePath)); + next(); + }, - /** - * download node into the target directory - */ + /** + * download node into the target directory + */ - function downloadNode (next) { - if (fs.existsSync(nodeFilePath)) return next(); + function downloadNode(next) { + if (fs.existsSync(nodeFilePath)) return next(); var uri = framework; - if(framework==="node") { + if (framework === "node") { uri = 'nodejs'; // if node, use nodejs uri - } else if(framework === 'nodejs') { + } else if (framework === 'nodejs') { framework = 'node'; // support nodejs, and node, as framework. } - var type = global.type; - var url, prefix = "https://"+uri+".org/dist"; + var type = global.type; + var url, prefix = "https://" + uri + ".org/dist"; - if (version === "latest") { - url = prefix + "/" + framework + "-" + version + ".tar.gz"; - } else { - url = prefix + "/v" + version + "/"+framework+"-v" + version + ".tar.gz"; - } + if (version === "latest") { + url = prefix + "/" + framework + "-" + version + ".tar.gz"; + } else { + url = prefix + "/v" + version + "/" + framework + "-v" + version + ".tar.gz"; + } - _log("downloading %s", url); + _log("downloading %s", url); - var output = fs.createWriteStream(nodeFilePath, { "flags": "w+" }); + var output = fs.createWriteStream(nodeFilePath, { + "flags": "w+" + }); - // need to set user-agent to bypass some corporate firewalls - var requestOptions = { - url: url, - headers: { - "User-Agent": "Node.js" - } - } + // need to set user-agent to bypass some corporate firewalls + var requestOptions = { + url: url, + headers: { + "User-Agent": "Node.js" + } + } - _logProgress(request(requestOptions)).pipe(output); + _logProgress(request(requestOptions)).pipe(output); - output.on("close", function () { next(); }); - }, + output.on("close", function() { + next(); + }); + }, - /** - * unzip in the same directory - */ + /** + * unzip in the same directory + */ - function unzipNodeTarball (next) { + function unzipNodeTarball(next) { var onError = function(err) { console.log(err.stack); _log("error", "failed to extract the node source"); process.exit(1); } - if(isWin) { - _log("extracting the node source [node-tar.gz]"); + if (isWin) { + _log("extracting the node source [node-tar.gz]"); // tar-stream method w/ gunzip-maybe - var read = fs.createReadStream(nodeFilePath); + var read = fs.createReadStream(nodeFilePath); var extract = tarstream.extract() var basedir = nodeFileDir; - if(!fs.existsSync(nodeFileDir)) { + if (!fs.existsSync(nodeFileDir)) { fs.mkdirSync(nodeFileDir); } @@ -380,16 +382,16 @@ function _downloadNode(version, directory, nodeConfigureArgs, nodeMakeArgs, comp // call next when you are done with this entry var absolutepath = path.join(basedir, header.name); - if(header.type === 'directory') { + if (header.type === 'directory') { // handle directories. // console.log('dir:', header.name); fs.mkdirSync(absolutepath); return callback(); - } else if(header.type === 'file') { + } else if (header.type === 'file') { // handle files // console.log('file:', header.name); } else { - console.log(header.type+':', header.name); + console.log(header.type + ':', header.name); _log('warn', 'unhandled type in tar extraction, skipping'); return callback(); } @@ -419,32 +421,32 @@ function _downloadNode(version, directory, nodeConfigureArgs, nodeMakeArgs, comp }) read.pipe(gunzip()).pipe(extract); - } else { + } else { _log("extracting the node source [native tar]"); - var cmd = ["tar", "-xf", nodeFilePath, "-C", nodeFileDir]; - _log(cmd.join(" ")); + var cmd = ["tar", "-xf", nodeFilePath, "-C", nodeFileDir]; + _log(cmd.join(" ")); - var tar = spawn(cmd.shift(), cmd); - tar.stdout.pipe(process.stdout); - tar.stderr.pipe(process.stderr); + var tar = spawn(cmd.shift(), cmd); + tar.stdout.pipe(process.stdout); + tar.stderr.pipe(process.stderr); - tar.on("close", function () { + tar.on("close", function() { return next(); }); tar.on("error", onError); - } - }, + } + }, - /** - * return the compiler object for the node version - */ + /** + * return the compiler object for the node version + */ - function (next, type) { - _getNodeCompiler(nodeFileDir, nodeConfigureArgs, nodeMakeArgs, next, type) - }, + function(next, type) { + _getNodeCompiler(nodeFileDir, nodeConfigureArgs, nodeMakeArgs, next, type) + }, - ], complete); + ], complete); } /** @@ -452,99 +454,103 @@ function _downloadNode(version, directory, nodeConfigureArgs, nodeMakeArgs, comp * it. */ -function _getNodeCompiler (nodeFileDir, nodeConfigureArgs, nodeMakeArgs, complete, type) { - var dir = _getFirstDirectory(nodeFileDir); +function _getNodeCompiler(nodeFileDir, nodeConfigureArgs, nodeMakeArgs, complete, type) { + var dir = _getFirstDirectory(nodeFileDir); - // standard - var executable = "node.exe"; - var binary = "node"; + // standard + var executable = "node.exe"; + var binary = "node"; - // iojs specifics. - if(framework === "iojs") { - executable = "iojs.exe"; - binary = "iojs"; - } + // iojs specifics. + if (framework === "iojs") { + executable = "iojs.exe"; + binary = "iojs"; + } - if (dir) { - if(isWin) { - complete(null, { - dir: dir, - version: path.basename(nodeFileDir), - releasePath: path.join(dir, "Release", executable), - make: function(next) { - // create a new env with minimal impact on old one - var newEnv = process.env + if (dir) { + if (isWin) { + complete(null, { + dir: dir, + version: path.basename(nodeFileDir), + releasePath: path.join(dir, "Release", executable), + make: function(next) { + // create a new env with minimal impact on old one + var newEnv = process.env - if(isPy!=="python") { - // add the dir of the suposed python exe to path - newEnv.path = process.env.PATH+";"+path.dirname(isPy) - } + if (isPy !== "python") { + // add the dir of the suposed python exe to path + newEnv.path = process.env.PATH + ";" + path.dirname(isPy) + } - // spawn a vcbuild process with our custom enviroment. - var vcbuild = spawn("vcbuild.bat", ["nosign", "release"], { - cwd: dir, - env: newEnv - }); - vcbuild.stdout.pipe(process.stdout); - vcbuild.stderr.pipe(process.stderr); - vcbuild.on("close", function() { - next(); - }); - } - }); - } else { - complete(null, { - dir: dir, - version: path.basename(nodeFileDir), - releasePath: path.join(dir, "out", "Release", binary), - make: function (next) { - var cfg = "./configure", - configure; + // spawn a vcbuild process with our custom enviroment. + var vcbuild = spawn("vcbuild.bat", ["nosign", "release"], { + cwd: dir, + env: newEnv + }); + vcbuild.stdout.pipe(process.stdout); + vcbuild.stderr.pipe(process.stderr); + vcbuild.on("close", function() { + next(); + }); + } + }); + } else { + complete(null, { + dir: dir, + version: path.basename(nodeFileDir), + releasePath: path.join(dir, "out", "Release", binary), + make: function(next) { + var cfg = "./configure", + configure; var conf = [cfg]; - if(isPy !== "python") { + if (isPy !== "python") { conf = [conf].concat(nodeConfigureArgs); } // should work for all use cases now. - configure = spawn(isPy, conf, { + configure = spawn(isPy, conf, { cwd: dir.toString('ascii') }); - // local function, move to top eventually - function _loop(dir) { - /* eventually try every python file */ - var pdir = fs.readdirSync(dir); + // local function, move to top eventually + function _loop(dir) { + /* eventually try every python file */ + var pdir = fs.readdirSync(dir); - pdir.forEach(function(v, i) { - var stat = fs.statSync(dir+"/"+v); - if(stat.isFile()) { - // only process Makefiles and .mk targets. - if(v !== "Makefile" && path.extname(v) !== ".mk") { - return; - } + pdir.forEach(function(v, i) { + var stat = fs.statSync(dir + "/" + v); + if (stat.isFile()) { + // only process Makefiles and .mk targets. + if (v !== "Makefile" && path.extname(v) !== ".mk") { + return; + } - _log("patching "+v); + _log("patching " + v); - /* patch the file */ - var py = fs.readFileSync(dir+"/"+v, {encoding: 'utf8'}); - py = py.replace(/([a-z]|\/)*python(\w|)/gm, isPy); // this is definently needed - fs.writeFileSync(dir+"/"+v, py, {encoding: 'utf8'}); // write to file + /* patch the file */ + var py = fs.readFileSync(dir + "/" + v, { + encoding: 'utf8' + }); + py = py.replace(/([a-z]|\/)*python(\w|)/gm, isPy); // this is definently needed + fs.writeFileSync(dir + "/" + v, py, { + encoding: 'utf8' + }); // write to file - delete pv; - } else if(stat.isDirectory()) { - // must be dir? - // skip tests because we don't need them here - if(v !== "test") { - _loop(dir+"/"+v) - } - } - }); - } + pv = undefined; + } else if (stat.isDirectory()) { + // must be dir? + // skip tests because we don't need them here + if (v !== "test") { + _loop(dir + "/" + v) + } + } + }); + } - configure.stdout.pipe(process.stdout); - configure.stderr.pipe(process.stderr); + configure.stdout.pipe(process.stdout); + configure.stderr.pipe(process.stderr); // on error configure.on("error", function(err) { @@ -561,136 +567,138 @@ function _getNodeCompiler (nodeFileDir, nodeConfigureArgs, nodeMakeArgs, complet var configure_size = fs.statSync(configure_path).size; - console.log('configure is non-zero size,', ((configure_size > 0 ) ? colors.green('yes') : colors.red('no'))); + console.log('configure is non-zero size,', ((configure_size > 0) ? colors.green('yes') : colors.red('no'))); _log("error", "failed to launch configure."); process.exit(1); }); // when it's finished - configure.on("close", function () { - if(isPy !== "python") { - /** - * Originally I thought this only applied to io.js, - * however I soon found out this affects node.js, - * so it is now mainstream. - */ - _log("preparing python"); + configure.on("close", function() { + if (isPy !== "python") { + /** + * Originally I thought this only applied to io.js, + * however I soon found out this affects node.js, + * so it is now mainstream. + */ + _log("preparing python"); - // loop over depends - _loop(dir); - } + // loop over depends + _loop(dir); + } - if(nodeMakeArgs === undefined) { + if (nodeMakeArgs === undefined) { nodeMakeArgs = []; } - var platformMake = "make"; - if (os.platform().match(/bsd$/) != null) { - platformMake = "gmake"; - } + var platformMake = "make"; + if (os.platform().match(/bsd$/) != null) { + platformMake = "gmake"; + } - var make = spawn(platformMake, nodeMakeArgs, { cwd: dir }); - make.stdout.pipe(process.stdout); - make.stderr.pipe(process.stderr); + var make = spawn(platformMake, nodeMakeArgs, { + cwd: dir + }); + make.stdout.pipe(process.stdout); + make.stderr.pipe(process.stderr); make.on("error", function(err) { console.log(err); _log("error", "failed to run make."); process.exit(1); }) - make.on("close", function () { - next(); - }); - }) - } - }); - } - return true; - } + make.on("close", function() { + next(); + }); + }) + } + }); + } + return true; + } - return false; + return false; } /** */ -function _monkeyPatchNodeConfig (compiler, complete) { - async.waterfall([ - /** - * monkeypatch the gyp file to include the nexe.js and nexeres.js files - */ - function (next) { - _monkeyPatchGyp(compiler, next) - }, +function _monkeyPatchNodeConfig(compiler, complete) { + async.waterfall([ + /** + * monkeypatch the gyp file to include the nexe.js and nexeres.js files + */ + function(next) { + _monkeyPatchGyp(compiler, next) + }, - /** - * monkeypatch main entry point - */ - function (next) { - _monkeyPatchMainJs(compiler, next) - } - ], complete); + /** + * monkeypatch main entry point + */ + function(next) { + _monkeyPatchMainJs(compiler, next) + } + ], complete); } /** * patch the gyp file to allow our custom includes */ -function _monkeyPatchGyp (compiler, complete) { +function _monkeyPatchGyp(compiler, complete) { - var gypPath = path.join(compiler.dir, "node.gyp"); + var gypPath = path.join(compiler.dir, "node.gyp"); - _monkeypatch( - gypPath, - function (content) { - return ~content.indexOf("nexe.js"); - }, - function (content, next) { - next(null, content.replace("'lib/fs.js',", "'lib/fs.js', 'lib/nexe.js', 'lib/nexeres.js', ")) - }, - complete - ) + _monkeypatch( + gypPath, + function(content) { + return ~content.indexOf("nexe.js"); + }, + function(content, next) { + next(null, content.replace("'lib/fs.js',", "'lib/fs.js', 'lib/nexe.js', 'lib/nexeres.js', ")) + }, + complete + ) } /** */ -function _monkeyPatchMainJs (compiler, complete) { - var mainPath = path.join(compiler.dir, "src", "node.js"); +function _monkeyPatchMainJs(compiler, complete) { + var mainPath = path.join(compiler.dir, "src", "node.js"); - _monkeypatch( - mainPath, - function (content) { - return ~content.indexOf("nexe"); - }, - function (content, next) { - next(null, content.replace(/\(function\(process\) \{/,'\ + _monkeypatch( + mainPath, + function(content) { + return ~content.indexOf("nexe"); + }, + function(content, next) { + next(null, content.replace(/\(function\(process\) \{/, '\ (function(process) {\n\ process._eval = \'require("nexe");\';\n\ if (process.argv[1] !== "nexe.js") {\n\ process.argv.splice(1, 0, "nexe.js");\n\ }\n\ ')) - }, - complete - ); + }, + complete + ); } /** */ function _monkeyPatchChildProcess(compiler, complete) { - var childProcPath = path.join(compiler.dir, "lib", "child_process.js"); + var childProcPath = path.join(compiler.dir, "lib", "child_process.js"); - _monkeypatch( - childProcPath, - function (content) { - return ~content.indexOf("--child_process"); - }, - function (content, next) { - next(null, content.replace(/return spawn\(/, 'args.unshift("nexe.js", "--child_process");\n return spawn(')); - }, - complete - ); + _monkeypatch( + childProcPath, + function(content) { + return ~content.indexOf("--child_process"); + }, + function(content, next) { + next(null, content.replace(/return spawn\(/, 'args.unshift("nexe.js", "--child_process");\n return spawn(')); + }, + complete + ); } /** @@ -698,33 +706,35 @@ function _monkeyPatchChildProcess(compiler, complete) { */ function _monkeyPatchMainCc(compiler, complete) { - var mainPath = path.join(compiler.dir, "src", "node.cc"); - var mainC = fs.readFileSync(mainPath, {encoding: 'utf8'}); + var mainPath = path.join(compiler.dir, "src", "node.cc"); + var mainC = fs.readFileSync(mainPath, { + encoding: 'utf8' + }); // content split, and original start/end var constant_loc = 1; - var lines = mainC.split('\n'); + var lines = mainC.split('\n'); var startLine = lines.indexOf(' // TODO use parse opts'); - var endLine = lines.indexOf(' option_end_index = i;'); // pre node 0.11.6 compat + var endLine = lines.indexOf(' option_end_index = i;'); // pre node 0.11.6 compat var isPatched = lines.indexOf('// NEXE_PATCH_IGNOREFLAGS'); - if(isPatched !== -1) { + if (isPatched !== -1) { _log('already patched node.cc'); return complete(); } - /** - * This is the new method of passing the args. Tested on node.js 0.12.5 - * and iojs 2.3.1 - **/ - if(endLine === -1 && startLine === -1) { // only if the pre-0.12.5 failed. + /** + * This is the new method of passing the args. Tested on node.js 0.12.5 + * and iojs 2.3.1 + **/ + if (endLine === -1 && startLine === -1) { // only if the pre-0.12.5 failed. _log("using the after 0.12.5 method of ignoring flags."); startLine = lines.indexOf(" while (index < nargs && argv[index][0] == '-') {"); // beginning of the function endLine = lines.indexOf(' // Copy remaining arguments.'); endLine--; // space, then it's at the } - constant_loc = lines.length+1; + constant_loc = lines.length + 1; } else { _log('using 0.10.x > method of ignoring flags'); lines[endLine] = ' option_end_index = 1;'; @@ -733,18 +743,18 @@ function _monkeyPatchMainCc(compiler, complete) { /** * This is the method for 5.5.0 **/ - if(endLine === -1 || startLine === -1) { + if (endLine === -1 || startLine === -1) { _log("using the after 5.5.0 method of ignoring flags."); startLine = lines.indexOf(" while (index < nargs && argv[index][0] == '-' && !short_circuit) {"); // beginning of the function endLine = lines.indexOf(' // Copy remaining arguments.'); endLine--; // space, then it's at the } - constant_loc = lines.length+1; + constant_loc = lines.length + 1; } // other versions here. - if(endLine === -1 || startLine === -1) { // failsafe. + if (endLine === -1 || startLine === -1) { // failsafe. _log("error", "Failed to find a way to patch node.cc to ignoreFlags"); _log("startLine =", startLine, '| endLine =', endLine); process.exit(1); @@ -762,8 +772,10 @@ function _monkeyPatchMainCc(compiler, complete) { finalContents = lines.join('\n'); // write the file contents - fs.writeFile(mainPath, finalContents, {encoding: 'utf8'}, function(err) { - if(err) { + fs.writeFile(mainPath, finalContents, { + encoding: 'utf8' + }, function(err) { + if (err) { _log('error', 'failed to write to', mainPath); return process.exit(1); } @@ -777,10 +789,12 @@ function _monkeyPatchMainCc(compiler, complete) { * this function is very closely ready to accept custom injection code. **/ function _monkeyPatchv8FlagsCc(compiler, options, complete) { - var mainPath = path.join(compiler.dir, "deps/v8/src", "flags.cc"); + var mainPath = path.join(compiler.dir, "deps/v8/src", "flags.cc"); - fs.readFile(mainPath, {encoding: 'utf8'}, function(err, contents) { - if(err) { + fs.readFile(mainPath, { + encoding: 'utf8' + }, function(err, contents) { + if (err) { return _log('error', 'failed to read', mainPath); } @@ -795,7 +809,7 @@ SetFlagsFromString(nexevargs, nexevargslen);\n\ var injectionLength = injectionSplit.length; var contentsSplit = contents.split('\n'); var contentsLength = contentsSplit.length; - var lastInjectionLine = injectionSplit[injectionLength-2]; + var lastInjectionLine = injectionSplit[injectionLength - 2]; var lineToInjectAfter = contentsSplit.indexOf(' ComputeFlagListHash();'); var haveWeInjectedBefore = contentsSplit.indexOf(lastInjectionLine); @@ -803,15 +817,15 @@ SetFlagsFromString(nexevargs, nexevargslen);\n\ var lineInjectDifference = contentsLength - lineToInjectAfter; // support for 0.12.x - if(lineToInjectAfter===-1) { + if (lineToInjectAfter === -1) { _log('warn', 'Using an expiramental support patch for 0.12.x'); lineToInjectAfter = contentsSplit.indexOf('#undef FLAG_MODE_DEFINE_IMPLICATIONS'); } // support for 0.10.x - if(lineToInjectAfter===-1) { + if (lineToInjectAfter === -1) { _log('warn', '0.12.x patch failed. Trying 0.10.0 patch'); - lineToInjectAfter = contentsSplit.indexOf('#define FLAG_MODE_DEFINE_IMPLICATIONS')+1; + lineToInjectAfter = contentsSplit.indexOf('#define FLAG_MODE_DEFINE_IMPLICATIONS') + 1; } // this is debug, comment out. @@ -821,9 +835,9 @@ SetFlagsFromString(nexevargs, nexevargslen);\n\ // console.log(finalContents) var finalContents, - dontCombine; + dontCombine; - if(lineToInjectAfter !== -1 && haveWeInjectedBefore === -1) { + if (lineToInjectAfter !== -1 && haveWeInjectedBefore === -1) { _log('injecting v8/flags.cc'); // super debug @@ -832,44 +846,46 @@ SetFlagsFromString(nexevargs, nexevargslen);\n\ // _log('v8 inject needs to shift', lineInjectDifference, 'amount of lines by', injectionLength); // compute out the amount of space we'll need in this. - var startShiftLine = contentsLength-1; // minus one to make up for 0 arg line. + var startShiftLine = contentsLength - 1; // minus one to make up for 0 arg line. var endShiftLine = lineToInjectAfter; - var injectRoom = injectionLength-1; + var injectRoom = injectionLength - 1; injectionSplit[0] = injectionSplit[0].replace('{{args}}', options.jsFlags); for (var i = startShiftLine; i !== endShiftLine; i--) { - contentsSplit[i+injectRoom] = contentsSplit[i]; + contentsSplit[i + injectRoom] = contentsSplit[i]; contentsSplit[i] = ''; } var injectionPos = 0; - for(var i = 0; i !== injectionLength-1; i++) { - contentsSplit[(lineToInjectAfter+1)+injectionPos] = injectionSplit[injectionPos]; + for (var i = 0; i !== injectionLength - 1; i++) { + contentsSplit[(lineToInjectAfter + 1) + injectionPos] = injectionSplit[injectionPos]; injectionPos++; } - } else if(lineToInjectAfter !== -1 && haveWeInjectedBefore !== -1) { + } else if (lineToInjectAfter !== -1 && haveWeInjectedBefore !== -1) { _log('re-injecting v8 args'); dontCombine = true; finalContents = contentsSplit.join('\n'); finalContents = finalContents.replace(/const char\* nexevargs = "[A-Z\-\_]*";/gi, - 'const char* nexevargs = "'+options.jsFlags+'";'); + 'const char* nexevargs = "' + options.jsFlags + '";'); } else { _log('error', 'failed to find a suitable injection point for v8 args.', 'File a bug report with the node version and log.'); - _log('lineToInjectAfter='+lineToInjectAfter, 'haveWeInjectedBefore='+haveWeInjectedBefore); + _log('lineToInjectAfter=' + lineToInjectAfter, 'haveWeInjectedBefore=' + haveWeInjectedBefore); return process.exit(1); } - if(!dontCombine) { + if (!dontCombine) { finalContents = contentsSplit.join('\n'); } // write the file contents - fs.writeFile(mainPath, finalContents, {encoding: 'utf8'}, function(err) { - if(err) { + fs.writeFile(mainPath, finalContents, { + encoding: 'utf8' + }, function(err) { + if (err) { _log('error', 'failed to write to', mainPath); return process.exit(1); } @@ -883,37 +899,37 @@ SetFlagsFromString(nexevargs, nexevargslen);\n\ * Get the first directory of a string. */ -function _getFirstDirectory (dir) { - var files = glob.sync(dir + "/*"); +function _getFirstDirectory(dir) { + var files = glob.sync(dir + "/*"); - for (var i = files.length; i--;) { - var file = files[i]; - if (fs.statSync(file).isDirectory()) return file; - } + for (var i = files.length; i--;) { + var file = files[i]; + if (fs.statSync(file).isDirectory()) return file; + } - return false; + return false; } /** * Log the progress of a request object. */ -function _logProgress (req) { +function _logProgress(req) { - req.on("response", function (resp) { + req.on("response", function(resp) { - var len = parseInt(resp.headers["content-length"], 10), - bar = new ProgressBar("[:bar]", { - complete: "=", - incomplete: " ", - total: len, - width: 100 // just use 100 - }); + var len = parseInt(resp.headers["content-length"], 10), + bar = new ProgressBar("[:bar]", { + complete: "=", + incomplete: " ", + total: len, + width: 100 // just use 100 + }); - req.on("data", function (chunk) { - bar.tick(chunk.length); - }); - }); + req.on("data", function(chunk) { + bar.tick(chunk.length); + }); + }); req.on("error", function(err) { console.log(err); @@ -921,7 +937,7 @@ function _logProgress (req) { process.exit(1); }); - return req; + return req; } /** @@ -933,49 +949,50 @@ function _logProgress (req) { * @todo implement options overriding package defaults. * @todo make this much less hackily implemented.... * - * @return {object} nexe.compile options object -**/ + * @return {object} nexe.compile - options object + **/ exports.package = function(path, options) { - var _package; // scope + var _package; // scope - // check if the file exists - if(fs.existsSync(path)===false) { - _log("warn", "no package.json found."); - } else { - _package = require(path); - } + // check if the file exists + if (fs.existsSync(path) === false) { + _log("warn", "no package.json found."); + } else { + _package = require(path); + } - // replace ^$ w/ os specific extension on output - if(isWin) { - _package.nexe.output = _package.nexe.output.replace(/\^\$/, '.exe') // exe - } else { - _package.nexe.output = _package.nexe.output.replace(/\^\$/, '') // none - } + // replace ^$ w/ os specific extension on output + if (isWin) { + _package.nexe.output = _package.nexe.output.replace(/\^\$/, '.exe') // exe + } else { + _package.nexe.output = _package.nexe.output.replace(/\^\$/, '') // none + } - // construct the object - var obj = { - input: (_package.nexe.input || options.i), - output: (_package.nexe.output || options.o), - flags: (_package.nexe.runtime.ignoreFlags || (options.f || false)), - nodeMakeArgs: (_package.nexe.runtime.nodeMakeArgs || []), - resourceFiles: (_package.nexe.resourceFiles), - nodeVersion: (_package.nexe.runtime.version || options.r), + // construct the object + var obj = { + input: (_package.nexe.input || options.i), + output: (_package.nexe.output || options.o), + flags: (_package.nexe.runtime.ignoreFlags || (options.f || false)), + nodeMakeArgs: (_package.nexe.runtime.nodeMakeArgs || []), + resourceFiles: (_package.nexe.resourceFiles), + nodeVersion: (_package.nexe.runtime.version || options.r), nodeConfigureArgs: (_package.nexe.runtime.nodeConfigureArgs || []), nodeMakeArgs: (_package.nexe.runtime.nodeMakeArgs || []), - jsFlags: (_package.nexe.runtime['js-flags'] || false), - python: (_package.nexe.python || options.p), - nodeTempDir: (_package.nexe.temp || options.t), - framework: (_package.nexe.runtime.framework || options.f) - } + jsFlags: (_package.nexe.runtime['js-flags'] || options.j), + python: (_package.nexe.python || options.p), + debug: (_package.nexe.debug || options.d), + nodeTempDir: (_package.nexe.temp || options.t), + framework: (_package.nexe.runtime.framework || options.f) + } - Object.keys(_package.nexe).forEach(function(v,i) { - if(v!=="runtime") { - _log("log", v+" => '"+_package.nexe[v]+"'"); - } - }); - Object.keys(_package.nexe.runtime).forEach(function(v,i) { - _log("log", "runtime."+v+" => '"+_package.nexe.runtime[v]+"'"); - }); + Object.keys(_package.nexe).forEach(function(v, i) { + if (v !== "runtime") { + _log("log", v + " => '" + _package.nexe[v] + "'"); + } + }); + Object.keys(_package.nexe.runtime).forEach(function(v, i) { + _log("log", "runtime." + v + " => '" + _package.nexe.runtime[v] + "'"); + }); - return obj; + return obj; } diff --git a/package.json b/package.json index ef71a48..289715c 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "browserify": "^13.0.0", "builtins": "1.0.3", "colors": "^1.1.2", + "exorcist": "^0.4.0", "glob": "^6.0.4", "gunzip-maybe": "^1.3.1", "insert-module-globals": "^7.0.1", @@ -30,6 +31,7 @@ "outcome": "0.0.18", "progress": "^1.1.8", "request": "^2.67.0", + "source-map-support": "^0.4.0", "sprintf": "~0.1.5", "step": "0.0.x", "tar-stream": "^1.3.1", diff --git a/test/express-test/app.js b/test/express-test/app.js new file mode 100644 index 0000000..aa32aed --- /dev/null +++ b/test/express-test/app.js @@ -0,0 +1,61 @@ +var express = require('express'); +var path = require('path'); +var favicon = require('serve-favicon'); +var logger = require('morgan'); +var cookieParser = require('cookie-parser'); +var bodyParser = require('body-parser'); +var jade = require('jade'); + +var routes = require('./routes/index'); +var users = require('./routes/users'); + +var app = express(); + +// view engine setup +app.set('views', path.join(__dirname, 'views')); +app.set('view engine', 'jade'); + +// uncomment after placing your favicon in /public +//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); +app.use(logger('dev')); +app.use(bodyParser.json()); +app.use(bodyParser.urlencoded({ extended: false })); +app.use(cookieParser()); +app.use(express.static(path.join(__dirname, 'public'))); + +app.use('/', routes); +app.use('/users', users); + +// catch 404 and forward to error handler +app.use(function(req, res, next) { + var err = new Error('Not Found'); + err.status = 404; + next(err); +}); + +// error handlers + +// development error handler +// will print stacktrace +if (app.get('env') === 'development') { + app.use(function(err, req, res, next) { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: err + }); + }); +} + +// production error handler +// no stacktraces leaked to user +app.use(function(err, req, res, next) { + res.status(err.status || 500); + res.render('error', { + message: err.message, + error: {} + }); +}); + + +module.exports = app; diff --git a/test/express-test/bin/www b/test/express-test/bin/www new file mode 100755 index 0000000..058203c --- /dev/null +++ b/test/express-test/bin/www @@ -0,0 +1,94 @@ +#!/usr/bin/env node +require('source-map-support').install(); + +/** + * Module dependencies. + */ + +var app = require('../app'); +var debug = require('debug')('express-test:server'); +var http = require('http'); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || '3000'); +app.set('port', port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on('error', onError); +server.on('listening', onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== 'listen') { + throw error; + } + + var bind = typeof port === 'string' + ? 'Pipe ' + port + : 'Port ' + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + console.error(bind + ' requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error(bind + ' is already in use'); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === 'string' + ? 'pipe ' + addr + : 'port ' + addr.port; + debug('Listening on ' + bind); +} + +throw new Error('test'); +//# sourceMappingURL=./test.nex.map diff --git a/test/express-test/package.json b/test/express-test/package.json new file mode 100644 index 0000000..32ca0b7 --- /dev/null +++ b/test/express-test/package.json @@ -0,0 +1,28 @@ +{ + "name": "express-test", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "body-parser": "~1.13.2", + "cookie-parser": "~1.3.5", + "debug": "~2.2.0", + "express": "~4.13.1", + "jade": "~1.11.0", + "morgan": "~1.6.1", + "serve-favicon": "~2.3.0" + }, + "nexe": { + "input": "bin/www", + "output": "test.nex", + "temp": "src", + "debug": true, + "runtime": { + "framework": "node", + "version": "5.5.0", + "ignoreFlags": true + } + } +} diff --git a/test/express-test/public/stylesheets/style.css b/test/express-test/public/stylesheets/style.css new file mode 100644 index 0000000..9453385 --- /dev/null +++ b/test/express-test/public/stylesheets/style.css @@ -0,0 +1,8 @@ +body { + padding: 50px; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; +} + +a { + color: #00B7FF; +} diff --git a/test/express-test/routes/index.js b/test/express-test/routes/index.js new file mode 100644 index 0000000..ecca96a --- /dev/null +++ b/test/express-test/routes/index.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function(req, res, next) { + res.render('index', { title: 'Express' }); +}); + +module.exports = router; diff --git a/test/express-test/routes/users.js b/test/express-test/routes/users.js new file mode 100644 index 0000000..623e430 --- /dev/null +++ b/test/express-test/routes/users.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +router.get('/', function(req, res, next) { + res.send('respond with a resource'); +}); + +module.exports = router; diff --git a/test/express-test/views/error.jade b/test/express-test/views/error.jade new file mode 100644 index 0000000..51ec12c --- /dev/null +++ b/test/express-test/views/error.jade @@ -0,0 +1,6 @@ +extends layout + +block content + h1= message + h2= error.status + pre #{error.stack} diff --git a/test/express-test/views/index.jade b/test/express-test/views/index.jade new file mode 100644 index 0000000..3d63b9a --- /dev/null +++ b/test/express-test/views/index.jade @@ -0,0 +1,5 @@ +extends layout + +block content + h1= title + p Welcome to #{title} diff --git a/test/express-test/views/layout.jade b/test/express-test/views/layout.jade new file mode 100644 index 0000000..15af079 --- /dev/null +++ b/test/express-test/views/layout.jade @@ -0,0 +1,7 @@ +doctype html +html + head + title= title + link(rel='stylesheet', href='/stylesheets/style.css') + body + block content