🌟

Rust × Docker環境でGitフックによる任意コマンド実行を行う方法

2024/12/08に公開

背景

JavaScript界隈ではhuskyを用いてpre-commitpre-pushなどのGitフックを簡単に設定できます。
これにより、コミットやプッシュ時に自動でテストやリント、
フォーマットチェックを実行する運用が一般的です。

一方、Rustプロジェクトでも同様のことを行いたい場合があります。
ただし、npmpythonといった他言語ツールに依存せず、
Cargoエコシステム内で同様のフローを構築したいケースです。
そのような場面で役立つのがcargo-huskyになります。

本記事ではcargo-huskyを使用してRustプロジェクトでGitフックを管理する方法を紹介します。
pre-commitpre-pushなどのフックで任意コマンドを実行する手順と、
Docker環境下でコンテナ内コマンドを実行する際のポイントを示します。

cargo-huskyとは

cargo-huskycargo test実行時に.git/hooks配下へフックファイルを自動生成するツールです。
Cargo.tomldev-dependenciescargo-huskyを追加し、
cargo testを行うだけでデフォルトでpre-pushフックが設定されます。

インストール例

Cargo.tomlに以下を記述します。

[dev-dependencies]
cargo-husky = "1"

この状態でcargo testを実行すると、
git push時にcargo testが自動的に実行されるpre-pushフックが.git/hooks/pre-pushへ生成されます。

独自コマンドを実行したい場合

標準設定ではpush時にcargo testを実行します。
しかし、他のコマンド(ビルドツールやコード整形ツールなど)を使いたい場合や、
pre-commitフックで独自の処理を行いたい場合もあります。

そのようなときはcargo-huskyが提供するfeaturesフラグやuser-hooks機能を利用するとよいです。

user-hooks機能を使ったカスタムフック設定

user-hooks機能を有効にすると、cargo-huskyが自動生成するフックを抑制できます。
代わりに、.cargo-husky/hooksディレクトリへユーザー独自のフックスクリプトを配置して、
任意のコマンドを実行可能になります。

手順:

  1. Cargo.tomlを以下のように変更します。

    [dev-dependencies.cargo-husky]
    version = "1"
    default-features = false
    features = ["user-hooks"]
    

    この設定により、cargo testを実行した際に、
    デフォルトのpre-pushフック(cargo test実行)は生成されなくなります。

  2. .cargo-husky/hooksディレクトリを作成します。

    mkdir -p .cargo-husky/hooks
    
  3. たとえばpre-commitフックで独自コマンドmy_custom_commandを実行したい場合、
    以下のようなスクリプトを用意します。

    echo '#!/bin/sh
    set -e
    my_custom_command
    ' > .cargo-husky/hooks/pre-commit
    chmod +x .cargo-husky/hooks/pre-commit
    
  4. cargo testを実行すると、ビルドスクリプトが発動します。
    これにより.cargo-husky/hooks下のスクリプトが.git/hooks/pre-commitへコピーされます。

    cargo test
    

以上でgit commit時にmy_custom_commandが実行されるようになります。

Docker環境での実行例

Docker環境で開発する場合、フックスクリプト内でdocker compose execを利用すると、
コンテナ内で任意のコマンドを実行可能です。

echo '#!/bin/sh
set -e
docker compose exec -T my_container_name my_custom_command
' > .cargo-husky/hooks/pre-commit
chmod +x .cargo-husky/hooks/pre-commit

この設定により、git commit時にコンテナ内でmy_custom_commandが実行されます。
これによって外部ツールへの依存を減らし、
統合的なワークフローを実現できます。

よくある質問

git push時にcargo test --allが実行される理由

cargo-huskyは標準でpre-pushフックを生成し、cargo testを実行します。
別のコマンドを利用したい場合はdefault-features = falseを指定し、user-hooks機能を有効化してください。
これで独自のフックが定義できるようになります。

package.metadata.husky.hooksは使えるか

cargo-huskynpmhuskyとは異なる仕組みで動作します。
package.metadata.husky.hooksはサポートされていません。
代わりに[dev-dependencies.cargo-husky]user-hooksディレクトリを用いてカスタマイズします。

まとめ

  • cargo-huskyによりRustプロジェクトのGitフック管理が容易になります。
  • user-hooks機能を使うことで任意コマンドやコンテナ内コマンドの実行が可能です。
  • npmpythonに依存しないCargoネイティブなフック管理により、開発効率が向上します。
GitHubで編集を提案

Discussion