Theme
SD MILIEU

2019-7-14

リントエラー時にコミットをキャンセルさせる

結論

huskylint-stagedを導入すればいい。

導入手順

前提として、eslintがインストール済なこと

インストール

yarn add --dev husky lint-staged

package.json記述

{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.{js,vue}": "eslint"
  }
}

注意

husky 導入以前に、.git/hookspre-commitなどのフックファイルを作成していないこと

huskyはインストール時に.git/hookspre-commit等のフックファイルを自動生成する。

ただし、事前にフックファイルを時前で作っていると、存在しているフックファイルに関しては既存の物が優先され、huskyに必要なフックファイルが生成されずスキップされてしまう。

結果、huskyによるフックが正常に動作しなくなるので注意。

package.json がリポジトリのルートに存在していること

前述の通り、huskyはインストール時にフックファイルを自動生成するが、package.jsonと同じディレクトリに.gitディレクトリが存在しない場合は生成されない。

一つのリポジトリでフロントエンドからバックエンドまで一緒くたに管理している場合この状況に陥ってhuskyが動作しなくなるので注意。

以下、調べた事を雑に書く

.git/hooksディレクトリにpre-commit等フックのタイミングに応じた名前のシェルスクリプトを配置することで、特定のタイミングでシェルスクリプトを実行できる。

また、フックが異常終了した場合、その時の動作がキャンセルされる。例えばpre-commitで異常終了した場合はコミットがキャンセルされる。

#!/bin/sh

exit 1

なので、こんなpre-commitファイルを配置すると、コミットが常にキャンセルされる。

#!/bin/sh
# 実行場所を気にしないために、まず自身のディレクトリに移動
cd `dirname $0`
cd ../..
npx eslint main.js

こういうpre-commitファイルを配置すると、main.jsでリントエラーが発生した場合はコミットがキャンセルされる。

これを応用することでコミット時にリントを走らせて、エラーがあればコミットキャンセルすることで ESLint を常に守らせることができる。

ただ、.gitディレクトリは Git 監視対象外のディレクトリなので、このままだとプロジェクトメンバー全員に手動でpre-commitファイルの設定をしてもらわないといけない。

それを解決するのがhuskyhuskyをプロジェクトでインストールしているとpackage.jsonにフック動作を記述することが出来るのでフック動作を Git で管理することが可能になる。

また、lint-stagedを利用することで特定の拡張子を持つコミット対象のファイルのみリントの対象とすることが出来るので大体それも一緒に使う。

ESLint が npm 経由で実行すると、エラーを吐く

{
  "scripts": {
    "lint": "eslint main.js"
  }
}

とかして、npm run lintとかすると、リントエラー時に ESLint のエラーメッセージに加えて以下のようなエラーが出力される。

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! 8@1.0.0 lint: `eslint main.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the 8@1.0.0 lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/user/.npm/_logs/2019-07-14T05_53_02_446Z-debug.log

どうもこれは npm 自体のエラーで、ESLint のエラー時にはこのエラーが出るのが正常みたい。ただノイズにはなる。

そういう場合はnpm run -s lintとすればいいらしい。

npm scripts でエラーログを表示させたくない話 - はらへり日記

-sは npm のオプションで、npm のエラーを出力させたくない場合に使うみたい。

VueCLI で作られる package.json には「husky」ではなく「gitHooks」という記述だがあれは?

VueCLI ではhuskyから Evan 自ら fork したyorkieを使っているみたい。

GitHub - yyx990803/yorkie: Git hooks made easy