🐠

cSpellでgit commit -m <コミットメッセージ>のタイポをチェックする

に公開

やりたいこと

  • git commit -m "xxx" のxxxのタイポを検出したい
    • xxx = コミットメッセージ = コミット文

やらないこと

  • コードの中のタイポ。これは別途cSpellでやっている
  • 対象は英語で、日本語のコミットメッセージのタイポは対象外

VSCodeのSource Controlの入力チェックは容易

例えばここにあるように、
settings.jsonに書くと、GUI入力のタイポはチェックできる。

settings.json
  "cSpell.enabledLanguageIds": [
    "scminput"
  ]

検出している状態

コマンド入力をチェックする

よく分からなかったので、無理やりgit hooksでコミット時に判定することに。


①タイポチェックにかかってAbortしている
--forceをコミットメッセージに入れ、無理やりコミット
③確かにタイポのまま登録されている

中身

  • .git/hooks/commit-msgにhookを記述する。
    • COMMIT_MSG_FILEはコミット文が入ったファイル
  • --forceオプション: コミットメッセージ--force を入れるとUnknownがあってもコミットする。なお、--forceの部分はコミット文から削除される
    • 誤検出があったときのためにつけた
    • ※注意※ コマンドのオプションではなく、コミットメッセージ
  • 本来は、Unknownがあるとき以下のような出力になるが、Unknown以降だけを残すために消している
.git/COMMIT_EDITMSG:1:6 - Unknown word (thisss)
.git/COMMIT_EDITMSG:1:18 - Unknown word (pennn)

コード

開く
.git/hooks/commit-msg
# Perform spell check on the commit message file
COMMIT_MSG_FILE="$1"
CSPELL_OUTPUT=$(npx cspell --no-progress --no-summary "$COMMIT_MSG_FILE" 2>&1)

# Extract only the lines with unknown words
UNKNOWN_LINES=$(echo "$CSPELL_OUTPUT" | grep -o 'Unknown word ([^)]\+)')

if [ -n "$UNKNOWN_LINES" ]; then
  echo "$UNKNOWN_LINES"
  if grep -q -- '--force' "$COMMIT_MSG_FILE"; then
    echo "--force detected. Proceeding."

    # Remove "--force".
    # Switch `sed` command depending on the operating system.
    # macOS (Darwin) or others.
    if [[ "$(uname)" == "Darwin" ]]; then
      sed -i '' 's/--force//g' "$COMMIT_MSG_FILE"
    else
      sed -i 's/--force//g' "$COMMIT_MSG_FILE"
    fi

    exit 0
  else
    echo "Abort. Add --force to commit message to override."
    exit 1
  fi
fi

まとめ

  • git commit messageをcSpellでチェックすることができました
  • デメリットは、遅いこと。体感で2秒くらい遅くなります

Discussion