Llançador inicial amb GUI PySide6: descàrrega i execució de jocs
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"""Compilar y ejecutar un juego vía subprocess."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
|
||||
from .config import Game
|
||||
from .paths import repo_dir
|
||||
|
||||
LogFn = Callable[[str], None]
|
||||
|
||||
|
||||
def _noop(_: str) -> None:
|
||||
pass
|
||||
|
||||
|
||||
def _stream(cmd: str, cwd: Path, log: LogFn) -> int:
|
||||
"""Ejecuta un comando de shell en cwd, retransmitiendo stdout/err línea a línea."""
|
||||
log(f"$ {cmd} (cwd={cwd})")
|
||||
proc = subprocess.Popen(
|
||||
cmd,
|
||||
cwd=str(cwd),
|
||||
shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
bufsize=1,
|
||||
)
|
||||
assert proc.stdout is not None
|
||||
for line in proc.stdout:
|
||||
log(line.rstrip())
|
||||
return proc.wait()
|
||||
|
||||
|
||||
def run_game(root: Path, game: Game, log: LogFn = _noop) -> int:
|
||||
"""Compila (si hay build_cmd) y ejecuta el juego. Devuelve el código de salida.
|
||||
|
||||
Si build_cmd falla, aborta sin ejecutar. Lanza FileNotFoundError si el repo
|
||||
no está clonado.
|
||||
"""
|
||||
repo = repo_dir(root, game.id)
|
||||
if not (repo / ".git").exists():
|
||||
raise FileNotFoundError(
|
||||
f"{game.name} no está descargado. Pulsa Download primero."
|
||||
)
|
||||
|
||||
if game.build_cmd.strip():
|
||||
log(f"Compilando {game.name}…")
|
||||
code = _stream(game.build_cmd, repo, log)
|
||||
if code != 0:
|
||||
log(f"Compilación falló (código {code}). No se ejecuta.")
|
||||
return code
|
||||
|
||||
log(f"Ejecutando {game.name}…")
|
||||
return _stream(game.run_cmd, repo, log)
|
||||
Reference in New Issue
Block a user