Go言語でgit操作してGitHubにPRを出す
背景・モチベーション
社内ツールにos.Execを多用しているGoのツールがあり非常に厳しい感情になってしまったので、Goできちんと作るならどうなるのかを試してみたい。ツールの具体的な機能としては、ファイルをいじってcommit、pushしてGitHubにPRを出すものだ。
ちなみにGoでgit操作だったりGitHubのAPIを提供するライブラリの存在は知っているけれど使ったことはなかった。今回のモチベーションはこれらのライブラリの使い勝手を知っておきたいという理由の方がツールの調教欲よりも大きかったりする。
アプローチ
同じようなことを実現する際にはいくつかの手段があると思う。
- gitを使いつつPR作成だけは何かツールを使う。
- GitHubの公式cliを使う。 github.com
- cli使わず自作しちゃう。(今回はこれ)
今回は自作を前提としているため比較はしない。
作ったもの
github.com ツールというよりはライブラリを使ってみた程度のものなのでこれだけでは動かない。もし実装まで見るとしても参考程度でお願いしたい。
使ったもの
READMEにも書いているけれど下記のライブラリを使用している。 github.com github.com
特徴
特徴らしい特徴はないけれど、gitとGitHubへの操作ができる。(それはそう)
認証方法はアクセストークンとBasic認証+ワンタイムパスワードも実装している。
configのinsteadOfの操作がgo-gitの最新バージョンには含まれていないので、masterの最新バージョンをgo getしている。
感想
ドキュメントがわかりやすい
非常に使いやすかった。godoc読めばある程度操作がイメージできるようになっていて、go-githubに至ってはREADMEが非常にわかりやすかった。
gitわからん
しかし、開発中はgitの内部の知識がなくてgo-gitの動作確認に手こずることが多かった。
go-gitは.git配下を読むため、.git配下にどういうファイルがありそこに何が書かれているのかある程度知っている必要があった。.git/HEADに現在のブランチ名が入っていたり、.git/refs配下にブランチ名やタグ名のファイルがありその中にハッシュが書かれてることは今回初めて知った。ここは動かすために調べてた程度なので誤認しているかもしれない。
sshわからん
また、sshを使ったremoteリポジトリへのpushでは、引数のPushOption
というstructに認証情報を設定する必要があったが、認証情報であるAuthMethod
というinterfaceをどう満たしてあげれば良いかわからなかった。
最終的にはgodocや実装を見てNewPublicKeysFromFile
という関数で秘密鍵のファイルからAuthMethod
を満たした公開鍵情報を作成できることがわかったのが、そこにたどり着くまでに苦戦してしまった。
具体的には、本来は秘密鍵を食わせるべきところで公開鍵を渡してしまっていた。また、id_rsa.pubを渡した際にpem形式にしろと言われたのでid_rsa.pubをpem形式にするための方法を調べたりしていた。id_rsa.pubをpemファイル形式にする方法は調べたらわかったので一応貼っておく。
モチベーションの整理大事
今回は使えるツールを作ろうとせずにライブラリを触ってみたいというモチベーションだったので設計に拘ったりせず淡々と開発と検証をできた。モチベーションの整理って大事。開発・検証時間はおよそ3時間強くらいだった。簡単な検証って言いつつ若干時間使いすぎた気もする。
作ってみてCIでGoに依存した処理をしているならこういったツールの使い所が多少はあるかもしれないなと思いかけたけど、やっぱりシェルで十分だ
なと改めて思った。
雑談
年始に↓を観たけどウォール街の欲望が詰まっていてすごい良かった。