Skip to content

Commit 35faecc

Browse files
committed
feat(core): migration de la gestion des preferences venv vers VenvManager
- Deplace la logique de lecture/ecriture des preferences de venv (.ark/pref.json) de l'UI vers le Core. - Permet a l'executeur de compilation (engine_runner.py) de respecter le venv configure dans le workspace. - Simplifie VenvDialog.py en deleguant la persistance a la classe de base et en utilisant des callbacks.
1 parent e6e0aa3 commit 35faecc

3 files changed

Lines changed: 133 additions & 121 deletions

File tree

Core/Compiler/engine_runner.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,12 @@ def venv_manager(self):
277277
from Core.Venv_Manager.Manager import VenvManager
278278

279279
self._venv_manager = VenvManager(self)
280+
# Automatically load workspace preferences if available
281+
if hasattr(self, "workspace_dir") and self.workspace_dir:
282+
try:
283+
self._venv_manager.apply_workspace_pref(self.workspace_dir)
284+
except Exception:
285+
pass
280286
return self._venv_manager
281287

282288
@property

Core/Venv_Manager/Manager.py

Lines changed: 106 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,115 @@ def tr(self, fr: str, en: str) -> str:
108108
return str(res)
109109
return en
110110

111-
# ---------- Workspace pref stubs (Overridden in VenvManagerUI) ----------
111+
# ---------- Workspace pref management ----------
112+
def _workspace_pref_path(self, workspace_dir: str) -> str:
113+
"""Return the resolved workspace path information."""
114+
return os.path.join(os.path.abspath(workspace_dir), ".ark", "pref.json")
115+
116+
def _read_workspace_pref(self, workspace_dir: str) -> dict | None:
117+
"""Execute _read_workspace_pref logic for this component."""
118+
try:
119+
path = self._workspace_pref_path(workspace_dir)
120+
if not os.path.isfile(path):
121+
return None
122+
with open(path, encoding="utf-8") as f:
123+
import json
124+
125+
data = json.load(f)
126+
return data if isinstance(data, dict) else None
127+
except Exception:
128+
return None
129+
130+
def _write_workspace_pref(self, workspace_dir: str, data: dict) -> None:
131+
"""Execute _write_workspace_pref logic for this component."""
132+
try:
133+
path = self._workspace_pref_path(workspace_dir)
134+
os.makedirs(os.path.dirname(path), exist_ok=True)
135+
tmp = path + ".tmp"
136+
import json
137+
138+
with open(tmp, "w", encoding="utf-8") as f:
139+
json.dump(data, f, indent=2)
140+
os.replace(tmp, path)
141+
except Exception:
142+
pass
143+
112144
def apply_workspace_pref(self, workspace_dir: str) -> bool:
113-
"""Stub for applying workspace preferences. Overridden in UI layer."""
114-
return False
145+
"""Apply saved venv/system selection from .ark/pref.json if available."""
146+
try:
147+
data = self._read_workspace_pref(workspace_dir)
148+
if not data:
149+
return False
150+
mode = str(data.get("venv_mode", "")).strip().lower()
151+
venv_path = data.get("venv_path")
152+
153+
applied = False
154+
if mode == "system":
155+
try:
156+
setattr(self.parent, "use_system_python", True)
157+
applied = True
158+
except Exception:
159+
pass
160+
try:
161+
self.parent.venv_path_manuel = None
162+
except Exception:
163+
pass
164+
elif mode == "venv" and isinstance(venv_path, str) and venv_path:
165+
venv_path = os.path.abspath(venv_path)
166+
ok, _ = self.validate_venv_strict(venv_path)
167+
if ok:
168+
try:
169+
setattr(self.parent, "use_system_python", False)
170+
applied = True
171+
except Exception:
172+
pass
173+
try:
174+
self.parent.venv_path_manuel = venv_path
175+
except Exception:
176+
pass
177+
else:
178+
self._clear_workspace_pref(workspace_dir)
179+
180+
if applied:
181+
self._call_ui("on_pref_applied", mode, venv_path)
182+
return True
183+
return False
184+
except Exception:
185+
return False
115186

116187
def save_workspace_pref(self, workspace_dir: str | None) -> None:
117-
"""Stub for saving workspace preferences. Overridden in UI layer."""
118-
pass
188+
"""Persist current venv/system selection for a workspace."""
189+
if not workspace_dir:
190+
return
191+
try:
192+
if getattr(self.parent, "use_system_python", False):
193+
self._write_workspace_pref(
194+
workspace_dir,
195+
{"venv_mode": "system", "venv_path": None},
196+
)
197+
return
198+
venv_path = getattr(self.parent, "venv_path_manuel", None)
199+
if not venv_path and hasattr(self.parent, "venv_path"):
200+
venv_path = getattr(self.parent, "venv_path", None)
201+
202+
if venv_path:
203+
self._write_workspace_pref(
204+
workspace_dir,
205+
{"venv_mode": "venv", "venv_path": os.path.abspath(venv_path)},
206+
)
207+
return
208+
except Exception:
209+
pass
210+
self._clear_workspace_pref(workspace_dir)
211+
212+
def _clear_workspace_pref(self, workspace_dir: str) -> None:
213+
"""Clear the related cached state or UI values."""
214+
try:
215+
path = self._workspace_pref_path(workspace_dir)
216+
if os.path.isfile(path):
217+
os.remove(path)
218+
except Exception:
219+
pass
119220

120221
# ---------- Public helpers for engines ----------
121222
def resolve_existing_venv(self, workspace_dir: str | None = None) -> str | None:

Ui/Gui/Dialogs/VenvDialog.py

Lines changed: 21 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def __init__(self, parent_widget):
5252
"tr": self._ui_tr,
5353
"log": self._ui_log,
5454
"log_i18n": self._ui_log_i18n,
55+
"on_pref_applied": self._on_pref_applied,
5556
"update_venv_label": self._update_venv_label,
5657
"update_venv_path_edit": self._update_venv_path_edit,
5758
"ask_recreate_invalid_venv": self._ask_recreate_invalid_venv,
@@ -97,6 +98,25 @@ def _ui_log_i18n(self, level: str, text_fr: str, text_en: str) -> None:
9798
except Exception:
9899
pass
99100

101+
def _on_pref_applied(self, mode: str, venv_path: str | None) -> None:
102+
"""Handle UI updates when a preference is applied from Core."""
103+
if mode == "system":
104+
try:
105+
if hasattr(self.parent, "venv_path"):
106+
setattr(self.parent, "venv_path", None)
107+
except Exception:
108+
pass
109+
self._update_venv_label(self._pref_label_system())
110+
self._update_venv_path_edit(self._pref_label_system())
111+
elif mode == "venv" and venv_path:
112+
try:
113+
if hasattr(self.parent, "venv_path"):
114+
setattr(self.parent, "venv_path", venv_path)
115+
except Exception:
116+
pass
117+
self._update_venv_label(f"Venv sélectionné : {venv_path}")
118+
self._update_venv_path_edit(venv_path)
119+
100120
def _update_venv_label(self, text: str) -> None:
101121
"""Set the venv label on the parent widget if it exists."""
102122
try:
@@ -344,50 +364,9 @@ def _t(fr: str, en: str) -> str:
344364
pass
345365

346366
# ------------------------------------------------------------------
347-
# Workspace preference management (Moved from VenvManager)
367+
# Workspace preference management (Delegated to Core)
348368
# ------------------------------------------------------------------
349369

350-
def _workspace_pref_path(self, workspace_dir: str) -> str:
351-
"""Return the resolved workspace path information."""
352-
return os.path.join(os.path.abspath(workspace_dir), ".ark", "pref.json")
353-
354-
def _read_workspace_pref(self, workspace_dir: str) -> dict | None:
355-
"""Execute _read_workspace_pref logic for this component."""
356-
try:
357-
path = self._workspace_pref_path(workspace_dir)
358-
if not os.path.isfile(path):
359-
return None
360-
with open(path, encoding="utf-8") as f:
361-
import json
362-
363-
data = json.load(f)
364-
return data if isinstance(data, dict) else None
365-
except Exception:
366-
return None
367-
368-
def _write_workspace_pref(self, workspace_dir: str, data: dict) -> None:
369-
"""Execute _write_workspace_pref logic for this component."""
370-
try:
371-
path = self._workspace_pref_path(workspace_dir)
372-
os.makedirs(os.path.dirname(path), exist_ok=True)
373-
tmp = path + ".tmp"
374-
import json
375-
376-
with open(tmp, "w", encoding="utf-8") as f:
377-
json.dump(data, f, indent=2)
378-
os.replace(tmp, path)
379-
except Exception:
380-
pass
381-
382-
def _clear_workspace_pref(self, workspace_dir: str) -> None:
383-
"""Clear the related cached state or UI values."""
384-
try:
385-
path = self._workspace_pref_path(workspace_dir)
386-
if os.path.isfile(path):
387-
os.remove(path)
388-
except Exception:
389-
pass
390-
391370
def _pref_label_system(self) -> str:
392371
"""Execute _pref_label_system logic for this component."""
393372
return self.tr(
@@ -399,80 +378,6 @@ def _pref_label_none(self) -> str:
399378
"""Execute _pref_label_none logic for this component."""
400379
return self.tr("Venv sélectionné : Aucun", "Venv selected: None")
401380

402-
def apply_workspace_pref(self, workspace_dir: str) -> bool:
403-
"""Apply saved venv/system selection from .ark/pref.json if available."""
404-
try:
405-
data = self._read_workspace_pref(workspace_dir)
406-
if not data:
407-
return False
408-
mode = str(data.get("venv_mode", "")).strip().lower()
409-
venv_path = data.get("venv_path")
410-
if mode == "system":
411-
try:
412-
setattr(self.parent, "use_system_python", True)
413-
except Exception:
414-
pass
415-
try:
416-
self.parent.venv_path_manuel = None
417-
except Exception:
418-
pass
419-
try:
420-
if hasattr(self.parent, "venv_path"):
421-
setattr(self.parent, "venv_path", None)
422-
except Exception:
423-
pass
424-
self._update_venv_label(self._pref_label_system())
425-
self._update_venv_path_edit(self._pref_label_system())
426-
return True
427-
if mode == "venv" and isinstance(venv_path, str) and venv_path:
428-
venv_path = os.path.abspath(venv_path)
429-
ok, _ = self.validate_venv_strict(venv_path)
430-
if ok:
431-
try:
432-
setattr(self.parent, "use_system_python", False)
433-
except Exception:
434-
pass
435-
try:
436-
self.parent.venv_path_manuel = venv_path
437-
except Exception:
438-
pass
439-
try:
440-
if hasattr(self.parent, "venv_path"):
441-
setattr(self.parent, "venv_path", venv_path)
442-
except Exception:
443-
pass
444-
self._update_venv_label(f"Venv sélectionné : {venv_path}")
445-
self._update_venv_path_edit(venv_path)
446-
return True
447-
self._clear_workspace_pref(workspace_dir)
448-
return False
449-
except Exception:
450-
return False
451-
452-
def save_workspace_pref(self, workspace_dir: str | None) -> None:
453-
"""Persist current venv/system selection for a workspace."""
454-
if not workspace_dir:
455-
return
456-
try:
457-
if getattr(self.parent, "use_system_python", False):
458-
self._write_workspace_pref(
459-
workspace_dir,
460-
{"venv_mode": "system", "venv_path": None},
461-
)
462-
return
463-
venv_path = getattr(self.parent, "venv_path_manuel", None)
464-
if not venv_path:
465-
venv_path = getattr(self.parent, "venv_path", None)
466-
if venv_path:
467-
self._write_workspace_pref(
468-
workspace_dir,
469-
{"venv_mode": "venv", "venv_path": os.path.abspath(venv_path)},
470-
)
471-
return
472-
except Exception:
473-
pass
474-
self._clear_workspace_pref(workspace_dir)
475-
476381
def _apply_system_python(self) -> None:
477382
"""Apply system Python selection and update UI."""
478383
try:

0 commit comments

Comments
 (0)