Node製CLIで「BLEACH」の始解・卍解を確認したい！

唐突に「BLEACH」の登場人物の解号・始解・卍解をパッと確認できるやつ欲しい！と思ったので作りました。
「blch」コマンド。 [blch  -  npm](https://www.npmjs.com/package/blch)
nodeによるcli作成〜公開まで。

## TL;DR

`npm install -g blch`で！

できること

* 登場人物のリスト表示
* 指定した人物の解号・斬魄刀・卍解の表示
* 始解
* 卍解

＊全ての登場人物を網羅していません
＊基本的に**破面篇**までの登場人物を扱いますが、一部卍解は**千年血戦篇**以降で発現したものも扱っています
＊十刃(エスパーダ)の場合は始解・卍解ではなく帰刃を扱います

人物追加・編集・修正はこちらから自由にしていただいて構いません。
https://docs.google.com/spreadsheets/d/1e7Ms9sX2m1xu_4r20AgyIZHFgByRQp1s93ZE2PZlEaM/edit#gid=0
このデータからCSVを作成し、該当するものを整形して表示するという仕組みになっています。
＊スプレッドシート更新されたらコマンドも勝手に更新するような仕組みにはなってないです
＊CLIを作って公開までをやってみたかっただけなので作りは荒いです（レスポンス速度など考慮してなかったり）

## CLI紹介篇

### 人物リスト表示 - human

キャラクターをリスト表示します。
オプション指定により、護廷十三隊、仮面の軍勢(ヴァイザード)、十刃(エスパーダ)などのリスト表示ができます。
＊v1.1.0より完現術者（フルブリンガー）が追加されました。

```shell
blch human --gotei13
```

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149698/ae04b48b-a258-7bea-7838-6e29931b6aa4.gif)


### 概要表示 - tldr

登場人物の解号・斬魄刀・卍解を表示します。

```shell
blch tldr 黒崎一護
```

![output2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149698/e5417009-4e1d-1766-4230-6e0b2b8a9775.gif)

非常にお世話になっている`tldr`コマンドから着想を得ています。
shellコマンドの説明と使用方法を数行で紹介してくれます。
`brew install tldr`で！
https://github.com/tldr-pages/tldr

### 始解・卍解 - echo

echoコマンドにより、始解または卍解を行います。

```shell
blch echo --shikai 朽木白哉
blch echo --bankai 朽木白哉
```

![output3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149698/291cb253-4fd3-f37a-5e38-f049881bd4c6.gif)


### コマンド組み合わせ

```shell
blch human -a | fzf | xargs blch tldr
# もしくは（＊fish記法です）
blch tldr (blch human -a | fzf)
```

![output4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149698/6f46e846-fbea-b7c9-f16d-8da83a716908.gif)

ちなみにログインシェルはfishを使っていますが超おすすめです。
[ログインシェルをfishにしてみる - Qiita](https://qiita.com/bleru/items/047a4e8ea2afb654d9e1)

### help表示

それぞれのコマンドに`-h`をつけることでヘルプを見ることができます。

```shell
❯❯❯ blch hu -h
Usage: blch human|hu [options]

Output human names

Options:
  -a, --all          List all
  -g, --gotei13      List gotei 13
  -e, --espada       List espada
  -v, --visored      List visored
  -k, --karakuracho  List karakuracho
  -f, --fullbringer  List fullbringer
  -h, --help         output usage information

  Examples:

    $ blch human --gotei13
    $ blch hu -g

```

## CLI作成篇
### commander

node.jsにおけるCLIの完璧なソリューションです。
と書いてあります。実際使いやすかったです。↓
[commander  -  npm](https://www.npmjs.com/package/commander)

commanderの使い方を`blch  human`コマンドを例にとって説明してみます。
Typescriptです。

`index.ts`

```typescript
import * as program from 'commander';
=====

// バージョン情報の登録
// blch -V or blch --version でバージョンが確認できる
program
  .version('0.0.1', '-V, --version')

// blch humanコマンドの作成
program
  .command('human') // コマンド名の登録 ここで登録したものを`blch ~`の形で使える
  .alias('hu') // alias登録により、`blch hu`と打つことも可能
  .description('Output human names') // help用
	// optionの登録（省略可能）
  .option("-a, --all", "List all")
  .option("-g, --gotei13", "List gotei 13")
  .option("-e, --espada", "List espada")
  .option("-v, --visored", "List visored")
  .option("-o, --other", "List other")
  .action( async (cmd, options) => {

	  /**
		`blch human --gotei13`を実行した場合
		`cmd`に`gotei13`のBooleanパラメータがtrueで追加される
		`gotei13`は上記optionで設定した`--gotei13`の部分に該当する

		`blch human --gotei13 4`を実行した場合
		`blch human --gotei13`を実行した時とcmdの内容は同じ
		optionsは['4']となっている
		つまり`--gotei13 4`で指定したものが文字列として配列に入る
		
		今回のblchコマンドでは考慮していないが、
		オプションの重ねがけも可能。
		`blch -g -e`とするとcmdの`gotei13`も`espada`もtrueになる
		また、`--gotei13 4 5`とオプションに入れると
		optinosは、`['4', '5']`となる

		以下から`cmd`, `options`の値で条件分岐し出力する処理
	  */

	  // csvファイルから全リストを取得
    const dataList: Human[] = await files.getHumanDataList()

    let targetCode: GroupCode = 'all'
    if (cmd.gotei13) {
      targetCode = 'gotei13'
    }
    if (cmd.espada) {
      targetCode = 'espada'
    }
    if (cmd.visored) {
      targetCode = 'visored'
    }
    if (cmd.other) {
      targetCode = 'other'
    }
	  // オプションから対象を取得
    const humans = findHumansByGroupCode(dataList, targetCode, options)
    if (humans.length === 0) {
      console.log('No matching')
      return
    }
	  // ターミナルへ出力
    humans.forEach(human => console.log(human.name))

  })
	// helpの定義
  .on('--help', function() {
    console.log('\n  Examples:')
    console.log()
    console.log('    $ blch human --gotei13')
    console.log('    $ blch hu -g')
    console.log()
  })

// blch humanコマンド以外を作成する場合は同じように追加していく
program
  .command('tldr <target>')
======

// 最後にターミナル引数をparseする処理
program.parse(process.argv)
```

サクッとコマンド作れて良い。


### chalk

[chalk  -  npm](https://www.npmjs.com/package/chalk)
ターミナル出力に色をつけたり太字にしたりできます。

* chalk未使用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149698/c24ed2f8-d3dd-a0c5-aba8-ef30658e6c63.png)
* chalk使用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149698/82ba8b04-6e85-6211-92f3-551f8e594fd9.png)

chalkを使うことで味のある出力になります。

今回この2つくらいしかCLI用のパッケージは使ってないですが、NodeのCLIには他にも使えそうなものは色々あるんだなということを知れました。
こちらはgitのpackage解決周りでバグってビルドできなかったけど参考になりました。
[Build a JavaScript Command Line Interface (CLI) with Node.js — SitePoint](https://www.sitepoint.com/javascript-command-line-interface-cli-node-js/)

## CLI公開篇
ほぼこれに沿って行ったので参照のみ貼ります。
npmへの公開は思っていたより簡単でした。
https://qiita.com/TsutomuNakamura/items/f943e0490d509f128ae2

## まとめ
* nodeでのCLI作成〜公開を行った。意外とすんなりできた。
    * goとかrubyとかrustとかpythonでのCLI作成はどうなんだろう
* 完全に個人用のCLIだが作るきっかけができ、「BLEACH」に感謝。
    * 網羅できていない部分は申し訳ありません
    * (追記)千年血戦篇アニメめっちゃ楽しみ