evilmartians/lefthook

Option "skip" is not properly merged

madeofsun opened this issue ยท 5 comments

๐Ÿ”ง Summary

Option "skip" is not properly merged

Lefthook version

1.7.18

Steps to reproduce

Create some package with

// package.json
{
  "dependencies": {
    "lefthook": "1.7.18"
  }
}
# some-lefthook.yml
pre-commit:
  commands:
    my-cmd:
      skip: true
      run: exit 1
# lefthook.yml
extends:
  - ./some-lefthook.yml

pre-commit:
  commands:
    my-cmd:
      skip: false

Expected results

Hook must run and npx lefthook -v dump must output

extends:
  - ./some-lefthook.yml
pre-commit:
  commands:
    my-cmd:
      run: exit 1
      skip: false

Actual results

Hook is skipped and npx lefthook -v dump outputs

extends:
  - ./some-lefthook.yml
pre-commit:
  commands:
    my-cmd:
      run: exit 1
      skip: true

Possible Solution

Logs / Screenshots

LEFTHOOK_VERBOSE=true git commit -m tmp
+ '[' '' = 0 ']'
+ call_lefthook run pre-commit
+ test -n ''
+ lefthook -h
++ git rev-parse --show-toplevel
+ dir=/Users/nikita/Documents/code/test-lefthook
++ uname
++ tr '[:upper:]' '[:lower:]'
+ osArch=darwin
++ uname -m
++ sed 's/aarch64/arm64/;s/x86_64/x64/'
+ cpuArch=arm64
+ test -f /Users/nikita/Documents/code/test-lefthook/node_modules/lefthook-darwin-arm64/bin/lefthook
+ /Users/nikita/Documents/code/test-lefthook/node_modules/lefthook-darwin-arm64/bin/lefthook run pre-commit
โ”‚ [lefthook] cmd:    [git rev-parse --show-toplevel]
โ”‚ [lefthook] stdout: /Users/nikita/Documents/code/test-lefthook
                                                             
โ”‚ [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.7.18  hook: pre-commit โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
โ”‚ [lefthook] cmd:    [git status --short --porcelain]
โ”‚ [lefthook] dir:    /Users/nikita/Documents/code/test-lefthook
โ”‚ [lefthook] stdout: 
โ”‚  my-cmd (skip) settings
โ”‚ [lefthook] cmd:    [git stash list]
โ”‚ [lefthook] dir:    /Users/nikita/Documents/code/test-lefthook
โ”‚ [lefthook] stdout: 
                                      
  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
summary: (done in 0.01 seconds)       
On branch master
nothing to commit, working tree clean
Screenshot 2024-10-08 at 23 11 20

Hey @madeofsun! Why do you expect extends to be merged before the main config? I think this is a problem with documentation because it's not clear from it, but all extends, remotes and local config get merged after the settings in the main config file.

I think I get the idea of your configuration, but changing the order of merging may break behavior for other users.

Oh, sorry, I will check the docs again. I was expecting that it works similar to other tools (eslint / jest / babel / etc.), where you override configs that are extended.

Also, maybe there is another way to do what I need. I wish to have a config with some hooks enabled by default and some "optional" hooks that are skipped by default. And the end user can enable such "optional" hooks if they want.

There is an option to use lefthook-local.yml which is merged at the end and will do the override. This is the order of merges:

  1. Main settings in lefthook.yml
  2. Settings from extends
  3. Settings from remotes
  4. Settings from lefthook-local.yml

Does it work for your case? I guess this might be a bit inconvenient to have two configs ๐Ÿค” WDYT?

In our setup -local.yml is gitignored, so yep, it is not convenient to use.

As a workaround I think about placing optional hooks into separate configs. Such that end user will include them instead of overriding "skip" option.

I think the issue is no longer an issue, I mistakenly thought it is a bug.

I can suggest you the following structure:

# lefthook.yml
extends:
  - ./some-lefthook.yml
  - ./main-lefthook.yml
# some-lefthook.yml
pre-commit:
  commands:
    my-cmd:
      skip: true
      run: exit 1
# main-lefthook.yml
pre-commit:
  commands:
    my-cmd:
      skip: false

In this case only the order of extends matters and the settings from the last config will override the previous settings.