🐡

Gitコミット時にメソッドの行数および横幅チェックを追加する 11日目

2024/11/12に公開

はじめに

過去の記事にプログラムの品質を上げるため、警告をエラーとしてビルドを通さない施策を行いました。

https://zenn.dev/onecarat_tech/articles/89cc6c975ddd99

今回はコードの可読性をあげるために、Gitへのコミット時にメソッドの行と幅のチェックを導入します

コードの可読性とは

コードの可読性はシンプルで短いものが見やすいよね。メソッド名や引数名も一見で理解できるものがよいと思うけど、これってセンスもあると思うんだよ。なので、最低限の可読性を担保するためにメソッドの行数と幅数に上限を設けてみることにします。

今回参考にしているのは脳に収まるコードの書き方という良書、沢山の人に読んでもらいたい本です。

Gitフックを利用してメソッドの行と幅のチェックを導入

Gitフック(Git Hooks)とは、特定のGitイベント(例えば、コミットやプッシュ)が発生する際に自動的に実行されるスクリプトです。そちらを使用して、コミット時にメソッドの行数と幅の制限をチェックする設定手順を説明します。

1. Gitフック用のスクリプトを作成
※Gitフック(Git Hooks)とは、特定のGitイベント(例えば、コミットやプッシュ)が発生する際に自動的に実行されるスクリプト

1.1 Gitリポジトリのルートディレクトリに移動(リポジトリのパスに置き換えてください

Set-Location -Path "C:\path\to\your\repository"

1.2 .git/hooksディレクトリに移動

Set-Location -Path ".git/hooks"

1.3 pre-commitファイルを作成

New-Item -ItemType File -Name "pre-commit"

1.4 pre-commitファイルを編集してスクリプトを追加

#!/bin/bash

# 設定: メソッドの最大行数と行の最大幅を設定
MAX_LINES=32    # メソッドの最大行数
MAX_WIDTH=80    # 行の最大幅

# コミットされている変更ファイルのうち、拡張子が .cs のファイルを取得
FILES=$(git diff --cached --name-only --diff-filter=ACMR | grep '\.cs$')

# 各 C# ファイルに対して処理を行う
for FILE in $FILES; do
# メソッドの行数チェック: 32行を超えるメソッドがあるか確認
if awk -v max_lines="$MAX_LINES" -v max_width="$MAX_WIDTH" '
  # メソッドの開始を判定: "public", "private" などのアクセス修飾子で始まる行をメソッド開始とみなす
  /^[[:space:]]*(public|private|protected|internal)[[:space:]]+/ { 
      inMethod=1; count=0; braceCount=0   # メソッド開始フラグ、行数カウント、ブレースカウントを初期化
      methodName=$0  # メソッド名の行を記録
  }
  
  # メソッド内の "{" がある行でカウントを増やす
  inMethod && /\{/ { 
      braceCount++;   # 開始ブレースのカウント
  }
  
  # メソッド内の "}" がある行でカウントを減らし、メソッドの終了を判定
  inMethod && /\}/ { 
      braceCount--;   # 終了ブレースでカウントを減らす
      if (braceCount == 0) {   # ブレースカウントが0になったらメソッド終了
          if (count > max_lines) { 
              print "Error: Method in " FILENAME " exceeds " max_lines " lines.";
              print "Method name: " methodName;
              exit 1 
          }
          inMethod=0; count=0; braceCount=0  # フラグとカウントをリセット
      }
  }
  
  # メソッド内の行をカウントし、幅をチェック(先頭の空白とスペースを除外)
  inMethod { 
      count++;
      line = $0;
      sub(/^[[:space:]]+/, "", line);  # 行の先頭の空白とスペースを取り除く
      if (length(line) > max_width) { 
          print "Error: Line in method \"" methodName "\" exceeds " max_width " characters."
          print "Line content: " line
          exit 1
      }
  }
' "$FILE"; then
  exit 1   # エラーがあればスクリプトを終了
fi
done

# エラーがない場合は正常終了
exit 0

これでコミット時のチェックが行われます。

2. コミット時の動作確認

PS D:\works\HelloWorldApp> git add .
PS D:\works\HelloWorldApp> git commit -m "Gitのフック確認 限界値テスト行1" 
Error: Method in Controllers/HomeController.cs exceeds 32 lines.
Method name:     public HomeController(ILogger<HomeController> logger)
PS D:\works\HelloWorldApp> git add .
PS D:\works\HelloWorldApp> git commit -m "Gitのフック確認 限界値テスト幅1"
Error: Line in method "    public HomeController(ILogger<HomeController> logger)" exceeds 80 characters.
Line content: _logger.LogInformation("HomeCo                         ntroller has been instantiated23.");
PS D:\works\HelloWorldApp> 

正しい結果が得られました。
これでコミット時にメソッドの行幅のチェックが行われるようになりましたので、コードの可読性はあがると思います。また、複数のメンバーで作業するときにコード品質を保つ一助になるはずです。

次回はもう少し、コードの可読性を維持する工夫を考えてみたいと思います。

Discussion