【cli】君もgitmoji-cでエンジョイコミット

うちの会社には[gitmoji](https://gitmoji.carloscuesta.me/)文化がありまして、コミットの先頭に絵文字をつける風習があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/4778c8fe-5c34-1871-0efb-db29dd51e6d2.png)

どんなことをするのかというと、例えばAndroidのコミットは以下のemojiがひも付きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/d018bf6b-8a06-79ca-9334-ae43418e8e0f.png)

:robot:

これをgit commit時にprefixにつけるだけです。

`:robot: Build Error Fix`

すると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/3a80862b-c1e2-0753-1dec-6b119239b898.png)

github上でこんな見た目となり、「これはAnroidのbuildエラーを直したのかー」とわかりやすくなりますね！

メリットとしては単純に楽しい点もありますが、
「ログの情報量が上がる」点があります。

例えばAndroid特有の同じバグを二回踏んでしまったとき、前回なにやったかなーとcommitログを漁る機会がありました。そんなときもgit log のgrepか、githubのsearchでgitmojiを検索すれば一発でたどり着きました！

```shell
$ git log --oneline --grep :robot
xxxxxxx :robot::lipstick:[AIRCLOSET-2010] Fix: TextInputでタブバーが押し上げられる現象fix
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/c5f1dd2f-b28b-6296-6985-beeacad0d1dc.png)

楽しい、ググラビリティを上げるという点でgitmojiは一押しです。

淡白なcommit一覧もgitmojiがあれば、ほら、華やかさを感じませんか・・・？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/61a27aa1-fde2-4d1e-1244-0a4c318b9d7f.png)

## gitmojiのcode探すの面倒問題

gitmojiはwebページに公開されています。
https://gitmoji.carloscuesta.me/

emojiのcodeを毎回覚えているわけでもなく、commitのたびに都度サイトを見に行っていました。なんか面倒です。

レアな修正なんかが登場するとcodeは調べなきゃわかりません。
wip:construction:とか、CI:construction_worker:とか覚えてられない・・・

## typo問題
そして慣れ始めたころ、typoはやってくるのです・・・。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/a624da10-51dc-3e96-e60d-f8eccd28e7aa.png)

だ、ダサい・・・！

## 問題を解決するCLI

そんな問題点を解決するのにちょうどよいCLIを見つけました。

[gitmoji-cli](https://github.com/carloscuesta/gitmoji-cli)です。

このgitmoji-cli、

- gitmoji一覧がわかる
- gitmojiの検索ができる
- gitmojiを使ったコミットができる

おお、これがあればtypoコミットもないし、terminalでいつでもgitmoji検索できる！！！

といった機能があって大変よろしいのですが、１箇所不満があって、「gitmojiを使ったコミット」がgpgを求めてくるため、gpg設定をしないとコミットできないという点です。
（設定で解除できるかもしれませんが、デフォでgpg求めてくるのはよくない）

なんだかそれはめんどくさかったので、いい方法はないかなーと思案した結果、いい機会だしgpg求めないバージョンのgitmoji-cliを作ってみることにしました。

# できたもの
**[gitmoji-c](https://github.com/nitaking/gitmoji-c)**

```shell
$ yarn global add gitmoji-c
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/ee5377b3-c5b4-485f-548b-44fe18bd0f1b.png)


## gitmoji一覧がわかる

```shell
$ gitmoji list
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/eba30630-16d4-a2d7-b3d0-d2ff9f775f9f.png)

## gitmojiの検索ができる

```shell
$ gitmoji list -s <search word>
# or
$ gitmoji list --search=<search word>
# or
$ gitmoji list <search word>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/6fa31d22-9f4d-c3bd-06c3-2fd2413fd41e.png)

## gitmojiのコミットができる（応答型）

```shell
$ gitmoji commit
```
![2019-06-19 07 40 52](https://user-images.githubusercontent.com/10850034/59724737-dedeb400-9265-11e9-9d39-76beec62f99c.gif)

## その他
...僕の場合、「commitでgitmojiを複数書きたいと」いったニーズもあるため、gitmoji-cに機能拡張を行っていくつもりです！



そしてこれはたまたまなんですが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103475/211f5c9e-ae35-0e92-a37d-9205753b05d2.png)
shell上で絵文字が表示されるというメリットが付いてきました。やったね！

# 今回使用したライブラリ

## oclif

`CLI 作る` とかでググるとgoでつくる記事が多いのですが、goは触ったことがないので、nodeで作ってみました。

今回は [oclif](https://github.com/oclif/oclif)を使って作成します。

- [Open CLI Framework "oclif" - 独自CLIコマンド作成のためのオープンソースフレームワーク -Qiita](https://qiita.com/mokamoto/items/f70eaff72f795f1d7322)

結構これがなんでもよしなにやってくれるやつで、initialで作成する際にtypescriptを選べたり、ci選択でcircleciを選択すると自動で `.circleci/config.yml` を吐き出してくれたりとしてくれるので、サクッとCLIを作りたいユーザーには良いものです！

- [https://github.com/nitaking/gitmoji-c/blob/40b93e96ad/.circleci/config.yml](https://github.com/nitaking/gitmoji-c/blob/40b93e96ad/.circleci/config.yml)

### 注意

version 1.13.2までは`npm publish` したときにtsのbuildがうまくできず、コマンドが正常に実行できないバグがありました。

- [https://github.com/oclif/oclif/issues/246](https://github.com/oclif/oclif/issues/246)

こちらは1.13.3にて修正されたので現在は正常に動作するはずです！

publishしたのに動かなくて悲しかったのですがissueに上げたら数日で解決策を提示してくれました。コミュニケーションの早いライブラリは良いですね！

## inquirer

gitmoji-cliのコミットでは応答型CLIとなっていて、

1. 絵文字の選択
2. コミットタイトル
3. コミットメッセージ

の入力を求められます。

この応答型CLIを実装するのが[inquirer](https://github.com/SBoudrias/Inquirer.js/)です。

[](https://www.notion.so/5faae53431c84b3385187588917739aa#7443512335a64344a0e8730c942f04bd)

もともとは[enquirer](https://github.com/enquirer/enquirer)を使うつもりだったのですが、絵文字の選択時に外部データを使った選択肢を実装する方法がパッと見ではわかりませんでした。

本家でも[inquirer](https://github.com/SBoudrias/Inquirer.js/)は使用されているのでそのまま採用しました。`source` 要素として外部データを渡すと選択可能になります。

    class Prompt {
      public get questions() {
        return [
          {
            name: 'gitmoji',
            message: 'Choose a gitmoji:',
            type: 'autocomplete',
            async source(_: any, input: { toLowerCase(): void; }) {
              const emojiList = await gitmojis()
              const searchResult = emojiList.filter((gitmoji: IGitmoji) => {
                const emoji = gitmoji.name.concat(gitmoji.description).toLowerCase()
                // @ts-ignore
                return (!input || emoji.indexOf(input.toLowerCase()) !== -1)
              })
    
              return displayValue(searchResult)
            }
          },
          {
            name: 'title',
            message: 'Enter the commit title',
          },
          {
            name: 'message',
            message: 'Enter the commit message:',
          },
        ]
      }
    }

- [https://github.com/nitaking/gitmoji-c/blob/40b93e96ad/src/prompt.ts](https://github.com/nitaking/gitmoji-c/blob/40b93e96ad/src/prompt.ts)

### execa

「`git commit` 実行させたらええやん」と思っていたんですが、

「それどうやって実行させんの・・・？」と思っていたところに

execaの登場

    import * as execa from 'execa'
    
    const {stdout} = await execa('git', [
          'commit',
          '-m',
          title,
          '-m',
          message,
        ])

- [https://github.com/nitaking/gitmoji-c/blob/40b93e96ad/src/commands/commit.ts](https://github.com/nitaking/gitmoji-c/blob/40b93e96ad/src/commands/commit.ts)

第一引数にはコマンド名で、第二引数には配列でオプションを渡すことができます。

簡単でしたね！

---

さぁ、あなたもgitmoji、よかったらやってみませんか・・・？


[gitmoji-c](https://github.com/nitaking/gitmoji-c)