コミットメッセージをアスキーアートで装飾する

この記事は[Hamee Advent Calendar 2019](https://qiita.com/advent-calendar/2019/hamee)の14日目の記事です。

# はじめに
コマンドラインインターフェース(CLI)とアスキーアート(AA)は親和性が高く、`sl`や`cowsay`などその親和性を発揮したジョークコマンドが多数存在している

そこで、[git-hook](https://git-scm.com/book/ja/v2/Git-のカスタマイズ-Git-フック)を利用して`git commit`したときにコミットメッセージをAAで装飾するジョークhookを作った

## ぶち当たった壁
某掲示板を中心に発達したAAは主にWindowsのフォントで綺麗に表示されるようにできているため、別の環境でみようとした時に綺麗に見えない可能性がある。（というかフォントが変わると綺麗に見えなくなるのは当たり前だったが実際に見るまで酷さを知らなかった）

元々やろうとしてことはアスキーアートを大量に保存(もしくは外部から取得)しておき、コミットメッセージによってランダムなAAで装飾するものだったが、綺麗に表示されないAAが多かったため断念。

結局自分の環境で綺麗に表示され、できるだけ他のフォントでも崩れないようなAAをいくつか選んで装飾することにした。

# 装飾例
`Roboto Mono Medium for Powerline`サイズ12での表示

## 短いコミットメッセージの場合

```
タイポを修正
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch test
# Changes to be committed:
#       modified:   test
```

<img width="531" alt="20191214-011457.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277953/b002dd07-c94e-0abc-65a0-b8a90cb8ce45.png">

## 長いコミットメッセージの場合

```
簡潔な説明が書けず長ったらしくなったコミットメッセージの場合

詳細なメッセージが残されている場合もある
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch test
# Changes to be committed:
#       modified:   test
```

<img width="552" alt="20191214-001241.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277953/ae86ae56-66ae-0e0b-5388-a5888bae982e.png">


## マージコミットの場合

```
Merge branch 'test2' into test

# Conflicts:
#       test2
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
#       .git/MERGE_HEAD
# and try again.


# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch test
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#       modified:   test2
```

<img width="456" alt="20191214-003249.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277953/f4bef211-ca17-d890-96ba-30d997b37d50.png">


# 実装
```sh:commit-msg
#!/bin/sh

DOUNIDEMO(){
    cat << EOS
　　　　　　　*'\`\`・* 。
　　　　　　　　|　　　　 \`*。
　　　　 　　,｡∩∧_,,∧　 　*
　　　　　　+　(´･ω･\`)　*｡+ﾟ
　　　　　　\`*｡ ヽ、 つ *ﾟ*
　　　　　　 \`・+｡*・'ﾟ⊃ +ﾟ
　　　　　　　☆　　 ∪~ ｡*ﾟ
　 　　　　　　\`・+｡*・ ﾟ
EOS
}

DOG() {
    cat << EOS
＼
　 ￣ヽ、　　　_ノ￣￣￣￣￣￣￣￣￣￣￣￣￣￣￣￣￣￣￣￣￣￣￣
　 　　｀'ｰ '´
　　　　　　○
　　　　　　　Ｏ　
　　　　　　　　　__,.....--‐―― ― ― --..､　　
　　　　　　　,／　　　 l　 　 ヽ　 　 　＼
　　　　　 ／　　　 　 /　　　　　 　　 ヽ｀
　　　　　l　　　　　　 l　　　　　 　  　!　
　　　　　ヽ　　　　　/　　　●　　 　 　● |
　　　　　!　ヽ 　 　 l　　　　　　　　 ヽﾉ/　　と思うわんわんであった
　　　 　 ,! 　 ＼　│　　　　　　　　　＿ ヽ
　 　 　 ,!　　 　｀´　　　　　　　  （::）l
　　　　|　　　　　　 　｀---､　　　　 ￣　l 　
　　　　!　　 　 　  　 　 　｀ｰ ､..＿.／⌒iﾉ　
　　　　!　　　　　　　　　　　　 ヽ　　￣
EOS
}

N_TONE(){
    cat << EOS

　　　　　　　　 ,-､　　　　　　　　　　　,.-､
　　　　　　　 ./::::＼　　　　　　　  ／::::::ヽ
　　　　　　　/:::::::::;ゝ--──-- ､._/:::::::::::|
　　　　　　 /,.-‐''"´ 　　　　　　　　 ＼::::::::|
　　　　　／　 　　　　　　　　　　　　　　ヽ､::::|
　　　　/　　　　　　　　　　　　　　　　　　　ヽ|
　　 　l　　　　　　　　　　 　 　 　 　 　 　  l
　　　.|　　 　●　　　　　　　　　　　　　　　　|　　んーと
　 　　l　　, , ,　　　　　　　　　　　●　　　 l
　　　　\` ､　　　　　　(_人__丿　　　　､､､ 　 /　
　　　　　　\`ｰ ､__　　　　　　　　　　 　 　／
　　　　　　　　　/\`'''ｰ‐‐──‐‐‐┬'''""´

　　　　　　　　 ,-､　　　　　　　　　　　,.-､
　　　　　　　 ./::::＼　　　　　　　  ／::::::ヽ
　　　　　　　/:::::::::;ゝ--──-- ､._/:::::::::::|
　　　　　　 /,.-‐''"´ 　　　　　　　　 ＼::::::::|
　　　　　／　 　　　　　　　　　　　　　　ヽ､::::|
　　　　/　　  　●　　　 　 　 　 　 　 　 　 ヽ|
　　 　 l　　　, , ,　　 　 　 　 　  　●　　　l
　　　 .|　　　 　　　　(_人__丿　　　　　､､､　|　　$first_line
　 　 　l　　　　　　　　　　　　　　　　　　　l
　　　　\` ､　　　　　　　　 　 　 　 　 　 　 /
　　　　　　\`ｰ ､__　　　 　 　 　　　　　　／
　　　　　　　　　/\`'''ｰ‐‐──‐‐‐┬'''""´
EOS
}

max_len=0
first_line=''
is_merge=false

IFS=$'\n';
for line in `cat "$1"`
do
    # コミットメッセージのうち最も長い行の長さを調べる
    msg=$(echo $line | awk -F '[#]' '{print $1}');
    if [ ${#msg} -gt $max_len ]; then
        max_len=${#msg};
        
        if [ -z "$first_line" ]; then
            first_line=$msg;
        fi
    fi
    # マージコミットかどうかを調べる
    if [ "`echo $line | grep 'Merge'`" ]; then
        is_merge=true;
    fi
done

if [ $max_len -eq 0 ]; then
    exit 0;
fi

# マージコミット用のAA
if $is_merge; then
    echo "$( DOUNIDEMO )" >> $1;
    exit 0;
fi

# コミットメッセージの横の長さによってAAを変える
case $max_len in
    [1-9])
        echo "$( N_TONE )" > $1;;
    *)
        echo "$( DOG )" >> $1;;
esac
```
`git commit`でメッセージを確定させると末尾にAAが追加され、そのメッセージで`commit`する。


## 学べたこと
ざっくり簡潔に

- 文字列の長さを表示したい時は`${#hensumei}`と書く

---

- `while`でパイプを使うと別プロセスで実行され、ループ内部の変数の変化がループ外部で反映されない(ループ外部では値が変化していない)
-  `for`を使いパイプなしでファイルを一行ずつ読み込むことでそれを回避できる

---

- ヒアドキュメント内にカッコが片側だけある場合の出力

```sh:test.sh
#!/bin/sh

echo $(cat << EOS
ヒアドキュメントの

例(
EOS
)

#$ sh test.sh
#  test.sh: line 3: unexpected EOF while looking for matching `)'
#  test.sh: line 9: syntax error: unexpected end of file
```

- `` `" "` ``で囲むか`function`の戻り値から受け取ることでエラーを回避できる

```sh:test.sh
#!/bin/sh

echo "`cat << EOS
ヒアドキュメントの

例(
EOS
`"

#$ sh test.sh
#  ヒアドキュメントの
#
#  例(
```

```sh:test.sh
#!/bin/sh

MY_FUNC(){
    cat << EOS
ヒアドキュメントの

例(
EOS
}

echo "$( MY_FUNC )"

#$ sh test.sh
#  ヒアドキュメントの
#
#  例(
```

# おまけ
githubからコミットメッセージを見る

Mac
<img width="826" alt="20191214-004410.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277953/fce5f9a7-71c2-c2da-23b6-f58b4c821097.png">

Windows
![commit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277953/cd710d78-4a0d-753a-5845-d26eeeac20bf.png)

AAのバリエーションがもっと増やせるとよかったなあ　と思うわんわんであった