Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow list of files in exclude option #772

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,9 @@ pre-commit:

### `exclude`

You can provide a regular expression to exclude some files from being passed to [`run`](#run) command.
You can provide a list of filenames or a regular expression to exclude some files from being passed to [`run`](#run) command.

If you pass a list of filenames, they must contain the full path of the file from the project root.

The regular expression is matched against full paths to files in the repo,
relative to the repo root, using `/` as the directory separator on all platforms.
Expand All @@ -1280,6 +1282,23 @@ pre-commit:
run: bundle exec rubocop --force-exclusion {staged_files}
```

The same example using a list of filenames.

```yml
# lefthook.yml

pre-commit:
commands:
lint:
glob: "*.rb"
exclude:
- config/routes.rb
- config/application.rb
- spec/rails_helper.rb
run: bundle exec rubocop --force-exclusion {staged_files}
```


**Notes**

Be careful with the config file format's string quoting and escaping rules when writing regexps in it. For YAML, single quotes are often the simplest choice.
Expand Down
6 changes: 3 additions & 3 deletions internal/config/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ type Command struct {

FileTypes []string `json:"file_types,omitempty" mapstructure:"file_types" toml:"file_types,omitempty" yaml:"file_types,omitempty"`

Glob string `json:"glob,omitempty" mapstructure:"glob" toml:"glob,omitempty" yaml:",omitempty"`
Root string `json:"root,omitempty" mapstructure:"root" toml:"root,omitempty" yaml:",omitempty"`
Exclude string `json:"exclude,omitempty" mapstructure:"exclude" toml:"exclude,omitempty" yaml:",omitempty"`
Glob string `json:"glob,omitempty" mapstructure:"glob" toml:"glob,omitempty" yaml:",omitempty"`
Root string `json:"root,omitempty" mapstructure:"root" toml:"root,omitempty" yaml:",omitempty"`
Exclude interface{} `json:"exclude,omitempty" mapstructure:"exclude" toml:"exclude,omitempty" yaml:",omitempty"`

Priority int `json:"priority,omitempty" mapstructure:"priority" toml:"priority,omitempty" yaml:",omitempty"`
FailText string `json:"fail_text,omitempty" mapstructure:"fail_text" toml:"fail_text,omitempty" yaml:"fail_text,omitempty"`
Expand Down
40 changes: 32 additions & 8 deletions internal/lefthook/runner/filters/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,42 @@ func byGlob(vs []string, matcher string) []string {
return vsf
}

func byExclude(vs []string, matcher string) []string {
if matcher == "" {
func byExclude(vs []string, matcher interface{}) []string {
switch exclude := matcher.(type) {
case nil:
return vs
}
case string:
if len(exclude) == 0 {
return vs
}

vsf := make([]string, 0)
for _, v := range vs {
if res, _ := regexp.MatchString(matcher, v); !res {
vsf = append(vsf, v)
vsf := make([]string, 0)
for _, v := range vs {
if res, _ := regexp.MatchString(exclude, v); !res {
vsf = append(vsf, v)
}
}

return vsf
case []interface{}:
excludeNames := make(map[string]struct{}, len(exclude))
for _, name := range exclude {
excludeNames[name.(string)] = struct{}{}
}

vsf := make([]string, 0)
for _, v := range vs {
if _, excluded := excludeNames[v]; !excluded {
vsf = append(vsf, v)
}
}

return vsf
}
return vsf

log.Warn("invalid value for exclude option")

return vs
}

func byRoot(vs []string, matcher string) []string {
Expand Down
42 changes: 42 additions & 0 deletions testdata/exclude.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
exec git init
exec lefthook install
exec git config user.email "[email protected]"
exec git config user.name "Your Name"
exec git add -A
exec lefthook run -f all
stdout 'excluded.txt lefthook.yml not-excluded.txt'
exec lefthook run -f regexp
stdout 'lefthook.yml not-excluded.txt'
exec lefthook run -f array
stdout 'lefthook.yml not-excluded.txt'

-- lefthook.yml --
skip_output:
- skips
- meta
- summary
- execution_info
all:
commands:
echo:
run: echo {staged_files}

regexp:
commands:
echo:
run: echo {staged_files}
exclude: '^excluded.txt'

array:
commands:
echo:
run: echo {staged_files}
exclude:
- exclude.txt

-- not-excluded.txt --
sometext

-- excluded.txt --
somecode

Loading