Skip to content

Commit f8b6297

Browse files
committed
Refactor should_exclude_file function in ArkConfigManager and WorkspaceAdvancedManipulation
1 parent bab3197 commit f8b6297

2 files changed

Lines changed: 84 additions & 12 deletions

File tree

Core/ArkConfigManager.py

Lines changed: 68 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@
3131
"""
3232

3333
import os
34-
from pathlib import Path
35-
from typing import Any
34+
import fnmatch
35+
from pathlib import Path, PurePosixPath
36+
from typing import Any, Optional
3637
import yaml
3738

3839

@@ -262,15 +263,35 @@ def get_environment_manager_options(config: dict[str, Any]) -> dict[str, Any]:
262263
return config.get("environment_manager", {})
263264

264265

266+
def _normalize_exclusion_pattern(pattern: str) -> str:
267+
"""
268+
Normalise un pattern d'exclusion pour un matching fiable cross-plateforme.
269+
270+
- Convertit les séparateurs Windows en "/"
271+
- Retire le préfixe "./"
272+
- Si le pattern se termine par "/", on l'étend à "/**"
273+
"""
274+
p = str(pattern).strip()
275+
if not p:
276+
return ""
277+
p = p.replace("\\", "/")
278+
if p.startswith("./"):
279+
p = p[2:]
280+
if p.endswith("/"):
281+
p = p.rstrip("/") + "/**"
282+
return p
283+
284+
265285
def should_exclude_file(
266-
file_path: str, workspace_dir: str, exclusion_patterns: list[str]
286+
file_path: str, workspace_dir: str, exclusion_patterns: Optional[list[str]]
267287
) -> bool:
268288
"""
269289
Détermine si un fichier doit être exclu de la compilation.
270290
271291
Cette fonction compare le chemin du fichier avec les patterns
272-
d'exclusion définis dans la configuration. Elle utilise la méthode
273-
Path.match() qui supporte les patterns glob standards.
292+
d'exclusion définis dans la configuration. Elle normalise les
293+
séparateurs puis combine Path.match() et fnmatch pour supporter
294+
les patterns glob avec "**" de façon cross-plateforme.
274295
275296
Args:
276297
file_path: Chemin absolu du fichier à vérifier
@@ -281,23 +302,59 @@ def should_exclude_file(
281302
True si le fichier doit être exclu, False sinon
282303
"""
283304
try:
305+
if not file_path or not workspace_dir:
306+
return False
307+
284308
file_path_obj = Path(file_path)
285309
workspace_path_obj = Path(workspace_dir)
286310

311+
# Résolution pour éviter les surprises (symlinks, chemins relatifs)
312+
try:
313+
file_abs = file_path_obj.resolve()
314+
workspace_abs = workspace_path_obj.resolve()
315+
except Exception:
316+
file_abs = file_path_obj
317+
workspace_abs = workspace_path_obj
318+
287319
# Calcul du chemin relatif par rapport au workspace
288320
try:
289-
relative_path = file_path_obj.relative_to(workspace_path_obj)
321+
relative_path = file_abs.relative_to(workspace_abs)
290322
except ValueError:
291323
# Le fichier est hors du workspace
292324
return True
293325

326+
# Normalisation vers POSIX pour matcher les patterns avec "/"
327+
rel_posix = PurePosixPath(relative_path.as_posix())
328+
abs_posix = PurePosixPath(file_abs.as_posix())
329+
rel_str = rel_posix.as_posix()
330+
abs_str = abs_posix.as_posix()
331+
file_name = file_abs.name
332+
333+
patterns = exclusion_patterns or []
334+
294335
# Vérification des patterns d'exclusion
295-
for pattern in exclusion_patterns:
296-
# Comparaison avec le chemin relatif complet
297-
if relative_path.match(pattern):
298-
return True
336+
for pattern in patterns:
337+
pat = _normalize_exclusion_pattern(pattern)
338+
if not pat:
339+
continue
340+
341+
# Patterns avec "**" : matcher via fnmatch pour supporter les répertoires
342+
if "**" in pat:
343+
if fnmatch.fnmatch(rel_str, pat):
344+
return True
345+
if fnmatch.fnmatch(abs_str, pat):
346+
return True
347+
else:
348+
# Comparaison avec le chemin relatif complet
349+
if rel_posix.match(pat):
350+
return True
351+
352+
# Autoriser les patterns absolus si fournis par l'utilisateur
353+
if abs_posix.match(pat):
354+
return True
355+
299356
# Comparaison avec juste le nom du fichier (pour patterns comme "*.pyc")
300-
if file_path_obj.match(pattern):
357+
if "/" not in pat and PurePosixPath(file_name).match(pat):
301358
return True
302359

303360
return False

Core/WorkSpaceManager/WorkspaceAdvancedManipulation.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from PySide6.QtWidgets import QFileDialog, QMessageBox
2020

2121
from Core.Globals import _workspace_dir_cache, _workspace_dir_lock
22+
from Core.ArkConfigManager import load_ark_config, should_exclude_file
2223

2324

2425
class WorkspaceAdvancedManipulation:
@@ -138,14 +139,17 @@ def handle_drop_event(gui_instance, event: QDropEvent):
138139

139140
urls = event.mimeData().urls()
140141
added = 0
142+
excluded = 0
143+
workspace_dir = getattr(gui_instance, "workspace_dir", None)
144+
ark_config = load_ark_config(workspace_dir) if workspace_dir else {}
145+
exclusion_patterns = ark_config.get("exclusion_patterns", [])
141146

142147
for url in urls:
143148
path = url.toLocalFile()
144149
if os.path.isdir(path):
145150
added += SetupWorkspace.add_py_files_from_folder(gui_instance, path)
146151
elif path.endswith(".py"):
147152
# Vérifie que le fichier est dans workspace (si défini)
148-
workspace_dir = getattr(gui_instance, "workspace_dir", None)
149153
if (
150154
workspace_dir
151155
and not os.path.commonpath([path, workspace_dir]) == workspace_dir
@@ -155,6 +159,12 @@ def handle_drop_event(gui_instance, event: QDropEvent):
155159
f"⚠️ Ignored (outside workspace): {path}",
156160
)
157161
continue
162+
# Vérifie les patterns d'exclusion ARK
163+
if workspace_dir and should_exclude_file(
164+
path, workspace_dir, exclusion_patterns
165+
):
166+
excluded += 1
167+
continue
158168
if path not in gui_instance.python_files:
159169
gui_instance.python_files.append(path)
160170
relative_path = (
@@ -168,6 +178,11 @@ def handle_drop_event(gui_instance, event: QDropEvent):
168178
f"✅ {added} fichier(s) ajouté(s) via drag & drop.",
169179
f"✅ {added} file(s) added via drag & drop.",
170180
)
181+
if excluded > 0:
182+
gui_instance.log_i18n(
183+
f"⏩ Exclusion appliquée : {excluded} fichier(s) ignoré(s) (ARK_Main_Config.yml).",
184+
f"⏩ Exclusion applied: {excluded} file(s) ignored (ARK_Main_Config.yml).",
185+
)
171186

172187
if hasattr(gui_instance, "update_command_preview"):
173188
gui_instance.update_command_preview()

0 commit comments

Comments
 (0)