crate-ci/typosでtypoのチェックをする
本質から逸脱したnitsなレビュー
コードレビューにおいて、機能実装の本質とは逸れたnitsなレビューをしていませんか?
その最たる例がtypoのチェックでしょう。目視で必死にレビューしたとしても、見逃してしまうものです。アプリケーションのコードやテストデータならまだしも、テーブル名やカラム名を間違えてしまうと後の祭りです。このようなtypoチェックこそ完全に自動でチェックされるべきです。
crate-ci/typos
GitHub Actionsにおいて、crate-ciがtyposというアクションを提供しています。
crateという名称で察せますが、Rustで書かれたActionです。本記事ではこのActionを使います。
typosのローカルへのセットアップ
GitHub Actionsで実行する前に、手元のローカル環境で実行できるようにしましょう。
Rust製ツールなのでオーソドックスにcargoでインストール可能です。
$ cargo install typos-cli
チーム開発をしている場合、利用するCLIツールのバージョンを揃えたいところです。asdfを利用していれば、次の手順で簡単にインストールできます。
$ asdf plugin add typos
$ asdf install typos latest
$ asdf [local|global] typos latest
asdf local
コマンドで生成した.tool-versions
をリポジトリにコミットしておけば、任意のバージョンのtyposの利用を強制できます。
typos 1.22.1
サンプルデータ
typosに食わせるサンプルデータを作ります。以下はGo言語の適当なコードであり、コンパイルエラーが出ないようにGPT-4oに生成させたものです。リポジトリの直下にこのmain.goを配置します。
package main
import "fmt"
func main() {
// Typo: Helo should be Hello
fmt.Println("Helo, Wrld!") // Wrld should be World
// Typo: mesage should be message
var mesage string = "This is a sampe Go program with typos."
// Typo: sampe should be sample
fmt.Println(mesage)
// Call the function with a typo
prntFormattedMessage(mesage) // prntFormattedMessage should be printFormattedMessage
// Typo: comletion should be completion
fmt.Println("Program comletion.")
}
// New function with a proper name
func prntFormattedMessage(message string) {
// Typo: orignal should be original
fomattedMessage := fmt.Sprintf("The orignal message is: %s", message)
// Typo: Prntln should be Println
fmt.Println(fomattedMessage) // fmt.Prntln should be fmt.Println
}
リポジトリの直下でtypos
コマンドを実行します。次のようにtyposを検出してくれます。
GitHub Actionsで実行する
これをGitHub Actionsでも実行します。次のようなワークフロー設定ファイルを作成します。
name: Check typos
on:
push:
branches:
- main
pull_request:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: crate-ci/typos@v1.22.1
リポジトリのmainブランチにpushすると、ワークフローが実行されます。
また、Pull Requestを作成した場合はインラインでtypoの箇所を次のように指摘してくれます。人力でのnitsなレビューのほとんどは排除できるでしょう。
.typos.tomlでの細かい制御
typosのデフォルトの挙動を制御するには、.typos.toml
という設定ファイルを用意します。
例えば、マークダウンファイルへのチェックを除外したいときは、次のようなパターンを定義すればできます。
[files]
extend-exclude = [
"*.md"
]
通常だとtypoになるが、造語のように意図したスペルとして扱いたい場合はdefault.extend-words
を設定します。
[default.extend-words]
helo = "helo"
残念ながら辞書に無い単語もあります。例えば、hierarchy
というtypoしやすい単語をtyposすると、現状素通りしてしまいます。hieralky
とtypoした場合でも、次のように明示的に違反を検出してくれるよう設定できます。
[default.extend-words]
hieralky = "hierarchy"
$ typos
error: `hieralky` should be `hierarchy`
--> ./README.md:2:1
|
2 | hieralky
| ^^^^^^^^
|
まとめ
今回はRust製のcrate-ci/typosというツールを紹介しました。ローカル環境でも、GitHub Actionsでも活用してnitsなレビューに時間を割くより、もっと本質的なレビューに集中できる仕組みづくりをしていきましょう。
Discussion