Skip to content

Commit

Permalink
feat: add file type filters (#698)
Browse files Browse the repository at this point in the history
* feat: add file type filters

* chore: add a custom type

* fix: implement text checking only

* chore: fix naming and error handling

* fix: fix text file detector and add integrity tests

* ci: remove integrity test for windows

* chore: add a test on detectText

* docs: add documentation

* fix: slightly optimize the code and update the docs
  • Loading branch information
mrexox committed Apr 10, 2024
1 parent 36f1a09 commit 9f40122
Show file tree
Hide file tree
Showing 13 changed files with 480 additions and 129 deletions.
134 changes: 101 additions & 33 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ Lefthook [supports](#config-file) YAML, JSON, and TOML configuration. In this do
- [`source_dir`](#source_dir)
- [`source_dir_local`](#source_dir_local)
- [`rc`](#rc)
- [`remote`](#remote--deprecated-show-remotes-instead) :warning: DEPRECATED use [`remotes`](#remotes)
- [`remote`](#remote--deprecated-show-remotes-instead) :warning: **DEPRECATED** use [`remotes`](#remotes)
- [`git_url`](#git_url)
- [`ref`](#ref)
- [`config`](#config--deprecated-use-configs-like-specified-in-remotes)
- [`config`](#config)
- [`remotes`](#remotes)
- [`git_url`](#git_url-1)
- [`ref`](#ref-1)
Expand All @@ -41,6 +41,7 @@ Lefthook [supports](#config-file) YAML, JSON, and TOML configuration. In this do
- [`tags`](#tags)
- [`glob`](#glob)
- [`files`](#files)
- [`file_types`](#file_types)
- [`env`](#env)
- [`root`](#root)
- [`exclude`](#exclude)
Expand Down Expand Up @@ -202,7 +203,8 @@ LEFTHOOK_OUTPUT="meta,success,summary" lefthook run pre-commit

### `skip_output`

> **Deprecated:** This feature is deprecated and might be removed in future versions. Please, use `[output]` instead for managing verbosity.
> [!IMPORTANT]
> **DEPRECATED** This feature is deprecated and might be removed in future versions. Please, use `[output]` instead for managing verbosity.

You can manage the verbosity using the `skip_output` config. You can set whether lefthook should print some parts of its output.

Expand Down Expand Up @@ -330,7 +332,8 @@ Now any program that runs your hooks will have a tweaked PATH environment variab

## `remote`

> :warning: DEPRECATED use [`remotes`](#remotes) setting
> [!WARNING]
> **DEPRECATED** Use [`remotes`](#remotes) setting

You can provide a remote config if you want to share your lefthook configuration across many projects. Lefthook will automatically download and merge the configuration into your local `lefthook.yml`.

Expand All @@ -350,7 +353,8 @@ This can be changed in the future. For convenience, please use `remote` configur

### `git_url`

> :warning: DEPRECATED use [`remotes`](#remotes) setting
> [!WARNING]
> **DEPRECATED** Use [`remotes`](#remotes) setting

A URL to Git repository. It will be accessed with privileges of the machine lefthook runs on.

Expand All @@ -374,7 +378,8 @@ remote:

### `ref`

> :warning: DEPRECATED use [`remotes`](#remotes) setting
> [!WARNING]
> **DEPRECATED** Use [`remotes`](#remotes) setting

An optional *branch* or *tag* name.

Expand All @@ -388,13 +393,14 @@ remote:
ref: v1.0.0
```

> **Note**
> [!CAUTION]
>
> :warning: If you initially had `ref` option, ran `lefthook install`, and then removed it, lefthook won't decide which branch/tag to use as a ref. So, if you added it once, please, use it always to avoid issues in local setups.
> If you initially had `ref` option, ran `lefthook install`, and then removed it, lefthook won't decide which branch/tag to use as a ref. So, if you added it once, please, use it always to avoid issues in local setups.

### `config`

> :warning: DEPRECATED use [`remotes`](#remotes) setting
> [!WARNING]
> **DEPRECATED**. Use [`remotes`](#remotes) setting

**Default:** `lefthook.yml`

Expand All @@ -413,6 +419,7 @@ remote:

## `remotes`

> [!IMPORTANT]
> :test_tube: This feature is in **Beta** version

You can provide multiple remote configs if you want to share yours lefthook configurations across many projects. Lefthook will automatically download and merge configurations into your local `lefthook.yml`.
Expand Down Expand Up @@ -467,7 +474,7 @@ remotes:
ref: v1.0.0
```

> :warning: **Note**
> [!NOTE]
>
> If you initially had `ref` option, ran `lefthook install`, and then removed it, lefthook won't decide which branch/tag to use as a ref. So, if you added it once, please, use it always to avoid issues in local setups.

Expand Down Expand Up @@ -665,7 +672,8 @@ pre-commit:

Scripts to be executed for the hook. Each script has a name (filename in scripts dir) and associated run [options](#script).

**:warning: Important**: script must exist under `<source_dir>/<git-hook-name>/` folder. See [`source_dir`](#source_dir).
> [!IMPORTANT]
> Script must exist under `<source_dir>/<git-hook-name>/` folder. See [`source_dir`](#source_dir).

**Example**

Expand Down Expand Up @@ -938,33 +946,33 @@ pre-commit:
run: yarn test
```

**Notes**

Always skipping is useful when you have a `lefthook-local.yml` config and you don't want to run some commands locally. So you just overwrite the `skip` option for them to be `true`.

```yml
# lefthook.yml
pre-commit:
commands:
lint:
run: yarn lint
```

```yml
# lefthook-local.yml
pre-commit:
commands:
lint:
skip: true
```
> [!TIP]
>
> Always skipping is useful when you have a `lefthook-local.yml` config and you don't want to run some commands locally. So you just overwrite the `skip` option for them to be `true`.
>
> ```yml
> # lefthook.yml
>
> pre-commit:
> commands:
> lint:
> run: yarn lint
> ```
>
> ```yml
> # lefthook-local.yml
>
> pre-commit:
> commands:
> lint:
> skip: true
> ```

### `only`

You can force a command, script, or the whole hook to execute only in certain conditions. This option acts like the opposite of [`skip`](#skip). It accepts the same values but skips execution only if the condition is not satisfied.

> **Note**
> [!NOTE]
>
> `skip` option takes precedence over `only` option, so if you have conflicting conditions the execution will be skipped.

Expand Down Expand Up @@ -1092,6 +1100,66 @@ pre-push:
run: bundle exec rubocop --force-exclusion --parallel {files}
```

### `file_types`

Filter files in a [`run`](#run) templates by their type. Supported types:

|File type| Exlanation|
|---------|-----------|
|`text` | Any file that contains text. Symlinks are not followed. |
|`binary` | Any file that contains non-text bytes. Symlinks are not followed. |
|`executable` | Any file that has executable bits set. Symlinks are not followed. |
|`not executable` | Any file without executable bits in file mode. Symlinks included. |
|`symlink` | A symlink file. |
|`not symlink` | Any non-symlink file. |

> [!IMPORTANT]
> When passed multiple file types all constraints will be applied to the resulting list of files.

**Examples**

Apply some different linters on text and binary files.

```yml
# lefthook.yml
pre-commit:
commands:
lint-code:
run: yarn lint {staged_files}
file_types: text
check-hex-codes:
run: yarn check-hex {staged_files}
file_types: binary
```

Skip symlinks.

```yml
# lefthook.yml
pre-commit:
commands:
lint:
run: yarn lint --fix {staged_files}
file_types:
- not symlink
```

Lint executable scripts.

```yml
# lefthook.yml
pre-commit:
commands:
lint:
run: yarn lint --fix {staged_files}
file_types:
- executable
- text
```

### `env`

You can specify some ENV variables for the command or script.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.5.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
Expand Down
22 changes: 12 additions & 10 deletions internal/config/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,21 @@ import (
var errFilesIncompatible = errors.New("One of your runners contains incompatible file types")

type Command struct {
Run string `json:"run" mapstructure:"run" toml:"run" yaml:"run"`
Run string `json:"run" mapstructure:"run" toml:"run" yaml:"run"`
Files string `json:"files,omitempty" mapstructure:"files" toml:"files,omitempty" yaml:",omitempty"`

Skip interface{} `json:"skip,omitempty" mapstructure:"skip" toml:"skip,omitempty,inline" yaml:",omitempty"`
Only interface{} `json:"only,omitempty" mapstructure:"only" toml:"only,omitempty,inline" yaml:",omitempty"`
Tags []string `json:"tags,omitempty" mapstructure:"tags" toml:"tags,omitempty" yaml:",omitempty"`
Glob string `json:"glob,omitempty" mapstructure:"glob" toml:"glob,omitempty" yaml:",omitempty"`
Files string `json:"files,omitempty" mapstructure:"files" toml:"files,omitempty" yaml:",omitempty"`
Env map[string]string `json:"env,omitempty" mapstructure:"env" toml:"env,omitempty" yaml:",omitempty"`
Skip interface{} `json:"skip,omitempty" mapstructure:"skip" toml:"skip,omitempty,inline" yaml:",omitempty"`
Only interface{} `json:"only,omitempty" mapstructure:"only" toml:"only,omitempty,inline" yaml:",omitempty"`
Tags []string `json:"tags,omitempty" mapstructure:"tags" toml:"tags,omitempty" yaml:",omitempty"`
Env map[string]string `json:"env,omitempty" mapstructure:"env" toml:"env,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"`
Priority int `json:"priority,omitempty" mapstructure:"priority" toml:"priority,omitempty" yaml:",omitempty"`
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"`

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"`
Interactive bool `json:"interactive,omitempty" mapstructure:"interactive" toml:"interactive,omitempty" yaml:",omitempty"`
UseStdin bool `json:"use_stdin,omitempty" mapstructure:"use_stdin" toml:"use_stdin,omitempty" yaml:",omitempty"`
Expand Down
71 changes: 0 additions & 71 deletions internal/lefthook/runner/filter/filters.go

This file was deleted.

Loading

0 comments on commit 9f40122

Please sign in to comment.