What a strange sentence. First Hk will be faster than Lefthook because it will be written in Rust[1], but then later on it says that it doesn't actually matter? But either way it will be faster because it has "advanced parallelism"?
Looking at the comparison to Lefthook it's not clear to me why this isn't a PR to Lefthook. It's already a well-established solution which is present in many package managers. Surely the distinction between "checks" and "fixes" would be possible to introduce there as well?
Do we yet another tool instead of working together on improving the existing ones?
[1]: Which also is not a given. Programs which allocate a lot can be faster in Go since the garbage collector only works on the live set of objects whereas Rust have to explicitly deallocate all memory. CLI tooling is actually kinda a sweet-spot of GCs: You don't want to spend time reclaiming memory until you reach a certain threshold of used memory. In scenarios where you use less than the threshold you end up spending zero cycles on deallocation. (And completely leaking all memory is bound to cause problem on bigger commands or smaller machines.)
First, I intend to be able to define simple "dependencies", but IMO that's not the interesting part.
I am going to use rw mutexes on every file with staged changes. If 2 steps are running against disjoint files there is no problem. If 2 steps are running against "check" (not "fix" which edit files by convention), they can also run at the same time. The only scenario where blocking is necessary is when you have 2 "fix" or 1 "check" and 1 "fix" on an intersection of their files.
For that scenario there is going to be a setting that you can enable to run a steps "check" command first (only if this scenario is about to happen, if no files will be in contention it will simply run "fix"), and if "check" fails, then it will switch to "fix".
This is my current idea and in my head I think it would work. There are caveats, notably running "check" and then "fix" might be slower than just waiting and running "fix" once which is why it needs to be optional behavior. You also may not care about things stomping on each other (maybe the linters themselves have their own locking logic).