fix: add ability to provide a file with excludes

This commit is contained in:
Cesar Sanchez 2023-11-08 17:08:08 -05:00
parent 14169eb31d
commit 4d485507f3
No known key found for this signature in database
4 changed files with 35 additions and 2 deletions

View file

@ -110,6 +110,7 @@ MANIFEST_HOOK_DICT = cfgv.Map(
cfgv.Optional('files', 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_or', 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),
cfgv.Optional('files', 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(
'minimum_pre_commit_version',

View file

@ -63,6 +63,7 @@ def filter_by_include_exclude(
exclude: str,
) -> Generator[str, None, None]:
include_re, exclude_re = re.compile(include), re.compile(exclude)
return (
filename for filename in names
if include_re.search(filename)
@ -98,11 +99,23 @@ class Classifier:
yield filename
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(
filter_by_include_exclude(
self.filenames,
hook.files,
hook.exclude,
exclude,
),
hook.types,
hook.types_or,
@ -115,6 +128,7 @@ class Classifier:
filenames: Iterable[str],
include: str,
exclude: str,
exclude_file_path: str,
) -> Classifier:
# on windows we normalize all filenames to use forward slashes
# this makes it easier to filter using the `files:` regex
@ -122,6 +136,15 @@ class Classifier:
# see #1173
if os.altsep == '/' and os.sep == '\\':
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)
return Classifier(filenames)
@ -288,7 +311,7 @@ def _run_hooks(
"""Actually run the hooks."""
cols = _compute_cols(hooks)
classifier = Classifier.from_config(
_all_filenames(args), config['files'], config['exclude'],
_all_filenames(args), config['files'], config['exclude'], config['exclude_file_path'],
)
retval = 0
prior_diff = _get_diff()

View file

@ -20,6 +20,7 @@ class Hook(NamedTuple):
alias: str
files: str
exclude: str
exclude_file_path: str
types: Sequence[str]
types_or: Sequence[str]
exclude_types: Sequence[str]

View file

@ -1,6 +1,7 @@
from __future__ import annotations
import argparse
import os
from collections.abc import Sequence
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:
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(
git.get_all_files(), config['files'], config['exclude'],
)