120
77

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

commitlint の紹介

Last updated at Posted at 2017-12-22

commitlint というツールをご紹介します。

commitlint とは、Git のコミット規約(commit convention)に従わせるための npm ツールです。ESLint のように、ルールを JavaScript で設定・開発できます。

image.png

commitlint helps your team adhering to a commit convention. By supporting npm-installed configurations it makes sharing of commit conventions easy.

commitlint はチームがコミット規約に従うのを助けます。npm インストールされた設定をサポートすることにより、簡単にコミット規約を共有することができます。

「コミット規約」といえば、Angular チームの規約 が有名です。そのコミットメッセージ形式は、次の通りです。

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

例えば、こちらのコミットを見てみると、規約に従っているのが分かります。

feat(currencyFilter): trim whitespace around an empty currency symbol · angular/angular.js@62743a5

feat(currencyFilter): trim whitespace around an empty currency symbol

In most locales, this won't make a difference (since they do not have
whitespace around their currency symbols). In locales where there is a
whitespace separating the currency symbol from the number, it makes
sense to also remove such whitespace if the user specified an empty
currency symbol (indicating they just want the number).

Fixes #15018
Closes #15085

Closes #15105

commitlint大まかにはこの形式に従っており、ルール設定によってより細かな調整が可能です。

セットアップ

では、実際に使ってみましょう。インストールガイドは公式サイトが詳しいので、そちらに従っていきます。

commitlint インストール

まず、CLIパッケージ(@commitlint/cli)と設定パッケージ(@commitlint/config-conventional)をインストールします。

$ npm install --save-dev @commitlint/{cli,config-conventional}

次に、設定ファイル(commitlint.config.js)を作成します。

$ echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js

こんな感じです。

commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional']
};

ファイル名は .commitlintrc.js .commitlintrc.json .commitlintrc.yml も可能ですし、package.jsoncommitlint フィールドを定義してもよいです。これは cosmiconfig の仕様ですね。

husky インストール

さて、お次は husky をインストールします。

$ npm install --save-dev husky

huskyGitフックを設定するためのツールです。husky の詳細については、手前味噌ですがこちらの記事をご覧ください。

コミット前に Lint を強制するなら lint-staged が便利 - Qiita

また、Gitフックについてはこちらの記事が詳しいです。

Gitのフックの説明と挙動の検証 - Qiita

package.json を編集し、scripts.commitmsg を追加します。これで、コミットメッセージ編集の際に Git フックが走るようになります(これは husky の機能です)。

package.json
{
  "scripts": {
    "commitmsg": "commitlint -e $GIT_PARAMS"
  }
}

テスト

さあ、テストしてみましょう。

$ git commit -m "foo: this will fail"
husky > npm run -s commitmsg

⧗   input: foo: this will fail
✖   type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]
✖   found 1 problems, 0 warnings

husky > commit-msg hook failed (add --no-verify to bypass)


$ git commit -m "chore: lint on commitmsg"
husky > npm run -s commitmsg

⧗   input: chore: lint on commitmsg
✔   found 0 problems, 0 warnings

規約に沿わないコミットメッセージでは、コミットできないことが確認できます。

CIでの実行

いくら Git フックでチェックしていても、git commit --no-verify されてしまうとチェックをすり抜けられてしまいます。
また、GitHub などではブラウザ上からコミットすることも可能です。
そのようなケースでも対応できるよう、CIで commitlint を実行する方法も載っています。

こちらは Travis CI での設定例です。@commitlint/travis-cli というパッケージをインストールすると、node_modules/.bin/commitlint-travis というコマンドがインストールされます。

$ npm install --save-dev @commitlint/travis-cli
.travis.yml
language: node_js
script:
  - commitlint-travis
  - npm test

ルール

commitlint には様々なルールが存在します。

例えば、標準設定の @commitlint/config-conventional から抜粋してみます(v5.2.3 時点)。

  • type は次のいずれかでなければならない(type-enum ルール)。
    • build: ビルド
    • ci: CI
    • chore: 雑事(カテゴライズする必要ないようなもの)
    • docs: ドキュメント
    • feat: 新機能
    • fix: バグフィックス
    • perf: パフォーマンス
    • refactor: リファクタリング
    • revert: コミット取り消し(git revert
    • style: コードスタイル
    • test: テスト
  • type は小文字でなければならない(type-case ルール)。
  • type は必ず指定しなければならない(type-empty ルール)。
  • scope は小文字でなければならない(scope-case ルール)。
  • subject は次のいずれかの書式(case)でなければならない(subject-case ルール)。
    • sentence-case: (例.Sentence case)
    • start-case: (例.Start Case)
    • pascal-case: (例.PascalCase)
    • upper-case: (例.UPPERCASE)
  • subject は空ではいけない(subject-empty ルール)。
  • などなど…

すべてのルールの詳細は、README.md またはソースコード(index.js)をご覧ください。

上書き

ルールを上書きすることもできます。例えば、ベースは @commitlint/config-conventional を採用し、scope を独自のものにするには、commtlint.config.js ファイルを次のように編集します。

commtlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional'],

  rules: {
    'scope-enum': [2, 'always', ['web', 'job', 'api']]
  }
};

定義

ルールは ルール名: [配列] で定義します。ESLint に似ています。

'{ルール名}': [{レベル:0|1|2}, '{可否:always|never}', {値}]

ルールレベル:

  • 0: 無効
  • 1: 警告
  • 2: エラー

ルール定義の配列は、次の形式が可能です。

  • プレーンな配列
  • 配列を返す関数
  • 配列を返す非同期関数
  • Promise を返す関数
{
  'header-max-length': [0, 'always', 72],
  'header-max-length': () => [0, 'always', 72],
  'header-max-length': async () => [0, 'always', 72],
  'header-max-length': () => Promise.resolve([0, 'always', 72])
}

定義済みのルールの一覧については、公式ドキュメントをご覧ください。

独自ルールの共有

ESLint の "Shareable Configs" のような機能が、commitlint にもあります。

Shareable configuration - commitlint - Lint commit messages

カスタマイズされた rules を、npm パッケージとして公開することができます。

メリット/デメリット

今は仕事でもプライベートでも、このツールを使ってコミット規約を強制しています。個人的には、次のメリットを強く感じています。

メリット

  • 習慣づけ
    • わかりやすいコミットメッセージを書くことが、習慣づけされます。
    • 習慣の力は大きくて、仕組みとして強制されていれば、自然と書けるようになります。
    • 書けるようなると、思考もそれに順応するようになります(このコミットは「バグ修正」なのか「リファクタリング」なのかといった判断が的確になります)。
  • コミットの責任範囲の明確化
    • 色んな変更が混在したコミットを避けるようになり、1つのコミットが1つのことをするようになります。
    • 結果、レビューがしやすくなり、レビューにかかる時間を減らせます。
  • 不毛な宗教論争の回避
    • (当たり前ですが)コミットメッセージの形式のブレをなくせます。
    • これは他の Lint ツールにも言えることですが、機械的に修正できるものから人間の介在をなくせば、より重要なことにリソースを集中できます。
  • 迅速な内容把握
    • コミットのサマリーを見ただけで、簡単な内容が把握できます。
    • Slack などにコミットログが流れてくる場合、普通はサマリーしか表示されないので、サマリーだけで内容把握ができるようになると、大きいです。
  • 変更履歴作成の簡略化

デメリット

反対に、デメリットは次の点です。

  • 規約が厳しすぎると、チームメンバーによってバラつきが出て、最悪守られなくなります。type の選択(featfix か)も結局は個人の判断に委ねられてしまうので、前もって規約を十分に理解してないと、その選択にもブレが生じます。
  • 結果、チームメンバーのモチベーションが低下します。所詮ツールであり銀の弾丸ではないので、チームに導入する際は前もっての準備とメンバーの理解が必要不可欠です。

使用例

commitlint のリポジトリです。コミットログと Changelog はこのようになっています。

image.png

image.png

参考

ConventionalCommits.org なる団体も存在します。Angular のコミット規約がベースとなっています。

興味があれば、ぜひ使ってみてください!

120
77
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
120
77

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?