Gitコマンド打ってGopher君を怒らせてみた(GOPATH配下以外で)

# これ is 何
題名の通り。GOPATH配下以外のGitコマンドはGopher君が許しません。
Gopher君可愛いよGopher君
今回はShellScriptでの設定の話が多めになります。

~~Google様は絶対~~

**顔文字パターン**
![giphy.gif](https://media.giphy.com/media/1vZcElb8GkOXqNiRw6/giphy.gif)

**gifパターン**
![giphy.gif](https://media.giphy.com/media/39jPX8cr1knxonp5RT/giphy.gif)

---

# 経緯
GOPATH以下でないlocalのディレクトリで作業していたらdep ensureでうまく依存関係入らなくて詰んだ経験から。
他言語も全てGOPATH/srcで管理して入り人もいるようなので、僕も~~Googleさまの犬になるために~~、$GOPATH配下のディレクトリでしかgit cloneできない仕様に変えてしまうことにした。
Go Oriented.
~~Goに居ては(ry~~

---

# 動作環境
macOS Mojave　バージョン10.42.2
go 1.11.4
zsh
# プロセス
---

## 1.BashScriptを一から学ぶ
[Linux初心者のシェルスクリプト入門 - Qiita](https://qiita.com/lrf141/items/6c01d2f7afff79cd7286)
[シェルスクリプト(bash)：基本的な5つのTips - Qiita](https://qiita.com/Nao1215/items/5765c777d8f6ca6b82b2)
などを参考に。

特にエムスリーさんのこの記事よかった
[bashスクリプティング研修の資料を公開します - エムスリーテックブログ](https://www.m3tech.blog/entry/2018/08/21/bash-scripting)

---

## 2.gopherコマンドを作る
[Goで乱数 - Qiita](https://qiita.com/cubicdaiya/items/819886c57e9d17e4b019)
[本物の golang を... 本物の Gopher を、お見せしますよ。 - Qiita](https://qiita.com/mattn/items/b7889e3c036b408ae8bd)

[GitHub - mattn/gol-cmd](https://github.com/mattn/gol-cmd)
を参考に作成。

↓をコンパイルしてgopherコマンドとしてぶち込んだ
**main.go**

```
package main

import (
	"fmt"
	"io"
	"math/rand"
	"os"
	"time"
)

var out io.Writer = os.Stdout

func main() {
	fmt.Fprintln(out, "\x1b[2J")
	gopherMsg := makeGopherMsg()
	for i := 0; i < 75; i++ {
		fmt.Fprintf(out, "\x1b[10;%dH\x1bK", i)
		fmt.Print(gopherMsg)
		time.Sleep(50 * time.Millisecond)
	}
}

func makeGopherMsg() string {
	rand.Seed(time.Now().UnixNano())
	var gopherMsg string
	randInt := rand.Intn(4)
	switch randInt{
	case 1:
		gopherMsg = ` ʕ◔ϖ◔ʔ { Google万歳！！！！　`
	case 2:
		gopherMsg = ` ʕ◔ϖ◔ʔ { まだGOPATH以外で消耗してるの？ `
	case 3:
		gopherMsg = ` ʕ◔ϖ◔ʔ { まだGo言語以外で消耗してるの？ `
	case 4:
		gopherMsg = ` ʕ◔ϖ◔ʔ { お腹すいた `
	default:
		gopherMsg = ` ʕ◔ϖ◔ʔ { まだGo言語以外で消耗してるの？ `
	}
	return gopherMsg
}
```

---

乱数でメッセージを生成しています。

作成ソースはこちら
[GitHub - takafk9/gopher-cmd: gopher is 流れる](https://github.com/takafk9/gopher-cmd)

---

## 3.gitのaliasを＄GOPATH以下以外でgopherコマンドに変更するスクリプトを書く
[bashのif文でワイルドカード・正規表現を用いて条件判断をさせる \| 俺的備忘録 〜なんかいろいろ〜](https://orebibou.com/2017/01/bash%E3%81%AEif%E6%96%87%E3%81%A7%E3%83%AF%E3%82%A4%E3%83%AB%E3%83%89%E3%82%AB%E3%83%BC%E3%83%89%E3%83%BB%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6%E6%9D%A1%E4%BB%B6/)
[シェルスクリプトを書く際に便利なコマンド＆基本の覚え書き - Qiita](https://qiita.com/umasoya/items/f54fd3252245622f35ba)


**gopher.sh**

```
#!/bin/sh

if [[ $(pwd) != *$GOPATH* ]]
then
  # GOPATH配下以外ならgopher様に怒られろ
  # gifで怒る
  alias "git=imgcat ~/pictures/gopher.gif"
  # 顔文字で怒る
  # alias "git=gopher"
else
  # GOPATH配下なら正常に戻したい
  alias "git=git"
fi
```

ポイントは＄GOPATHを含む場合true返したいってことで
３行目にワイルドカードの記述を採用しているところ。bashでもこんな記述できるんやな、、、、

---

## 4.cdコマンドを魔改造して、cdするたびにgopher.shを反映するようにする

**.zshrc**

```
# cd魔改造
function gocd(){
  \cd $1;
  source ~/project/udemy/demo/gopher.sh;
}
alias cd=gocd
```
[bashで複数コマンドのエイリアス - Qiita](https://qiita.com/mikakane/items/ac27582e8e52228adced)
上のサイトを参考にcdコマンドを、毎回gopher.shを反映するように魔改造しました。

\cdにしないと無限ループになって悲しくなるので注意

---

## 5 imgcatインストールして、表示するgif作る

作成したgopher.shのgitのaliasを、gopherコマンドじゃなくてimgcatコマンドにするよ

[imgcat - ターミナル上で画像を表示するコマンド - Qiita](https://qiita.com/Sh1ma/items/093725d75f889bf3ec20)
まず、上を参考にimgcatをインストールするよ

[無料GIFアニメ作成「AlpacaDouga（アルパカドウガ）」](http://firealpaca.com/douga)
そして、上のアプリでgifを頑張って加工して反映させた

---

# 大変だったこと
1. shellscriptで部分一致でtrue返すとかどうやんねん
2. cdするたびにスクリプト読み込むってどうすればええんやってなった
3. gifカスタマイズ辛い

# 得られたこと
- bashscriptの基礎知識
- 作業場を間違えそうになるとgopher君が叱ってくれる環境

---

# 今後の展望
- インフラのコード化の文脈からしても、shellscriptもっとオベンキョせねば
- imgcatでも何パターンかのgopherくんに怒ってもらいたかったのですが、今後そこの処理を書いていきたい。

---

# 結論
**go moduleに移行してこんな設定にしない**