Skip to content

Commit 71d34a7

Browse files
committed
analyse deps: améliore la détection et la fiabilité
1 parent ff8c8fe commit 71d34a7

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

Core/deps_analyser/analyser.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import json
2020
import os
2121
import platform
22+
import configparser
2223
import re
2324
import subprocess
2425
import sys
@@ -166,6 +167,73 @@ def _collect_workspace_module_roots(filtered_files: list[str], workspace_dir: st
166167
ws_root = _normalize_realpath(workspace_dir)
167168
if not ws_root:
168169
return roots
170+
171+
def _sanitize_module_name(name: str) -> str:
172+
if not name:
173+
return ""
174+
token = str(name).strip().replace("-", "_").split(".")[0]
175+
return token if token.isidentifier() else ""
176+
177+
def _add_declared_project_names() -> None:
178+
pyproject_path = os.path.join(ws_root, "pyproject.toml")
179+
if os.path.isfile(pyproject_path):
180+
try:
181+
import tomllib
182+
183+
with open(pyproject_path, "rb") as f:
184+
data = tomllib.load(f)
185+
candidates = []
186+
project = data.get("project", {})
187+
if isinstance(project, dict):
188+
candidates.append(project.get("name", ""))
189+
tool = data.get("tool", {})
190+
if isinstance(tool, dict):
191+
poetry = tool.get("poetry", {})
192+
if isinstance(poetry, dict):
193+
candidates.append(poetry.get("name", ""))
194+
for candidate in candidates:
195+
module_name = _sanitize_module_name(candidate)
196+
if module_name:
197+
roots.add(module_name)
198+
except Exception:
199+
pass
200+
201+
setup_cfg_path = os.path.join(ws_root, "setup.cfg")
202+
if os.path.isfile(setup_cfg_path):
203+
try:
204+
parser = configparser.ConfigParser()
205+
parser.read(setup_cfg_path, encoding="utf-8")
206+
if parser.has_section("metadata"):
207+
module_name = _sanitize_module_name(
208+
parser.get("metadata", "name", fallback="")
209+
)
210+
if module_name:
211+
roots.add(module_name)
212+
except Exception:
213+
pass
214+
215+
def _add_chain_from_init(module_dir: str) -> None:
216+
# Si pkg/subpkg/__init__.py existe, on ajoute pkg comme racine interne.
217+
current_dir = module_dir
218+
top_package_name = ""
219+
while _is_path_under(current_dir, ws_root):
220+
init_py = os.path.join(current_dir, "__init__.py")
221+
if not os.path.isfile(init_py):
222+
break
223+
rel_dir = os.path.relpath(current_dir, ws_root)
224+
parts = [p for p in rel_dir.split(os.sep) if p]
225+
if parts:
226+
if parts[0] in {"src", "lib", "python"} and len(parts) > 1:
227+
top_package_name = parts[1]
228+
else:
229+
top_package_name = parts[0]
230+
parent = os.path.dirname(current_dir)
231+
if parent == current_dir:
232+
break
233+
current_dir = parent
234+
if top_package_name:
235+
roots.add(top_package_name)
236+
169237
for file_path in filtered_files:
170238
norm = _normalize_realpath(file_path)
171239
if not _is_path_under(norm, ws_root):
@@ -181,6 +249,26 @@ def _collect_workspace_module_roots(filtered_files: list[str], workspace_dir: st
181249
roots.add(parts[0])
182250
if len(parts) > 1 and parts[-1] == "__init__":
183251
roots.add(parts[-2])
252+
_add_chain_from_init(os.path.dirname(norm))
253+
254+
# Complément pour les layouts où certains packages ne sont pas dans la sélection.
255+
for layout in ("", "src", "lib", "python"):
256+
base_dir = ws_root if not layout else os.path.join(ws_root, layout)
257+
if not os.path.isdir(base_dir):
258+
continue
259+
try:
260+
for entry in os.listdir(base_dir):
261+
if entry.startswith("."):
262+
continue
263+
entry_path = os.path.join(base_dir, entry)
264+
if not os.path.isdir(entry_path):
265+
continue
266+
if os.path.isfile(os.path.join(entry_path, "__init__.py")) and entry.isidentifier():
267+
roots.add(entry)
268+
except Exception:
269+
pass
270+
271+
_add_declared_project_names()
184272
return roots
185273

186274

0 commit comments

Comments
 (0)