Skip to content

Commit ba5f1a6

Browse files
Merge pull request #207 from fosslight/dev_exclude_error
Add excluding_files
2 parents bc24827 + 3bd07b3 commit ba5f1a6

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

src/fosslight_util/exclude.py

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

0 commit comments

Comments
 (0)