Skip to content

Commit 674528f

Browse files
committed
Refactor: Consolidation finale de la gestion des dépendances dans VenvManager
- Intégration de SysDependencyManager pour la vérification des outils système. - Utilisation systématique de deps_analyser._find_pip_executable pour la détection de pip et python. - Expansion de la découverte des outils pour inclure les dépendances système des moteurs. - Amélioration de la robustesse de check_tools_in_venv avec un flux orchestré (système puis python). - Nettoyage des tests Qt obsolètes et mise à jour des tests heuristiques pour l'indépendance de PySide6.
1 parent 5928a93 commit 674528f

6 files changed

Lines changed: 53 additions & 385 deletions

File tree

Core/Venv_Manager/Manager.py

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from PySide6.QtCore import QProcess, QTimer
1010

1111
import Core.deps_analyser.analyser as deps_analyser
12+
import Core.SysDependencyManager as sys_deps
1213

1314

1415
class VenvManager:
@@ -45,6 +46,7 @@ def __init__(self, parent_widget):
4546

4647
# For tool check/installation
4748
self._venv_check_pkgs = []
49+
self._venv_check_sys_pkgs = []
4850
self._venv_check_index = 0
4951
self._venv_check_pip_exe = None
5052
self._venv_check_pip_args = []
@@ -199,20 +201,21 @@ def resolve_project_venv(self) -> str | None:
199201
return None
200202

201203
def pip_path(self, venv_root: str) -> str:
202-
"""Execute pip_path logic for this component."""
203-
return os.path.join(
204-
venv_root, "Scripts" if platform.system() == "Windows" else "bin", "pip"
205-
)
204+
"""Get the absolute path to the pip executable using deps_analyser."""
205+
pip_exe, _ = deps_analyser._find_pip_executable(venv_path=venv_root)
206+
return pip_exe
206207

207208
def python_path(self, venv_root: str) -> str:
208-
"""Execute python_path logic for this component."""
209+
"""Get the absolute path to the python executable using deps_analyser."""
210+
pip_exe, pip_args = deps_analyser._find_pip_executable(venv_path=venv_root)
211+
if "-m" in pip_args and "pip" in pip_args:
212+
return pip_exe
213+
# Fallback to internal detection if pip_exe is directly the pip binary
209214
base = os.path.join(
210215
venv_root, "Scripts" if platform.system() == "Windows" else "bin"
211216
)
212217
if platform.system() == "Windows":
213-
cand = os.path.join(base, "python.exe")
214-
return cand
215-
# Linux/macOS: prefer 'python', fallback to 'python3'
218+
return os.path.join(base, "python.exe")
216219
cand1 = os.path.join(base, "python")
217220
cand2 = os.path.join(base, "python3")
218221
return cand1 if os.path.isfile(cand1) else cand2
@@ -271,9 +274,10 @@ def has_tool_binary(self, venv_root: str, tool: str) -> bool:
271274
except Exception:
272275
return False
273276

274-
def _discover_engine_required_python_tools(self) -> list[str]:
275-
"""Discover python tools required by available engines dynamically."""
276-
tools: list[str] = []
277+
def _discover_engine_requirements(self) -> dict[str, list[str]]:
278+
"""Discover tools required by available engines dynamically."""
279+
python_tools: list[str] = []
280+
system_tools: list[str] = []
277281
try:
278282
import Core.engine as engines_loader
279283

@@ -290,19 +294,22 @@ def _discover_engine_required_python_tools(self) -> list[str]:
290294
for item in req.get("python", []) or []:
291295
name = str(item or "").strip()
292296
if name:
293-
tools.append(name)
297+
python_tools.append(name)
298+
for item in req.get("system", []) or []:
299+
name = str(item or "").strip()
300+
if name:
301+
system_tools.append(name)
294302
except Exception:
295303
pass
296304

297-
unique: list[str] = []
298-
seen: set[str] = set()
299-
for tool in tools:
300-
key = tool.lower()
301-
if key in seen:
302-
continue
303-
seen.add(key)
304-
unique.append(tool)
305-
return unique
305+
return {
306+
"python": sorted(set(python_tools), key=str.lower),
307+
"system": sorted(set(system_tools), key=str.lower),
308+
}
309+
310+
def _discover_engine_required_python_tools(self) -> list[str]:
311+
"""Discover python tools required by available engines dynamically (legacy helper)."""
312+
return self._discover_engine_requirements().get("python", [])
306313

307314
def is_tool_installed(self, venv_root: str, tool: str) -> bool:
308315
"""Non-blocking check for tool presence in venv.
@@ -316,7 +323,7 @@ def is_tool_installed_async(self, venv_root: str, tool: str, callback) -> None:
316323
Safe for UI: does not block. On any error, returns False.
317324
"""
318325
try:
319-
pip_exe = self.pip_path(venv_root)
326+
pip_exe, pip_args = deps_analyser._find_pip_executable(venv_path=venv_root)
320327
if not pip_exe or not os.path.isfile(pip_exe):
321328
callback(False)
322329
return
@@ -331,7 +338,7 @@ def _done(code, _status):
331338

332339
proc.finished.connect(_done)
333340
proc.setProgram(pip_exe)
334-
proc.setArguments(["show", tool])
341+
proc.setArguments(pip_args + ["show", tool])
335342
proc.setWorkingDirectory(venv_root)
336343
proc.start()
337344
except Exception:
@@ -705,7 +712,7 @@ def is_tool_installed_system(self, tool: str) -> bool:
705712
"""Check if a tool is installed in system Python via deps_analyser."""
706713
return deps_analyser._check_module_installed(tool)
707714
def check_tools_in_venv(self, venv_path: str):
708-
"""Execute check_tools_in_venv logic for this component."""
715+
"""Check both python and system requirements for the current workspace."""
709716
try:
710717
self._reset_cancel_state()
711718
ok, reason = self.validate_venv_strict(venv_path)
@@ -727,14 +734,33 @@ def _after_binding(ok_bind: bool):
727734
)
728735
return
729736

730-
pip_exe, pip_args = deps_analyser._find_pip_executable(venv_path=venv_path)
731-
self._venv_check_pkgs = self._discover_engine_required_python_tools()
732-
if not self._venv_check_pkgs:
737+
reqs = self._discover_engine_requirements()
738+
python_tools = reqs.get("python", [])
739+
system_tools = reqs.get("system", [])
740+
741+
# 1. Check system tools first (fast, usually non-blocking)
742+
if system_tools:
743+
missing_sys = [t for t in system_tools if not sys_deps.check_system_packages([t])]
744+
if missing_sys:
745+
self._safe_log(
746+
f"[WARNING] Outils systeme manquants : {', '.join(missing_sys)}",
747+
f"[WARNING] Missing system tools: {', '.join(missing_sys)}",
748+
)
749+
# On pourrait proposer l'installation, mais on laisse les engines gérer
750+
# ou on affiche juste l'avertissement.
751+
else:
752+
self._safe_log("[OK] Outils systeme verifies.")
753+
754+
# 2. Proceed with python tools in venv
755+
if not python_tools:
733756
self._safe_log(
734757
"[INFO] Aucun outil Python requis detecte depuis les engines.",
735758
"[INFO] No required Python tools detected from engines.",
736759
)
737760
return
761+
762+
pip_exe, pip_args = deps_analyser._find_pip_executable(venv_path=venv_path)
763+
self._venv_check_pkgs = python_tools
738764
self._venv_check_index = 0
739765
self._venv_check_pip_exe = pip_exe
740766
self._venv_check_pip_args = pip_args

tests/test_deps_analyser_heuristics.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020

2121
import pytest
2222

23-
pytest.importorskip("PySide6")
24-
2523
from Core.deps_analyser.analyser import (
2624
_classify_module_origin,
2725
_collect_workspace_module_roots,

tests/test_theme_coverage.py

Lines changed: 0 additions & 67 deletions
This file was deleted.

tests/test_ui_smoke.py

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)