✔️

crate-ci/typosでtypoのチェックをする

2024/06/06に公開

本質から逸脱したnitsなレビュー

コードレビューにおいて、機能実装の本質とは逸れたnitsなレビューをしていませんか?

その最たる例がtypoのチェックでしょう。目視で必死にレビューしたとしても、見逃してしまうものです。アプリケーションのコードやテストデータならまだしも、テーブル名やカラム名を間違えてしまうと後の祭りです。このようなtypoチェックこそ完全に自動でチェックされるべきです。

crate-ci/typos

GitHub Actionsにおいて、crate-ciがtyposというアクションを提供しています。

https://github.com/marketplace/actions/typos-action

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の利用を強制できます。

.tool-versions
typos 1.22.1

サンプルデータ

typosに食わせるサンプルデータを作ります。以下はGo言語の適当なコードであり、コンパイルエラーが出ないようにGPT-4oに生成させたものです。リポジトリの直下にこのmain.goを配置します。

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でも実行します。次のようなワークフロー設定ファイルを作成します。

~/.github/workflows/typos.yml
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という設定ファイルを用意します。

例えば、マークダウンファイルへのチェックを除外したいときは、次のようなパターンを定義すればできます。

.typos.toml
[files]
extend-exclude = [
  "*.md"
]

通常だとtypoになるが、造語のように意図したスペルとして扱いたい場合はdefault.extend-wordsを設定します。

.typos.toml
[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