mirror of
https://github.com/pre-commit/pre-commit.git
synced 2026-02-19 00:54:42 +04:00
fix: add ability to provide a file with excludes
This commit is contained in:
parent
14169eb31d
commit
4d485507f3
4 changed files with 35 additions and 2 deletions
|
|
@ -110,6 +110,7 @@ MANIFEST_HOOK_DICT = cfgv.Map(
|
||||||
|
|
||||||
cfgv.Optional('files', check_string_regex, ''),
|
cfgv.Optional('files', check_string_regex, ''),
|
||||||
cfgv.Optional('exclude', check_string_regex, '^$'),
|
cfgv.Optional('exclude', check_string_regex, '^$'),
|
||||||
|
cfgv.Optional('exclude_file_path', check_string_regex, '^$'),
|
||||||
cfgv.Optional('types', cfgv.check_array(check_type_tag), ['file']),
|
cfgv.Optional('types', cfgv.check_array(check_type_tag), ['file']),
|
||||||
cfgv.Optional('types_or', cfgv.check_array(check_type_tag), []),
|
cfgv.Optional('types_or', cfgv.check_array(check_type_tag), []),
|
||||||
cfgv.Optional('exclude_types', cfgv.check_array(check_type_tag), []),
|
cfgv.Optional('exclude_types', cfgv.check_array(check_type_tag), []),
|
||||||
|
|
@ -357,6 +358,7 @@ CONFIG_SCHEMA = cfgv.Map(
|
||||||
StagesMigration('default_stages', STAGES),
|
StagesMigration('default_stages', STAGES),
|
||||||
cfgv.Optional('files', check_string_regex, ''),
|
cfgv.Optional('files', check_string_regex, ''),
|
||||||
cfgv.Optional('exclude', check_string_regex, '^$'),
|
cfgv.Optional('exclude', check_string_regex, '^$'),
|
||||||
|
cfgv.Optional('exclude_file_path', check_string_regex, '^$'),
|
||||||
cfgv.Optional('fail_fast', cfgv.check_bool, False),
|
cfgv.Optional('fail_fast', cfgv.check_bool, False),
|
||||||
cfgv.Optional(
|
cfgv.Optional(
|
||||||
'minimum_pre_commit_version',
|
'minimum_pre_commit_version',
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ def filter_by_include_exclude(
|
||||||
exclude: str,
|
exclude: str,
|
||||||
) -> Generator[str, None, None]:
|
) -> Generator[str, None, None]:
|
||||||
include_re, exclude_re = re.compile(include), re.compile(exclude)
|
include_re, exclude_re = re.compile(include), re.compile(exclude)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
filename for filename in names
|
filename for filename in names
|
||||||
if include_re.search(filename)
|
if include_re.search(filename)
|
||||||
|
|
@ -98,11 +99,23 @@ class Classifier:
|
||||||
yield filename
|
yield filename
|
||||||
|
|
||||||
def filenames_for_hook(self, hook: Hook) -> Generator[str, None, None]:
|
def filenames_for_hook(self, hook: Hook) -> Generator[str, None, None]:
|
||||||
|
exclude = hook.exclude or '$^'
|
||||||
|
file_exclude = ''
|
||||||
|
if hook.exclude_file_path is not None:
|
||||||
|
if os.path.isfile(hook.exclude_file_path):
|
||||||
|
with open(hook.exclude_file_path) as exclude_file:
|
||||||
|
file_exclude = '|'.join(
|
||||||
|
line.strip() for line in exclude_file.readlines()
|
||||||
|
) or '$^'
|
||||||
|
|
||||||
|
if file_exclude:
|
||||||
|
exclude = f'{exclude}|{file_exclude}'
|
||||||
|
|
||||||
return self.by_types(
|
return self.by_types(
|
||||||
filter_by_include_exclude(
|
filter_by_include_exclude(
|
||||||
self.filenames,
|
self.filenames,
|
||||||
hook.files,
|
hook.files,
|
||||||
hook.exclude,
|
exclude,
|
||||||
),
|
),
|
||||||
hook.types,
|
hook.types,
|
||||||
hook.types_or,
|
hook.types_or,
|
||||||
|
|
@ -115,6 +128,7 @@ class Classifier:
|
||||||
filenames: Iterable[str],
|
filenames: Iterable[str],
|
||||||
include: str,
|
include: str,
|
||||||
exclude: str,
|
exclude: str,
|
||||||
|
exclude_file_path: str,
|
||||||
) -> Classifier:
|
) -> Classifier:
|
||||||
# on windows we normalize all filenames to use forward slashes
|
# on windows we normalize all filenames to use forward slashes
|
||||||
# this makes it easier to filter using the `files:` regex
|
# this makes it easier to filter using the `files:` regex
|
||||||
|
|
@ -122,6 +136,15 @@ class Classifier:
|
||||||
# see #1173
|
# see #1173
|
||||||
if os.altsep == '/' and os.sep == '\\':
|
if os.altsep == '/' and os.sep == '\\':
|
||||||
filenames = (f.replace(os.sep, os.altsep) for f in filenames)
|
filenames = (f.replace(os.sep, os.altsep) for f in filenames)
|
||||||
|
file_exclude = ''
|
||||||
|
if exclude_file_path is not None:
|
||||||
|
if os.path.isfile(exclude_file_path):
|
||||||
|
with open(exclude_file_path) as exclude_file:
|
||||||
|
file_exclude = '|'.join(
|
||||||
|
line.strip() for line in exclude_file.readlines()
|
||||||
|
) or '$^'
|
||||||
|
if file_exclude:
|
||||||
|
exclude = f'{exclude}|{file_exclude}'
|
||||||
filenames = filter_by_include_exclude(filenames, include, exclude)
|
filenames = filter_by_include_exclude(filenames, include, exclude)
|
||||||
return Classifier(filenames)
|
return Classifier(filenames)
|
||||||
|
|
||||||
|
|
@ -288,7 +311,7 @@ def _run_hooks(
|
||||||
"""Actually run the hooks."""
|
"""Actually run the hooks."""
|
||||||
cols = _compute_cols(hooks)
|
cols = _compute_cols(hooks)
|
||||||
classifier = Classifier.from_config(
|
classifier = Classifier.from_config(
|
||||||
_all_filenames(args), config['files'], config['exclude'],
|
_all_filenames(args), config['files'], config['exclude'], config['exclude_file_path'],
|
||||||
)
|
)
|
||||||
retval = 0
|
retval = 0
|
||||||
prior_diff = _get_diff()
|
prior_diff = _get_diff()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ class Hook(NamedTuple):
|
||||||
alias: str
|
alias: str
|
||||||
files: str
|
files: str
|
||||||
exclude: str
|
exclude: str
|
||||||
|
exclude_file_path: str
|
||||||
types: Sequence[str]
|
types: Sequence[str]
|
||||||
types_or: Sequence[str]
|
types_or: Sequence[str]
|
||||||
exclude_types: Sequence[str]
|
exclude_types: Sequence[str]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import os
|
||||||
from collections.abc import Sequence
|
from collections.abc import Sequence
|
||||||
|
|
||||||
import pre_commit.constants as C
|
import pre_commit.constants as C
|
||||||
|
|
@ -13,6 +14,12 @@ from pre_commit.store import Store
|
||||||
|
|
||||||
def check_all_hooks_match_files(config_file: str) -> int:
|
def check_all_hooks_match_files(config_file: str) -> int:
|
||||||
config = load_config(config_file)
|
config = load_config(config_file)
|
||||||
|
exclude_file_path = config['exclude_file_path']
|
||||||
|
if exclude_file_path is not None:
|
||||||
|
if os.path.isfile(exclude_file_path):
|
||||||
|
with open(exclude_file_path, 'r') as f:
|
||||||
|
config['exclude'] = f.read().splitlines()
|
||||||
|
|
||||||
classifier = Classifier.from_config(
|
classifier = Classifier.from_config(
|
||||||
git.get_all_files(), config['files'], config['exclude'],
|
git.get_all_files(), config['files'], config['exclude'],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue