Compare commits
168 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5dc698be9d | |||
| 1bf334399b | |||
| a30db5fc5d | |||
| 77cfcf0da4 | |||
| d8541a82ac | |||
| 489bd0f0fe | |||
| a3f30bf783 | |||
| 61ff0b1052 | |||
| e02d39a6bf | |||
| ca414f03db | |||
| 4200724316 | |||
| 686f67fac2 | |||
| 494618cca1 | |||
| 86fe200bfd | |||
| c272f52994 | |||
| 93ed48a537 | |||
| 740e3f441d | |||
| 8204feadaa | |||
| cdf53e133b | |||
| 65c07d4e4a | |||
| 4c3443655e | |||
| 6d20d4da22 | |||
| b72b14b6c3 | |||
| 9134bcf351 | |||
| 1c0d8d0fc0 | |||
| a7c3fda721 | |||
| 7d75480a6f | |||
| 67361b27e1 | |||
| 3b6f9ff4b7 | |||
| 6fcfb10e38 | |||
| 06cab4f43b | |||
| 2cacd8340b | |||
| 0e90ac9f16 | |||
| efd3f78c9d | |||
| 54967d1ab0 | |||
| bb489a3cb7 | |||
| 6097c20204 | |||
| 39665a8d5c | |||
| f49ece0c86 | |||
| 5aca22d28e | |||
| e79b0fb23e | |||
| cac698609c | |||
| b040337a94 | |||
| 06d7730802 | |||
| ad4da1d193 | |||
| 5927b45e70 | |||
| e4155c8fed | |||
| e91f5b52af | |||
| 3b1d5a9fe1 | |||
| 3ac298fe4f | |||
| 229f0516c6 | |||
| 29d5f6aaeb | |||
| 174599df30 | |||
| 3ca6bbbda2 | |||
| 97dbd37068 | |||
| b615e125c0 | |||
| c34f6719b5 | |||
| 2342fe6fdd | |||
| 333cc697c3 | |||
| ece4b2d62a | |||
| ba62973dca | |||
| 9b5892e6ad | |||
| f7ad9a8e83 | |||
| 7c1331bed8 | |||
| e55dacf8c8 | |||
| ec79ff85d4 | |||
| 99a8cbe9b3 | |||
| f458298ffb | |||
| c3fa94a2e5 | |||
| 961f72b1d9 | |||
| d91d91fc2b | |||
| 273bfa3e4d | |||
| 31b01469c7 | |||
| b94d0c3719 | |||
| 275a7b025b | |||
| 71d7b97736 | |||
| faf0a85b36 | |||
| 56578c09b1 | |||
| 6ad1ec436c | |||
| 62461dbc41 | |||
| 7f34aa8854 | |||
| 76072f6df9 | |||
| 83daa5553b | |||
| ff09ef6755 | |||
| 85c8831248 | |||
| 3d2ae606ef | |||
| d4f27aea7f | |||
| 87abd1a295 | |||
| 9fd462da2f | |||
| 60849404a2 | |||
| 00fa37fff0 | |||
| 270350fda6 | |||
| dd2aa5a831 | |||
| afc7140b6b | |||
| 1d47091304 | |||
| 36bbdd4aa9 | |||
| e73804a4dd | |||
| bd1152357e | |||
| c53f229848 | |||
| 3cb81249d8 | |||
| 518fbc7280 | |||
| dd5607886a | |||
| 666774b5b5 | |||
| 3f75ae462e | |||
| dacb31fd67 | |||
| d4e62c668e | |||
| b267d9ba41 | |||
| 75932723ac | |||
| 28442e6714 | |||
| 9bb3b76a65 | |||
| 6702ce326a | |||
| 27075a778d | |||
| 368195be77 | |||
| b11ce7540c | |||
| 069c910b7b | |||
| 934c7bb3d5 | |||
| 8c8a1eddd7 | |||
| 3eea6784dd | |||
| cef44e9b77 | |||
| b6f555c223 | |||
| 87cacafd3e | |||
| 9caa365a3e | |||
| e7e80f5a2c | |||
| 4284c399dd | |||
| 89eeeda575 | |||
| 3b1b82dc40 | |||
| a9a97fefe1 | |||
| 12a7069a32 | |||
| 533ed8c500 | |||
| 875d6d0ff7 | |||
| ea2cfdf5ee | |||
| 60ebde86cc | |||
| d927887355 | |||
| 04280a3016 | |||
| 3c084b9573 | |||
| 708851cc40 | |||
| 2214dccd4a | |||
| ca9fced819 | |||
| 684b285217 | |||
| 1dc6243b75 | |||
| f1a8a7269f | |||
| 4e8830365e | |||
| 34e6f79096 | |||
| e58e22a329 | |||
| 4866e04c13 | |||
| bedcdfe26f | |||
| 5fe8618236 | |||
| 127377a92b | |||
| d6a083778a | |||
| a52eae6665 | |||
| 75ecf22ba9 | |||
| 7f444e93de | |||
| 818da103a8 | |||
| b565aaafc0 | |||
| 67282e2506 | |||
| 3c432a0d3a | |||
| a831244c3d | |||
| ad5532eaad | |||
| 8b03984ca8 | |||
| 953d57240f | |||
| dfb751ca12 | |||
| 0813ef0f67 | |||
| 1e12cad040 | |||
| 015b60ee24 | |||
| 66d3454129 | |||
| b385069ebb | |||
| 51879ed636 | |||
| c018684658 |
@@ -1,2 +1,4 @@
|
|||||||
[commands]
|
[commands]
|
||||||
proj = subl --project project.sublime-project
|
proj = subl .
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
*.nex
|
||||||
|
src
|
||||||
|
nexe.exe
|
||||||
|
nexe
|
||||||
|
npm-debug.log
|
||||||
|
examples/**/src
|
||||||
|
examples/**/out.nex
|
||||||
@@ -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
@@ -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.
|
||||||
@@ -1,58 +1,177 @@
|
|||||||
Compile javascript **with** node.js. This allows you to move your executable around *without* needing to install the node.js runtime.
|
### Nexe
|
||||||
|
|
||||||
## Requirements
|
[](https://gitter.im/crcn/nexe?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://david-dm.org/crcn/nexe)
|
||||||
|
[](http://waffle.io/crcn/nexe)
|
||||||
|
|
||||||
- Linux / Mac
|
Nexe is a command-line utility that compiles your Node.js application into a single executable file.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
### __dirname
|
||||||
|
|
||||||
|
Once the module is bundled it is part of the executable. __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 __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: __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
|
## Installation
|
||||||
|
|
||||||
Via NPM:
|
Via NPM:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install nexe
|
npm install nexe [-g]
|
||||||
```
|
```
|
||||||
|
|
||||||
Or git:
|
Or git:
|
||||||
|
|
||||||
```bash
|
```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
|
### CLI Usage
|
||||||
|
|
||||||
````text
|
```text
|
||||||
|
|
||||||
Commands:
|
|
||||||
-i the input javascript files
|
|
||||||
-o the output executable
|
|
||||||
--runtime the runtime version of node.js to compile with
|
|
||||||
|
|
||||||
Examples:
|
Usage: nexe -i [sources] -o [binary] [options]
|
||||||
-i input.js -o my-binary --runtime=0.6.2 compile javascript file with node
|
|
||||||
|
|
||||||
````
|
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',
|
||||||
});
|
output: 'path/to/bin',
|
||||||
|
nodeVersion: '0.12.5',
|
||||||
````
|
nodeTempDir: 'src',
|
||||||
|
python: 'path/to/python',
|
||||||
|
resourceFiles: [ 'path/to/a/file' ],
|
||||||
|
flags: true,
|
||||||
|
framework: "nodejs"
|
||||||
|
}, function(err) {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
```
|
||||||
|
"nexe": {
|
||||||
|
"input": "./bin/nexe",
|
||||||
|
"output": "nexe^$",
|
||||||
|
"temp": "src",
|
||||||
|
"runtime": {
|
||||||
|
"framework": "iojs",
|
||||||
|
"version": "2.3.1",
|
||||||
|
"ignoreFlags": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* output: can use ^$ for platform specific file extension
|
||||||
|
|
||||||
|
## Maintainers
|
||||||
|
|
||||||
|
* __Jared Allard__ ([@jaredallard](https://github.com/jaredallard)) <[jaredallard@outlook.com](mailto:jaredallard@outlook.com)> (Active)
|
||||||
|
* __Christopher Karper__ ([@ckarper](https://github.com/CKarper)) <[Christopher.Karper@gmail.com](mailto:Christopher.Karper@gmail.com)> (Active)
|
||||||
|
* __Craig Jefferds__ ([@crcn](https://github.com/crcn)) <[craig.j.condon@gmail.com](mailto:craig.j.condon@gmail.com)> (Not Active)
|
||||||
|
|||||||
@@ -1,2 +1,96 @@
|
|||||||
#!/usr/bin/env node
|
#!/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) {
|
||||||
|
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) {
|
||||||
|
console.log(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
console.log("hello browser!");
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
var nexe = require('../..');
|
||||||
|
|
||||||
|
nexe.compile(
|
||||||
|
{
|
||||||
|
input: "./index.js",
|
||||||
|
output: "./out.nex",
|
||||||
|
nodeVersion: "3.0.0",
|
||||||
|
framework: "iojs",
|
||||||
|
nodeTempDir: "src",
|
||||||
|
python: "python",
|
||||||
|
flags: true,
|
||||||
|
resourceFiles: ["./message.txt"]
|
||||||
|
},
|
||||||
|
function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Hello World!!!
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
var http = require("http"),
|
||||||
|
fs = require("fs"),
|
||||||
|
path = require("path"),
|
||||||
|
nexeres = require("nexeres"),
|
||||||
|
childProc = require("child_process"),
|
||||||
|
port = 1337;
|
||||||
|
|
||||||
|
//Fork a new process to execute the broser.js
|
||||||
|
childProc.fork(path.join(__dirname, "browser.js"));
|
||||||
|
if (false) {
|
||||||
|
require("./browser.js"); //force the bundler to include the .js file
|
||||||
|
}
|
||||||
|
|
||||||
|
//start a web server on specified port (or default if not given)
|
||||||
|
console.log("started HTTP server on port %d", port = Number(process.argv.concat().pop()) || port);
|
||||||
|
|
||||||
|
http.createServer(function(req, res) {
|
||||||
|
//return the embeded file in response to any request
|
||||||
|
|
||||||
|
res.write(nexeres.get("message.txt"));
|
||||||
|
|
||||||
|
res.end();
|
||||||
|
}).listen(port);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
hello world!
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"main": "./index.js",
|
||||||
|
"browser": "./index.js"
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
console.log("hello browser!");
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
var nexe = require('../..');
|
||||||
|
|
||||||
|
nexe.compile(
|
||||||
|
{
|
||||||
|
input: "./index.js",
|
||||||
|
output: "./out.nex",
|
||||||
|
nodeVersion: "3.0.0",
|
||||||
|
nodeTempDir: "./src",
|
||||||
|
framework: "iojs",
|
||||||
|
python: 'python',
|
||||||
|
flags: true
|
||||||
|
},
|
||||||
|
function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
Executable
+23
@@ -0,0 +1,23 @@
|
|||||||
|
var http = require("http"),
|
||||||
|
fs = require("fs"),
|
||||||
|
path = require("path"),
|
||||||
|
nexeres = require("nexeres"),
|
||||||
|
childProc = require("child_process"),
|
||||||
|
port = 1337;
|
||||||
|
|
||||||
|
//Fork a new process to execute the broser.js
|
||||||
|
childProc.fork(path.join(__dirname, "browser.js"));
|
||||||
|
if (false) {
|
||||||
|
require("./browser.js"); //force the bundler to include the .js file
|
||||||
|
}
|
||||||
|
|
||||||
|
//start a web server on specified port (or default if not given)
|
||||||
|
console.log("started HTTP server on port %d", port = Number(process.argv.concat().pop()) || port);
|
||||||
|
|
||||||
|
http.createServer(function(req, res) {
|
||||||
|
//return the embeded file in response to any request
|
||||||
|
|
||||||
|
res.write("Hello, world!");
|
||||||
|
|
||||||
|
res.end();
|
||||||
|
}).listen(port);
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
hello world!
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"main": "./index.js",
|
||||||
|
"browser": "./index.js"
|
||||||
|
}
|
||||||
+185
@@ -0,0 +1,185 @@
|
|||||||
|
/**
|
||||||
|
* 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 mdeps = require("module-deps"),
|
||||||
|
through = require("through"),
|
||||||
|
async = require("async"),
|
||||||
|
builtins = require("builtins");
|
||||||
|
|
||||||
|
var _log = require("./log");
|
||||||
|
|
||||||
|
function bundle (input, complete) {
|
||||||
|
|
||||||
|
async.waterfall([
|
||||||
|
|
||||||
|
/**
|
||||||
|
* first we resolve all of the deps
|
||||||
|
*/
|
||||||
|
|
||||||
|
function resolveDeps (next) {
|
||||||
|
|
||||||
|
|
||||||
|
var deps = [];
|
||||||
|
|
||||||
|
|
||||||
|
var md = mdeps({
|
||||||
|
xtransform: function (tr, file) {
|
||||||
|
|
||||||
|
var buffer = [];
|
||||||
|
console.log(tr);
|
||||||
|
|
||||||
|
|
||||||
|
return through(write, end);
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
|
||||||
|
function write (chunk) {
|
||||||
|
buffer.push(chunk.toString());
|
||||||
|
// console.log(chunk.toString(""))
|
||||||
|
console.log(tr);
|
||||||
|
}
|
||||||
|
|
||||||
|
function end() {
|
||||||
|
var content = buffer.join("");
|
||||||
|
// console.log(content);
|
||||||
|
/*
|
||||||
|
// TODO add uglify flag
|
||||||
|
var source = uglify.parse(content, {
|
||||||
|
strict: false
|
||||||
|
});
|
||||||
|
source.figure_out_scope();
|
||||||
|
source.compute_char_frequency();
|
||||||
|
source.mangle_names();
|
||||||
|
|
||||||
|
// TODO - production
|
||||||
|
content = source.print_to_string({
|
||||||
|
ascii_only: true,
|
||||||
|
quote_keys: true
|
||||||
|
});*/
|
||||||
|
|
||||||
|
this.queue(content);
|
||||||
|
this.queue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
filter: function (id) {
|
||||||
|
if ([ 'nexeres', 'sys', 'readline' ].indexOf(id) > -1) { return false; }
|
||||||
|
return !~builtins.indexOf(id);
|
||||||
|
},
|
||||||
|
extensions: [ '.js', '.json' ],
|
||||||
|
ignoreMissing: true
|
||||||
|
});
|
||||||
|
|
||||||
|
/** event for missing packages, fixes conditional requires **/
|
||||||
|
md.on('missing', function(id, parent) {
|
||||||
|
_log("warn", "couldn't find require '" + id + "', errors may occur.");
|
||||||
|
});
|
||||||
|
|
||||||
|
md.pipe(through(function (chunk) {
|
||||||
|
deps.push(chunk);
|
||||||
|
}, function () {
|
||||||
|
next(null, deps);
|
||||||
|
}));
|
||||||
|
|
||||||
|
md.end({ file: input })
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
function bundleScript (deps, next) {
|
||||||
|
var buffer = [loader.toString()];
|
||||||
|
var dbuffer = [];
|
||||||
|
|
||||||
|
for (var i = deps.length; i--;) {
|
||||||
|
var dep = deps[i];
|
||||||
|
|
||||||
|
var req = "function (require, module, exports, __dirname) { \n"
|
||||||
|
if (dep.id.toLowerCase().indexOf(".json", dep.id.length - 5) !== -1) {
|
||||||
|
//this is the result of require("someFile.json"), so we need to export it from the function
|
||||||
|
req += "module.exports = "
|
||||||
|
}
|
||||||
|
if ((/^\#\!/).test(dep.source)) {
|
||||||
|
dep.source = '//' + dep.source;
|
||||||
|
}
|
||||||
|
|
||||||
|
req += dep.source + "}";
|
||||||
|
|
||||||
|
dbuffer.push(JSON.stringify(dep.id) + ": ["+req+", "+!!dep.entry+", "+JSON.stringify(dep.deps)+"]")
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = ["(" + loader.toString() + ").call(null, {"+dbuffer.join(",")+"}," + JSON.stringify(deps[deps.length-1].id) + ")"].toString();
|
||||||
|
|
||||||
|
next(null, buffer);
|
||||||
|
}
|
||||||
|
], complete)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var loader = function (deps, key) {
|
||||||
|
var pathModule = global.require("path");
|
||||||
|
var darr = [];
|
||||||
|
var dir = global.require("path").dirname(process.execPath);
|
||||||
|
|
||||||
|
var argv3 = process.argv[3];
|
||||||
|
if (argv3) {
|
||||||
|
argv3 = pathModule.relative(pathModule.dirname(process.execPath), argv3);
|
||||||
|
argv3 = pathModule.resolve(pathModule.dirname(key), argv3);
|
||||||
|
}
|
||||||
|
if (process.argv[2] == "--child_process" && deps[argv3]) {
|
||||||
|
//we've been forked and should run the module specified by argv3[3] instead of the start up module
|
||||||
|
key = argv3;
|
||||||
|
process.argv.splice(2, 2); //restore the argv to [0] = executable, [1] = nexejs
|
||||||
|
}
|
||||||
|
else if (process.argv[2] == "--child_process") {
|
||||||
|
//fork called, but for a module not bundled.
|
||||||
|
argv3 = process.argv[3];
|
||||||
|
process.argv.splice(1, 2); //restore the argv to [0] = executable, [1] = script
|
||||||
|
global.require(argv3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
darr.push(deps[key]); //start up module.
|
||||||
|
|
||||||
|
function initModule (dep) {
|
||||||
|
if (dep.module) return dep.module.exports;
|
||||||
|
dep.module = { exports: {} };
|
||||||
|
|
||||||
|
dep[0](function (path) {
|
||||||
|
var rdep = deps[dep[2][path]];
|
||||||
|
var exports = rdep ? rdep.module ? rdep.module.exports : initModule(rdep) : global.require(path);
|
||||||
|
return exports;
|
||||||
|
}, dep.module, dep.module.exports, dir);
|
||||||
|
|
||||||
|
return dep.module.exports;
|
||||||
|
}
|
||||||
|
|
||||||
|
//run the startup module
|
||||||
|
darr.forEach(initModule);
|
||||||
|
|
||||||
|
return darr.filter(function (dep) {
|
||||||
|
return dep[1];
|
||||||
|
}).map(function (dep) {
|
||||||
|
return dep.module || {};
|
||||||
|
}).pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = bundle;
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/**
|
||||||
|
* 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 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;
|
||||||
+674
@@ -0,0 +1,674 @@
|
|||||||
|
/**
|
||||||
|
* 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"),
|
||||||
|
outcome = require("outcome"),
|
||||||
|
mkdirp = require("mkdirp"),
|
||||||
|
request = require("request"),
|
||||||
|
path = require("path"),
|
||||||
|
fs = require("fs"),
|
||||||
|
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",
|
||||||
|
"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, next);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bundle the application into one script
|
||||||
|
*/
|
||||||
|
|
||||||
|
function combineProject (nc, next) {
|
||||||
|
nodeCompiler = nc;
|
||||||
|
_log("bundle %s", options.input);
|
||||||
|
bundle(options.input, next);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write the bundle to the lib directory of the target node version
|
||||||
|
*/
|
||||||
|
|
||||||
|
function writeBundle (source, next) {
|
||||||
|
bundlePath = path.join(nodeCompiler.dir, "lib", "nexe.js");
|
||||||
|
_log("bundle -> %s", bundlePath);
|
||||||
|
|
||||||
|
//Remove all non-ascii code from sources
|
||||||
|
source = source.replace(/[^\x00-\x7F]/g, "");
|
||||||
|
// same path as all the other JS files
|
||||||
|
fs.writeFile(bundlePath, source, 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();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* monkeypatch child_process.js so nexejs knows when it is a forked process
|
||||||
|
*/
|
||||||
|
function monkeyPatchChildProc(next) {
|
||||||
|
_monkeyPatchChildProcess(nodeCompiler, next);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* compile the node application
|
||||||
|
*/
|
||||||
|
|
||||||
|
function makeExe (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(); });
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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, 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, 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 type = global.type;
|
||||||
|
var url, prefix = "https://"+framework+".org/dist";
|
||||||
|
|
||||||
|
// pick which url depending on the version
|
||||||
|
if(framework==="nodejs") framework = "node"; // cmon node why can't you stay the same
|
||||||
|
|
||||||
|
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(); })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the compiler object for the node version
|
||||||
|
*/
|
||||||
|
|
||||||
|
function (next, type) {
|
||||||
|
_getNodeCompiler(nodeFileDir, next, type)
|
||||||
|
},
|
||||||
|
|
||||||
|
], complete);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the compilier we will use for whatever platform we may be on and configure
|
||||||
|
* it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function _getNodeCompiler (nodeFileDir, 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;
|
||||||
|
if(isPy !== "python") {
|
||||||
|
configure = spawn(isPy, [cfg], { cwd: dir });
|
||||||
|
} else {
|
||||||
|
configure = spawn(cfg, [], { cwd: dir });
|
||||||
|
}
|
||||||
|
|
||||||
|
// local function, move to top eventually
|
||||||
|
function _loop(dir) {
|
||||||
|
/* eventually try every python file */
|
||||||
|
var pdir = fs.readdirSync(dir);
|
||||||
|
|
||||||
|
pdir.forEach(function(v, i) {
|
||||||
|
var stat = fs.statSync(dir+"/"+v);
|
||||||
|
if(stat.isFile()) {
|
||||||
|
// only process Makefiles and .mk targets.
|
||||||
|
if(v !== "Makefile" && path.extname(v) !== ".mk") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_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);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
var platformMake = "make";
|
||||||
|
if (os.platform().match(/bsd$/) != null) {
|
||||||
|
platformMake = "gmake";
|
||||||
|
}
|
||||||
|
var make = spawn(platformMake, [], { cwd: dir });
|
||||||
|
make.stdout.pipe(process.stdout);
|
||||||
|
make.stderr.pipe(process.stderr);
|
||||||
|
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 process.argv.splice(1, 0, "nexe.js");\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("--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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
|
||||||
|
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: ((isWin) ? 100 : process.stdout.columns - 2) // windows doesn't output colums correctly
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on("data", function (chunk) {
|
||||||
|
bar.tick(chunk.length);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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.
|
||||||
|
*
|
||||||
|
* @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),
|
||||||
|
resourceFiles: (_package.nexe.resourceFiles),
|
||||||
|
nodeVersion: (_package.nexe.runtime.version || options.r),
|
||||||
|
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
@@ -1,3 +1 @@
|
|||||||
exports.compile = function(ops, callback) {
|
module.exports = require("./exe");
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* standard output, takes 3 different types.
|
||||||
|
* log, error, and warn
|
||||||
|
*
|
||||||
|
* @param {any} arguments - Text to output.
|
||||||
|
* @return undefined
|
||||||
|
**/
|
||||||
|
function _log () {
|
||||||
|
|
||||||
|
var colors = require('colors');
|
||||||
|
|
||||||
|
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;
|
||||||
@@ -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;
|
||||||
Generated
-2
@@ -1,2 +0,0 @@
|
|||||||
node_modules/
|
|
||||||
node_modules/*
|
|
||||||
-4
@@ -1,4 +0,0 @@
|
|||||||
lib-cov/*
|
|
||||||
*.swp
|
|
||||||
*.swo
|
|
||||||
node_modules
|
|
||||||
-21
@@ -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
@@ -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
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
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
@@ -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
@@ -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
@@ -1,7 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
var argv = require('optimist')
|
|
||||||
.boolean('v')
|
|
||||||
.argv
|
|
||||||
;
|
|
||||||
console.dir(argv.v);
|
|
||||||
console.dir(argv._);
|
|
||||||
-8
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,2 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
console.dir(require('optimist').argv);
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
var argv = require('optimist').argv;
|
|
||||||
console.log('(%d,%d)', argv.x, argv.y);
|
|
||||||
-11
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,2 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
console.log(JSON.stringify(process.argv));
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
var argv = require('../../index').argv
|
|
||||||
console.log(JSON.stringify(argv._));
|
|
||||||
-304
@@ -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
@@ -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,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
+41
-7
@@ -1,16 +1,50 @@
|
|||||||
{
|
{
|
||||||
"author": "Craig Condon <craig.j.condon@gmail.com>",
|
"author": "Jared Allard <jaredallard@outlook.com>",
|
||||||
"name": "nexe",
|
"name": "nexe",
|
||||||
"description": "Roll node.s applications into a single executable",
|
"description": "create single executables out of your [node/io].js applications",
|
||||||
"version": "0.0.1",
|
"license": "MIT",
|
||||||
|
"version": "0.4.1",
|
||||||
|
"contributors": [
|
||||||
|
{
|
||||||
|
"name": "Criag Condon",
|
||||||
|
"email": "craig.j.condon@gmail.com",
|
||||||
|
"url": "http://crcn.io/"
|
||||||
|
}
|
||||||
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/crcn/nexe.git"
|
"url": "git://github.com/jaredallard/nexe.git"
|
||||||
},
|
},
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"optimist":"*",
|
"async": "1.2.1",
|
||||||
"sardines":"*"
|
"builtins": "1.0.1",
|
||||||
|
"colors": "^1.0.3",
|
||||||
|
"glob": "^5.0.5",
|
||||||
|
"mkdirp": "^0.5.0",
|
||||||
|
"module-deps": "^3.6.4",
|
||||||
|
"ncp": "^2.0.0",
|
||||||
|
"outcome": "0.0.18",
|
||||||
|
"progress": "^1.1.8",
|
||||||
|
"request": "^2.53.0",
|
||||||
|
"sprintf": "~0.1.5",
|
||||||
|
"step": "0.0.x",
|
||||||
|
"tar.gz": "0.1.1",
|
||||||
|
"through": "^2.3.6",
|
||||||
|
"yargs": "^3.2.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {}
|
"nexe": {
|
||||||
|
"input": "./bin/nexe",
|
||||||
|
"output": "nexe^$",
|
||||||
|
"temp": "src",
|
||||||
|
"runtime": {
|
||||||
|
"framework": "iojs",
|
||||||
|
"version": "2.3.1",
|
||||||
|
"ignoreFlags": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"preferGlobal": "true",
|
||||||
|
"bin": {
|
||||||
|
"nexe": "./bin/nexe"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user