Skip to content

Commit 6d8eb03

Browse files
Add excluding_files
Signed-off-by: Wonjae Park <[email protected]>
1 parent bc24827 commit 6d8eb03

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

src/fosslight_util/exclude.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
import os
4+
import fnmatch
5+
6+
def excluding_files(patterns: list[str], path_to_scan: str) -> list[str]:
7+
excluded_paths = set()
8+
9+
# Normalize patterns: e.g., 'sample/', 'sample/*' -> 'sample'
10+
# Replace backslash with slash
11+
normalized_patterns = []
12+
for pattern in patterns:
13+
if pattern.endswith('/') or pattern.endswith('/*'):
14+
pattern = pattern.rstrip('/*')
15+
pattern = pattern.replace('\\', '/')
16+
normalized_patterns.append(pattern)
17+
18+
# Traverse directories
19+
for root, dirs, files in os.walk(path_to_scan):
20+
remove_dir_list = []
21+
22+
# (1) Directory matching
23+
for d in dirs:
24+
dir_name = d
25+
dir_path = os.path.relpath(os.path.join(root, d), path_to_scan).replace('\\', '/')
26+
matched = False
27+
28+
for pat in normalized_patterns:
29+
# Match directory name
30+
if fnmatch.fnmatch(dir_name, pat):
31+
matched = True
32+
33+
# Match the full relative path
34+
if not matched:
35+
if fnmatch.fnmatch(dir_path, pat) or fnmatch.fnmatch(dir_path, pat + "/*"):
36+
matched = True
37+
38+
# If matched, exclude all files under this directory and stop checking patterns
39+
if matched:
40+
sub_root_path = os.path.join(root, d)
41+
for sr, _, sf in os.walk(sub_root_path):
42+
for sub_file in sf:
43+
sub_file_path = os.path.relpath(os.path.join(sr, sub_file), path_to_scan)
44+
excluded_paths.add(sub_file_path.replace('\\', '/'))
45+
remove_dir_list.append(d)
46+
break
47+
48+
# (1-2) Prune matched directories from further traversal
49+
for rd in remove_dir_list:
50+
dirs.remove(rd)
51+
52+
# (2) File matching
53+
for f in files:
54+
file_path = os.path.relpath(os.path.join(root, f), path_to_scan).replace('\\', '/')
55+
for pat in normalized_patterns:
56+
if fnmatch.fnmatch(file_path, pat) or fnmatch.fnmatch(file_path, pat + "/*"):
57+
excluded_paths.add(file_path)
58+
break
59+
60+
return sorted(excluded_paths)

0 commit comments

Comments
 (0)