From cef44e9b77e4041bbe54585d8ed7af0a7a4396da Mon Sep 17 00:00:00 2001 From: Craig Condon Date: Fri, 28 Feb 2014 10:20:53 -0800 Subject: [PATCH 1/9] Update README.md --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 429c2de..90af22b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,15 @@ Compile javascript **with** node.js. This allows you to move your executable around *without* needing to install the node.js runtime. + +### Motivation + +- Developing client-side utilities without requiring to install a bunch of dependencies first (node.js, npm). +- Ability to run multiple node.js applications with *different* node.js runtimes. +- Distributable packages without needing node / npm. +- Starts faster. +- Lockdown specific application versions, and easily rollback. +- Faster deployments. + ## Requirements - Linux / Mac @@ -23,14 +33,6 @@ Or git: git clone ``` - -### Motivation - -- Developing client-side utilities without requiring to install a bunch of dependencies first (node.js, npm). -- Ability to run multiple node.js applications with *different* node.js runtimes. -- Distributable packages without needing node / npm. -- Loads faster. - ### CLI Usage ````text From 3eea6784dd86edc34176dd5158160a508a00b6f5 Mon Sep 17 00:00:00 2001 From: Craig Condon Date: Fri, 28 Feb 2014 10:21:17 -0800 Subject: [PATCH 2/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 90af22b..7d967fe 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Compile javascript **with** node.js. This allows you to move your executable aro ### Motivation -- Developing client-side utilities without requiring to install a bunch of dependencies first (node.js, npm). +- Developing client-side utilities without requiring to install a bunch of dependencies first (node.js, npm, additional deps). - Ability to run multiple node.js applications with *different* node.js runtimes. - Distributable packages without needing node / npm. - Starts faster. From 8c8a1eddd7a40a6b15e1cf05e85125765916c0b5 Mon Sep 17 00:00:00 2001 From: Craig Condon Date: Fri, 28 Feb 2014 10:21:27 -0800 Subject: [PATCH 3/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7d967fe..723cba7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Compile javascript **with** node.js. This allows you to move your executable aro ### Motivation -- Developing client-side utilities without requiring to install a bunch of dependencies first (node.js, npm, additional deps). +- Developing client-side utilities without requiring to install a bunch of dependencies first (node.js, npm, other libs). - Ability to run multiple node.js applications with *different* node.js runtimes. - Distributable packages without needing node / npm. - Starts faster. From 934c7bb3d5bff489cbe34e8f8673737b509d2e93 Mon Sep 17 00:00:00 2001 From: Craig Condon Date: Fri, 28 Feb 2014 10:23:04 -0800 Subject: [PATCH 4/9] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 723cba7..ea751f8 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,8 @@ Compile javascript **with** node.js. This allows you to move your executable aro ### Motivation -- Developing client-side utilities without requiring to install a bunch of dependencies first (node.js, npm, other libs). -- Ability to run multiple node.js applications with *different* node.js runtimes. -- Distributable packages without needing node / npm. +- Ability to run multiple applications with *different* node.js runtimes. +- Distributable binaries without needing node / npm. - Starts faster. - Lockdown specific application versions, and easily rollback. - Faster deployments. From 069c910b7b7ba857363212d894c8bf04f7ecd6cd Mon Sep 17 00:00:00 2001 From: Craig Condon Date: Fri, 28 Feb 2014 10:23:40 -0800 Subject: [PATCH 5/9] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index ea751f8..14922c2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -Compile javascript **with** node.js. This allows you to move your executable around *without* needing to install the node.js runtime. - +#### Nexe is a command-line utility that compiles your Node.js application into a single executable file. ### Motivation From b11ce7540c424ca0cdc86fcd294d5600e156712c Mon Sep 17 00:00:00 2001 From: Craig Condon Date: Fri, 28 Feb 2014 10:23:52 -0800 Subject: [PATCH 6/9] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 14922c2..30960a1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -#### Nexe is a command-line utility that compiles your Node.js application into a single executable file. +### Nexe + +Nexe is a command-line utility that compiles your Node.js application into a single executable file. ### Motivation From 368195be77514fbf96b1a80536587dad459afa6a Mon Sep 17 00:00:00 2001 From: Craig Condon Date: Fri, 28 Feb 2014 10:33:18 -0800 Subject: [PATCH 7/9] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 30960a1..12cf2e5 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ Nexe is a command-line utility that compiles your Node.js application into a single executable file. +![screen shot 2014-02-28 at 10 32 54 am](https://f.cloud.github.com/assets/757408/2296993/c276f7b6-a0a6-11e3-86d3-e6c5feba2a85.png) + + ### Motivation - Ability to run multiple applications with *different* node.js runtimes. From 27075a778da5fa1fe6939b64bcd377ba7d27d8f8 Mon Sep 17 00:00:00 2001 From: Craig Condon Date: Fri, 28 Feb 2014 10:39:13 -0800 Subject: [PATCH 8/9] move utils to their own file --- bin/nexe | 2 +- lib/exe.js | 50 +++++----------------------------------------- lib/index.js | 4 +++- lib/log.js | 19 ++++++++++++++++++ lib/monkeypatch.js | 32 +++++++++++++++++++++++++++++ package.json | 7 +++++-- 6 files changed, 65 insertions(+), 49 deletions(-) create mode 100644 lib/log.js create mode 100644 lib/monkeypatch.js diff --git a/bin/nexe b/bin/nexe index 6230898..8f9f7ac 100755 --- a/bin/nexe +++ b/bin/nexe @@ -55,7 +55,7 @@ require('../lib').compile({ input : toRelative(argv.i), output : toRelative(argv.o), nodeVersion : argv.r, - temp : toRelative(argv.t) }, function(error) { + nodeTempDir : toRelative(argv.t) }, function(error) { if(error) console.log(error.message); }); diff --git a/lib/exe.js b/lib/exe.js index 98c1d07..f26d762 100644 --- a/lib/exe.js +++ b/lib/exe.js @@ -11,6 +11,10 @@ glob = require("glob"), sardines = require("sardines"), spawn = child_process.spawn; + +var _log = require("./log"), +_monkeypatch = require("./monkeypatch"); + /** */ @@ -25,7 +29,7 @@ exports.compile = function (options, complete) { */ function downloadNode (next) { - _downloadNode(options.nodeVersion, "/tmp/nexe", next); + _downloadNode(options.nodeVersion, options.nodeTempDir, next); }, /** @@ -252,33 +256,6 @@ function _monkeyPatchMainJs (compiler, complete) { ); } -/** - */ - -function _monkeypatch (filePath, monkeyPatched, processor, complete) { - - async.waterfall([ - - function read (next) { - fs.readFile(filePath, "utf8", next); - }, - - // TODO - need to parse gyp file - this is a bit hacker - function monkeypatch (content, next) { - - if (monkeyPatched(content)) return complete(); - - _log("monkey patch %s", filePath); - processor(content, next); - }, - - function write (content, next) { - fs.writeFile(filePath, content, "utf8", next); - } - ], complete); -} - - /** */ @@ -316,20 +293,3 @@ function _logProgress (req) { return req; } -/** - */ - -function _log () { - - var args = Array.prototype.slice.call(arguments, 0), - level = args.shift(); - - if (!~["log", "error", "warn"].indexOf(level)) { - args.unshift(level); - level = "log"; - } - - args[0] = "----> " + args[0]; - - console[level].apply(console, args); -} \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index ba6760c..d7c212c 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1 +1,3 @@ -module.exports = require("./exe"); \ No newline at end of file +module.exports = require("./exe"); + + diff --git a/lib/log.js b/lib/log.js new file mode 100644 index 0000000..a162c30 --- /dev/null +++ b/lib/log.js @@ -0,0 +1,19 @@ +module.exports = _log; + +/** + */ + +function _log () { + + var args = Array.prototype.slice.call(arguments, 0), + level = args.shift(); + + if (!~["log", "error", "warn"].indexOf(level)) { + args.unshift(level); + level = "log"; + } + + args[0] = "----> " + args[0]; + + console[level].apply(console, args); +} \ No newline at end of file diff --git a/lib/monkeypatch.js b/lib/monkeypatch.js new file mode 100644 index 0000000..0e78562 --- /dev/null +++ b/lib/monkeypatch.js @@ -0,0 +1,32 @@ +var async = require("async"), +fs = require("fs"); + +module.exports = _monkeypatch; + + +/** + */ + + +function _monkeypatch (filePath, monkeyPatched, processor, complete) { + + async.waterfall([ + + function read (next) { + fs.readFile(filePath, "utf8", next); + }, + + // TODO - need to parse gyp file - this is a bit hacker + function monkeypatch (content, next) { + + if (monkeyPatched(content)) return complete(); + + _log("monkey patch %s", filePath); + processor(content, next); + }, + + function write (content, next) { + fs.writeFile(filePath, content, "utf8", next); + } + ], complete); +} \ No newline at end of file diff --git a/package.json b/package.json index 3f6c268..88a4843 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Craig Condon ", "name": "nexe", "description": "Roll node.s applications into a single executable", - "version": "0.2.4", + "version": "0.2.5", "repository": { "type": "git", "url": "git://github.com/crcn/nexe.git" @@ -25,5 +25,8 @@ "bin": { "nexe": "./bin/nexe" }, - "devDependencies": {} + "devDependencies": { + "expect.js": "~0.3.1", + "mocha": "~1.17.1" + } } From 9bb3b76a651f911083ad9140a6b63b3ec68e25c4 Mon Sep 17 00:00:00 2001 From: Craig Condon Date: Fri, 28 Feb 2014 10:46:43 -0800 Subject: [PATCH 9/9] remove old file --- lib/index-old.js | 254 ----------------------------------------------- 1 file changed, 254 deletions(-) delete mode 100644 lib/index-old.js diff --git a/lib/index-old.js b/lib/index-old.js deleted file mode 100644 index 5df53b6..0000000 --- a/lib/index-old.js +++ /dev/null @@ -1,254 +0,0 @@ -var step = require("step"), -outcome = require("outcome"), -request = require("request"), -fs = require("fs"), -mkdirp = require("mkdirp"), -path = require("path"), -child_process = require("child_process"), -exec = child_process.exec, -spawn = child_process.spawn, -sprintf = require("sprintf").sprintf, -ncp = require("ncp").ncp, -sardines = require("sardines"); - -/** - */ - -exports.compile = function(args, next) { - - var on = outcome.error(next); - - args.input = require.resolve(args.input); - - step( - - /** - * 1. download node - */ - - function() { - downloadNode(args.runtime, args.temp, this); - }, - - /** - * 2. build the script into ONE file - */ - - on.success(function(node) { - console.log("making application bundle with %s", args.input); - this.node = node; - - sardines({ entries: [args.input], platform: "node" }, this); - }), - - - on.success(function(content) { - console.log("writing application bundle: \n\n%s\n\n", content); - fs.writeFile(this.nexePath = path.join(this.node.dir, "lib", "nexe.js"), content, "utf8", this); - }), - - /** - * 4. monkeypatch the node entry - */ - - on.success(function() { - console.log("monkey patching node.js file"); - monkeyPatchNodejs(this.node, this); - }), - - /** - * 5. bundle it all together - */ - - on.success(function() { - console.log("building node.js"); - this.node.make(this); - }), - - /** - * 6. copy the executable - */ - - on.success(function() { - console.log("copying binary to output directory to %s", args.output); - - mkdirp(path.dirname(args.output), this); - }), - - /** - */ - - function() { - ncp(this.node.releasePath, args.output, this); - }, - - /** - */ - - next - - ); -}; - -/** - */ - -function downloadNode(version, temp, next) { - - var tmpPath = path.join(temp, "node-" + version + ".tar.gz"), - srcDr = tmpPath.replace(/\.tar.gz$/, ""); - - - step( - - /** - * download - */ - - function() { - - //zip exists? - if(fs.existsSync(tmpPath) || fs.existsSync(srcDr)) return this(); - - console.log("downloading node %s", version); - - var output = fs.createWriteStream(tmpPath, { "flags": "w+" }), - req = request("http://nodejs.org/dist/node-" + version + ".tar.gz").pipe(output); - - output.on("close", this); - }, - - /** - * untar - */ - - function() { - - //source dir exists? - if(fs.existsSync(srcDr)) return this(); - - try { - mkdirp.sync(srcDr); - } catch(e) { - - } - - //TODO - use native zlib library for this - exec(sprintf("tar -xf '%s' -C '%s'", tmpPath, srcDr), { cwd: path.dirname(tmpPath) }, this); - }, - - /** - * cleanup the node.js file - */ - - function() { - fs.unlink(tmpfile, this); - }, - - /** - * return make script - */ - - function() { - - console.log(srcDr) - - vDir = path.join(srcDr, fs.readdirSync(srcDr).filter(function(dir) { - return !/^\./.test(dir); - }).pop()); - - next(null, { - - //the directory to the node.js file - dir: vDir, - - releasePath: path.join(vDir, "out/Release/node"), - - //makes node.js - make: function(next) { - var configure = spawn('./configure', [], { cwd: vDir }); - configure.stdout.on('data', function(data) { - process.stdout.write(data.toString()); - }); - configure.stderr.on('data', function(data) { - process.stderr.write(data.toString()); - }); - configure.on('close', function() { - var make = spawn('make', [], { cwd: vDir }); - make.stdout.on('data', function(data) { - process.stdout.write(data.toString()); - }); - make.stderr.on('data', function(data) { - process.stderr.write(data.toString()); - }); - make.on('close', next); - }); - } - }); - } - ); -} - -/** - */ - -function monkeyPatchNodejs(node, next) { - - var nodejsPath = path.join(node.dir, "src", "node.js"), - nodegypPath = path.join(node.dir, "node.gyp"), - on = outcome.error(next); - - step( - - /** - * read the node.js file - */ - - function() { - fs.readFile(nodejsPath, "utf8", this); - }, - - /** - * inject nexe as _eval IF it hasn't already been injected - */ - - on.success(function(content) { - - //nexe already injected? - if(~content.indexOf('nexe')) return this(); - - fs.writeFile(nodejsPath, - content.replace(/\(function\(process\) \{/,'(function(process) {\n process._eval = \'require("nexe");\';\n process.argv.unshift("node");\n'), - "utf8", - this); - }), - - /** - * next, find node.gyp and add nexe as a native lib file - */ - - on.success(function() { - fs.readFile(nodegypPath, "utf8", this); - }), - - /** - * finally, monkeypatch node.gyp - */ - - on.success(function(content) { - - //nexe already included as dep? - if(~content.indexOf('lib/nexe.js')) return this(); - - fs.writeFile(nodegypPath, - content.replace("'lib/fs.js',", "'lib/fs.js', 'lib/nexe.js', "), - "utf8", - this); - }), - - /** - */ - - next - ); -}