lefthook icon indicating copy to clipboard operation
lefthook copied to clipboard

lefthook's location is ignored in the hooks in a monorepo

Open shamilovtim opened this issue 1 year ago • 2 comments

: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

  1. 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.

  2. 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.

shamilovtim avatar Mar 09 '23 04:03 shamilovtim