forked from pixee/codemodder-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode_directory.py
More file actions
86 lines (74 loc) · 2.53 KB
/
code_directory.py
File metadata and controls
86 lines (74 loc) · 2.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from typing import Optional, Sequence
import fnmatch
import itertools
from pathlib import Path
DEFAULT_INCLUDED_PATHS = ["**.py", "**/*.py"]
DEFAULT_EXCLUDED_PATHS = [
"**/test/**",
"**/tests/**",
"**/conftest.py",
"**/build/**",
"**/dist/**",
"**/venv/**",
"**/.venv/**",
"**/.tox/**",
"**/.nox/**",
"**/.eggs/**",
"**/.git/**",
"**/.mypy_cache/**",
"**/.pytest_cache/**",
"**/.hypothesis/**",
"**/.coverage*",
]
def file_line_patterns(file_path: str | Path, patterns: Sequence[str]):
"""
Find the lines included or excluded for a given file_path among the patterns
"""
return [
int(result[1])
for pat in patterns
if len(result := pat.split(":")) == 2
and fnmatch.fnmatch(str(file_path), result[0])
]
def filter_files(names: Sequence[str], patterns: Sequence[str], exclude: bool = False):
patterns = (
[x.split(":")[0] for x in (patterns or [])]
if not exclude
# An excluded line should not cause the entire file to be excluded
else [x for x in (patterns or []) if ":" not in x]
)
return itertools.chain(*[fnmatch.filter(names, pattern) for pattern in patterns])
def match_files(
parent_path: str | Path,
exclude_paths: Optional[Sequence[str]] = None,
include_paths: Optional[Sequence[str]] = None,
):
"""
Find pattern-matching files starting at the parent_path, recursively.
If a file matches any exclude pattern, it is not matched. If any include
patterns are passed in, a file must match `*.py` and at least one include patterns.
:param parent_path: str name for starting directory
:param exclude_paths: list of UNIX glob patterns to exclude
:param include_paths: list of UNIX glob patterns to exclude
:return: list of <pathlib.PosixPath> files found within (including recursively) the parent directory
that match the criteria of both exclude and include patterns.
"""
all_files = [str(path) for path in Path(parent_path).rglob("*")]
included_files = set(
filter_files(
all_files,
include_paths if include_paths is not None else DEFAULT_INCLUDED_PATHS,
)
)
excluded_files = set(
filter_files(
all_files,
exclude_paths if exclude_paths is not None else DEFAULT_EXCLUDED_PATHS,
exclude=True,
)
)
return [
path
for p in sorted(list(included_files - excluded_files))
if (path := Path(p)).is_file() and path.suffix == ".py"
]