2
Help us understand the problem. What are the problem?

posted at

updated at

お手軽構築!docker-compose+Circle CI環境下でのスペルチェック環境

この記事 is 何

ソースコードをcommit/push(後の本流へmerge)した後に「あっ、これtypoしてる...」という経験はありませんか?
英語が苦手な私はよくあります。VSCodeの拡張機能でスペルチェッカーを入れてますが、それでも見落としがちです...
そのようなときにCIで自動で検出/ブロック出来たらいいですよね!

この記事では、その対策方法について解説しました。

この記事では解説しないこと

解説している素晴らしい記事はたくさんあるので、既存の記事にお任せしました!

  • Docker、Docker-composeの導入方法/解説
  • Circle CIとは?
  • githubとCircle CIの連携方法
  • Visual Studio Codeの導入方法/解説

動作環境

  • Local環境
    • Windows 10
    • Docker Desktop 2.2.0.4
    • docker-compose 1.25.4
    • Visual Studio Code 1.66.1
      • Code Spell Checker 2.1.11
  • github
    • Freeプラン
  • Circle CI
    • Freeプラン
    • version: 2.1
    • machine: circleci/classic:edge
      • 非推奨のため、今後変更予定ですが、本記事には影響しないはず...

ディレクトリ構成

/
├ .circleci
│ └ config.yml
├ app
│ └ アプリ本体
├ cspell
│ └ project-words.txt
├ docker
│ ├ app
│ │ └ Dockerfile
│ ├ spell_checker
│ │ └ Dockerfile
│ └ ...
├ cspell.json
└ docker-compose.yml

appディレクトリ以下に実際のアプリを記述する構成を使っていますが、本記事の内容はroot直下に直接記述する方式でも採用可能です。
cspellについては記事内で説明します。

(閑話: 上記のツリーは AsciiTree を使用して作りました。手軽にツリーかけるので便利ですよ!)

環境構築方針

  • docker + docker-composeを使う
    • ローカル環境を汚したくない
      • 今回使用するライブラリの都合上、node.jsの環境が必要
  • Visual Studio Code(以下VSCode)上でのスペルチェックと連動させる
  • VSCodeを使っていない開発者がいる場合でも、同様にスペルチェックできるようにする
    • やっぱり自分の手慣れた環境で開発したいですよね!
  • Circle CIでtypoがあった場合は自動でこけるようにする

実際に導入してみよう!

まずはローカル環境の構築から。

1. VSCodeにスペルチェッカーを導入

(VSCode使用者向け)VSCodeにはスペルチェッカーのCode Spell Checkerという素晴らしい拡張機能が存在します。まずは、下記の記事参考に導入しましょう。
VSCode に Code Spell Checker を導入して typo と戦う

2. スペルチェック用のDockerコンテナを導入

docker経由でコマンドライン上からでもスペルチェックをできるようにしましょう。
VSCode拡張のCode Spell Checkerのベースとなっている、 cspell を使用します。
プロジェクトの docker-compose.yml にスペルチェック用のコンテナの定義を追加します。

docker-compose.yml
services:
    spell_checker:
        build: ./docker/spell_checker
        tty: true
        volumes:
            - ./:/usr/src/app
docker/spell_checker/Dockerfile
FROM node:latest

RUN npm install -g cspell

WORKDIR /usr/src/app

volumesでプロジェクト全体を共有することにより、スペルチェックをできるようにするのがポイント。

buildでの指定パスはプロジェクトの流儀に合わせてください。本記事のプロジェクトでは、Docker周りの設定はdocker/[containerName]/...に置くようにしています。

3. コンテナ上でスペルチェックを実行

2.の手順でコンテナを定義、以下のように実行することでスペルチェックができるようになっているはずです!

command line
 # コンテナの立ち上げ(コンテナが上がってないときに1回実行する)
docker-compose up -d cspell

 # スペルチェックの実行
 # 今回は.php, .jsファイルへのスペルチェックを想定
 # すべてのファイルを対象とするには "**" を引数に実行する(割と重い。対象の拡張子がわかっている場合は、拡張子を指定したほうが無難かも)
docker-compose exec spell_checker cspell "**/*.php" "**/*.js" --gitignore

実行結果

command line
PS D:\sources\project> docker-compose exec spell_checker bash
root@f1c7d382e567:/usr/src/app# cspell "**/*.php" "**/*.js" --gitignore
  1/225 ./laravel/app/Console/Commands/Make/MakeGraphqlDefinitionCommand.php 537.01ms
  2/225 ./laravel/app/Console/Commands/Make/MakeModelCommand.php 7.38ms
  ...
  225/225 ./mock/webpack.config.js 16.85ms
  CSpell: Files checked: 225, Issues found: 1 in 1 files

cspellを実行する際に --gitignore を引数で渡すのがポイントです。これをすることでプロジェクト内の .gitignore が読み込まれ、 node_modules など、プロジェクトのリポジトリ上では管理しないファイルをチェック対象外にすることができます。

他にも様々なオプションがあるので、使いこなしたい方は公式ドキュメントを読んでみてください!

2,3-番外 ローカルのnode.jsを使用する

node.jsがインストールされているよ!という方は、 cspell パッケージをインストールするだけでもローカルで実行可能です。

command line
npm install -g cspell

スペルチェックの実行方法

command line
cspell "**/*.php" "**/*.js" --gitignore

4. 例外ワードを設定できるようにする

スペルチェックにかけていると、ソース内の固有名称や、コマンド名、関数名などでスペルチェックに引っかかる場合が出てきます。
スペルチェッカー側に「この単語はあっているよ!」という情報を伝える設定ファイルを定義しましょう。

まず、プロジェクトのrootに cspell.json を作成します。

cspell.json
{
    "version": "0.2",
    "dictionaryDefinitions": [
        {
          "name": "project-words",
          "path": "./cspell/project-words.txt",
          "addWords": true
        }
    ],
    "dictionaries": ["project-words"]
}

project-words という辞書を作成し、使用するといった内容が記載されています。(詳細は 公式ドキュメント をご参照ください。)
次に、辞書ファイル(許可する単語帳)を作成します。
プロジェクトのroot配下に cspell ディレクトリを作成し、 project-words.txt を作成し、許可する単語を改行区切りで記述していきます。

cspell/project-words.txt
laravel
graphql
...

登録する単語が多くてだるい...と思いましたか?次の手順でプロジェクト内の既存の未登録単語は一括出力できるので、ご安心ください!

VSCodeの拡張機能のCode Spell Checkerは開いているフォルダ直下の cspell.json を自動で見てくれるため、ここでの設定は共有されます。便利!

5. プロジェクト内の未登録単語を辞書に登録

導入時のプロジェクト内には、未登録単語がいくらかあると思います。
なので、未登録単語を抽出し、辞書へ登録します。
以下のコマンドを実行することで、未登録単語一覧を出力できます。

command line
 # --words-only: 未登録単語のみ出力
 # --unique: 重複を削除
 # --no-progress: 進捗を非表示(チェック対象のファイル名などを非表示)
docker-compose exec spell_checker cspell "**/*.php" "**/*.js" --gitignore --words-only --unique --no-progress

すると、以下のように単語一覧が出力されるので、結果をproject-words.txtにコピペします。

command line
PS D:\sources\project> docker-compose exec spell_checker cspell "**/*.php" "**/*.js" --gitignore --words-only --unique --no-progress
koyuu
hogehoge
fugafuga
CSpell: Files checked: 225, Issues found: 3 in 2 files
cspell/project-words.txt
koyuu
hogehoge
fugafuga

また、この手順で本当のtypoがあった場合、githubでのtypo修正のissueを立てるといいでしょう。

6. Circle CIへスペルチェックのテストを定義

これで、スペルチェックをする方法は確立できたので、CIでの自動テストにスペルチェッカーの登録を行います。
Circle CIの設定ファイルに、スペルチェックを行うstepを登録します。

.circleci/config.yml
jobs:
  test:
    steps:
      - ...(既存の処理)
      # docker-composeのコンテナ立ち上げの処理が、既存の処理になかった場合、下記を追加
      - run: docker-compose up -d spell_checker
      - run:
          name: spell check
          command: docker-compose exec spell_checker cspell "**/*.php" "**/*.js" --gitignore
          when: always

scpellは未登録単語が検出した場合に、終了ステータスが1、検出されなかった場合0になるため、そのまま流せば実行できます。

また、「辞書ファイル散らからない・・・?」と思う方もいるでしょう。その場合、最低限の秩序を保つために、並び替えがされているかをテストするのも有効かと思います。

.circleci/config.yml
jobs:
  test:
    steps:
      - ...(既存の処理)
      - run:
          name: is spell check project dictionary sorted
          # note: diffコマンドは差分がある場合、終了ステータスが1になるので、ソート前と後に差分があったらCI上でエラーとみなされる
          command: diff ./cspell/project-words.txt <(cat ./cspell/project-words.txt | sort)
          when: always

実際の導入例

私の個人プロジェクトへ導入した際の差分になります。(専用のリポジトリ用意はできてないです。申し訳なし)
導入前にtypoしてますね...

アプリ本体のコードもあるので、ファイル多いですが、参考にどうぞ!
https://github.com/moriyadetteiu/clapton/pull/160/files

まとめ

というわけで、typo撲滅を自動化できる部分は自動化しようぜ!という記事でした。
既存の記事を拝見してた時に「あれ、VSCodeとcircle CIでうまく連携するスペルチェックの記事見かけないな」と思ってたので、同じこと思ってた人の助けになれれば幸いです!
はじめてのQiita投稿のため、至らないところがあるかと思いますが、その際はご指摘いただけると嬉しいです!

現在転職活動をする予定のため、お声がけありましたら、お待ちしております。

参考記事、参考サイト

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
2
Help us understand the problem. What are the problem?