lefthook
lefthook copied to clipboard
lefthook's location is ignored in the hooks in a monorepo
:wrench: Summary
The lefthook.yml supports the root:
directive in order to run the hooks from a separate monorepo folder. However it does not pass this information to the hooks at all. So the hooks end up doing this:
dir="$(git rev-parse --show-toplevel)"
osArch=$(echo "$(uname)" | tr '[:upper:]' '[:lower:]')
cpuArch=$(echo "$(uname -m)" | sed 's/aarch64/arm64/')
if lefthook -h >/dev/null 2>&1
then
eval lefthook $@
elif test -f "$dir/node_modules/lefthook/bin/index.js"
then
eval "\"$dir/node_modules/lefthook/bin/index.js\" $@"
elif test -f "$dir/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
eval "\"$dir/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook\" $@"
elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook"
then
eval "\"$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook\" $@"
elif bundle exec lefthook -h >/dev/null 2>&1
then
bundle exec lefthook $@
elif yarn lefthook -h >/dev/null 2>&1
then
yarn lefthook $@
elif pnpm lefthook -h >/dev/null 2>&1
then
pnpm lefthook $@
elif npx @evilmartians/lefthook -h >/dev/null 2>&1
then
npx @evilmartians/lefthook $@
else
echo "Can't find lefthook in PATH"
fi
git rev-parse --show-toplevel
only gets the root of the whole repository. nowhere do the hooks account for lefthook being installed in a deeper nested directory. this is a problem because lefthook can be part of a monorepo which is not just a top level javascript project. for example:
./JS-project/
./go-project/
./ios-project/
./android-project/
No top level package.json is desirable here, and lefthook lives inside of ./js-project/
but tells the hooks to check ./node_modules/
rather than /JS-project/node_modules
which is where it actually lives. as a fallback condition it tries to hack using npx lefthook
which is even worse because it retrieves some random cached version somewhere globally on the machine, which is even worse and causes version mismatches.
Lefthook version
1.3.3
Possible Solution
-
The hooks generated need to know where to look for lefthook in a monorepo. Add a directive to point to where lefthook is installed in the monorepo and propagate it to the hooks. For example
lefthook_location: "my-js-dir/
. Then pass that to the generated hooks as a param. -
For the npx fallback, this is an unrelated bug but it also needs to be fixed. Change:
npx @evilmartians/lefthook $@
to:npx @evilmartians/lefthook@latest $@
The former is incorrect and will always get a globally installed random version of lefthook that was cached on the user's machine at some random point in time. The latter will always get the latest released version with bugfixes.