thinceller blog

Conventional Commits をする CLI git-cc を Rust で作った

2022-05-09 公開

最近 Rust を勉強しているに書いたように、プライベートの時間を使ってRustの勉強をしています。 今回、Conventional Commitsを作成するCLIをRustで作成しました。

thinceller/git-cc: A command line tool to create commit messages following the Conventional Commits specs

Conventional Commits

Conventional Commitsはコミットメッセージの仕様です。 「人間と機械が読みやすい」ことをコンセプトにした仕様で、SemVerと連携しつつ様々な自動化を容易にすることが可能になります。 例えば、後方互換性のある新しいAPIを追加するコミットのメッセージは feat: add new api のようになり、type にあたる feat を読み取ることでマイナーバージョンアップを行います。 仕様の詳細は下記のページが参考になります。

Conventional Commits

Angular のコミットメッセージガイドラインにインスパイアされたものらしく、WebフロントエンドやNode.js系のコミュニティでよく使われているのを見かけます。 最近だとDenoの開発でも使用されていますね。

業務においてチームとしてきっちりルールを決めて運用したような経験はないですが、個人的にこの仕様に則ったコミットメッセージを書くことが多いです。 コミットメッセージの一行目を見るだけで

  • どのような種類の変更であるか
  • どのような変更であるか

が一定のルールで記述されるので、Conventional Commitsに則ってメッセージを作成することで理解しやすいコミットを自然と作成できることがメリットだと感じています(逆に、適切なコミットメッセージをつけられるようなコミットの粒度を意識するように矯正できるとも言えます)。

普段はVSCodeのConventional Commits拡張機能(Conventional Commits - Visual Studio Marketplace)を使ってコミットすることが多かったのですが、ターミナル上でGitコマンドと一緒に動かせるものを探した結果自分で作ってみることにしました。

Git-cc

CLIは以下のような方針で作成しました。

  • git-xxx というCLIにする
  • Rustで作る
  • インタラクティブなUIをもつ

Gitには git-subcommand という実行可能ファイルをPATHに追加しておくと git subcommand で実行できる仕組みがあります。 git add したのちに git xxx でコミットできるような統一感がほしいなーと思い、git-cc というCLIを作ることにしました。 (cc はconventional commitsあるいはcommit conventionallyの略です)

使用言語は現在勉強しているRustにしました。 書き捨てるための Rust - Qiitaという記事を読んで、とりあえず動くものを書いてみてリファクタリングしながらRustへの理解をより深めていこうと思いました。 CLIを作るためのcrateも充実していたのでさほど困ることも多くなかったです。 と言いつつ、v0.1.0の時点では最低限の実装しかしていないため、インタラクティブなプロンプトを提供してくれる dialoguer にのみ依存しています。 使用していたVSCode拡張機能と似たような使い勝手にしたかったので、質問に1つ1つ回答していけば自然とConventional Commitsなコミットメッセージができあがるようにしました。

利用方法

インストール

2022年5月9日時点では cargo install によるインストールのみ対応しています。

$ cargo install git-cc

使い方

インデックスにファイルがある状態で git-cc または git cc を呼び出すだけです。

$ git add hoge.txt

$ git-cc
# or
$ git cc

デモ

まとめ

The Book のコマンドラインプログラムのパートCommand Line Applications in Rust を読みながら実装をすることで詰まることなく簡単なCLIの作成ができました。 core APIやcrateのドキュメントが充実していてかつ統一的で見やすいこともRustの利点だと感じました(Goでも似たような経験はできますね)。 自分でも使い倒しながらブラッシュアップしていきます。