lefthook
lefthook copied to clipboard
Inconsistent behaviour when running custom commands from different folders
:wrench: Summary
Custom command run
has a strange (and buggy) behavior
Lefthook version
1.4.3
Steps to reproduce
- Take any repo and create a subfolder in it with
mkdir sub && touch sub/foo.rb
- Create the attached
lefthook.yml
- Run lefthook from both root folder and sub folder
monorepo:
commands:
command that emit fullpath:
root: sub
files: echo sub/foo.rb foo.rb
run: "echo list of files: {files}"
command that emit relative path:
root: sub
files: echo sub/foo.rb foo.rb
run: "echo list of files: {files}"
Expected results
I'd expect that files
command works independently from current working directory and either must emit relative paths from git root or relative paths from root
folder, and can be run at any level of git repo.
So I expect to have at least one of the two commands works consistently from any level of my hierarchy (even in subfolders)
Actual results
When running from git root:
$ LEFTHOOK_VERBOSE=1 lefthook run monorepo
Lefthook v1.4.3
RUNNING HOOK: monorepo
[lefthook] cmd: [sh -c echo sub/foo.rb]
[lefthook] err: <nil>
[lefthook] out: sub/foo.rb
[lefthook] files before filters:
[sub/foo.rb]
[lefthook] files after filters:
[.//foo.rb]
[lefthook] files after escaping:
[.//foo.rb]
[lefthook] executing: echo list of files: .//foo.rb
EXECUTE > command that emit fullpath
list of files: .//foo.rb
[lefthook] cmd: [sh -c echo foo.rb]
[lefthook] err: <nil>
[lefthook] out: foo.rb
command that emit relative path: (skip) no files for inspection
SUMMARY: (done in 0.01 seconds)
✔️ command that emit fullpath
In this case only the first version, the one with full paths (from git root) is working as expected since files are not filtered out and they have the sub
part replaced by .//
(actually I don't get exactly why a double slash from code).
The second task is getting skipped likely because of this check for file existence
When running from sub
folder
$ LEFTHOOK_VERBOSE=1 lefthook run monorepo
Lefthook v1.4.3
RUNNING HOOK: monorepo
[lefthook] cmd: [sh -c echo sub/foo.rb]
[lefthook] err: <nil>
[lefthook] out: sub/foo.rb
command that emit fullpath: (skip) no files for inspection
[lefthook] cmd: [sh -c echo foo.rb]
[lefthook] err: <nil>
[lefthook] out: foo.rb
[lefthook] files before filters:
[foo.rb]
[lefthook] files after filters:
[]
[lefthook] files after escaping:
[]
command that emit relative path: (skip) no files for inspection
SUMMARY: (SKIP EMPTY)
In this case none of the commands work, in the first case I guess the culprit is the same existence check of above, file sub/foo.rb
doesn't exist when concatenated to current working directory. In the second task the existence check passes but then one of these filters remove it from the array (I think the third one).
So I found no way to run a custom command from a subfolder.
Possible Solution
We should decide how the software should work when giving the root
option and document it, there are couple of possibilities
-
files
should always emit paths relative to git root, if so command should be executed with git root as working dir ignoring current working directory -
files
should always emit paths relative toroot
directory
According to the choice then the run
command should be tweaked accordingly. As user I'd expect that run
has root
folder as process working directory and {files}
gets replaced with paths relative to it, but it's not a choice I can make.
In any case I'd expect that custom commands (or any other executed hook) works independently of my shell working directory as git does.
Logs / Screenshots
Transcript attached in the previous section.