evilmartians / lefthook

Fast and powerful Git hooks manager for any type of projects.
MIT License
5k stars 218 forks source link

Command titles get truncated if they contain a dot #864

Closed VanTanev closed 3 weeks ago

VanTanev commented 3 weeks ago

:wrench: Summary

If a command title contains a dot (.), everything after the dot is omitted in lefthook output:

Lefthook version

1.8.2 9996e0d9db43a6b856074d2b836adf924a24b992

Steps to reproduce

# lefthook.yml
pre-commit:
  "everything after the dot. will be missing":
     run: echo Hello
pnpm lefthook run pre-commit

Expected results

➜  pnpm lefthook run pre-commit
╭──────────────────────────────────────╮
│ 🥊 lefthook v1.8.2  hook: pre-commit │
╰──────────────────────────────────────╯
sync hooks: ✔️ (post-rewrite, pre-commit, post-merge, post-checkout, _shared_)
┃  everything after the dot. will be missing ❯ 

  ────────────────────────────────────
summary: (done in 0.02 seconds)       
✔️  everything after the dot. will be missing

Actual results

➜  pnpm lefthook run pre-commit
╭──────────────────────────────────────╮
│ 🥊 lefthook v1.8.2  hook: pre-commit │
╰──────────────────────────────────────╯
sync hooks: ✔️ (post-rewrite, pre-commit, post-merge, post-checkout, _shared_)
┃  everything after the dot ❯ 

  ────────────────────────────────────
summary: (done in 0.02 seconds)       
✔️  everything after the dot

Logs / Screenshots

LEFTHOOK_VERBOSE=true pnpm lefthook run pre-commit
│ [lefthook] cmd:    [git rev-parse --show-toplevel]
│ [lefthook] stdout: /home/ivan/monorepo

│ [lefthook] cmd:    [git rev-parse --git-path hooks]
│ [lefthook] stdout: .git/hooks

│ [lefthook] cmd:    [git rev-parse --git-path info]
│ [lefthook] stdout: .git/info

│ [lefthook] cmd:    [git rev-parse --git-dir]
│ [lefthook] stdout: .git

│ [lefthook] cmd:    [git hash-object -t tree /dev/null]
│ [lefthook] stdout: 4b825dc642cb6eb9a060e54bf8d69288fbee4904

╭──────────────────────────────────────╮
│ 🥊 lefthook v1.8.2  hook: pre-commit │
╰──────────────────────────────────────╯
│ [lefthook] cmd:    [git status --short --porcelain]
│ [lefthook] dir:    /home/ivan/monorepo
│ [lefthook] stdout: MM lefthook.yml

│ [lefthook] saving partially staged files
│ [lefthook] cmd:    [git diff --binary --unified=0 --no-color --no-ext-diff --src-prefix=a/ --dst-prefix=b/ --patch --submodule=short --output .git/info/lefthook-unstaged.patch -- lefthook.yml]
│ [lefthook] dir:    /home/ivan/monorepo
│ [lefthook] stdout: 
│ [lefthook] cmd:    [git stash create]
│ [lefthook] dir:    /home/ivan/monorepo
│ [lefthook] stdout: 93ee51e317d9e4be8751ea2aabe5dbe8e6e9eeca

│ [lefthook] cmd:    [git stash store --quiet --message lefthook auto backup 93ee51e317d9e4be8751ea2aabe5dbe8e6e9eeca]
│ [lefthook] dir:    /home/ivan/monorepo
│ [lefthook] stdout: 
│ [lefthook] cmd:    [git checkout --force -- lefthook.yml]
│ [lefthook] dir:    /home/ivan/monorepo
│ [lefthook] stdout: 
│ [lefthook] stderr: + [ 0 = 0 ]
+ exit 0                      

│ [lefthook] hide partially staged files: [lefthook.yml]

│ [lefthook] cmd:    [git diff --name-only --cached --diff-filter=ACMR]
│ [lefthook] dir:    /home/ivan/monorepo
│ [lefthook] stdout: lefthook.yml

│ [lefthook] files before filters:
[lefthook.yml]                  
│ [lefthook] files after filters:
[lefthook.yml]                 
┃  everything after the dot ❯ 

│ [lefthook] cmd:    [git apply -v --whitespace=nowarn --recount --unidiff-zero .git/info/lefthook-unstaged.patch]
│ [lefthook] dir:    /home/ivan/monorepo
│ [lefthook] stdout: 
│ [lefthook] stderr: Checking patch lefthook.yml...
Applied patch lefthook.yml cleanly.              

│ [lefthook] cmd:    [git stash list]
│ [lefthook] dir:    /home/ivan/monorepo
│ [lefthook] stdout: stash@{0}: lefthook auto backup

│ [lefthook] cmd:    [git stash drop --quiet stash@{0}]
│ [lefthook] dir:    /home/ivan/monorepo
│ [lefthook] stdout: 

  ────────────────────────────────────
summary: (done in 0.03 seconds)       
✔️  everything after the dot
VanTanev commented 3 weeks ago

Wait, this is actually much worse than I thought!

If a title contains a dot, the command isn't even executed at all!

# lefthook.yml
pre-commit:
  "if title contains a dot. this always passes!":
     run: exit 1
➜  pnpm lefthook run pre-commit
╭──────────────────────────────────────╮
│ 🥊 lefthook v1.8.2  hook: pre-commit │
╰──────────────────────────────────────╯
sync hooks: ✔️ (pre-commit, post-merge, _shared_, post-checkout, post-rewrite)
┃  if title contains dot ❯ 

  ────────────────────────────────────
summary: (done in 0.02 seconds)       
✔️  if title contains dot
➜  $?
zsh: command not found: 0
mrexox commented 3 weeks ago

Hey! Yes, this is a side effect of using viper package. It considers dot as a short syntax for YAML nesting:

some.nested.option:
  value: true

is the same as

some:
  nested:
    option:
      value: true

But this is YAML syntax, and there's (probably) nothing to do with it. Right now I'm working on a slightly different way to configure lefthook. It solves this issue because it doesn't use keys for command names.

VanTanev commented 3 weeks ago

...I really hate YAML.

If you're changing the config format, it might be worth considering support for different config format. Even JSON is preferable, YAML has so many edge cases.

mrexox commented 3 weeks ago

Actually lefthook supports JSON and TOML. Do lefthook dump --format=json for migration :)

VanTanev commented 3 weeks ago

Thanks!

I think this issue can be closed. Maybe the most we could do is add a warning to the docs?