BLOG
dothese — 進捗は、コミットログに聞く
2023.07.04

2021年の秋から2023年の夏まで、社内で作り続けていたチーム向けタスク管理ツールの話です。名前は「SHINCHOKU DOTHESE(進捗どうです)」。「進捗どうですか?」と聞かなくても進捗が分かるようにしたい、という願いをそのまま名前にしました。安直ですね。
チーム → プロジェクト → チケット → タスクという階層のCakePHP製で、ここまでは素直なタスク管理です。一番頑張ったのはgit連携でした。
進捗は、コミットログに聞く
仕組みの入口は、命名規約だけです。
- コミットメッセージの頭に
[task#123]を付ける - ブランチ名は
ticket#45_で始める
これだけで、タスクの画面に「このタスクに関連するコミット一覧」が出ます。中では git log --grep=task#123 を叩いているだけ。タスクが「完了」になっているのにコミットが1つも無ければ、それも分かる(push済みかどうかを返すAPIまで作りました)。「終わりました」と「pushされている」は別物だ、というのが当時のチームの実感だったからです。
ちなみにdothese自身の開発もdotheseで管理していたので、このツールのコミットログは全部 [task#…] 形式で残っています。
GitHub風の差分表示を自前で
チケットを開くと、対応するブランチとmasterの差分がファイル単位・行番号付きで見えます。GitHubのdiff画面のようなものですが、外部サービスは使っていません。GitHubを使えば済む話に見えますが、当時は契約上、顧客のコードを外部サービスに置けない案件があり、リポジトリは自社サーバーで運用していました。だから、そのサーバーのリポジトリに直接つなぐ道具が要ったのです。中では git diff を実行して、出力を自前でパースしています。diff --git の行でファイルを区切り、@@ のハンク行から行番号を数え、新規・削除・リネームを判定して……という地道な文字列処理です。git log の方は --pretty=format: でJSONの形をした文字列を吐かせて json_decode する、という荒技でした。
本丸はblame
一番作り込んだのはblameです。git blame --line-porcelain の出力をパースして、ファイルの各行がどのタスク由来の変更なのかを行単位で表示します。コミットメッセージの [task#123] からタスク名を引いてきて、行の横に添える。「このコードは何のために書かれたのか」に行単位で答えられる画面で、これはいま見ても悪くない発想だと思っています。
いま振り返ると
外部サービスのAPIに頼らず、生のgitコマンドを叩いて出力をパースする作り方は泥臭いですが、おかげでgitの出力形式にはずいぶん詳しくなりました。道具はその後の世代に譲りましたが、「タスクとコミットを規約で紐付ける」という思想はいまも現役です。コードを書いた理由を、人の記憶ではなくコミットログに残す——このツールで身についた習慣が、いまの開発の土台になっています。