Skip to content

Commit d01b0c1

Browse files
committed
refactor(core): rendre la selection engine/tools dynamique
1 parent 9124a19 commit d01b0c1

3 files changed

Lines changed: 80 additions & 26 deletions

File tree

Core/Compiler/__init__.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,19 @@
131131
"_continue_compile_all",
132132
]
133133

134+
135+
def _resolve_default_engine_id() -> str:
136+
"""Resolve a default engine dynamically from the registered engines."""
137+
try:
138+
import EngineLoader as engines_loader
139+
140+
engine_ids = list(engines_loader.available_engines())
141+
if engine_ids:
142+
return str(engine_ids[0])
143+
except Exception:
144+
pass
145+
return "engine"
146+
134147
__version__ = "1.0.0"
135148
__author__ = "Ague Samuel Amen"
136149

@@ -327,7 +340,7 @@ def _t(_key: str, fr: str, en: str) -> str:
327340
)
328341

329342
if not engine_id:
330-
engine_id = "pyinstaller" # Moteur par défaut
343+
engine_id = _resolve_default_engine_id()
331344

332345
# Sauvegarder la configuration UI de l'engine actif dans le workspace
333346
try:
@@ -829,7 +842,7 @@ def try_start_processes(self) -> bool:
829842
pass
830843

831844
if not engine_id:
832-
engine_id = "pyinstaller"
845+
engine_id = _resolve_default_engine_id()
833846

834847
# Compiler le premier fichier
835848
return start_compilation_process(self, engine_id, self.python_files[0])

Core/Venv_Manager/Manager.py

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -496,17 +496,22 @@ def has_tool_binary(self, venv_root: str, tool: str) -> bool:
496496
)
497497
if not os.path.isdir(bindir):
498498
return False
499+
raw = str(tool or "").strip()
500+
if not raw:
501+
return False
502+
lower = raw.lower()
503+
variants = {lower}
504+
if "_" in lower:
505+
variants.add(lower.replace("_", "-"))
506+
variants.add(lower.replace("_", ""))
507+
if "-" in lower:
508+
variants.add(lower.replace("-", "_"))
509+
variants.add(lower.replace("-", ""))
510+
variants.add(f"{lower}3")
511+
499512
names: list[str] = []
500-
t = tool.strip().lower()
501-
if t == "pyinstaller":
502-
names = ["pyinstaller", "pyinstaller.exe", "pyinstaller-script.py"]
503-
elif t == "nuitka":
504-
names = ["nuitka", "nuitka3", "nuitka.exe", "nuitka-script.py"]
505-
elif t == "cx_freeze":
506-
names = ["cxfreeze", "cxfreeze.exe", "cxfreeze-script.py"]
507-
else:
508-
# generic: try tool, tool.exe, and tool-script.py
509-
names = [t, f"{t}.exe", f"{t}-script.py"]
513+
for name in sorted(variants):
514+
names.extend([name, f"{name}.exe", f"{name}-script.py"])
510515
for n in names:
511516
p = os.path.join(bindir, n)
512517
if os.path.isfile(p):
@@ -518,6 +523,39 @@ def has_tool_binary(self, venv_root: str, tool: str) -> bool:
518523
except Exception:
519524
return False
520525

526+
def _discover_engine_required_python_tools(self) -> list[str]:
527+
"""Discover python tools required by available engines dynamically."""
528+
tools: list[str] = []
529+
try:
530+
import EngineLoader as engines_loader
531+
532+
for engine_id in list(engines_loader.available_engines()):
533+
try:
534+
engine = engines_loader.create(engine_id)
535+
except Exception:
536+
engine = None
537+
if engine is None:
538+
continue
539+
req = getattr(engine, "required_tools", {"python": [], "system": []})
540+
if not isinstance(req, dict):
541+
continue
542+
for item in req.get("python", []) or []:
543+
name = str(item or "").strip()
544+
if name:
545+
tools.append(name)
546+
except Exception:
547+
pass
548+
549+
unique: list[str] = []
550+
seen: set[str] = set()
551+
for tool in tools:
552+
key = tool.lower()
553+
if key in seen:
554+
continue
555+
seen.add(key)
556+
unique.append(tool)
557+
return unique
558+
521559
def is_tool_installed(self, venv_root: str, tool: str) -> bool:
522560
"""Non-blocking check for tool presence in venv.
523561
Uses has_tool_binary() only (no subprocess run). If uncertain, returns False
@@ -1374,7 +1412,13 @@ def _after_binding(ok_bind: bool):
13741412
"Scripts" if platform.system() == "Windows" else "bin",
13751413
"pip",
13761414
)
1377-
self._venv_check_pkgs = ["pyinstaller", "nuitka", "cx_freeze"]
1415+
self._venv_check_pkgs = self._discover_engine_required_python_tools()
1416+
if not self._venv_check_pkgs:
1417+
self._safe_log(
1418+
"ℹ️ Aucun outil Python requis détecté depuis les engines.",
1419+
"ℹ️ No required Python tools detected from engines.",
1420+
)
1421+
return
13781422
self._venv_check_index = 0
13791423
self._venv_check_pip_exe = pip_exe
13801424
self._venv_check_path = venv_path
@@ -1384,7 +1428,9 @@ def _after_binding(ok_bind: bool):
13841428
self._bind_cancel_for_dialog(
13851429
self.venv_check_progress, "vérification des outils du venv"
13861430
)
1387-
self.venv_check_progress.set_message("Vérification de PyInstaller...")
1431+
self.venv_check_progress.set_message(
1432+
f"Vérification de {self._venv_check_pkgs[0]}..."
1433+
)
13881434
self.venv_check_progress.set_progress(0, len(self._venv_check_pkgs))
13891435
self.venv_check_progress.show()
13901436
self._check_next_venv_pkg()
@@ -1692,8 +1738,7 @@ def _score_venv(self, venv_path: str, workspace_dir: str) -> tuple[int, str]:
16921738
16931739
Scoring criteria:
16941740
- Has requirements.txt satisfied: +100
1695-
- Has pyinstaller: +50
1696-
- Has nuitka: +50
1741+
- Has required engine python tools: +50 each
16971742
- Has pip/setuptools/wheel: +30
16981743
- Is valid venv: +10
16991744
- Has binding verified: +20
@@ -1727,14 +1772,10 @@ def _score_venv(self, venv_path: str, workspace_dir: str) -> tuple[int, str]:
17271772
reasons.append("requirements_unknown")
17281773

17291774
# Check for key tools
1730-
tools_to_check = [
1731-
("pyinstaller", 50),
1732-
("nuitka", 50),
1733-
("cx_freeze", 50),
1734-
]
1735-
for tool, tool_score in tools_to_check:
1775+
tools_to_check = self._discover_engine_required_python_tools()
1776+
for tool in tools_to_check:
17361777
if self.has_tool_binary(venv_path, tool):
1737-
score += tool_score
1778+
score += 50
17381779
reasons.append(f"has_{tool}")
17391780

17401781
# Check for pip/setuptools/wheel
@@ -1940,7 +1981,7 @@ def create_venv_if_needed(self, path: str, prefer_manager: bool = True):
19401981
self._arm_process_timeout(process, 600_000, "venv creation")
19411982
except Exception as e:
19421983
self._safe_log(
1943-
f"❌ Échec de création du venv ou installation de PyInstaller : {e}"
1984+
f"❌ Échec de création du venv ou installation des outils : {e}"
19441985
)
19451986

19461987
def _on_venv_output(self, process, error=False):
@@ -3270,7 +3311,7 @@ def setup_workspace(self, workspace_dir: str, check_tools: bool = True) -> bool:
32703311
32713312
Args:
32723313
workspace_dir: Path to the workspace directory
3273-
check_tools: Whether to check and install tools (pyinstaller, nuitka, cx_freeze)
3314+
check_tools: Whether to check and install tools required by discovered engines
32743315
after venv creation. Defaults to True.
32753316
32763317
Returns:

EngineLoader/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def required_tools(self) -> dict[str, list[str]]:
169169
Return dict of required tools with installation modes.
170170
Keys: 'python' for pip-installable tools, 'system' for system packages.
171171
Used by VenvManager for Python tools and system installer for system tools.
172-
Example: {'python': ['pyinstaller'], 'system': ['build-essential']}
172+
Example: {'python': ['<tool_name>'], 'system': ['<system_package>']}
173173
"""
174174
return {"python": [], "system": []}
175175

0 commit comments

Comments
 (0)