なっく日報

技術やら生活やらのメモ

monorepo構成のリポジトリでGitのフックスクリプトを仕掛ける方法

今担当しているプロジェクトで、monorepo構成を試しているのですが、

Gitのフックスクリプトを仕掛けるいい方法は何かないか?と思い、調べてみました。

ちなみに、monorepoって何?という方は↓を見てください。

yukidarake.hateblo.jp

monorepoのプロジェクトを見ていく

meteor

https://github.com/meteor/meteor/blob/devel/scripts/admin/git-hooks/pre-commit https://github.com/meteor/meteor/blob/devel/scripts/admin/eslint/eslint.sh

変更があったファイルのみを対象に、ESLintをかけているよう。

思ったよりは力技感があります。

react

https://github.com/facebook/react/blob/master/scripts/git/pre-commit

こちらも変更があったファイルのみを対象に、ESLintをかけています。

babel, ember.js

パッと見た感じGitのフックスクリプトは見当たりませんでした。

どうしよう

一応自分なりに考えてみました。

トップレベルにghooksを仕掛ける

github.com

コレ。package.json

{
  …
  "config": {
    "ghooks": {
      "pre-commit": "gulp lint",
      "commit-msg": "validate-commit-msg",
      "pre-push": "make test",
      "post-merge": "npm install",
      "post-rewrite": "npm install",
      …
    }
  }}

な感じで書けば、gitで操作した際にフックしてくれる便利なブツ。

pre-commitに仕掛ける

その中でpre-commit時に↓のようなシェルを動かします。

#!/bin/sh
set -eux

PACKAGES_TO_VERIFY=$(git diff --cached --name-only | perl -lanE 'm!packages/([^/]+)! && say $1' | sort | uniq)
SCRIPT=git-hook:pre-commit

for p in ${PACKAGES_TO_VERIFY[@]}; do
  (cd packages/$p &&  npm run $SCRIPT)
done

変更のあったpackages以下のプロジェクトに対してnpm run git-hook:pre-commitするという感じ。

この作りだと、packages配下のプロジェクトはNode.jsのプロジェクトでなおかつgit-hook:pre-commitを定義しないとダメなんで、 あんまりイケている訳ではないですが、とりあえず一旦はこの方向で引き続き進めてみようと思います。