ことの発端はこの発言。
世間ではSourceTreeがよく使われているらしい。だが安心してほしい。弊社のコードでは、Source Treeを使うとコミットができないようになっている。もちろんcliなら問題ないので自然とcliの操作に慣れることができるだろう。
— 衣装をください (@hnle0) September 24, 2016
まあどういうことかと言うと、現在進行中のプロジェクトではコードの質を担保するため、Linter、この場合はphpcsに引っかかったものをprecommitを使うことで阻止していた。
ところが、PHP7.0+前提のコードを書いているため、Macにデフォルトで搭載されているPHP5.5(これはSierraでも変わらなかったのか)ではSyntax Errorを起こす。
具体的には、phpcsが走る際にcomposerのオートロードでLaravelのhelper関数をロードするときにエラーが発生する。PHP7関係ない。
そのため、.bash_profile
や.zshrc
できちんとphp5.6+にPATHが通っていれば問題なようだが、そうでなかった場合に上記の理由によりSourceTreeからコミットできないメンバーが居た。
それをネタにツイートしたのだが、「嘘じゃん、コミットできるじゃん」と指摘されたので「ならば禁止してやろう」という事になった。
(誤字がガバガバ)普通にSourceTreeでコミットきるんだけどって上から指摘されたのでSourceTree判定ShellScript(ガバガバ)書きました。 https://t.co/2Oljv3zsfV
— 衣装をください (@hnle0) 2016年9月24日
枕が長すぎたけどココからが本題。
まずprecommit
.git/hooks/pre-commit
にコミット前に走らせたいスクリプト等を置いておけばそれが走り、0以外で終了すればコミットが中断される。
とは言え、.git以下は言うまでもなく共有が面倒なのでnpmモジュールpre-commit
を利用してチーム全体で低品質なコードをコミットできないようにするの手法を使用している。
pre-commitのためだけにnpmを使っているが、どうせ全員の環境にあるしnpm install
しといて〜だけで共有できてとても手軽である。もちろん、一度npm install
を済ませれば後の変更にはいくらでも耐えれる。
pre-commmitでシェルスクリプトが走るようにしておけばいいだろう。
SourceTree からのコミットを検出
SourceTreeからのコミットを禁止するのだから、それを検出する必要がある。
きっと何かそれらしい環境変数(シェル変数)をSourceTreeが付けてるだろうという甘い考えでそれらを眺めてみたのだが、割とココが厄介だった。
まず、固有の変数というものが見当たらなかった。
ならばSourceTreeの文字列を含むものを、と探してみたのだが、それらしいものもなんというかイマイチ。
強いて言えばPYTHONPATHのようなPATHにSourceTree.appのパスが含まれているが、これを使うのはどうかという感想。
ただ一つ、SourceはGitのcredential.helper
としてsourcetree
というSourceTreeに内臓のものを利用しているらしいと言うことがわかった。
(ちなみに普段CLIの際、自分はosxkeychain
を利用している。)
ならば、これを利用するしか無い。(これって設定で変えられたりしないよな?)
シェルスクリプトを書く
別にシェルスクリプトで書かなくてもいいのだが、正直これで済ませるのが一番手っ取り早いので上記の条件をシェルスクリプトにした。
ただ単にhelper見るだけだけど。
if [[ `git config --get credential.helper` = "sourcetree" ]]
then
echo "SourceTree でのコミットは認めていません。" ; exit 1
fi
これをpre-commitスクリプトに書くだけ。神。
もちろんcliやその他のアプリからは問題なくコミット可能。神。
なおSourceTreeでのコミット禁止とかSourceTreeが嫌いみたいに見えるかもしれませんが毎度複雑になりすぎたツリー見るにはGUIさまさまです。
流石につらすぎる。まあSourceTreeにはつらい思い出もあるけど……