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: use glob in exclude array #777

Merged
merged 3 commits into from
Jul 22, 2024
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
48 changes: 27 additions & 21 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ pre-commit:

**Default: `false`**

> **Note**
> [!NOTE]
>
> Lefthook runs commands and scripts **sequentially** by default.

Expand All @@ -571,7 +571,7 @@ Run commands and scripts concurrently.

**Default: `false`**

> **Note**
> [!NOTE]
>
> Lefthook will return an error if both `piped: true` and `parallel: true` are set.

Expand Down Expand Up @@ -613,7 +613,7 @@ pre-push:
run: yarn test
```

> **Note**
> [!NOTE]
>
> If used with [`parallel`](#parallel) the output can be a mess, so please avoid setting both options to `true`.

Expand Down Expand Up @@ -786,7 +786,7 @@ pre-push:

Simply run `bundle exec rubocop` on all files with `.rb` extension excluding `application.rb` and `routes.rb` files.

> **Note**
> [!NOTE]
>
> `--force-exclusion` will apply `Exclude` configuration setting of Rubocop.

Expand All @@ -798,7 +798,9 @@ pre-commit:
rubocop:
tags: backend style
glob: "*.rb"
exclude: '(^|/)(application|routes)\.rb$'
exclude:
- config/application.rb
- config/routes.rb
run: bundle exec rubocop --force-exclusion {all_files}
```

Expand Down Expand Up @@ -1259,17 +1261,21 @@ pre-commit:

### `exclude`

You can provide a list of filenames or a regular expression to exclude some files from being passed to [`run`](#run) command.
For the `exclude` option two variants are supported:

If you pass a list of filenames, they must contain the full path of the file from the project root.
- A list of globs to be excluded
- A single regular expression (deprecated)

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.
File paths do not begin with the separator or any other prefix.

> [!NOTE]
>
> 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.
> File paths do not begin with the separator or any other prefix.

**Example**

Run Rubocop on staged files with `.rb` extension except for `application.rb`, `routes.rb`, and `rails_helper.rb` (wherever they are).
Run Rubocop on staged files with `.rb` extension except for `application.rb`, `routes.rb`, `rails_helper.rb`, and all Ruby files in `config/initializers/`.

```yml
# lefthook.yml
Expand All @@ -1278,11 +1284,15 @@ pre-commit:
commands:
lint:
glob: "*.rb"
exclude: '(^|/)(application|routes|rails_helper)\.rb$'
exclude:
- config/routes.rb
- config/application.rb
- config/initializers/*.rb
- spec/rails_helper.rb
run: bundle exec rubocop --force-exclusion {staged_files}
```

The same example using a list of filenames.
The same example using a regular expression.

```yml
# lefthook.yml
Expand All @@ -1291,14 +1301,10 @@ pre-commit:
commands:
lint:
glob: "*.rb"
exclude:
- config/routes.rb
- config/application.rb
- spec/rails_helper.rb
exclude: '(^|/)(application|routes|rails_helper|initializers/\w+)\.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 Expand Up @@ -1367,7 +1373,7 @@ pre-commit:

**Default: `false`**

> **Note**
> [!NOTE]
>
> If you want to pass stdin to your command or script but don't need to get the input from CLI, use [`use_stdin`](#use_stdin) option instead.

Expand All @@ -1381,7 +1387,7 @@ Whether to use interactive mode. This applies the certain behavior:

**Default: `0`**

> **Note**
> [!NOTE]
>
> This option makes sense only when `parallel: false` or `piped: true` is set.
>
Expand Down Expand Up @@ -1464,7 +1470,7 @@ When you try to commit `git commit -m "bad commit text"` script `template_checke

### `use_stdin`

> **Note**
> [!NOTE]
>
> With many commands or scripts having `use_stdin: true`, only one will receive the data. The others will have nothing. If you need to pass the data from stdin to every command or script, please, submit a [feature request](https://github.com/evilmartians/lefthook/issues/new?assignees=&labels=feature+request&projects=&template=feature_request.md).

Expand Down
14 changes: 10 additions & 4 deletions internal/lefthook/runner/filters/filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,21 @@ func byExclude(vs []string, matcher interface{}) []string {

return vsf
case []interface{}:
excludeNames := make(map[string]struct{}, len(exclude))
if len(exclude) == 0 {
return vs
}

globs := make([]glob.Glob, 0, len(exclude))
for _, name := range exclude {
excludeNames[name.(string)] = struct{}{}
globs = append(globs, glob.MustCompile(name.(string)))
}

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

Expand Down
5 changes: 3 additions & 2 deletions testdata/exclude.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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'
stdout 'not-excluded.txt'

-- lefthook.yml --
skip_output:
Expand All @@ -25,14 +25,15 @@ regexp:
commands:
echo:
run: echo {staged_files}
exclude: '^excluded.txt'
exclude: '^excluded\.[tx]+'

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

-- not-excluded.txt --
sometext
Expand Down
Loading