コマンド引数パーサーのminimistを再実装した

> [chopsticks@0.4.0 - More greedy argument parser like a minimist!](https://github.com/59naga/chopsticks/tree/v0.4.0)

```bash
npm install chopsticks
```

```js
const parse = require('chopsticks');
parse('-f true --no-foo true noop! -- huh'.split(' '), { unknown: true });
// {
//   "_": [
//     "huh"
//   ],
//   "unknown": [
//     Flag { type: 'short', name: 'f', value: 'true' },
//     Flag { type: 'long', name: 'foo', value: false },
//     "true",
//     "noop!"
//   ]
// }
```

[minimist-v1.2.0](https://github.com/substack/minimist/tree/1.2.0#methods)をes6で再実装しました。ビルド後のコードは[minimist-v1.2.0のテストが全て通ります](https://travis-ci.org/59naga/chopsticks/jobs/121327676#L163)。

したかったこと（以下のような機能追加）
---
* `$ npm-run-all --serial cover lint report --parallel foo bar baz`[^1] のような引数の巻き込み
* `$ abby cover, lint, report`[^2]のようなカンマ区切りの構文のサポート
* [200行弱の関数が１つだけexportされていて、読めない](https://github.com/substack/minimist/blob/1.2.0/index.js#L94)

最後に関しては、自分の読解力の無さが原因で、書いてみるとそこまで難しい処理はないように見えました。
自分のライブラリでは、[クラスベースに書き直し](https://github.com/59naga/chopsticks/blob/v0.2.0/src/Chopsticks.js#L6)、役割ごとにメソッドを切るようにして可読性の改善を試みています。（[max complexity](http://saturday-dory-fever.blogspot.jp/2012/04/cyclomatic-complexity.html)は`34` -> `17`に減りました）

ほか、試してみたこと
---
* [bundleDependencies](http://qiita.com/mysticatea/items/7018ca26abfa7701debc#5013-bundleddependencies-%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F)の代わりに、[rollup](http://qiita.com/cognitom/items/e3ac0da00241f427dad6#%E4%BD%BF%E3%81%84%E6%96%B9)の[rollup-plugin-node-resolve](https://github.com/rollup/rollup-plugin-node-resolve#rollup-plugin-node-resolve)で依存モジュールを固定しました。`dependencies`を削除して、依存を全て`devDependencies`に定義し、[browserify](http://akabeko.me/blog/2014/12/browserify/)のように１つのファイルだけ生成して、npmにアップロードしています（しかし、`process`や`Buffer`の置き換えなどは行わないため、軽量です）。[^3]
* [array-from](https://github.com/59naga/array-from)を使用して[ショートフラグで絵文字をサポートしました](https://github.com/59naga/chopsticks/#new-features)。`$ foo -🍣👹👺 baz`は`minimist@1.2.0`でパースできません。
* `unknown=true`を追加しました。`minimist`は関数の定義が必須でしたが、`chopsticks`は`unknown`に解析情報を返します。
* ショートフラグの16進数サポート…`-i012`は`{i:012}`としてパースされますが、[`-i0xdeadbeef`は`{i:0xdeadbeef}`でパースされません](https://github.com/59naga/chopsticks/blob/v0.2.0/test/no-options/short.js#L48-L55)。これを修正しています。
* ロングフラグで相対パスを指定できるようにしました。[フラグをそのままプラグインのON／OFFにするようなデザインのCLI](https://github.com/abigailjs/abigail#usage)の場合、野良プラグインをすぐに試せる機構として`--./plugin.js value`は、`{"./plugin.js": "value"}`とパースします。`minimist`には既に[`-i/path/to/dir`で`{i: "/path/to/dir"}`が返る構文が存在する](https://github.com/substack/minimist/blob/1.2.0/test/parse.js#L147-L157)ので、[この機能はロングフラグ、かつ`--.`で始まるフラグ限定です](https://github.com/59naga/chopsticks/blob/v0.4.0/test/no-options/long.js#L88-L103)。

速度差ですが、[matcha](https://github.com/logicalparadox/matcha)で`minimist`との実行結果を測ってみたところ、`chopsticks`には余分な処理が多いせいか、`minimist`のほうが高速に動作することを確認しています。これは課題です…。
 
[^1]: [npm-run-all](https://github.com/mysticatea/npm-run-all#readme) by @mysticatea - A CLI tool to run multiple npm-scripts in parallel or sequential.

[^2]: [abigail](https://github.com/abigailjs/abigail#usage) by @59naga - lightweight, pluggable, a minimal task runner. using your npm-scripts.

[^3]: とは言うものの、[複数のプラグインを経由して](https://github.com/59naga/chopsticks/blob/v0.2.0/rollup.config.js#L12)圧縮したコードは、[ソースマップ抜きで`15KB`が限界でした](https://npmcdn.com/chopsticks@0.2.0)