|
13 | 13 | from collections.abc import Iterable |
14 | 14 | from collections.abc import MutableMapping |
15 | 15 | from collections.abc import Sequence |
| 16 | +from pathlib import Path |
16 | 17 | from typing import Any |
17 | 18 |
|
18 | 19 | from identify.identify import tags_from_path |
|
27 | 28 | from pre_commit.repository import install_hook_envs |
28 | 29 | from pre_commit.staged_files_only import staged_files_only |
29 | 30 | from pre_commit.store import Store |
| 31 | +from pre_commit.util import chdir_context |
30 | 32 | from pre_commit.util import cmd_output_b |
31 | 33 |
|
32 | 34 |
|
@@ -61,12 +63,21 @@ def filter_by_include_exclude( |
61 | 63 | names: Iterable[str], |
62 | 64 | include: str, |
63 | 65 | exclude: str, |
| 66 | + workdir: str = '', |
64 | 67 | ) -> Generator[str]: |
65 | 68 | include_re, exclude_re = re.compile(include), re.compile(exclude) |
| 69 | + if not workdir: |
| 70 | + return ( |
| 71 | + filename for filename in names |
| 72 | + if include_re.search(filename) |
| 73 | + if not exclude_re.search(filename) |
| 74 | + ) |
66 | 75 | return ( |
67 | | - filename for filename in names |
68 | | - if include_re.search(filename) |
69 | | - if not exclude_re.search(filename) |
| 76 | + str(filename) |
| 77 | + for filename in map(Path, names) |
| 78 | + if filename.is_relative_to(workdir) and |
| 79 | + include_re.search(str(filename.relative_to(workdir))) and |
| 80 | + not exclude_re.search(str(filename.relative_to(workdir))) |
70 | 81 | ) |
71 | 82 |
|
72 | 83 |
|
@@ -103,6 +114,7 @@ def filenames_for_hook(self, hook: Hook) -> Generator[str]: |
103 | 114 | self.filenames, |
104 | 115 | hook.files, |
105 | 116 | hook.exclude, |
| 117 | + hook.workdir, |
106 | 118 | ), |
107 | 119 | hook.types, |
108 | 120 | hook.types_or, |
@@ -189,7 +201,16 @@ def _run_single_hook( |
189 | 201 | filenames = () |
190 | 202 | time_before = time.monotonic() |
191 | 203 | language = languages[hook.language] |
192 | | - with language.in_env(hook.prefix, hook.language_version): |
| 204 | + with contextlib.ExitStack() as stack: |
| 205 | + stack.enter_context( |
| 206 | + language.in_env(hook.prefix, hook.language_version), |
| 207 | + ) |
| 208 | + if hook.workdir: |
| 209 | + stack.enter_context(chdir_context(hook.workdir)) |
| 210 | + filenames = tuple( |
| 211 | + str(Path(filename).relative_to(hook.workdir)) |
| 212 | + for filename in filenames |
| 213 | + ) |
193 | 214 | retcode, out = language.run_hook( |
194 | 215 | hook.prefix, |
195 | 216 | hook.entry, |
|
0 commit comments