3333from pathlib import Path
3434from typing import Any , Callable , Optional
3535
36- from Core .process_security import hardened_popen_kwargs , secure_command
37-
3836# BuildContext lives in engine_sdk; imported here so callers of this module
3937# only need to import from Core.Compiler.
4038from Core .engine .build_context import BuildContext
39+ from Core .process_security import hardened_popen_kwargs , secure_command
4140
4241
4342class EngineRunnerError (RuntimeError ):
@@ -66,11 +65,10 @@ def resolve_engine_command(
6665 """
6766 try :
6867 import Core .engine as engines_loader
68+
6969 engine = engines_loader .create (engine_id )
7070 except Exception as exc :
71- raise EngineRunnerError (
72- f"Unable to load engine '{ engine_id } ': { exc } "
73- ) from exc
71+ raise EngineRunnerError (f"Unable to load engine '{ engine_id } ': { exc } " ) from exc
7472
7573 try :
7674 setattr (engine , "_config_overrides" , dict (engine_config or {}))
@@ -92,7 +90,7 @@ def resolve_engine_command(
9290 raise EngineRunnerError (f"Engine '{ engine_id } ' returned no command" )
9391
9492 program , args = resolved
95-
93+
9694 # Retrieve engine-specific environment
9795 try :
9896 env = engine .environment () if hasattr (engine , "environment" ) else {}
@@ -148,10 +146,10 @@ def _on_stderr(line: str):
148146
149147 result ["stdout" ] = "\n " .join (captured_stdout )
150148 result ["stderr" ] = "\n " .join (captured_stderr )
151-
149+
152150 if not result ["success" ] and not result .get ("error" ):
153151 result ["error" ] = result ["stderr" ].strip () or "Build failed"
154-
152+
155153 return result
156154
157155
@@ -188,11 +186,14 @@ def run_engine_compile_streaming(
188186 # ── 2. Resolve (program, args, env) from engine ──────────────────────────
189187 try :
190188 if on_stdout :
191- on_stdout ("🔨 Étape 1/3 : Vérification et installation des outils requis..." )
192-
189+ on_stdout (
190+ "🔨 Étape 1/3 : Vérification et installation des outils requis..."
191+ )
192+
193193 import Core .engine as engines_loader
194+
194195 engine_instance = engines_loader .create (engine_id )
195-
196+
196197 # Ensure tools are installed (this may take time, so we do it in the thread)
197198 def _log (fr , en ):
198199 if on_stdout :
@@ -202,21 +203,29 @@ def _log(fr, en):
202203 class LogBridge :
203204 def __init__ (self , log_cb ):
204205 self .log_cb = log_cb
205- def tr (self , fr , en ): return en # Simple fallback
206+
207+ def tr (self , fr , en ):
208+ return en # Simple fallback
206209
207210 if hasattr (engine_instance , "ensure_tools_installed" ):
208- if not engine_instance .ensure_tools_installed (LogBridge (_log ), stop_signal = stop_signal ):
211+ if not engine_instance .ensure_tools_installed (
212+ LogBridge (_log ), stop_signal = stop_signal
213+ ):
209214 if stop_signal and stop_signal ():
210215 return _failure ("Compilation annulée par l'utilisateur." )
211- return _failure (f"Échec de l'installation des outils pour '{ engine_id } '" )
216+ return _failure (
217+ f"Échec de l'installation des outils pour '{ engine_id } '"
218+ )
212219
213220 if stop_signal and stop_signal ():
214221 return _failure ("Compilation annulée." )
215222
216223 if on_stdout :
217224 on_stdout ("⚙️ Étape 2/3 : Génération de la commande de compilation..." )
218225
219- program , args , engine_env = resolve_engine_command (engine_id , context , engine_config )
226+ program , args , engine_env = resolve_engine_command (
227+ engine_id , context , engine_config
228+ )
220229 except EngineRunnerError as exc :
221230 return _failure (str (exc ))
222231 except Exception as exc :
@@ -235,7 +244,7 @@ def tr(self, fr, en): return en # Simple fallback
235244
236245 # ── 4. Run with streaming ────────────────────────────────────────────────
237246 command = [safe_program ] + safe_args
238-
247+
239248 if on_stdout :
240249 on_stdout (f"🚀 Étape 3/3 : Exécution du processus de compilation..." )
241250 on_stdout (f" 💻 Commande : { ' ' .join (command )} " )
@@ -267,16 +276,21 @@ def _read_stream(stream, callback):
267276 callback (line .rstrip ())
268277 stream .close ()
269278
270- stdout_thread = threading .Thread (target = _read_stream , args = (process .stdout , on_stdout ))
271- stderr_thread = threading .Thread (target = _read_stream , args = (process .stderr , on_stderr ))
272-
279+ stdout_thread = threading .Thread (
280+ target = _read_stream , args = (process .stdout , on_stdout )
281+ )
282+ stderr_thread = threading .Thread (
283+ target = _read_stream , args = (process .stderr , on_stderr )
284+ )
285+
273286 stdout_thread .start ()
274287 stderr_thread .start ()
275288
276289 try :
277290 while process .poll () is None :
278291 if stop_signal and stop_signal ():
279292 from Core .Compiler .process_killer import kill_process_tree
293+
280294 kill_process_tree (process .pid )
281295 break
282296 time .sleep (0.05 )
@@ -293,9 +307,9 @@ def _read_stream(stream, callback):
293307 }
294308
295309
296-
297310# ── helpers ──────────────────────────────────────────────────────────────────
298311
312+
299313def _failure (error : str ) -> dict [str , Any ]:
300314 return {
301315 "success" : False ,
0 commit comments