Skip to content

Commit

Permalink
fix: apply local extends only if they are present (#754)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrexox committed Jun 20, 2024
1 parent 8959135 commit b48923b
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 7 deletions.
26 changes: 19 additions & 7 deletions internal/config/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"path/filepath"
"regexp"
"slices"
"strings"

"github.com/spf13/afero"
Expand All @@ -20,7 +21,10 @@ const (
DefaultSourceDirLocal = ".lefthook-local"
)

var hookKeyRegexp = regexp.MustCompile(`^(?P<hookName>[^.]+)\.(scripts|commands)`)
var (
hookKeyRegexp = regexp.MustCompile(`^(?P<hookName>[^.]+)\.(scripts|commands)`)
localConfigNames = []string{"lefthook-local", ".lefthook-local"}
)

// NotFoundError wraps viper.ConfigFileNotFoundError for lefthook.
type NotFoundError struct {
Expand Down Expand Up @@ -109,13 +113,21 @@ func mergeAll(fs afero.Fs, repo *git.Repository) (*viper.Viper, error) {
return nil, err
}

// Save global extends to compare them after merging local config
globalExtends := extends.GetStringSlice("extends")

if err := mergeRemotes(fs, repo, extends); err != nil {
return nil, err
}

if err := mergeOne([]string{"lefthook-local", ".lefthook-local"}, "", extends); err == nil {
if err = extend(extends, repo.RootPath); err != nil {
return nil, err
//nolint:nestif
if err := mergeLocal(extends); err == nil {
// Local extends need to be re-applied only if they have different settings
localExtends := extends.GetStringSlice("extends")
if !slices.Equal(globalExtends, localExtends) {
if err = extend(extends, repo.RootPath); err != nil {
return nil, err
}
}
} else {
var notFoundErr viper.ConfigFileNotFoundError
Expand Down Expand Up @@ -216,9 +228,9 @@ func merge(name, path string, v *viper.Viper) error {
return v.MergeInConfig()
}

func mergeOne(names []string, path string, v *viper.Viper) error {
for _, name := range names {
err := merge(name, path, v)
func mergeLocal(v *viper.Viper) error {
for _, name := range localConfigNames {
err := merge(name, "", v)
if err == nil {
break
}
Expand Down
58 changes: 58 additions & 0 deletions internal/config/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,64 @@ pre-push:
},
},
},
{
name: "with extends and local",
global: `
extends:
- global-extend.yml
pre-commit:
parallel: true
exclude_tags: [linter]
commands:
global-lint:
run: bundle exec rubocop
glob: "*.rb"
tags: [backend, linter]
global-other:
run: bundle exec rubocop
tags: [other]
`,
local: `
pre-commit:
exclude_tags: [backend]
`,
otherFiles: map[string]string{
"global-extend.yml": `
pre-commit:
exclude_tags: [test]
commands:
extended-tests:
run: bundle exec rspec
tags: [backend, test]
`,
},
result: &Config{
SourceDir: DefaultSourceDir,
SourceDirLocal: DefaultSourceDirLocal,
Extends: []string{"global-extend.yml"},
Hooks: map[string]*Hook{
"pre-commit": {
Parallel: true,
ExcludeTags: []string{"backend"},
Commands: map[string]*Command{
"global-lint": {
Run: "bundle exec rubocop",
Tags: []string{"backend", "linter"},
Glob: "*.rb",
},
"global-other": {
Run: "bundle exec rubocop",
Tags: []string{"other"},
},
"extended-tests": {
Run: "bundle exec rspec",
Tags: []string{"backend", "test"},
},
},
},
},
},
},
} {
fs := afero.Afero{Fs: afero.NewMemMapFs()}
repo := &git.Repository{
Expand Down

0 comments on commit b48923b

Please sign in to comment.