reviewdogとDanger JSでコード内のスペルミスを発見し、修正を自動的に促す方法をご紹介します。
- はじめに
- 「regist」という単語について
- Danger JS について
- reviewdog について
- プルリクエスト作成時に「regist」を検出し警告する
- reviewdogとDanger JSの使い分け
- 終わりに
はじめに
こんにちは、プロダクト技術本部の小川です。
みなさんは「regist」という単語、見覚えがありますか? この単語を見ると、「それって"register"じゃないの?」と思いませんか? もしそう思ったなら、あなたが正しいです。「regist」は英語では存在せず、「register」が正しい表現です。
しかし、なぜか特に情報技術の世界では、無意識のうちに「regist」が使われることが多いです。プログラマーにとって、他人のコードを見る際に予想外のスペルミスを発見するというのは、理解を阻害し時間を無駄にする要因となります。
この記事では、reviewdogとDanger JSというツールを使用してそのようなスペルミスを発見し、自動的に修正を促す方法をご紹介します。 それでは、さっそく詳細について見ていきましょう。
「regist」という単語について
「regist」という単語は一般的に私たちが思い浮かべるような単語でしょうか?
実際にGoogleでその意味を検索してみましょう。
※ Google および Google ロゴは Google LLC の商標です。
ん?この単語の意味は「登録する」だと思っている人も多いのではないでしょうか。
ってかコルシカ語って何?英語じゃないん??
そうなんです…!!実は「regist」という英単語は存在しないんです…!「登録する」を意味する正しい英単語は「register」なんです!!!!
これを誤解している方が多いように思います。6、7年ほどエンジニアとして働いてきましたがソースコード上に「登録する」という意味の単語として「regist」を使用する場面を数々見てきました。
読者のみなさんも見覚えがあるのではないでしょうか?ほら・・・いつも面倒を見ているソースコードにも・・・😇
私個人としては、「regist」という単語がソースコードに混じっていると大変気になってしまいます。意味が全く通じないというほどのものではないですが、タイポした単語がソースコードに残されることはコード全体の記述の統一性の点からみてもよろしいとは言えないでしょう。
そこで、「regist」をソースコードから「駆逐」してやりましょう。Danger JSとreviewdogを使って。
Danger JS について
Danger JSはコードレビューの効率化・自動化を行うためのツールです。特に「チーム内で慣習的に行われているコードレビューの自動化」を目的にしています。例えば以下のようなルールや内容を自動的にチェックし、プルリクエストのコメントとして自動投稿することができます。
- リリースノートが作成されていること
- プルリクエストのタイトルや本文が特定のルールに従った内容であること
- プルリクエストにラベルが設定されていること
- 特定のファイルが変更されていること
プルリクエストのメタデータを基に、Danger JSでルールを定義することで上記のようなコードレビューのルールが遵守されているかを検知することができます。
reviewdog について
reviewdogは、Linterなどのチェックツールの結果をGitHubのプルリクエストにコメントするためのツールです。プルリクエストで変更された内容にLinterのルールに違反する内容が含まれる場合に、reviewdogはLintの結果をコメントとして投稿をします。 ツールの作成にいたる背景などのより詳しい内容はreviewdog開発者様のブログをご参照ください。
プルリクエスト作成時に「regist」を検出し警告する
GitHub Actionsを使用して、プルリクエスト作成時にreviewdogとDanger JSを動かし、「regist」の存在をプルリクエスト内で検出します。そのために、リポジトリの.github/workflows
ディレクトリにGitHub Actionsのワークフローを定義します。
Danger JSをGitHub Actionsで動かす設定
まず、GitHub Actionsのワークフローを定義します。リポジトリの.github/workflows
ディレクトリにyamlファイルを作成します。
name: danger on: - pull_request jobs: build: name: Danger JS runs-on: ubuntu-latest permissions: write-all steps: - uses: actions/checkout@v3 - name: Danger uses: danger/danger-js@11.0.2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} DANGER_DISABLE_TRANSPIRATION: true
次に、プロジェクトのルートディレクトリにのdangerfile.ts
を作成します。
このファイルは、Danger JSが実行する際に読み込む設定ファイルです。
import { GitHubPRDSL, danger, markdown, warn } from "danger"; const findRegist = (content: string) => { return content.match(/\bregist\b/) } const warnRegist = (createdBy: string) => { const body = ` ## 👮👮👮regist警察出動!!!👮👮👮 @${createdBy} ⚠️⚠️⚠️ちょっとまってください!⚠️⚠️⚠️ もしかして、『**regist**』という単語を使おうとしていませんか?? 『regist』という単語は**存在しません!!** 「登録する」という意味の英単語は『『『**register**』』』です!!!!以後、気をつけるように!!! ### 参考資料 + [ソースコードの頻出単語 regist (覚えるべからず) | MSeeeeN](https://mseeeen.msen.jp/resist-regist/) + [“regist” という単語は存在しない | text.Baldanders.info](https://text.baldanders.info/remark/2017/04/regist-dose-not-exist/) + [regist 存在しない - Google 検索](https://www.google.com/search?q=regist+%E5%AD%98%E5%9C%A8%E3%81%97%E3%81%AA%E3%81%84&rlz=1C5CHFA_enJP1007JP1008&oq=regist+%E5%AD%98%E5%9C%A8%E3%81%97%E3%81%AA%E3%81%84&gs_lcrp=EgZjaHJvbWUyBggAEEUYOTIICAEQABgKGB7SAQgzMjYyajFqN6gCALACAA&sourceid=chrome&ie=UTF-8)` warn("Warning!!!") markdown(body) } const warnRegistInPullRequest = (pullRequest: GitHubPRDSL) => { const title = pullRequest.title const body = pullRequest.body const createdBy = pullRequest.user.login if (findRegist(title) || findRegist(body)) { warnRegist(createdBy) } } warnRegistInPullRequest(danger.github.pr)
Danger JSが実行される際、warnRegistInPullRequest
関数が実行されます。
この関数は、プルリクエストのタイトルと本文の両方を findRegist
関数に渡して "regist" の存在をチェックし、もし存在した場合は warnRegist
関数を呼び出して警告メッセージを投稿します。
reviewdog を GitHub Actionsで動かす設定
こちらも同様にGitHub Actionsのワークフローを.github/workflows
ディレクトリに定義します。
name: reviewdog on: pull_request: branches: - "**" jobs: reviewdog: runs-on: ubuntu-latest name: reviewdog permissions: pull-requests: write steps: - name: Checkout uses: actions/checkout@v3 - name: Set up JDK uses: actions/setup-java@v1 with: java-version: 17 - name: Download checkstyle run: wget -O - -q https://github.com/checkstyle/checkstyle/releases/download/checkstyle-10.12.6/checkstyle-10.12.6-all.jar > ./checkstyle.jar - name: Setup reviewdog run: | mkdir -p $HOME/bin && curl -sfL https://raw.githubusercontent.com/reviewdog/reviewdog/master/install.sh| sh -s -- -b $HOME/bin echo "$HOME/bin" >> $GITHUB_PATH - name: Run reviewdog with checkstyle env: REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: java -jar checkstyle.jar -c ./checkstyle/checkstyle.xml ./ -f xml | reviewdog -f=checkstyle -reporter=github-pr-review
このワークフローでは、プルリクエストが作成されると、Checkstyleをダウンロードして実行し、その結果をreviewdogにパイプします。reviewdogはその結果をGitHubのプルリクエストに警告コメントとして投稿します。
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd"> <module name="Checker"> <module name="TreeWalker"> <module name="Regexp"> <property name="format" value="(^|\b|(?<=[a-zA-Z\-_]))((R|r)egist)(\b|(?=[A-Z\-_])|$)|(^|\b|(?<=[\-_]))REGIST(\b|(?=[\-_])|$)"/> <property name="illegalPattern" value="true"/> <message key="illegal.regexp" value="「regist」という単語が使用されています!!「登録する」という単語は「register」を使用してください!!"/> </module> </module> </module>
Checkstyleの設定ファイルは上記の内容です。今回はcheckstyle
というディレクトリをプロジェクトルートに作成し、checkstyle.xml
というファイル名で配置します。
プルリクエスト作成
たとえば、以下のように「createをregistに修正する」ような変更を含むプルリクエストを作成します。
public class Sample { - public static void create() { - var sample = "create is great!"; - var PRE_CREATE_VALUE = "sample"; + public static void regist() { + var sample = "Regist is great!"; + var PRE_REGIST_VALUE = "sample"; System.out.println(sample); } }
Danger JSがプルリクエストのタイトルに含まれた『regist』という単語を検知します。
すると、このような おせっかいな コメントを残してくれます。
また、CheckstyleによるLintの結果をreviewdogがプルリクエストにコメントとして残してくれます。 これで「regist」を駆逐できそうです。
reviewdogとDanger JSの使い分け
今回、reviewdogとDanger JSという2種類のツールを使用しました。これら二つは共にコードレビューを自動化するためのツールですが、それぞれのツールに異なる特徴があります。 reviewdogは様々なプログラミング言語の静的解析ツールと連携し、その結果を提供することができます。一方、Danger JSはGitやプルリクエストのメタデータ(コミットメッセージや変更されたファイル、プルリクエストの説明など)に基づきルールを設定し、フィードバックを提供します。例えば、「プルリクエストの説明がX文字以下であれば警告を出す」、「プルリクエストのタイトルに特定のフレーズが含まれていなければ警告を出す」といったルールを設定することで、プルリクエストの品質を一定以上に保つことができます。
したがって、静的解析結果を基にしたフィードバックが必要な場合はreviewdogを、プルリクエストのメタデータに基づいたルールが必要な場合はDanger JSを使用すると良いでしょう。
終わりに
reviewdogは自分が関わっているシステムでも組み込まれていて存在は知っていましたが、自分で1から設定して動かす機会は初めてであったため学びになりました。 またDanger JSは初めての導入でしたが、GitHub Actionsで動かすのにそれほど難しい設定もなく動かすことができたので、手軽さを知ることができました。 これからもチームの生産性向上に繋げられる活動を続けられればよいなと思っております。
ここまで読んでくださって、ありがとうございました!
参考
- Danger JS
- reviewdog/reviewdog: 🐶 Automated code review tool integrated with any code analysis tools regardless of programming language
- ソースコードの頻出単語 regist (覚えるべからず) | MSeeeeN
- “regist” という単語は存在しない | text.Baldanders.info
※ GitHubは、GitHub, Inc.の米国およびその他の国における商標または登録商標です。