Skip to content

Commit 139ed57

Browse files
authored
Pass Ignore Patterns to Hooks (#38)
feat: suppoort '--hook:ignore-dir=PATTERN' to ignore files based on their directories feat: suppoort '--hook:ignore-file=PATTERN' to ignore files based on file patterns feat: suppoort '--hook:ignore-pattern=PATTERN' to ignore files based on general (bash-specific) patterns docs: add 'Passing Ignore Patterns To Hooks' section refactor: configure 'vendor' exclusions in a manner equivalent to '--hook:ignore-dir=vendor' ci(shellcheck): treat 'source=' directives as being relative to the script they're in chore(formatting): Normalize leading whitespace to tabs
1 parent 60dd6e1 commit 139ed57

File tree

6 files changed

+350
-19
lines changed

6 files changed

+350
-19
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ repos:
2323
files: \.(sh|bash)$
2424
types: [file]
2525
alias: shck
26-
args: [ '-x', '-e', 'SC2034' ]
26+
args: [ '-x', '-P', 'SCRIPTDIR', '-e', 'SC2034' ]
2727
# shfmt
2828
#
2929
- id: shfmt

README.md

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ You can copy/paste the following snippet into your `.pre-commit-config.yaml` fil
2626
# that Pre-Commit passes into the hook.
2727
# For repo-based hooks, '--' is not needed.
2828
#
29-
# NOTE: You can pass environment variables to hooks using args with the
29+
# NOTE: You can pass environment variables to hooks using args with the
3030
# following format:
3131
#
3232
# --hook:env:NAME=VALUE
@@ -228,6 +228,115 @@ You can pass multiple `--hook:env:` arguments.
228228
229229
The arguments can appear anywhere in the `args:` list.
230230
231+
#### Passing Ignore Patterns To Hooks
232+
233+
You can pass arguments to hooks to specify files / directories to ignore.
234+
235+
##### Ignoring Directories
236+
237+
To specify a directory to ignore, use:
238+
239+
* `--hook:ignore-dir=PATTERN`
240+
241+
**Pattern Syntax**
242+
243+
Here's a table with examples of how the directory ignore patterns work:
244+
245+
| <sub>(see legend below)</sub> | `/foo` | `/foo/bar` | `/foo/*/bar` | `bar` | `bing/bar` | `bing/*/bar` | `foo/*/bang/*/bar` |
246+
|:------------------------------|:------:|:----------:|:------------:|:-----:|:----------:|:------------:|:------------------:|
247+
| `file` | | | | | | | |
248+
| `foo/file` | ✔ | | | | | | |
249+
| `foo/bar/file` | ✔ | ✔ | | ✔ | | | |
250+
| `foo/bing/bar/file` | ✔ | | ✔ | ✔ | ✔ | | |
251+
| `foo/bing/bang/bar/file` | ✔ | | ✔ | ✔ | | ✔ | |
252+
| `foo/bing/bang/baz/bar/file` | ✔ | | ✔ | ✔ | | ✔ | ✔ |
253+
| `bar/file` | | | | ✔ | | | |
254+
| `bing/bar/file` | | | | ✔ | ✔ | | |
255+
| `bing/bang/bar/file` | | | | ✔ | | ✔ | |
256+
257+
<sub>rows = filenames. columns = ignore patterns. ✔ = directory ignored (matched).</sub>
258+
259+
NOTES:
260+
* Only the directory portion of the filename is considered for matching
261+
* File `foo/bar/file` would attempt to match patterns against the directory `foo/bar`
262+
* Patterns with leading slash (`/`) indicate that the pattern is _anchored_ and must match the **beginning** of the directory path
263+
* Pattern `/bar` would match filenames `bar/file` and `bar/bang/file`, but **not** `foo/bar/file`
264+
* Patterns without leading slash (`/`) indicate that the pattern is _floating_ and can match **anywhere** in the directory path
265+
* Pattern `bar` would match **all** filenames `bar/file`, `bar/bang/file` and `foo/bar/file`
266+
* Trailing slashes (`foo/`) are not supported and are ignored
267+
* Explicit Leading and trailing wildcards (`*/foo`, `foo/*`, `*/foo/*`) are not supported
268+
* Recursive directory patterns (`**`) are not supported
269+
270+
##### Ignoring Files
271+
272+
To specify files to ignore, use:
273+
274+
* `--hook:ignore-file=PATTERN`
275+
276+
**Pattern Syntax**
277+
278+
Here's a table with examples of how the file ignore patterns work:
279+
280+
| <sub>(see legend below)</sub> | `file1.txt` | `file?.txt` | `file2.*` | `*.md` | `bar/*.md` | `/bar/*.txt` |
281+
|:------------------------------|:-----------:|:-----------:|:---------:|:------:|:----------:|:------------:|
282+
| `file1.txt` | ✔ | ✔ | | | | |
283+
| `file2.txt` | | ✔ | ✔ | | | |
284+
| `file3.md` | | | | ✔ | | |
285+
| `foo/file1.txt` | ✔ | ✔ | | | | |
286+
| `bar/file1.txt` | ✔ | ✔ | | | | ✔ |
287+
| `bar/file2.md` | | | ✔ | ✔ | ✔ | |
288+
| `foo/bar/file4.txt` | | ✔ | | | | |
289+
| `foo/bar/file5.md` | | | | ✔ | ✔ | |
290+
291+
<sub>rows = filenames. columns = ignore patterns. ✔ = file ignored (matched).</sub>
292+
293+
NOTES:
294+
* Patterns with no slashes (`/`) are only matched against the filename portion of the file path
295+
* Pattern `file.txt` would match filenames `file.txt`, `foo/file.txt`, and `bar/file.txt`
296+
* Patterns with leading slash (`/`) indicate that the pattern is _anchored_ and must match the **full** file path
297+
* Pattern `/bar/file` would match filename `bar/file`, but **not** `foo/bar/file`
298+
* Patterns without leading slash (`/`) indicate that the pattern is _trailing_ and just needs to match the **end** of the file path
299+
* Pattern `bar/file` would match filenames `bar/file` and `foo/bar/file`
300+
* Explicit Leading (`*/foo/file`) are not supported
301+
* Recursive directory patterns (`**`) are not supported
302+
303+
304+
##### Ignore By Pattern
305+
306+
If the directory and file-based convenience options are not enough, you can specify a more complicated (bash-specific) pattern.
307+
308+
To specify these types of patterns to ignore, use:
309+
310+
* `--hook:ignore-pattern=PATTERN`
311+
312+
**Pattern Syntax**
313+
314+
Here's a table with examples of how the general ignore patterns work:
315+
316+
| <sub>(see legend below)</sub> | `file` | `foo/bar/*` | `foo/*/bar/*` | `*/file` | `*/bar/file` | `*/bar/*` | `*/bing/*/bar/*` | `*/b?ng/*/file` |
317+
|:------------------------------|:------:|:-----------:|:-------------:|:--------:|:------------:|:---------:|:----------------:|:---------------:|
318+
| `file` | ✔ | | | | | | | |
319+
| `foo/file` | | | | ✔ | | | | |
320+
| `foo/bar/file` | | ✔ | | ✔ | ✔ | ✔ | | |
321+
| `foo/bing/bar/file` | | | ✔ | ✔ | ✔ | ✔ | | ✔ |
322+
| `foo/bang/bar/file` | | | ✔ | ✔ | ✔ | ✔ | | ✔ |
323+
| `foo/bing/bang/bar/file` | | | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
324+
| `foo/bing/bang/baz/bar/file` | | | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
325+
| `bar/file` | | | | ✔ | | | | |
326+
| `bing/bar/file` | | | | ✔ | ✔ | ✔ | | |
327+
| `bing/bang/bar/file` | | | | ✔ | ✔ | ✔ | | ✔ |
328+
| `.file` | | | | | | | | |
329+
| `.bar/file` | | | | ✔ | | | | |
330+
| `foo/.bang/bar/file` | | | ✔ | ✔ | ✔ | ✔ | | |
331+
332+
<sub>rows = filenames. columns = ignore patterns. ✔ = file ignored (matched).</sub>
333+
334+
NOTES:
335+
* Patterns are matched against the **full** (relative) file path
336+
* Patterns are Bash-specific (although _possibly_ POSIX compliant) and are **not** regular expressions (regex)
337+
* See the Official Bash documentation for [Pattern Matching](https://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching)
338+
* Patterns based on `extglob` setting/syntax are **not** supported
339+
231340
#### Always Run
232341
By default, hooks ONLY run when matching file types (usually `*.go`) are staged.
233342

go-revive.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env bash
22
cmd=(revive)
33
if [ -f "revive.toml" ]; then
4-
cmd+=( "-config=revive.toml" )
4+
cmd+=("-config=revive.toml")
55
fi
6-
ignore_file_pattern_array=( "revive.toml" )
6+
ignore_file_pattern_array=("revive.toml")
77
. "$(dirname "${0}")/lib/cmd-files.bash"

lib/cmd-mod.bash

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export GO111MODULE=on
1212
error_code=0
1313
# Assume parent folder of go.mod is module root folder
1414
#
15+
# TODO Try to reduce the redundancy by generating the dirname's first
1516
for sub in $(find_module_roots "${FILES[@]}" | sort -u); do
1617
pushd "${sub}" > /dev/null || exit 1
1718
if [ "${error_on_output:-}" -eq 1 ]; then

lib/cmd-repo-mod.bash

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@ export GO111MODULE=on
1212
error_code=0
1313
# Assume parent folder of go.mod is module root folder
1414
#
15-
for sub in $(find . -name go.mod -not -path '*/vendor/*' -exec dirname "{}" ';' | sort -u); do
16-
pushd "${sub}" > /dev/null || exit 1
15+
for file in $(find . -name go.mod | sort -u); do
16+
file_dir=$(dirname "${file}")
17+
if is_path_ignored_by_dir_pattern "${file_dir}" || is_path_ignored_by_file_pattern "${file}" || is_path_ignored_by_pattern "${file}"; then
18+
continue
19+
fi
20+
pushd "${file_dir}" > /dev/null || exit 1
1721
if [ "${error_on_output:-}" -eq 1 ]; then
1822
output=$(/usr/bin/env "${ENV_VARS[@]}" "${cmd[@]}" "${OPTIONS[@]}" 2>&1)
1923
if [ -n "${output}" ]; then

0 commit comments

Comments
 (0)