Compare commits

...

210 Commits

Author SHA1 Message Date
Jared Allard bbe26640df npm: prepare version 1.0.7, release 1.0.6 2016-01-28 15:38:43 -08:00
Jared Allard 54675f0e23 bundle: search top-level directories for browserify as well. Fixes #170. Implement support for js-flags in 0.12.x 2016-01-28 15:32:33 -08:00
Jared Allard 3ac02efd18 readme: document opts for nexe.compile and package.json 2016-01-28 14:50:37 -08:00
Jared Allard b100922d91 test: dont append os ext to test file. 2016-01-28 14:29:21 -08:00
Jared Allard 87660c3682 exe: fixes #168. Implements package.json nexe.runtime.js-flags for v8 flags. 2016-01-28 14:25:31 -08:00
Jared Allard 635cd62196 exe: handle tar extraction & download failures better 2016-01-24 21:08:38 -08:00
Jared Allard 336a5ea2e3 misc: remove .cupboard 2016-01-24 21:01:58 -08:00
Jared Allard 7fe0d207de exe: better configure error, logs, fix a bug in handling spawn args for certain node versions 2016-01-24 20:59:58 -08:00
Jared Allard 3e708ca916 npm: prepare 1.0.5 2016-01-24 17:30:40 -08:00
Jared Allard de84339c80 exe: dont check for options, yet. fixes #163 2016-01-24 17:28:04 -08:00
Jared Allard fb81a9c75e npm: prepare 1.0.4 2016-01-22 15:00:23 -08:00
Jared Allard 0e34905ddc npm/bundle: remove through depend that wasnt even used 2016-01-22 14:58:31 -08:00
Jared Allard c1e7416644 npm: fix version issue, and don't bundle src in builds 2016-01-22 14:51:16 -08:00
Jared Allard 53daa903ea readme: remove 5.x.x notice 2016-01-22 14:42:40 -08:00
Jared Allard 9e2a5f1c78 exe/bundle: fix bugs intoduced in 1.0.0. v1.0.1. Fixes #162 2016-01-22 14:37:27 -08:00
Jared Allard 82a6e8f1c7 merge: master browserify 2016-01-22 12:49:55 -08:00
Jared Allard 7641afa5a4 test: express test 2016-01-22 12:36:39 -08:00
Jared Allard 34210a3bd6 merge: manually merge master commits 2016-01-22 12:35:41 -08:00
Jared Allard 6ce224d6e4 browserify: implement error checks, path checks, and support express 2016-01-22 12:26:26 -08:00
Jared Allard 53a9c5a210 breaking changes notification 2015-11-30 13:24:11 -08:00
Jared Allard 727f081e87 Merge pull request #149 from jamiechard/master
Make checkThatExecutableExists backwards compatible
2015-11-12 14:35:49 -08:00
Jamie Chard 907be00fdc Make checkThatExecutableExists backwards compatible 2015-11-12 15:56:29 +11:00
Jared Allard 14d1ec38d1 Merge pull request #147 from jackdoe/master
add nodeConfigureArgs and nodeMakeArgs from package.json
2015-11-05 08:39:31 -08:00
borislav nikolov de531ba750 add nodeConfigureArgs and nodeMakeArgs from package.json
example:

        "runtime": {
            "framework": "nodejs",
            "version": "5.0.0",
            "ignoreFlags": true,
            "nodeConfigureArgs": ["--fully-static"],
            "nodeMakeArgs": ["-j","4"]
        }

there is no check if those flags change, which means
if they are changed you must rm -rf the temp directory

will probably push a commit that writes a checksum of them
in the node temp directory so it knows when it is invalid
2015-11-05 15:13:58 +01:00
Jared Allard a497851a74 Merge pull request #143 from vilic/master
proxy browserResolve, fix `child_process.fork` results in bad option, efforts on commander.js compatibility.
2015-10-23 16:40:24 -07:00
vilicvane 915181d0b0 Do not change --child_process path if it's absolute 2015-10-23 12:21:41 +08:00
vilicvane 002727e10f proxy browserResolve for better compatibility; fix node bad option error; change process.argv[1] to current module path for commander.js compatibility. 2015-10-22 14:45:30 +08:00
Jared Allard a9aa1f81fa Merge pull request #142 from vilic/patch-1
Fix a bug caused by last line being a `//` comment
2015-10-21 17:59:40 -07:00
vilicvane 16139e1dc7 Fix a bug caused by last line being a // comment
Such as `//# sourceMappingURL=...`.
2015-10-21 17:59:38 +08:00
Jared Allard 2bc181f2ab Merge pull request #139 from jaredallard/master
merge with master
2015-09-28 16:36:40 -07:00
Jared Allard 4c80d88013 Merge pull request #136 from 1j01/handle-build-failure
Handle build failure
2015-09-16 10:25:35 -07:00
Isaiah Odhner 36094e8d47 Handle build failure 2015-09-16 09:38:49 -04:00
Jared Allard af42599a15 use browserify cli to do this... 2015-08-19 15:59:26 -07:00
Jared Allard 78ca929350 fix insertGlobalVars 2015-08-19 15:48:22 -07:00
Jared Allard 024b9f8cb3 even more fixes
insertGlobalVars
2015-08-19 15:45:42 -07:00
Jared Allard 312a63a0b6 no wait, theirs more
insertGlobal vars, per the browserify --node  source.
2015-08-19 15:42:17 -07:00
Jared Allard 995e03eeea use the correct opts for browserify 2015-08-19 15:36:18 -07:00
Jared Allard b803ae7ddd yes, we do need that replace
fixed issues with building due to non ASCII chars.
2015-08-19 15:32:25 -07:00
Jared Allard d2e954b5ab emit error 2015-08-19 15:29:08 -07:00
Jared Allard ec421204d0 doesn't seem to work on *nix.. ? 2015-08-19 15:28:23 -07:00
Jared Allard 292063c482 remove examples, base of browserify 2015-08-19 14:59:12 -07:00
Jared Allard a0a82e9547 prepare for next version (incase of merge) 2015-08-19 14:22:30 -07:00
Jared Allard e1b30b86ae minor comsetic logging fix. vbump to v0.4.1 2015-08-09 08:42:18 -07:00
Jared Allard 4c88a01003 fix second run issues with --flag enabled. better error handling 2015-08-09 08:32:18 -07:00
Jared Allard 5dbd6b4048 package: finally got around to adding contrib 2015-06-29 10:41:16 -07:00
Jared Allard ce6c570c01 retarget 2.3.1 for nexe 2015-06-26 18:36:26 -07:00
Jared Allard 44581eb3d3 readme: note on output. 2015-06-26 18:30:35 -07:00
Jared Allard d4be3712cd exe: fixes #122, implement base nexe package field 2015-06-26 18:27:26 -07:00
Jared Allard 882c838cb5 nexe: vbump / remove devdepends 2015-06-26 15:30:02 -07:00
Jared Allard e6e49bbbd9 changelog: maintainer fix 2015-06-19 21:49:15 -07:00
Jared Allard 0ae40b9a3c manifest: async 0.9.0 => 1.2.1 2015-06-19 21:46:00 -07:00
Jared Allard 879b1598bc readme: author update 2015-06-19 21:43:23 -07:00
Jared Allard 5c40ca30af readme: clairify that all platforms require python 2015-05-31 11:53:07 -07:00
Jared Allard afb143daf4 readme: clairify building requirements. 2015-05-31 11:50:54 -07:00
RainbowDashDC 3dd5a2102f nexe: vbump and dependencies. 2015-05-01 13:29:42 -07:00
Jared Allard 2cfd10261a Merge pull request #114 from shivamadhavan/master
Updated version of dependency builtins to 1.0.1 ( inclusion of console to the built in module list )
2015-04-16 21:11:54 -07:00
Shiva Kumar Madhavan e7c7878675 Updated version of dependency builtins to 1.0.1 ( inclusion of console to the built in module list ) 2015-04-16 17:17:08 +08:00
Craig Jefferds 3b42e4a5e8 Merge pull request #111 from lahdekorpi/patch-1
Fixed typo in README.md
2015-03-30 08:51:44 -07:00
Toni Lähdekorpi c9431fc206 Fixed typo in README.md 2015-03-30 18:51:18 +03:00
Jared Allard dd68923607 Add 'readline' not include rule.
For some reason nexe attempts to include readline, this solves it. readline is a bultin of node as of 10
2015-03-20 22:08:31 -07:00
Jared Allard 8901e4a2fa Update README.md
Fixing a spelling mistake. Ugh.
2015-03-20 10:55:09 -07:00
Jared Allard 38a920be24 Update README to show new feature 2015-03-20 09:26:30 -07:00
Jared Allard ce7a36958f Merge pull request #108 from crcn/iojs
Implement io.js support! And a few fixes
2015-03-20 09:20:39 -07:00
RainbowDashDC b0644f0d62 Fixes #107, implements --framework/-F. Fetchs iojs latest. 2015-03-19 23:50:48 -07:00
RainbowDashDC 4e402bf937 Initial iojs support. 2015-03-16 10:36:39 -07:00
Jared Allard 5a3bbbad3a Add waffle.io board label 2015-03-08 20:49:52 -07:00
Christopher Karper 1d14ca6359 Freshened up all dependencies 2015-02-22 21:32:59 -05:00
Christopher Karper 1114a581ae Updated deps 2015-02-22 15:05:47 -05:00
Christopher Karper 7ab7f986cf Renamed relative to absolute 2015-02-21 19:42:04 -05:00
Christopher Karper 1d09a6b001 Update README.md
Added myself as a maintainer.
2015-02-21 19:35:17 -05:00
Christopher Karper 636268504e This was bothering me... 2015-02-21 19:02:16 -05:00
RainbowDashDC e8dead82bb Update changelog for 0.3.6 and 0.3.7 2015-02-21 01:32:20 -05:00
RainbowDashDC d2d703e9ea Publish new version to hopefully fix #103 2015-02-21 01:16:34 -05:00
Craig Jefferds 09f36c48e0 Update README.md 2015-02-18 14:18:47 -08:00
Craig Jefferds 6e2870e5d0 Update README.md 2015-02-18 14:18:29 -08:00
Jared Allard cd0e5a012c Merge pull request #102 from gitter-badger/gitter-badge
Add a Gitter chat badge to README.md
2015-02-18 13:40:14 -08:00
The Gitter Badger 17fe557afa Added Gitter badge 2015-02-18 19:35:28 +00:00
RainbowDashDC e4a8d86237 Fixes #98 by giving win32 a 100 length progress bar. 2015-02-15 19:38:35 -08:00
Jared Allard 7b3bcac07c Merge pull request #101 from CKarper/master
Lighter weight way to accomplish the exclusion of the sys module
2015-02-15 15:00:05 -08:00
Christopher Karper fb637e0da3 Lighter weight way to accomplish the exclusion of the sys module 2015-02-15 17:51:05 -05:00
Jared Allard 17c506c9cc Merge pull request #100 from CKarper/master
Stub to ignore require('sys')
2015-02-15 12:57:05 -08:00
Christopher Karper 7a25c2bfd9 This handles embedding 'bin' scripts with shebang interpreter directives at the start 2015-02-15 15:02:58 -05:00
Christopher Karper f784c79ca1 Stub to ignore require('sys') 2015-02-15 14:52:40 -05:00
RainbowDashDC bd75617a2a V bump to solve critical error. 2015-02-15 11:10:34 -08:00
RainbowDashDC b7ffb8266a Fixes #99, resolves #97 by warning on missing file. New examples. New log functions 2015-02-15 11:05:24 -08:00
Jared Allard 08b7ad765d Merge pull request #96 from CKarper/patch-1
Support .json extensions in require() resolution
2015-02-15 07:39:13 -08:00
Christopher Karper 3a7eb91d3b Support .json extensions in require() resolution
Embarrassingly simple fix.  Added .json to the list of extensions to search when a require with no extension is found.  

This resolves #57
2015-02-15 00:33:28 -05:00
RainbowDashDC a0017ed3fe Add changelog.md, add resourceFiles to example, MIT-LICENSE.txt => LICENSE.txt 2015-02-14 19:53:30 -08:00
RainbowDashDC d4205a70c3 Version bump 0.3.5, update depends 2015-02-14 09:44:49 -08:00
RainbowDashDC 380b0e9541 Add example, fix outdated examples 2015-02-14 01:57:54 -08:00
RainbowDashDC 86fa69920c Modify readme, implement cross-plat --python <loc> closes #94 2015-02-14 01:50:32 -08:00
Jared Allard 3144ae8d6f Merge pull request #95 from LorenzGardner/master
Make process.argv consistent in the child fork case
2015-02-09 17:46:51 -08:00
Lorenz Gardner 322f432756 Merge branch 'master' of https://github.com/LorenzGardner/nexe 2015-02-09 16:06:29 -06:00
Lorenz Gardner dcf44f7a80 Make process.argv consistent in the child fork cas
(argv.[0] must = the executable)
2015-02-09 16:05:09 -06:00
LorenzGardner 7b68d7bfee Merge pull request #2 from crcn/master
Pull in changes to master
2015-02-09 15:56:29 -06:00
Jared Allard 1684c8fe5d Merge pull request #93 from LorenzGardner/embedFiles
Embed files
2015-01-31 18:56:18 -08:00
Lorenz Gardner 2c132110b9 Add support for embedded files. 2015-01-06 19:05:01 -06:00
Lorenz Gardner cf97acfcdb Make the example code demonstrate forked process and dynamic require 2015-01-05 17:58:57 -06:00
LorenzGardner a1405a3b36 Merge pull request #1 from crcn/master
update
2014-12-30 12:07:37 -06:00
Craig Jefferds 6c844fa5f7 Merge pull request #92 from LorenzGardner/child.fork
Add child_process.fork support.
2014-12-23 19:59:18 -03:00
LorenzGardner a40454a5ae update read me mentioning usage of child_process.fork 2014-12-23 12:16:49 -06:00
Lorenz Gardner 94c5a54d5f Add child_process.fork support. 2014-12-23 12:01:33 -06:00
Craig Jefferds 99e228a145 Merge pull request #88 from LorenzGardner/master
Add support for JSON files, and __dirname
2014-12-19 16:05:25 -08:00
LorenzGardner 564dffe925 clarify workaround for native module support 2014-12-19 14:23:40 -06:00
Lorenz Gardner 7b9f235715 It actually makes way more sense for __driname to be exectuable dir rather
than the cwd.
2014-12-18 18:02:48 -06:00
LorenzGardner e7b28d0aa5 Update README.md
update the readme to explain how to workaround the limitations (not supporting dynamic require statements and lack of native module support the pseudo support of __dirname)
2014-12-18 17:46:55 -06:00
Lorenz Gardner bc37c3ce7b Merge branch 'JSON-Support'
Conflicts:
	lib/bundle.js
2014-12-18 17:02:29 -06:00
Lorenz Gardner 87c5e1df7d add __dirname support 2014-12-17 18:52:04 -06:00
Lorenz Gardner 05ecc6b8a5 Add JSON support for require statments. 2014-12-17 13:09:00 -06:00
LorenzIndus e89844fa78 update version of builtins in deps
Get the fix they did to include the "constants" builtin module.
2014-12-17 08:48:01 -06:00
Craig Jefferds 0637e17eb0 Merge pull request #83 from rknell/patch-1
Update README.md
2014-11-04 14:41:23 -08:00
rknell c8562c384d Update README.md
Adding missing comma to example
2014-11-05 07:57:53 +10:00
Craig Jefferds c07e1d62c7 Merge pull request #82 from RainbowDashDC/master
Prevent Windows Paths from causing issues.
2014-10-27 18:21:34 -07:00
Jared Allard ec60175d8f Prevent Windows Paths from causing issues. 2014-10-27 15:14:55 -07:00
Craig Condon 81192a7b3a v bump 2014-10-10 09:23:51 -07:00
Craig Condon 029487c187 Merge branch 'master' of github.com:crcn/nexe 2014-10-10 09:23:31 -07:00
Craig Condon 71eef791c6 fix issue loading native modules 2014-10-10 09:23:20 -07:00
Craig Jefferds e1eaaa2bfc Update README.md 2014-09-19 12:09:10 -07:00
Craig Jefferds 7ef54aa56f Merge pull request #78 from tm1000/patch-1
Update README.md
2014-09-16 11:31:11 -07:00
Craig Jefferds c09bca3462 Merge pull request #79 from tm1000/patch-2
Remove all non-ascii code from external sources
2014-09-16 11:31:01 -07:00
Andrew Nagy 552158485c Remove all non-ascii code from external sources
Remove all non-ascii code from external sources
2014-09-16 10:32:45 -07:00
Andrew Nagy 553d9a2fff Update README.md
Fix the documentation :-)
2014-09-12 16:14:04 -07:00
Craig Jefferds fcd2acfed6 Merge pull request #74 from caffeinewriter/replace-yargs
Replace optimist with yargs
2014-08-29 19:13:00 -07:00
Brandon Anzaldi 5c20233ba5 Replace optimist with yargs in nexe bin 2014-08-29 18:44:52 -07:00
Brandon Anzaldi 3a74fddcf6 Replace Optimist with Yargs in Package.json 2014-08-29 18:43:06 -07:00
Craig Condon 839741d36f cleanup 2014-08-10 23:46:38 -07:00
Craig Condon 9080b05b72 include all node.js builtins 2014-08-10 23:32:01 -07:00
Craig Condon de0a2cd517 v bump 2014-07-30 12:22:50 -07:00
Craig Condon 0f038b1de1 filter http 2014-07-30 12:22:37 -07:00
Craig Condon d7a909da71 remove commented out code 2014-07-30 11:38:16 -07:00
Craig Condon aeeb24c757 v bump 2014-07-30 11:37:20 -07:00
Craig Condon 3cc7c68b12 remove sardines - move into nexe. Use bundle.js 2014-07-30 11:37:05 -07:00
Craig Condon 9247016635 start on using browserify 2014-07-30 11:12:20 -07:00
Craig Condon bc4f50f69b fix #48 - ability to just run ----> bundle /Users/craig/Developer/Public/nexe/lib/index.js
unable to include script /Users/craig/Developer/Public/nexe/lib/exe.js from /Users/craig/Developer/Public/nexe/lib/index.js, Error: Cannot find module 'nexe'
    at Function.module.exports [as sync] (/Users/craig/Developer/Public/nexe/node_modules/sardines/node_modules/amdify/node_modules/resolve/lib/sync.js:32:11)
    at resolvePath (/Users/craig/Developer/Public/nexe/node_modules/sardines/node_modules/amdify/lib/pathInfo.js:135:20)
    at self.getPathInfo (/Users/craig/Developer/Public/nexe/node_modules/sardines/node_modules/amdify/lib/pathInfo.js:88:24)
    at /Users/craig/Developer/Public/nexe/node_modules/sardines/node_modules/amdify/lib/analyzeDeps.js:324:13
    at /Users/craig/Developer/Public/nexe/node_modules/async/lib/async.js:111:13
    at Array.forEach (native)
    at _each (/Users/craig/Developer/Public/nexe/node_modules/async/lib/async.js:32:24)
    at Object.async.each (/Users/craig/Developer/Public/nexe/node_modules/async/lib/async.js:110:9)
    at scanRequired (/Users/craig/Developer/Public/nexe/node_modules/sardines/node_modules/amdify/lib/analyzeDeps.js:321:9)
    at Function.on.success.deps.forEach.dep.source (/Users/craig/Developer/Public/nexe/node_modules/sardines/node_modules/amdify/lib/analyzeDeps.js:245:5) in cwd. Resolves package.json main script
2014-05-28 10:47:52 -07:00
Craig Condon 8a0121023e Merge pull request #55 from fritx/patch-1
Update README.md
2014-05-28 10:28:08 -07:00
Fritz Lin 7308d9665d Update README.md
Better style with Code Usage in README.md
2014-05-28 22:02:28 +08:00
Craig Condon 95afa87f71 v bump 2014-05-13 11:42:44 -07:00
Craig Condon adff5a3a7c Merge pull request #52 from jhbruhn/master
Windows support
2014-05-12 14:40:28 -07:00
Jan-Henrik 9f86d88ec5 Added Windows support to Readme 2014-05-12 20:33:04 +02:00
Jan-Henrik fd01aac2e7 Added Windows Support using vcbuild.bat 2014-05-12 20:29:02 +02:00
Craig Condon 9d372ffecd added progress to package.json 2014-03-06 11:28:00 -08:00
Craig Condon 5148a0b980 Merge pull request #46 from northshorenetworks/master
Updated README.md
2014-02-28 19:43:16 -08:00
Adam Snodgrass a20406b427 Updated README.md 2014-02-28 21:40:59 -06:00
Craig Condon f74a47f483 Merge pull request #45 from northshorenetworks/master
Remove duplicate _log definition in monkeypatch.js
2014-02-28 19:39:44 -08:00
Adam Snodgrass 1e982d0e82 Remove duplicate _log definition 2014-02-28 21:35:56 -06:00
Adam Snodgrass 7fd13d837c Merge pull request #2 from crcn/master
Pull in crcn/nexe master changes
2014-02-28 21:33:12 -06:00
Craig Condon 932db9813d Merge pull request #44 from northshorenetworks/master
Add option to pass through CLI flags but ignore node and v8 flags
2014-02-28 19:31:00 -08:00
Adam Snodgrass a0202559bc Add option to disable node and v8 flags and pass through app flags 2014-02-28 21:16:38 -06:00
Craig Condon c9025d1c74 fix typo 2014-02-28 19:01:16 -08:00
Adam Snodgrass fb57b09e66 Added progress to package.json dependencies; Defined _log in monkeypatch.js 2014-02-28 18:54:38 -06:00
Adam Snodgrass 9742681c09 Merge pull request #1 from crcn/master
Pull in crcn/nexe master changes
2014-02-28 18:14:51 -06:00
Craig Condon ca3ab97bee remove old file 2014-02-28 10:46:43 -08:00
Craig Condon 078540697c resolve merge conflict 2014-02-28 10:40:07 -08:00
Craig Condon c583e2f029 move utils to their own file 2014-02-28 10:39:13 -08:00
Craig Condon 5a7a7c9fe5 Update README.md 2014-02-28 10:33:18 -08:00
Craig Condon 0868535bbe Update README.md 2014-02-28 10:23:52 -08:00
Craig Condon 2164621498 Update README.md 2014-02-28 10:23:40 -08:00
Craig Condon 2683359460 Update README.md 2014-02-28 10:23:04 -08:00
Craig Condon 94a82867fe Update README.md 2014-02-28 10:21:27 -08:00
Craig Condon a91d0428df Update README.md 2014-02-28 10:21:17 -08:00
Craig Condon 1dee735cdb Update README.md 2014-02-28 10:20:53 -08:00
Craig Condon ed36ebb795 Merge pull request #42 from northshorenetworks/master
Add platform detection for openbsd & freebsd compatibility
2014-02-28 10:17:06 -08:00
Adam Snodgrass 10af1803ab Add platform detection for openbsd & freebsd compatibility 2014-02-27 23:08:33 -08:00
Craig Condon 9f93ac0e1e Merge branch 'master' of github.com:crcn/nexe 2014-02-27 16:49:56 -08:00
Craig Condon 66bde4c761 refactor 2014-02-27 16:49:35 -08:00
Craig Condon 3803fdaf15 Merge pull request #36 from tallesl/issue35
Solves #35
2013-12-12 22:18:07 -08:00
Talles L 847616a295 Solves #35 2013-12-13 03:25:03 -02:00
Craig Condon 085e475bd4 cleanup 2013-10-14 10:40:46 -07:00
Craig Condon 273e864e07 download latest version 2013-10-14 10:29:35 -07:00
Craig Condon 46b2761db8 v bump 2013-10-14 10:26:47 -07:00
Craig Condon 254615894f Merge branch 'master' of github.com:crcn/nexe 2013-10-14 10:25:57 -07:00
Craig Condon 1aa897e132 update node version 2013-10-14 10:25:46 -07:00
Craig Condon 8552619bc5 Merge pull request #32 from samyakbhuta/master
Installing 'nexe' globally.
2013-10-14 10:22:52 -07:00
Samyak Bhuta 9007a080cf Added preference for global install. 2013-10-14 18:47:33 +05:30
Samyak Bhuta 46503af805 'nexe', can be installed globally. 2013-10-14 16:28:08 +05:30
Craig Condon 758803540b Merge pull request #29 from alexwhitman/node-argv
Unshift 'node' onto process.argv
2013-08-18 10:36:51 -07:00
Alex Whitman 424a7bdcbb Unshift 'node' onto process.argv
The node executable is the first value in argv. This was missing after
compiling.
2013-08-18 18:16:23 +01:00
Craig Condon d44199e592 Merge pull request #28 from alexwhitman/fixup
Linting, spawning and temp directory
2013-08-17 08:37:59 -07:00
Alex Whitman 7d783ced63 Add temp option to README 2013-08-17 12:40:00 +01:00
Alex Whitman 85b9250b9a Add -t|--temp option to specify location for node.js sources 2013-08-17 12:04:38 +01:00
Alex Whitman b2871f09cd Rewrite configure/make spawning 2013-08-17 11:36:03 +01:00
Alex Whitman 6ff539b4e6 Fix up linting warnings
- Mix of tabs and spaces
- Trailing whitepsace
- Missing semi-colons
2013-08-17 10:31:55 +01:00
Craig Condon e8ea712a45 fix #26 - should resolve to absolute path unless / is the first character 2013-07-26 13:40:54 -07:00
Craig Condon c3c1ddaaf0 added mit license 2013-06-04 14:32:26 -07:00
Craig Condon b89f9650c5 update readme 2013-04-29 12:41:14 -07:00
Craig Condon b78cea8c35 updated example 2013-04-09 13:52:47 -07:00
Craig Condon ddea854649 replace browserify with sardines 2013-04-09 13:37:45 -07:00
Craig Condon 0281273cd0 v bump 2013-02-27 11:27:10 -08:00
Craig Condon 336a30e7c0 added ability to use -h or --help for help menu 2013-02-27 11:26:44 -08:00
Craig Condon 4f9c040d74 properly parse relative path 2013-02-01 11:39:52 -08:00
Craig Condon cdbdbfbb0d cleanup 2013-02-01 11:39:32 -08:00
Craig Condon 63ba6a307b Merge branch 'master' of github.com:crcn/nexe 2013-02-01 11:37:03 -08:00
Craig Condon bea9181be6 properly parse relative path 2013-02-01 11:36:47 -08:00
Craig Condon 6a62ea8f10 Update README.md 2013-02-01 11:30:47 -08:00
Craig Condon f1a0eb88fd added dependency 2013-01-31 12:19:14 -08:00
Craig Condon e43a473559 Update README.md 2012-12-02 12:08:10 -06:00
Craig Condon 207e381309 remove node modules 2012-11-30 20:17:44 -06:00
Craig Condon 14005e70d9 cleanup 2012-11-30 20:16:17 -06:00
Craig Condon d6b65478ce finally works 2012-11-30 20:12:56 -06:00
Craig Condon 11aaccdf66 finally works 2012-11-30 20:11:55 -06:00
Craig Condon 45dd2d2680 fix package repo 2012-02-17 14:54:58 -06:00
Craig Condon a1a06e310c update pkg 2011-11-30 12:55:16 -06:00
Craig Condon 716d947914 updated readme 2011-11-26 17:34:11 -06:00
Craig Condon 5076c15e76 typo 2011-11-26 17:30:50 -06:00
Craig Condon 2995a3d916 can build node.js file from cwd now 2011-11-26 17:30:13 -06:00
Craig Condon d0e259be6f can build node.js file from cwd now 2011-11-26 17:24:25 -06:00
Craig Condon b2f621d7d0 updated readme 2011-11-26 17:03:30 -06:00
Craig Condon a2f6492d71 updated readme 2011-11-26 17:03:08 -06:00
Craig Condon c8aa6a8326 updated readme 2011-11-26 17:01:47 -06:00
Craig Condon 9b82355175 ability to build executables 2011-11-26 17:00:12 -06:00
45 changed files with 1627 additions and 1870 deletions
-2
View File
@@ -1,2 +0,0 @@
[commands]
proj = subl --project project.sublime-project
+12
View File
@@ -0,0 +1,12 @@
node_modules
.DS_Store
*.nex
src
nexe.exe
nexe
npm-debug.log
test/**/src
test/**/out.nex
test/**/test.nex
test/**/tmp
test/**/node_modules
+59
View File
@@ -0,0 +1,59 @@
# Nexe ChangeLog
## 2015-02-20, Version v0.3.7, @jaredallard
### Noteable Changes
* Fixed #103.
* Made not-available require not a fatal error.
* Stub and system to ignore certain requires.
* Added 'sys' to ignore list.
* We have a gitter!
* Gave win32 a 100 length progress bar.
### Commits
* [**2cacd83**] Update README.md (@crcn)
* [**0e90ac9**] Update README.md (@crcn)
* [**54967d1**] Added Gitter badge (@jaredallard)
* [**bb489a3**] Fixes #98 by giving win32 a 100 length progress bar. (@jaredallard)
* [**39665a8**] Lighter weight way to accomplish the exclusion of the sys module (@CKarper)
* [**5aca22d**] This handles embedding 'bin' scripts with shebang interpreter... (@CKarper)
* [**e79b0fb**] Stub to ignore require('sys') (@CKarper)
## 2015-02-15, Version v0.3.6, @jaredallard
### Noteable Changes
* Now support .json in require.
* Fixed a major --python flag bug.
### Commits
* [**cac6986**] V bump to solve critical error. (@jaredallard)
* [**b040337**] Fixes #99, resolves #97 by warning on missing file. New examples... (@jaredallard)
* [**ad4da1d**] Support .json extensions in require() resolution (@CKarper)
## 2015-02-14, Version v0.3.5, @jaredallard
### Noteable Changes
* Added new flag: `--python </path/to/python>`
* Added resourceFiles option which allows embedding files and getting them via embed.js
* Updated a bunch of the dependencies.
* `process.argv` is now consistent in a child fork case.
* Added `child_process.fork` support.
* Added new collaborators:
* Jared Allard (@jaredallard)
### Commits
* [**e4155c8**] Version bump 0.3.5, update depends (@jaredallard)
* [**e91f5b5**] Add example, fix outdated examples (@jaredallard)
* [**3b1d5a9**] Modify README, implement cross-plat `--python <loc>` closes #94 (@jaredallard)
* [**29d5f6a**] Make `process.argv` consistent in the child fork case (@LorenzGardner)
* [**97dbd37**] Add support for embedded files. (@LorenzGardner)
* [**b615e12**] Make the example code demonstrate forked process and dynamic require (@LorenzGardner)
* [**333cc69**] update read me mentioning usage of `child_process.fork` (@LorenzGardner)
* [**ece4b2d**] Add `child_process.fork` support. (@LorenzGardner)
+20
View File
@@ -0,0 +1,20 @@
Copyright (c) 2013 Craig Condon
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+157 -29
View File
@@ -1,58 +1,186 @@
Compile javascript **with** node.js. This allows you to move your executable around *without* needing to install the node.js runtime.
### Nexe
## Requirements
[![Join the chat at https://gitter.im/crcn/nexe](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/jaredallard/nexe?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Dependency Status](https://david-dm.org/jaredallard/nexe.svg)](https://david-dm.org/crcn/nexe)
[![Stories in Ready](https://badge.waffle.io/jaredallard/nexe.svg?label=ready&title=Ready)](http://waffle.io/jaredallard/nexe)
- Linux / Mac
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.
- Distributable binaries without needing node / npm.
- Starts faster.
- Lockdown specific application versions, and easily rollback.
- Faster deployments.
## Building Requirements
- Linux / Mac / BSD / Windows
- Python 2.6 or 2.7 (use --python if not in PATH)
- Windows: Visual Studio 2010+
## Caveats
### Doesn't support native modules
- Use the techniques below for working around dynamic require statements to exclude the module from the bundling, and deploy along side the executable in a node_module folder so your app can find it. Note: On windows you may need to have your app be named node.exe if .node file depends on node.
### Doesn't support dynamic require statements
Such As:
```javascript
var x = require(someVar);
```
In this case nexe won't bundle the file
```javascript
var x;
if (someCheck) {
x = require("./ver1.js");
} else {
x = require("./var2.js");
}
```
In this case nexe will bundle both files.
Workarounds:
1) for dynamic requires that you want bundled add the following into your project
```javascript
var dummyToForceIncludeForBundle = false;
if (dummyToForceIncludeForBundle) {
require("./loadedDynamicallyLater.js");
// ...
}
```
this will trick the bundler into including them.
2) for dynamic files getting included that you don't want to be
```javascript
var moduleName = "./ver2.js";
if (someCheck) {
moduleName = "./ver1.js";
}
var x = require(moduleName);
```
Note: neither file will be bundled.
Using these two techniques you can change your application code so modules are not bundles, and generate a includes.js file as part of your build process so that the right files get bundled for your build configuration.
### &#95;&#95;dirname
Once the module is bundled it is part of the executable. &#95;&#95;dirname is therefore the executable dir (process.execPath). Thus if you put resources on a relative path from the the executable your app will be able to access them.
If you had a data file at `/dev/myNodeApp/stateManager/handler/data/some.csv`
and a file at `/dev/myNodeApp/stateManager/handler/loader.js`
```javascript
module.exports = fw.readFileSync(path.join(__dirname, "./data/some.csv"));
```
You would need to deploy some.csv in a sub dir `data/` along side your executable
There are potential use cases for &#95;&#95;dirname where the executable path is not the correct substitution, and could result in a silent error (possibly even in a dependency that you are unaware of).
Note: &#95;&#95;filename will be 'undefined'
### child_process.fork
child_process.spawn works is unmodified, but child_process.fork will make an attempt to launch a new instance of your executable and run the bundled module.
## Installation
Via NPM:
```bash
npm install nexe
npm install nexe [-g]
```
Or git:
```bash
git clone
git clone https://github.com/crcn/nexe.git
```
### 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.
### CLI Usage
````text
Commands:
-i the input javascript files
-o the output executable
--runtime the runtime version of node.js to compile with
```text
Examples:
-i input.js -o my-binary --runtime=0.6.2 compile javascript file with node
Usage: nexe -i [sources] -o [binary] [options]
````
Options:
-i, --input The entry javascript files [default: cwd]
-o, --output The output binary [default: out.nex]
-r, --runtime The node.js runtime to use [default: "latest"]
-t, --temp The path to store node.js sources [default: ./tmp/nexe]
-f, --flags Don't parse node and v8 flags, pass through app flags [default: false]
-v, --version Display version number
-p, --python Set path of python to use. [default: "python"]
-F, --framework Set the framework to use. [default: "nodejs"]
```
### Code usage
### Code Usage
````javascript
```javascript
var nexe = require('nexe');
var nexe = require('nexe');
nexe.compile('input.js', 'output.bin', function() {
});
````
nexe.compile({
input: 'input.js', // where the input file is
output: 'path/to/bin', // where to output the compiled binary
nodeVersion: '5.5.0', // node version
nodeTempDir: 'src', // where to store node source.
nodeConfigureArgs: ['opt', 'val'], // for all your configure arg needs.
nodeMakeArgs: ["-j", "4"], // when you want to control the make process.
python: 'path/to/python', // for non-standard python setups. Or python 3.x forced ones.
resourceFiles: [ 'path/to/a/file' ], // array of files to embed.
flags: true, // use this for applications that need command line flags.
jsFlags: "--use_strict", // v8 flags
framework: "node" // node, nodejs, or iojs
}, function(err) {
if(err) {
return console.log(err);
}
// do whatever
});
```
### package.json inclusion
As of 0.4.0 you can now embed nexe options into package.json. Note that this Format
is still in works, so it is likely to change.
```json
"nexe": {
"input": "./bin/nexe",
"output": "nexe^$",
"temp": "src",
"runtime": {
"framework": "node",
"version": "5.5.0",
"js-flags": "--use_strict",
"ignoreFlags": true
}
}
```
Notes:
* output: can use ^$ for platform specific file extension
* js-flags: this is also known as v8 flags, and supports *all* v8 flags.
## Maintainers
* __Jared Allard__ ([@jaredallard](https://github.com/jaredallard)) &lt;[jaredallard@outlook.com](mailto:jaredallard@outlook.com)&gt; (Active)
* __Christopher Karper__ ([@ckarper](https://github.com/CKarper)) &lt;[Christopher.Karper@gmail.com](mailto:Christopher.Karper@gmail.com)&gt; (Active)
* __Craig Condon__ ([@crcn](https://github.com/crcn)) &lt;[craig.j.condon@gmail.com](mailto:craig.j.condon@gmail.com)&gt; (Old Project Owner)
Regular → Executable
+94
View File
@@ -1,2 +1,96 @@
#!/usr/bin/env node
var path = require('path'),
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()
}).
options('o', {
demand: true,
alias: 'output',
desc: 'The output binary',
default: "out.nex"
}).
options('r', {
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'
}).
options('f', {
alias: 'flags',
description: 'Don\'t parse node and v8 flags, pass through app flags',
default: false
}).
options('v', {
alias: 'version',
description: 'Display version number'
}).
options('p', {
alias: 'python',
description: 'Set path of python to use.',
default: 'python'
}).
options('F', {
alias: 'framework',
description: 'Set the framework to use',
default: 'nodejs'
});
var argv = cli.argv;
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();
}
/**
* 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(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);
}
}
);
}
+108
View File
@@ -0,0 +1,108 @@
/**
* Copyright (c) 2013 Craig Condon
* Copyright (c) 2015-2016 Jared Allard
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**/
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");
/**
* 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)
**/
function bundle (input, nc, complete) {
var bundlePath = path.join(nc, "lib", "nexe.js");
var ws = fs.createWriteStream(bundlePath);
var browserifyExec;
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;
}
}
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");
})
ws.on('error', function(err) {
console.log(err);
_log('error', 'Failed to save stdout to disk');
process.exit(1);
})
ws.on('close', function() {
var source = fs.readFileSync(bundlePath, 'utf8');
source = source.replace(/[^\x00-\x7F]/g, "");
// write the source modified to nexe.js
fs.writeFile(bundlePath, source, 'utf8', function(err) {
if(err) {
_log('error', 'failed to save source');
process.exit(1);
}
complete();
});
});
}
module.exports = bundle;
+65
View File
@@ -0,0 +1,65 @@
/**
* Copyright (c) 2013 Craig Condon
* Copyright (c) 2015-2016 Jared Allard
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**/
var path = require("path"),
fs = require("fs");
/**
* TODO: Optimize this code. (more like document it so I understand it better.)
**/
function embed(resourceFiles, resourceRoot, complete) {
function encode(filePath) {
return fs.readFileSync(filePath).toString('base64');
}
resourceFiles = resourceFiles || [];
resourceRoot = resourceRoot || "";
if (!Array.isArray(resourceFiles)) {
throw new Error("Bad Argument: resourceFiles is not an array");
}
var buffer = "var embeddedFiles = {\n";
for (var i = 0; i < resourceFiles.length; ++i) {
buffer += JSON.stringify(path.relative(resourceRoot, resourceFiles[i])) + ': "';
buffer += encode(resourceFiles[i]) + '",\n';
}
buffer += "\n};\n\nmodule.exports.keys = function () { return Object.keys(embeddedFiles); }\n\nmodule.exports.get = ";
buffer += accessor.toString();
complete(null, buffer);
}
var accessor = function (key) {
if (embeddedFiles.hasOwnProperty(key)) {
return new Buffer(embeddedFiles[key], 'base64');
}
else {
//file was not embedded, throw err.
throw new Error('Embedded file not found');
}
}
module.exports = embed;
+879
View File
@@ -0,0 +1,879 @@
/**
* Copyright (c) 2013 Craig Condon
* Copyright (c) 2015-2016 Jared Allard
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* 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"),
path = require("path"),
fs = require("fs"),
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"),
targz = require('tar.gz'),
_log = require("./log"),
_monkeypatch = require("./monkeypatch"),
spawn = child_process.spawn;
var isWin = /^win/.test(process.platform);
var isPy;
var framework;
var version;
var option_list = [
"python",
"input",
"output",
"nodeTempDir",
"flags",
"framework",
"nodeConfigureArgs",
"nodeMakeArgs",
"nodeVersion"
]
/**
* Compiliation process.
*/
exports.compile = function (options, complete) {
var nodeCompiler, nexeEntryPath;
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;
}
_log("set python as "+isPy);
} else {
isPy="python";
}
// remove dots
options.framework = options.framework.replace(/\./g, "");
// set outter-scope framework variable.
framework = options.framework;
_log("framework => "+framework);
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.
// 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);
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);
// continue down along the async road
next();
});
} else {
next();
}
},
/**
* first download node
*/
function downloadNode (next) {
_downloadNode(version, options.nodeTempDir, options.nodeConfigureArgs, options.nodeMakeArgs, next);
},
/**
* bundle the application into one script
*/
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 writeResources (resources, next) {
resourcePath = path.join(nodeCompiler.dir, "lib", "nexeres.js");
_log("resource -> %s", resourcePath);
fs.writeFile(resourcePath, resources, next);
},
/**
* monkeypatch some files so that the nexe.js file is loaded when the app runs
*/
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();
}
},
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);
},
/**
* 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();
}
});
},
/**
* compile the node application
*/
function makeExecutable (next) {
if(isWin) {
_log("vcbuild [make stage]");
} else {
_log("make");
}
nodeCompiler.make(next);
},
/**
* we create the output directory if needed
*/
function makeOutputDirectory (next) {
mkdirp(path.dirname(options.output), function(){ next(); });
},
/**
* 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();
}
});
},
/**
* 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');
next();
});
}
], complete);
}
/**
* Download a version of node
*
* @param {string} version, version of node to download
* @param {string} directory, where to store the downloaded src
* @param {function} complete, callback
*/
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"));
// might already be downloaded, and unzipped
if (_getNodeCompiler(nodeFileDir, nodeConfigureArgs, nodeMakeArgs, complete)) {
return;
}
async.waterfall([
/**
* first make the directory where the zip file will live
*/
function makeDirectory (next) {
mkdirp.sync(path.dirname(nodeFilePath));
next();
},
/**
* download node into the target directory
*/
function downloadNode (next) {
if (fs.existsSync(nodeFilePath)) return next();
var uri = framework;
if(framework==="node") {
uri = 'nodejs'; // if node, use nodejs uri
} else if(framework === 'nodejs') {
framework = 'node'; // support nodejs, and node, as framework.
}
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";
}
_log("downloading %s", url);
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"
}
}
_logProgress(request(requestOptions)).pipe(output);
output.on("close", function () { next(); });
},
/**
* unzip in the same directory
*/
function unzipNodeTarball (next) {
if(isWin) {
_log("Extracting the .tar.gz.");
new targz().extract(nodeFilePath, nodeFileDir, next);
} else {
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);
tar.on("close", function () { next(); })
tar.on("error", function (err) {
console.log(err);
_log("error", "failed to extract the node tar file.");
process.exit(1);
});
}
},
/**
* return the compiler object for the node version
*/
function (next, type) {
_getNodeCompiler(nodeFileDir, nodeConfigureArgs, nodeMakeArgs, next, type)
},
], complete);
}
/**
* Get the compilier we will use for whatever platform we may be on and configure
* it.
*/
function _getNodeCompiler (nodeFileDir, nodeConfigureArgs, nodeMakeArgs, complete, type) {
var dir = _getFirstDirectory(nodeFileDir);
// standard
var executable = "node.exe";
var binary = "node";
// 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(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;
var conf = [cfg];
if(isPy !== "python") {
conf = [conf].concat(nodeConfigureArgs);
}
// should work for all use cases now.
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);
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);
/* 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)
}
}
});
}
configure.stdout.pipe(process.stdout);
configure.stderr.pipe(process.stderr);
// on error
configure.on("error", function(err) {
console.log('Error:', err);
console.log('');
console.log('Details:');
console.log('command =', isPy, cfg, conf_args || '');
console.log('cwd =', dir);
var configure_path = path.join(dir, 'configure');
var contains_configure = fs.existsSync(configure_path);
console.log('cwd contains configure,', (contains_configure ? colors.green('yes') : colors.red('no')));
var configure_size = fs.statSync(configure_path).size;
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");
// loop over depends
_loop(dir);
}
if(nodeMakeArgs === undefined) {
nodeMakeArgs = [];
}
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);
make.on("error", function(err) {
console.log(err);
_log("error", "failed to run make.");
process.exit(1);
})
make.on("close", function () {
next();
});
})
}
});
}
return true;
}
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)
},
/**
* monkeypatch main entry point
*/
function (next) {
_monkeyPatchMainJs(compiler, next)
}
], complete);
}
/**
* patch the gyp file to allow our custom includes
*/
function _monkeyPatchGyp (compiler, complete) {
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
)
}
/**
*/
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\) \{/,'\
(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
);
}
/**
*/
function _monkeyPatchChildProcess(compiler, complete) {
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
);
}
/**
* Patch node.cc to not check the internal arguments.
*/
function _monkeyPatchMainCc(compiler, complete) {
var mainPath = path.join(compiler.dir, "src", "node.cc");
_monkeypatch(
mainPath,
function (content) {
return ~content.indexOf('// // TODO use parse opts');
},
function (content, next) {
var lines = content.split('\n');
var endLine = lines.indexOf(' option_end_index = i;'); // pre node 0.11.6 compat
if(endLine !== -1) { // check if it succedded or not.
lines[endLine] = ' option_end_index = 1;';
_log("patched node.cc")
}
/**
* This is the new method of passing the args. Tested on node.js 0.12.5
* and iojs 2.3.1
**/
if(endLine === -1) { // only if the pre-0.12.5 failed.
var startLine = lines.indexOf(' while (index < nargs && argv[index][0] == \'-\') {'); // beginning of the function
endLine = lines.indexOf(' // Copy remaining arguments.');
endLine = endLine-1; // space, then it's at the }
// remove the offending lines
if(startLine !== -1) {
for (var i = startLine; i < endLine; i++) {
lines[i] = undefined; // set the value to undefined so it's skipped by the join
}
_log('patched node.cc');
}
}
lines = lines.join('\n');
next(null, lines);
},
complete
);
}
/**
* Patch flags.cc from deps/v8/src to use hard-coded flags.
* 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");
fs.readFile(mainPath, {encoding: 'utf8'}, function(err, contents) {
if(err) {
return _log('error', 'failed to read', mainPath);
}
// Super simple injection here. Perhaps make it an array at somepoint?
var injection = '\
const char* nexevargs = "{{args}}";\n\
int nexevargslen = strlen(nexevargs);\n\
SetFlagsFromString(nexevargs, nexevargslen);\n\
';
var injectionSplit = injection.split('\n');
var injectionLength = injectionSplit.length;
var contentsSplit = contents.split('\n');
var contentsLength = contentsSplit.length;
var lastInjectionLine = injectionSplit[injectionLength-2];
var lineToInjectAfter = contentsSplit.indexOf(' ComputeFlagListHash();');
var haveWeInjectedBefore = contentsSplit.indexOf(lastInjectionLine);
var lineInjectDifference = contentsLength - lineToInjectAfter;
// support for 0.12.x
if(lineToInjectAfter===-1) {
_log('warn', 'Using an expiramental support patch for 0.12.x');
lineToInjectAfter = contentsSplit.indexOf('#undef FLAG_MODE_DEFINE_IMPLICATIONS');
}
// this is debug, comment out.
// _log('v8 injection is', injectionLength, 'newlines long');
// _log('v8 flags source is', contentsLength, 'newlines long');
// console.log(finalContents)
var finalContents,
dontCombine;
if(lineToInjectAfter !== -1 && haveWeInjectedBefore === -1) {
_log('injecting v8 args c++');
// super debug
// _log('v8 injection determined by', lastInjectionLine);
// _log('v8 inject after line', lineToInjectAfter);
// _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 endShiftLine = lineToInjectAfter;
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] = '';
}
var injectionPos = 0;
for(var i = 0; i !== injectionLength-1; i++) {
contentsSplit[(lineToInjectAfter+1)+injectionPos] = injectionSplit[injectionPos];
injectionPos++;
}
} 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+'";');
} else {
_log('warn', '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);
return process.exit(1);
}
if(!dontCombine) {
finalContents = contentsSplit.join('\n');
}
fs.writeFile(mainPath, finalContents, {encoding: 'utf8'}, function(err) {
if(err) {
_log('error', 'failed to write to', mainPath);
return process.exit(1);
}
return complete();
})
});
}
/**
* Get the first directory of a string.
*/
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;
}
return false;
}
/**
* Log the progress of a request object.
*/
function _logProgress (req) {
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
});
req.on("data", function (chunk) {
bar.tick(chunk.length);
});
});
req.on("error", function(err) {
console.log(err);
_log("error", "failed to download node sources,");
process.exit(1);
});
return req;
}
/**
* Attempt to parse the package.json for nexe information.
*
* @param {string} path - path to package.json
* @param {object} options - fallback options
*
* @todo implement options overriding package defaults.
* @todo make this much less hackily implemented....
*
* @return {object} nexe.compile options object
**/
exports.package = function(path, options) {
var _package; // scope
// 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
}
// 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)
}
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;
}
+1 -3
View File
@@ -1,3 +1 @@
exports.compile = function(ops, callback) {
}
module.exports = require("./exe");
+57
View File
@@ -0,0 +1,57 @@
/**
* Copyright (c) 2013 Craig Condon
* Copyright (c) 2015-2016 Jared Allard
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**/
var colors = require('colors');
/**
* standard output, takes 3 different types.
* log, error, and warn
*
* @param {any} arguments - Text to output.
* @return undefined
**/
function _log () {
var args = Array.prototype.slice.call(arguments, 0),
level = args.shift();
if (!~["log", "error", "warn"].indexOf(level)) {
args.unshift(level);
level = "log";
}
if(level == "log") {
args[0] = "----> " + args[0];
} else if(level == "error") {
args[0] = "....> " + colors.red("ERROR: ") + args[0]
} else if(level == "warn") {
args[0] = "....> " + colors.yellow("WARNING: ") + args[0]
}
console[level].apply(console, args);
}
// export the log function, for require()
module.exports = _log;
+63
View File
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2013 Craig Condon
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**/
var async = require("async"),
fs = require("fs"),
_log = require("./log");
/**
* Monkey patch a file.
*
* @param {string} filePath - path to file.
* @param {function} monkeyPatched - function to process contents
* @param {function} processor - TODO: detail what this is
* @param {function} complete - callback
*
* @return undefined
*/
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);
}
// export the function for require()
module.exports = _monkeypatch;
-2
View File
@@ -1,2 +0,0 @@
node_modules/
node_modules/*
-4
View File
@@ -1,4 +0,0 @@
lib-cov/*
*.swp
*.swo
node_modules
-21
View File
@@ -1,21 +0,0 @@
Copyright 2010 James Halliday (mail@substack.net)
This project is free software released under the MIT/X11 license:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-474
View File
@@ -1,474 +0,0 @@
optimist
========
Optimist is a node.js library for option parsing for people who hate option
parsing. More specifically, this module is for people who like all the --bells
and -whistlz of program usage but think optstrings are a waste of time.
With optimist, option parsing doesn't have to suck (as much).
examples
========
With Optimist, the options are just a hash! No optstrings attached.
-------------------------------------------------------------------
xup.js:
````javascript
#!/usr/bin/env node
var argv = require('optimist').argv;
if (argv.rif - 5 * argv.xup > 7.138) {
console.log('Buy more riffiwobbles');
}
else {
console.log('Sell the xupptumblers');
}
````
***
$ ./xup.js --rif=55 --xup=9.52
Buy more riffiwobbles
$ ./xup.js --rif 12 --xup 8.1
Sell the xupptumblers
![This one's optimistic.](http://substack.net/images/optimistic.png)
But wait! There's more! You can do short options:
-------------------------------------------------
short.js:
````javascript
#!/usr/bin/env node
var argv = require('optimist').argv;
console.log('(%d,%d)', argv.x, argv.y);
````
***
$ ./short.js -x 10 -y 21
(10,21)
And booleans, both long and short (and grouped):
----------------------------------
bool.js:
````javascript
#!/usr/bin/env node
var util = require('util');
var argv = require('optimist').argv;
if (argv.s) {
util.print(argv.fr ? 'Le chat dit: ' : 'The cat says: ');
}
console.log(
(argv.fr ? 'miaou' : 'meow') + (argv.p ? '.' : '')
);
````
***
$ ./bool.js -s
The cat says: meow
$ ./bool.js -sp
The cat says: meow.
$ ./bool.js -sp --fr
Le chat dit: miaou.
And non-hypenated options too! Just use `argv._`!
-------------------------------------------------
nonopt.js:
````javascript
#!/usr/bin/env node
var argv = require('optimist').argv;
console.log('(%d,%d)', argv.x, argv.y);
console.log(argv._);
````
***
$ ./nonopt.js -x 6.82 -y 3.35 moo
(6.82,3.35)
[ 'moo' ]
$ ./nonopt.js foo -x 0.54 bar -y 1.12 baz
(0.54,1.12)
[ 'foo', 'bar', 'baz' ]
Plus, Optimist comes with .usage() and .demand()!
-------------------------------------------------
divide.js:
````javascript
#!/usr/bin/env node
var argv = require('optimist')
.usage('Usage: $0 -x [num] -y [num]')
.demand(['x','y'])
.argv;
console.log(argv.x / argv.y);
````
***
$ ./divide.js -x 55 -y 11
5
$ node ./divide.js -x 4.91 -z 2.51
Usage: node ./divide.js -x [num] -y [num]
Options:
-x [required]
-y [required]
Missing required arguments: y
EVEN MORE HOLY COW
------------------
default_singles.js:
````javascript
#!/usr/bin/env node
var argv = require('optimist')
.default('x', 10)
.default('y', 10)
.argv
;
console.log(argv.x + argv.y);
````
***
$ ./default_singles.js -x 5
15
default_hash.js:
````javascript
#!/usr/bin/env node
var argv = require('optimist')
.default({ x : 10, y : 10 })
.argv
;
console.log(argv.x + argv.y);
````
***
$ ./default_hash.js -y 7
17
And if you really want to get all descriptive about it...
---------------------------------------------------------
boolean_single.js
````javascript
#!/usr/bin/env node
var argv = require('optimist')
.boolean('v')
.argv
;
console.dir(argv);
````
***
$ ./boolean_single.js -v foo bar baz
true
[ 'bar', 'baz', 'foo' ]
boolean_double.js
````javascript
#!/usr/bin/env node
var argv = require('optimist')
.boolean(['x','y','z'])
.argv
;
console.dir([ argv.x, argv.y, argv.z ]);
console.dir(argv._);
````
***
$ ./boolean_double.js -x -z one two three
[ true, false, true ]
[ 'one', 'two', 'three' ]
Optimist is here to help...
---------------------------
You can describe parameters for help messages and set aliases. Optimist figures
out how to format a handy help string automatically.
line_count.js
````javascript
#!/usr/bin/env node
var argv = require('optimist')
.usage('Count the lines in a file.\nUsage: $0')
.demand('f')
.alias('f', 'file')
.describe('f', 'Load a file')
.argv
;
var fs = require('fs');
var s = fs.createReadStream(argv.file);
var lines = 0;
s.on('data', function (buf) {
lines += buf.toString().match(/\n/g).length;
});
s.on('end', function () {
console.log(lines);
});
````
***
$ node line_count.js
Count the lines in a file.
Usage: node ./line_count.js
Options:
-f, --file Load a file [required]
Missing required arguments: f
$ node line_count.js --file line_count.js
20
$ node line_count.js -f line_count.js
20
methods
=======
By itself,
````javascript
require('optimist').argv
`````
will use `process.argv` array to construct the `argv` object.
You can pass in the `process.argv` yourself:
````javascript
require('optimist')([ '-x', '1', '-y', '2' ]).argv
````
or use .parse() to do the same thing:
````javascript
require('optimist').parse([ '-x', '1', '-y', '2' ])
````
The rest of these methods below come in just before the terminating `.argv`.
.alias(key, alias)
------------------
Set key names as equivalent such that updates to a key will propagate to aliases
and vice-versa.
Optionally `.alias()` can take an object that maps keys to aliases.
.default(key, value)
--------------------
Set `argv[key]` to `value` if no option was specified on `process.argv`.
Optionally `.default()` can take an object that maps keys to default values.
.demand(key)
------------
If `key` is a string, show the usage information and exit if `key` wasn't
specified in `process.argv`.
If `key` is a number, demand at least as many non-option arguments, which show
up in `argv._`.
If `key` is an Array, demand each element.
.describe(key, desc)
--------------------
Describe a `key` for the generated usage information.
Optionally `.describe()` can take an object that maps keys to descriptions.
.options(key, opt)
------------------
Instead of chaining together `.alias().demand().default()`, you can specify
keys in `opt` for each of the chainable methods.
For example:
````javascript
var argv = require('optimist')
.options('f', {
alias : 'file',
default : '/etc/passwd',
})
.argv
;
````
is the same as
````javascript
var argv = require('optimist')
.alias('f', 'file')
.default('f', '/etc/passwd')
.argv
;
````
Optionally `.options()` can take an object that maps keys to `opt` parameters.
.usage(message)
---------------
Set a usage message to show which commands to use. Inside `message`, the string
`$0` will get interpolated to the current script name or node command for the
present script similar to how `$0` works in bash or perl.
.check(fn)
----------
Check that certain conditions are met in the provided arguments.
If `fn` throws or returns `false`, show the thrown error, usage information, and
exit.
.boolean(key)
-------------
Interpret `key` as a boolean. If a non-flag option follows `key` in
`process.argv`, that string won't get set as the value of `key`.
If `key` never shows up as a flag in `process.arguments`, `argv[key]` will be
`false`.
If `key` is an Array, interpret all the elements as booleans.
.string(key)
------------
Tell the parser logic not to interpret `key` as a number or boolean.
This can be useful if you need to preserve leading zeros in an input.
If `key` is an Array, interpret all the elements as strings.
.wrap(columns)
--------------
Format usage output to wrap at `columns` many columns.
.help()
-------
Return the generated usage string.
.showHelp(fn=console.error)
---------------------------
Print the usage data using `fn` for printing.
.parse(args)
------------
Parse `args` instead of `process.argv`. Returns the `argv` object.
.argv
-----
Get the arguments as a plain old object.
Arguments without a corresponding flag show up in the `argv._` array.
The script name or node command is available at `argv.$0` similarly to how `$0`
works in bash or perl.
parsing tricks
==============
stop parsing
------------
Use `--` to stop parsing flags and stuff the remainder into `argv._`.
$ node examples/reflect.js -a 1 -b 2 -- -c 3 -d 4
{ _: [ '-c', '3', '-d', '4' ],
'$0': 'node ./examples/reflect.js',
a: 1,
b: 2 }
negate fields
-------------
If you want to explicity set a field to false instead of just leaving it
undefined or to override a default you can do `--no-key`.
$ node examples/reflect.js -a --no-b
{ _: [],
'$0': 'node ./examples/reflect.js',
a: true,
b: false }
numbers
-------
Every argument that looks like a number (`!isNaN(Number(arg))`) is converted to
one. This way you can just `net.createConnection(argv.port)` and you can add
numbers out of `argv` with `+` without having that mean concatenation,
which is super frustrating.
duplicates
----------
If you specify a flag multiple times it will get turned into an array containing
all the values in order.
$ node examples/reflect.js -x 5 -x 8 -x 0
{ _: [],
'$0': 'node ./examples/reflect.js',
x: [ 5, 8, 0 ] }
installation
============
With [npm](http://github.com/isaacs/npm), just do:
npm install optimist
or clone this project on github:
git clone http://github.com/substack/node-optimist.git
To run the tests with [expresso](http://github.com/visionmedia/expresso),
just do:
expresso
inspired By
===========
This module is loosely inspired by Perl's
[Getopt::Casual](http://search.cpan.org/~photo/Getopt-Casual-0.13.1/Casual.pm).
-10
View File
@@ -1,10 +0,0 @@
#!/usr/bin/env node
var util = require('util');
var argv = require('optimist').argv;
if (argv.s) {
util.print(argv.fr ? 'Le chat dit: ' : 'The cat says: ');
}
console.log(
(argv.fr ? 'miaou' : 'meow') + (argv.p ? '.' : '')
);
-7
View File
@@ -1,7 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist')
.boolean(['x','y','z'])
.argv
;
console.dir([ argv.x, argv.y, argv.z ]);
console.dir(argv._);
-7
View File
@@ -1,7 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist')
.boolean('v')
.argv
;
console.dir(argv.v);
console.dir(argv._);
-8
View File
@@ -1,8 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist')
.default({ x : 10, y : 10 })
.argv
;
console.log(argv.x + argv.y);
-7
View File
@@ -1,7 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist')
.default('x', 10)
.default('y', 10)
.argv
;
console.log(argv.x + argv.y);
-8
View File
@@ -1,8 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist')
.usage('Usage: $0 -x [num] -y [num]')
.demand(['x','y'])
.argv;
console.log(argv.x / argv.y);
-20
View File
@@ -1,20 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist')
.usage('Count the lines in a file.\nUsage: $0')
.demand('f')
.alias('f', 'file')
.describe('f', 'Load a file')
.argv
;
var fs = require('fs');
var s = fs.createReadStream(argv.file);
var lines = 0;
s.on('data', function (buf) {
lines += buf.toString().match(/\n/g).length;
});
s.on('end', function () {
console.log(lines);
});
-29
View File
@@ -1,29 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist')
.usage('Count the lines in a file.\nUsage: $0')
.options({
file : {
demand : true,
alias : 'f',
description : 'Load a file'
},
base : {
alias : 'b',
description : 'Numeric base to use for output',
default : 10,
},
})
.argv
;
var fs = require('fs');
var s = fs.createReadStream(argv.file);
var lines = 0;
s.on('data', function (buf) {
lines += buf.toString().match(/\n/g).length;
});
s.on('end', function () {
console.log(lines.toString(argv.base));
});
-29
View File
@@ -1,29 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist')
.usage('Count the lines in a file.\nUsage: $0')
.wrap(80)
.demand('f')
.alias('f', [ 'file', 'filename' ])
.describe('f',
"Load a file. It's pretty important."
+ " Required even. So you'd better specify it."
)
.alias('b', 'base')
.describe('b', 'Numeric base to display the number of lines in')
.default('b', 10)
.describe('x', 'Super-secret optional parameter which is secret')
.default('x', '')
.argv
;
var fs = require('fs');
var s = fs.createReadStream(argv.file);
var lines = 0;
s.on('data', function (buf) {
lines += buf.toString().match(/\n/g).length;
});
s.on('end', function () {
console.log(lines.toString(argv.base));
});
-4
View File
@@ -1,4 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist').argv;
console.log('(%d,%d)', argv.x, argv.y);
console.log(argv._);
-2
View File
@@ -1,2 +0,0 @@
#!/usr/bin/env node
console.dir(require('optimist').argv);
-3
View File
@@ -1,3 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist').argv;
console.log('(%d,%d)', argv.x, argv.y);
-11
View File
@@ -1,11 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist')
.string('x', 'y')
.argv
;
console.dir([ argv.x, argv.y ]);
/* Turns off numeric coercion:
./node string.js -x 000123 -y 9876
[ '000123', '9876' ]
*/
-19
View File
@@ -1,19 +0,0 @@
var optimist = require('./../index');
var argv = optimist.usage('This is my awesome program', {
'about': {
description: 'Provide some details about the author of this program',
required: true,
short: 'a',
},
'info': {
description: 'Provide some information about the node.js agains!!!!!!',
boolean: true,
short: 'i'
}
}).argv;
optimist.showHelp();
console.log('\n\nInspecting options');
console.dir(argv);
-10
View File
@@ -1,10 +0,0 @@
#!/usr/bin/env node
var argv = require('optimist').argv;
if (argv.rif - 5 * argv.xup > 7.138) {
console.log('Buy more riffiwobbles');
}
else {
console.log('Sell the xupptumblers');
}
-457
View File
@@ -1,457 +0,0 @@
var path = require('path');
var wordwrap = require('wordwrap');
/* Hack an instance of Argv with process.argv into Argv
so people can do
require('optimist')(['--beeble=1','-z','zizzle']).argv
to parse a list of args and
require('optimist').argv
to get a parsed version of process.argv.
*/
var inst = Argv(process.argv.slice(2));
Object.keys(inst).forEach(function (key) {
Argv[key] = typeof inst[key] == 'function'
? inst[key].bind(inst)
: inst[key];
});
var exports = module.exports = Argv;
function Argv (args, cwd) {
var self = {};
if (!cwd) cwd = process.cwd();
self.$0 = process.argv
.slice(0,2)
.map(function (x) {
var b = rebase(cwd, x);
return x.match(/^\//) && b.length < x.length
? b : x
})
.join(' ')
;
if (process.argv[1] == process.env._) {
self.$0 = process.env._.replace(
path.dirname(process.execPath) + '/', ''
);
}
var flags = { bools : {}, strings : {} };
self.boolean = function (bools) {
if (!Array.isArray(bools)) {
bools = [].slice.call(arguments);
}
bools.forEach(function (name) {
flags.bools[name] = true;
});
return self;
};
self.string = function (strings) {
if (!Array.isArray(strings)) {
strings = [].slice.call(arguments);
}
strings.forEach(function (name) {
flags.strings[name] = true;
});
return self;
};
var aliases = {};
self.alias = function (x, y) {
if (typeof x === 'object') {
Object.keys(x).forEach(function (key) {
self.alias(key, x[key]);
});
}
else if (Array.isArray(y)) {
y.forEach(function (yy) {
self.alias(x, yy);
});
}
else {
var zs = (aliases[x] || []).concat(aliases[y] || []).concat(x, y);
aliases[x] = zs.filter(function (z) { return z != x });
aliases[y] = zs.filter(function (z) { return z != y });
}
return self;
};
var demanded = {};
self.demand = function (keys) {
if (typeof keys == 'number') {
if (!demanded._) demanded._ = 0;
demanded._ += keys;
}
else if (Array.isArray(keys)) {
keys.forEach(function (key) {
self.demand(key);
});
}
else {
demanded[keys] = true;
}
return self;
};
var usage;
self.usage = function (msg, opts) {
if (!opts && typeof msg === 'object') {
opts = msg;
msg = null;
}
usage = msg;
if (opts) self.options(opts);
return self;
};
function fail (msg) {
self.showHelp();
if (msg) console.error(msg);
process.exit(1);
}
var checks = [];
self.check = function (f) {
checks.push(f);
return self;
};
var defaults = {};
self.default = function (key, value) {
if (typeof key === 'object') {
Object.keys(key).forEach(function (k) {
self.default(k, key[k]);
});
}
else {
defaults[key] = value;
}
return self;
};
var descriptions = {};
self.describe = function (key, desc) {
if (typeof key === 'object') {
Object.keys(key).forEach(function (k) {
self.describe(k, key[k]);
});
}
else {
descriptions[key] = desc;
}
return self;
};
self.parse = function (args) {
return Argv(args).argv;
};
self.option = self.options = function (key, opt) {
if (typeof key === 'object') {
Object.keys(key).forEach(function (k) {
self.options(k, key[k]);
});
}
else {
if (opt.alias) self.alias(key, opt.alias);
if (opt.demand) self.demand(key);
if (opt.default) self.default(key, opt.default);
if (opt.boolean || opt.type === 'boolean') {
self.boolean(key);
}
if (opt.string || opt.type === 'string') {
self.string(key);
}
var desc = opt.describe || opt.description || opt.desc;
if (desc) {
self.describe(key, desc);
}
}
return self;
};
var wrap = null;
self.wrap = function (cols) {
wrap = cols;
return self;
};
self.showHelp = function (fn) {
if (!fn) fn = console.error;
fn(self.help());
};
self.help = function () {
var keys = Object.keys(
Object.keys(descriptions)
.concat(Object.keys(demanded))
.concat(Object.keys(defaults))
.reduce(function (acc, key) {
if (key !== '_') acc[key] = true;
return acc;
}, {})
);
var help = keys.length ? [ 'Options:' ] : [];
if (usage) {
help.unshift(usage.replace(/\$0/g, self.$0), '');
}
var switches = keys.reduce(function (acc, key) {
acc[key] = [ key ].concat(aliases[key] || [])
.map(function (sw) {
return (sw.length > 1 ? '--' : '-') + sw
})
.join(', ')
;
return acc;
}, {});
var switchlen = longest(Object.keys(switches).map(function (s) {
return switches[s] || '';
}));
var desclen = longest(Object.keys(descriptions).map(function (d) {
return descriptions[d] || '';
}));
keys.forEach(function (key) {
var kswitch = switches[key];
var desc = descriptions[key] || '';
if (wrap) {
desc = wordwrap(switchlen + 4, wrap)(desc)
.slice(switchlen + 4)
;
}
var spadding = new Array(
Math.max(switchlen - kswitch.length + 3, 0)
).join(' ');
var dpadding = new Array(
Math.max(desclen - desc.length + 1, 0)
).join(' ');
var type = null;
if (flags.bools[key]) type = '[boolean]';
if (flags.strings[key]) type = '[string]';
if (!wrap && dpadding.length > 0) {
desc += dpadding;
}
var prelude = ' ' + kswitch + spadding;
var extra = [
type,
demanded[key]
? '[required]'
: null
,
defaults[key] !== undefined
? '[default: ' + JSON.stringify(defaults[key]) + ']'
: null
,
].filter(Boolean).join(' ');
var body = [ desc, extra ].filter(Boolean).join(' ');
if (wrap) {
var dlines = desc.split('\n');
var dlen = dlines.slice(-1)[0].length
+ (dlines.length === 1 ? prelude.length : 0)
body = desc + (dlen + extra.length > wrap - 2
? '\n'
+ new Array(wrap - extra.length + 1).join(' ')
+ extra
: new Array(wrap - extra.length - dlen + 1).join(' ')
+ extra
);
}
help.push(prelude + body);
});
help.push('');
return help.join('\n');
};
Object.defineProperty(self, 'argv', {
get : parseArgs,
enumerable : true,
});
function parseArgs () {
var argv = { _ : [], $0 : self.$0 };
Object.keys(flags.bools).forEach(function (key) {
setArg(key, defaults[key] || false);
});
function setArg (key, val) {
var num = Number(val);
var value = typeof val !== 'string' || isNaN(num) ? val : num;
if (flags.strings[key]) value = val;
if (key in argv && !flags.bools[key]) {
if (!Array.isArray(argv[key])) {
argv[key] = [ argv[key] ];
}
argv[key].push(value);
}
else {
argv[key] = value;
}
(aliases[key] || []).forEach(function (x) {
argv[x] = argv[key];
});
}
for (var i = 0; i < args.length; i++) {
var arg = args[i];
if (arg === '--') {
argv._.push.apply(argv._, args.slice(i + 1));
break;
}
else if (arg.match(/^--.+=/)) {
var m = arg.match(/^--([^=]+)=(.*)/);
setArg(m[1], m[2]);
}
else if (arg.match(/^--no-.+/)) {
var key = arg.match(/^--no-(.+)/)[1];
setArg(key, false);
}
else if (arg.match(/^--.+/)) {
var key = arg.match(/^--(.+)/)[1];
var next = args[i + 1];
if (next !== undefined && !next.match(/^-/)
&& !flags.bools[key]) {
setArg(key, next);
i++;
}
else if (flags.bools[key] && /true|false/.test(next)) {
setArg(key, next === 'true');
i++;
}
else {
setArg(key, true);
}
}
else if (arg.match(/^-[^-]+/)) {
var letters = arg.slice(1,-1).split('');
var broken = false;
for (var j = 0; j < letters.length; j++) {
if (letters[j+1] && letters[j+1].match(/\W/)) {
setArg(letters[j], arg.slice(j+2));
broken = true;
break;
}
else {
setArg(letters[j], true);
}
}
if (!broken) {
var key = arg.slice(-1)[0];
if (args[i+1] && !args[i+1].match(/^-/)
&& !flags.bools[key]) {
setArg(key, args[i+1]);
i++;
}
else if (args[i+1] && flags.bools[key] && /true|false/.test(args[i+1])) {
setArg(key, args[i+1] === 'true');
i++;
}
else {
setArg(key, true);
}
}
}
else {
var n = Number(arg);
argv._.push(flags.strings['_'] || isNaN(n) ? arg : n);
}
}
Object.keys(defaults).forEach(function (key) {
if (!(key in argv)) {
argv[key] = defaults[key];
}
});
if (demanded._ && argv._.length < demanded._) {
fail('Not enough non-option arguments: got '
+ argv._.length + ', need at least ' + demanded._
);
}
var missing = [];
Object.keys(demanded).forEach(function (key) {
if (!argv[key]) missing.push(key);
});
if (missing.length) {
fail('Missing required arguments: ' + missing.join(', '));
}
checks.forEach(function (f) {
try {
if (f(argv) === false) {
fail('Argument check failed: ' + f.toString());
}
}
catch (err) {
fail(err)
}
});
return argv;
}
function longest (xs) {
return Math.max.apply(
null,
xs.map(function (x) { return x.length })
);
}
return self;
};
// rebase an absolute path to a relative one with respect to a base directory
// exported for tests
exports.rebase = rebase;
function rebase (base, dir) {
var ds = path.normalize(dir).split('/').slice(1);
var bs = path.normalize(base).split('/').slice(1);
for (var i = 0; ds[i] && ds[i] == bs[i]; i++);
ds.splice(0, i); bs.splice(0, i);
var p = path.normalize(
bs.map(function () { return '..' }).concat(ds).join('/')
).replace(/\/$/,'').replace(/^$/, '.');
return p.match(/^[.\/]/) ? p : './' + p;
};
-43
View File
@@ -1,43 +0,0 @@
{
"name" : "optimist",
"version" : "0.2.8",
"description" : "Light-weight option parsing with an argv hash. No optstrings attached.",
"main" : "./index.js",
"directories" : {
"lib" : ".",
"test" : "test",
"example" : "examples"
},
"dependencies" : {
"wordwrap" : ">=0.0.1 <0.1.0"
},
"devDependencies" : {
"hashish": "0.0.x",
"expresso" : "0.7.x"
},
"scripts" : {
"test" : "expresso"
},
"repository" : {
"type" : "git",
"url" : "http://github.com/substack/node-optimist.git"
},
"keywords" : [
"argument",
"args",
"option",
"parser",
"parsing",
"cli",
"command"
],
"author" : {
"name" : "James Halliday",
"email" : "mail@substack.net",
"url" : "http://substack.net"
},
"license" : "MIT/X11",
"engine" : {
"node" : ">=0.4"
}
}
-66
View File
@@ -1,66 +0,0 @@
var spawn = require('child_process').spawn;
var assert = require('assert');
exports.dotSlashEmpty = function () {
testCmd('./bin.js', []);
};
exports.dotSlashArgs = function () {
testCmd('./bin.js', [ 'a', 'b', 'c' ]);
};
exports.nodeEmpty = function () {
testCmd('node bin.js', []);
};
exports.nodeArgs = function () {
testCmd('node bin.js', [ 'x', 'y', 'z' ]);
};
exports.whichNodeEmpty = function () {
var which = spawn('which', ['node']);
which.stdout.on('data', function (buf) {
testCmd(buf.toString().trim() + ' bin.js', []);
});
which.stderr.on('data', function (err) {
assert.fail(err.toString());
});
};
exports.whichNodeArgs = function () {
var which = spawn('which', ['node']);
which.stdout.on('data', function (buf) {
testCmd(buf.toString().trim() + ' bin.js', [ 'q', 'r' ]);
});
which.stderr.on('data', function (err) {
assert.fail(err.toString());
});
};
function testCmd (cmd, args) {
var to = setTimeout(function () {
assert.fail('Never got stdout data.')
}, 5000);
var oldDir = process.cwd();
process.chdir(__dirname + '/_');
var cmds = cmd.split(' ');
var bin = spawn(cmds[0], cmds.slice(1).concat(args.map(String)));
process.chdir(oldDir);
bin.stderr.on('data', function (err) {
assert.fail(err.toString());
});
bin.stdout.on('data', function (buf) {
clearTimeout(to);
var _ = JSON.parse(buf.toString());
assert.eql(_.map(String), args.map(String));
});
}
-2
View File
@@ -1,2 +0,0 @@
#!/usr/bin/env node
console.log(JSON.stringify(process.argv));
-3
View File
@@ -1,3 +0,0 @@
#!/usr/bin/env node
var argv = require('../../index').argv
console.log(JSON.stringify(argv._));
-304
View File
@@ -1,304 +0,0 @@
var optimist = require('../index');
var assert = require('assert');
var path = require('path');
var localExpresso = path.normalize(
__dirname + '/../node_modules/.bin/expresso'
);
var expresso = process.argv[1] === localExpresso
? 'node ./node_modules/.bin/expresso'
: 'expresso'
;
exports['short boolean'] = function () {
var parse = optimist.parse([ '-b' ]);
assert.eql(parse, { b : true, _ : [], $0 : expresso });
assert.eql(typeof parse.b, 'boolean');
};
exports['long boolean'] = function () {
assert.eql(
optimist.parse([ '--bool' ]),
{ bool : true, _ : [], $0 : expresso }
);
};
exports.bare = function () {
assert.eql(
optimist.parse([ 'foo', 'bar', 'baz' ]),
{ _ : [ 'foo', 'bar', 'baz' ], $0 : expresso }
);
};
exports['short group'] = function () {
assert.eql(
optimist.parse([ '-cats' ]),
{ c : true, a : true, t : true, s : true, _ : [], $0 : expresso }
);
};
exports['short group next'] = function () {
assert.eql(
optimist.parse([ '-cats', 'meow' ]),
{ c : true, a : true, t : true, s : 'meow', _ : [], $0 : expresso }
);
};
exports['short capture'] = function () {
assert.eql(
optimist.parse([ '-h', 'localhost' ]),
{ h : 'localhost', _ : [], $0 : expresso }
);
};
exports['short captures'] = function () {
assert.eql(
optimist.parse([ '-h', 'localhost', '-p', '555' ]),
{ h : 'localhost', p : 555, _ : [], $0 : expresso }
);
};
exports['long capture sp'] = function () {
assert.eql(
optimist.parse([ '--pow', 'xixxle' ]),
{ pow : 'xixxle', _ : [], $0 : expresso }
);
};
exports['long capture eq'] = function () {
assert.eql(
optimist.parse([ '--pow=xixxle' ]),
{ pow : 'xixxle', _ : [], $0 : expresso }
);
};
exports['long captures sp'] = function () {
assert.eql(
optimist.parse([ '--host', 'localhost', '--port', '555' ]),
{ host : 'localhost', port : 555, _ : [], $0 : expresso }
);
};
exports['long captures eq'] = function () {
assert.eql(
optimist.parse([ '--host=localhost', '--port=555' ]),
{ host : 'localhost', port : 555, _ : [], $0 : expresso }
);
};
exports['mixed short bool and capture'] = function () {
assert.eql(
optimist.parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
{
f : true, p : 555, h : 'localhost',
_ : [ 'script.js' ], $0 : expresso,
}
);
};
exports['short and long'] = function () {
assert.eql(
optimist.parse([ '-h', 'localhost', '-fp', '555', 'script.js' ]),
{
f : true, p : 555, h : 'localhost',
_ : [ 'script.js' ], $0 : expresso,
}
);
};
exports.no = function () {
assert.eql(
optimist.parse([ '--no-moo' ]),
{ moo : false, _ : [], $0 : expresso }
);
};
exports.multi = function () {
assert.eql(
optimist.parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]),
{ v : ['a','b','c'], _ : [], $0 : expresso }
);
};
exports.comprehensive = function () {
assert.eql(
optimist.parse([
'--name=meowmers', 'bare', '-cats', 'woo',
'-h', 'awesome', '--multi=quux',
'--key', 'value',
'-b', '--bool', '--no-meep', '--multi=baz',
'--', '--not-a-flag', 'eek'
]),
{
c : true,
a : true,
t : true,
s : 'woo',
h : 'awesome',
b : true,
bool : true,
key : 'value',
multi : [ 'quux', 'baz' ],
meep : false,
name : 'meowmers',
_ : [ 'bare', '--not-a-flag', 'eek' ],
$0 : expresso
}
);
};
exports.nums = function () {
var argv = optimist.parse([
'-x', '1234',
'-y', '5.67',
'-z', '1e7',
'-w', '10f',
'--hex', '0xdeadbeef',
'789',
]);
assert.eql(argv, {
x : 1234,
y : 5.67,
z : 1e7,
w : '10f',
hex : 0xdeadbeef,
_ : [ 789 ],
$0 : expresso
});
assert.eql(typeof argv.x, 'number');
assert.eql(typeof argv.y, 'number');
assert.eql(typeof argv.z, 'number');
assert.eql(typeof argv.w, 'string');
assert.eql(typeof argv.hex, 'number');
assert.eql(typeof argv._[0], 'number');
};
exports['flag boolean'] = function () {
var parse = optimist([ '-t', 'moo' ]).boolean(['t']).argv;
assert.eql(parse, { t : true, _ : [ 'moo' ], $0 : expresso });
assert.eql(typeof parse.t, 'boolean');
};
exports['flag boolean value'] = function () {
var parse = optimist(['--verbose', 'false', 'moo', '-t', 'true'])
.boolean(['t', 'verbose']).default('verbose', true).argv;
assert.eql(parse, {
verbose: false,
t: true,
_: ['moo'],
$0 : expresso
});
assert.eql(typeof parse.verbose, 'boolean');
assert.eql(typeof parse.t, 'boolean');
};
exports['flag boolean default false'] = function () {
var parse = optimist(['moo'])
.boolean(['t', 'verbose'])
.default('verbose', false)
.default('t', false).argv;
assert.eql(parse, {
verbose: false,
t: false,
_: ['moo'],
$0 : expresso
});
assert.eql(typeof parse.verbose, 'boolean');
assert.eql(typeof parse.t, 'boolean');
};
exports['boolean groups'] = function () {
var parse = optimist([ '-x', '-z', 'one', 'two', 'three' ])
.boolean(['x','y','z']).argv;
assert.eql(parse, {
x : true,
y : false,
z : true,
_ : [ 'one', 'two', 'three' ],
$0 : expresso
});
assert.eql(typeof parse.x, 'boolean');
assert.eql(typeof parse.y, 'boolean');
assert.eql(typeof parse.z, 'boolean');
};
exports.strings = function () {
var s = optimist([ '-s', '0001234' ]).string('s').argv.s;
assert.eql(s, '0001234');
assert.eql(typeof s, 'string');
var x = optimist([ '-x', '56' ]).string('x').argv.x;
assert.eql(x, '56');
assert.eql(typeof x, 'string');
};
exports.stringArgs = function () {
var s = optimist([ ' ', ' ' ]).string('_').argv._;
assert.eql(s.length, 2);
assert.eql(typeof s[0], 'string');
assert.eql(s[0], ' ');
assert.eql(typeof s[1], 'string');
assert.eql(s[1], ' ');
};
exports.slashBreak = function () {
assert.eql(
optimist.parse([ '-I/foo/bar/baz' ]),
{ I : '/foo/bar/baz', _ : [], $0 : expresso }
);
assert.eql(
optimist.parse([ '-xyz/foo/bar/baz' ]),
{ x : true, y : true, z : '/foo/bar/baz', _ : [], $0 : expresso }
);
};
exports.alias = function () {
var argv = optimist([ '-f', '11', '--zoom', '55' ])
.alias('z', 'zoom')
.argv
;
assert.equal(argv.zoom, 55);
assert.equal(argv.z, argv.zoom);
assert.equal(argv.f, 11);
};
exports.multiAlias = function () {
var argv = optimist([ '-f', '11', '--zoom', '55' ])
.alias('z', [ 'zm', 'zoom' ])
.argv
;
assert.equal(argv.zoom, 55);
assert.equal(argv.z, argv.zoom);
assert.equal(argv.z, argv.zm);
assert.equal(argv.f, 11);
};
exports['boolean default true'] = function () {
var argv = optimist.options({
sometrue: {
boolean: true,
default: true
}
}).argv;
assert.equal(argv.sometrue, true);
};
exports['boolean default false'] = function () {
var argv = optimist.options({
somefalse: {
boolean: true,
default: false
}
}).argv;
assert.equal(argv.somefalse, false);
};
-256
View File
@@ -1,256 +0,0 @@
var Hash = require('hashish');
var optimist = require('../index');
var assert = require('assert');
exports.usageFail = function () {
var r = checkUsage(function () {
return optimist('-x 10 -z 20'.split(' '))
.usage('Usage: $0 -x NUM -y NUM')
.demand(['x','y'])
.argv;
});
assert.deepEqual(
r.result,
{ x : 10, z : 20, _ : [], $0 : './usage' }
);
assert.deepEqual(
r.errors.join('\n').split(/\n+/),
[
'Usage: ./usage -x NUM -y NUM',
'Options:',
' -x [required]',
' -y [required]',
'Missing required arguments: y',
]
);
assert.deepEqual(r.logs, []);
assert.ok(r.exit);
};
exports.usagePass = function () {
var r = checkUsage(function () {
return optimist('-x 10 -y 20'.split(' '))
.usage('Usage: $0 -x NUM -y NUM')
.demand(['x','y'])
.argv;
});
assert.deepEqual(r, {
result : { x : 10, y : 20, _ : [], $0 : './usage' },
errors : [],
logs : [],
exit : false,
});
};
exports.checkPass = function () {
var r = checkUsage(function () {
return optimist('-x 10 -y 20'.split(' '))
.usage('Usage: $0 -x NUM -y NUM')
.check(function (argv) {
if (!('x' in argv)) throw 'You forgot about -x';
if (!('y' in argv)) throw 'You forgot about -y';
})
.argv;
});
assert.deepEqual(r, {
result : { x : 10, y : 20, _ : [], $0 : './usage' },
errors : [],
logs : [],
exit : false,
});
};
exports.checkFail = function () {
var r = checkUsage(function () {
return optimist('-x 10 -z 20'.split(' '))
.usage('Usage: $0 -x NUM -y NUM')
.check(function (argv) {
if (!('x' in argv)) throw 'You forgot about -x';
if (!('y' in argv)) throw 'You forgot about -y';
})
.argv;
});
assert.deepEqual(
r.result,
{ x : 10, z : 20, _ : [], $0 : './usage' }
);
assert.deepEqual(
r.errors.join('\n').split(/\n+/),
[
'Usage: ./usage -x NUM -y NUM',
'You forgot about -y'
]
);
assert.deepEqual(r.logs, []);
assert.ok(r.exit);
};
exports.checkCondPass = function () {
function checker (argv) {
return 'x' in argv && 'y' in argv;
}
var r = checkUsage(function () {
return optimist('-x 10 -y 20'.split(' '))
.usage('Usage: $0 -x NUM -y NUM')
.check(checker)
.argv;
});
assert.deepEqual(r, {
result : { x : 10, y : 20, _ : [], $0 : './usage' },
errors : [],
logs : [],
exit : false,
});
};
exports.checkCondFail = function () {
function checker (argv) {
return 'x' in argv && 'y' in argv;
}
var r = checkUsage(function () {
return optimist('-x 10 -z 20'.split(' '))
.usage('Usage: $0 -x NUM -y NUM')
.check(checker)
.argv;
});
assert.deepEqual(
r.result,
{ x : 10, z : 20, _ : [], $0 : './usage' }
);
assert.deepEqual(
r.errors.join('\n').split(/\n+/).join('\n'),
'Usage: ./usage -x NUM -y NUM\n'
+ 'Argument check failed: ' + checker.toString()
);
assert.deepEqual(r.logs, []);
assert.ok(r.exit);
};
exports.countPass = function () {
var r = checkUsage(function () {
return optimist('1 2 3 --moo'.split(' '))
.usage('Usage: $0 [x] [y] [z] {OPTIONS}')
.demand(3)
.argv;
});
assert.deepEqual(r, {
result : { _ : [ '1', '2', '3' ], moo : true, $0 : './usage' },
errors : [],
logs : [],
exit : false,
});
};
exports.countFail = function () {
var r = checkUsage(function () {
return optimist('1 2 --moo'.split(' '))
.usage('Usage: $0 [x] [y] [z] {OPTIONS}')
.demand(3)
.argv;
});
assert.deepEqual(
r.result,
{ _ : [ '1', '2' ], moo : true, $0 : './usage' }
);
assert.deepEqual(
r.errors.join('\n').split(/\n+/),
[
'Usage: ./usage [x] [y] [z] {OPTIONS}',
'Not enough non-option arguments: got 2, need at least 3',
]
);
assert.deepEqual(r.logs, []);
assert.ok(r.exit);
};
exports.defaultSingles = function () {
var r = checkUsage(function () {
return optimist('--foo 50 --baz 70 --powsy'.split(' '))
.default('foo', 5)
.default('bar', 6)
.default('baz', 7)
.argv
;
});
assert.eql(r.result, {
foo : '50',
bar : 6,
baz : '70',
powsy : true,
_ : [],
$0 : './usage',
});
};
exports.defaultHash = function () {
var r = checkUsage(function () {
return optimist('--foo 50 --baz 70'.split(' '))
.default({ foo : 10, bar : 20, quux : 30 })
.argv
;
});
assert.eql(r.result, {
foo : '50',
bar : 20,
baz : 70,
quux : 30,
_ : [],
$0 : './usage',
});
};
exports.rebase = function () {
assert.equal(
optimist.rebase('/home/substack', '/home/substack/foo/bar/baz'),
'./foo/bar/baz'
);
assert.equal(
optimist.rebase('/home/substack/foo/bar/baz', '/home/substack'),
'../../..'
);
assert.equal(
optimist.rebase('/home/substack/foo', '/home/substack/pow/zoom.txt'),
'../pow/zoom.txt'
);
};
function checkUsage (f) {
var _process = process;
process = Hash.copy(process);
var exit = false;
process.exit = function () { exit = true };
process.env = Hash.merge(process.env, { _ : 'node' });
process.argv = [ './usage' ];
var errors = [];
var logs = [];
console._error = console.error;
console.error = function (msg) { errors.push(msg) };
console._log = console.log;
console.log = function (msg) { logs.push(msg) };
var result = f();
process = _process;
console.error = console._error;
console.log = console._log;
return {
errors : errors,
logs : logs,
exit : exit,
result : result,
};
};
+45 -7
View File
@@ -1,16 +1,54 @@
{
"author": "Craig Condon <craig.j.condon@gmail.com>",
"author": "Jared Allard <jaredallard@outlook.com>",
"name": "nexe",
"description": "Roll node.s applications into a single executable",
"version": "0.0.1",
"description": "create single executables out of your [node/io].js applications",
"license": "MIT",
"version": "1.0.7",
"contributors": [
{
"name": "Criag Condon",
"email": "craig.j.condon@gmail.com",
"url": "http://crcn.io/"
}
],
"repository": {
"type": "git",
"url": "git://github.com/crcn/nexe.git"
"url": "git://github.com/jaredallard/nexe.git"
},
"main": "./lib/index.js",
"dependencies": {
"optimist":"*",
"sardines":"*"
"async": "1.5.2",
"browserify": "^13.0.0",
"builtins": "1.0.3",
"colors": "^1.1.2",
"glob": "^6.0.4",
"insert-module-globals": "^7.0.1",
"mkdirp": "^0.5.1",
"module-deps": "^4.0.5",
"ncp": "^2.0.0",
"outcome": "0.0.18",
"progress": "^1.1.8",
"request": "^2.67.0",
"sprintf": "~0.1.5",
"step": "0.0.x",
"tar.gz": "1.0.2",
"yargs": "^3.32.0"
},
"devDependencies": {}
"nexe": {
"input": "./bin/nexe",
"output": "nexe^$",
"temp": "src",
"runtime": {
"framework": "nodejs",
"version": "5.5.0",
"ignoreFlags": true
}
},
"preferGlobal": true,
"bin": {
"nexe": "./bin/nexe"
},
"devDependencies": {
"nodeunit": "^0.9.1"
}
}
-23
View File
@@ -1,23 +0,0 @@
{
"folders":
[
{
"path": "."
}
],
"build_systems":
[
{
"name":"cbd make",
"cmd":["cbd","make","nexe"]
},
{
"name":"cbd start",
"cmd":["cbd","start","nexe"]
},
{
"name":"cbd make+start",
"cmd":["cbd","make+start","nexe"]
}
]
}
+13
View File
@@ -0,0 +1,13 @@
/**
* Test to verify if we support strict mode (flags)
*
* @author Jared Allard <jaredallard@outlook.com>
* @version 0.0.1
* @license MIT
**/
// "use strict"; w/o --use_strict
var isStrict = (function() { return !this; })();
console.log('test:strict-mode:status =', isStrict);
+15
View File
@@ -0,0 +1,15 @@
{
"name": "flags-test",
"nexe": {
"input": "./index.js",
"output": "test.nex",
"temp": "src",
"runtime": {
"framework": "node",
"version": "0.10.0",
"ignoreFlags": false,
"js-flags": "--use_strict",
"node-args": ""
}
}
}
+23
View File
@@ -0,0 +1,23 @@
"use strict";
var gulp = require('gulp');
var nexe = require('nexe');
gulp.task( "compile", ( callback ) => {
let options = {
input: "index.js",
output: "test.nex",
python: "python",
nodeTempDir: "./tmp",
nodeVersion: "latest",
flags: false,
framework: "nodejs"
};
nexe.compile( options, ( err ) => {
console.log( err );
callback( err );
} );
} );
gulp.task('default', ['compile']);
+1
View File
@@ -0,0 +1 @@
console.log('Hello, world!');
+15
View File
@@ -0,0 +1,15 @@
{
"name": "gulp-test-170",
"version": "0.0.1",
"description": "gulpfile.js issue #170",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Jared Allard <jaredallard@outlook.com>",
"license": "MIT",
"dependencies": {
"gulp": "^3.9.0",
"nexe": "^1.0.5"
}
}