|
|
@@ -2,6 +2,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
import subprocess
|
|
|
|
from collections.abc import Callable
|
|
|
|
from collections.abc import Callable
|
|
|
|
from pathlib import Path
|
|
|
|
from pathlib import Path
|
|
|
@@ -11,11 +12,38 @@ from .paths import repo_dir
|
|
|
|
|
|
|
|
|
|
|
|
LogFn = Callable[[str], None]
|
|
|
|
LogFn = Callable[[str], None]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Directorios habituales de herramientas de línea de comandos (Homebrew, MacPorts…).
|
|
|
|
|
|
|
|
# Una .app de macOS lanzada desde Finder/Dock NO hereda el PATH del shell de login,
|
|
|
|
|
|
|
|
# así que herramientas como cmake, instaladas con Homebrew en /opt/homebrew/bin
|
|
|
|
|
|
|
|
# (Apple Silicon) o /usr/local/bin (Intel), quedan fuera del PATH y `make` no las
|
|
|
|
|
|
|
|
# encuentra. Las añadimos explícitamente. En Linux estos paths no existen y se
|
|
|
|
|
|
|
|
# filtran solos.
|
|
|
|
|
|
|
|
_EXTRA_PATH_DIRS = (
|
|
|
|
|
|
|
|
"/opt/homebrew/bin",
|
|
|
|
|
|
|
|
"/opt/homebrew/sbin",
|
|
|
|
|
|
|
|
"/usr/local/bin",
|
|
|
|
|
|
|
|
"/usr/local/sbin",
|
|
|
|
|
|
|
|
"/opt/local/bin",
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _noop(_: str) -> None:
|
|
|
|
def _noop(_: str) -> None:
|
|
|
|
pass
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _launch_env() -> dict[str, str]:
|
|
|
|
|
|
|
|
"""Entorno para los subprocesos con un PATH que incluye los directorios de
|
|
|
|
|
|
|
|
herramientas habituales aunque la app se lance desde Finder/Dock."""
|
|
|
|
|
|
|
|
env = os.environ.copy()
|
|
|
|
|
|
|
|
parts = env.get("PATH", "").split(os.pathsep)
|
|
|
|
|
|
|
|
parts = [p for p in parts if p]
|
|
|
|
|
|
|
|
for d in _EXTRA_PATH_DIRS:
|
|
|
|
|
|
|
|
if d not in parts and os.path.isdir(d):
|
|
|
|
|
|
|
|
parts.append(d)
|
|
|
|
|
|
|
|
env["PATH"] = os.pathsep.join(parts)
|
|
|
|
|
|
|
|
return env
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _stream(cmd: str, cwd: Path, log: LogFn) -> int:
|
|
|
|
def _stream(cmd: str, cwd: Path, log: LogFn) -> int:
|
|
|
|
"""Ejecuta un comando de shell en cwd, retransmitiendo stdout/err línea a línea."""
|
|
|
|
"""Ejecuta un comando de shell en cwd, retransmitiendo stdout/err línea a línea."""
|
|
|
|
log(f"$ {cmd} (cwd={cwd})")
|
|
|
|
log(f"$ {cmd} (cwd={cwd})")
|
|
|
@@ -27,6 +55,7 @@ def _stream(cmd: str, cwd: Path, log: LogFn) -> int:
|
|
|
|
stderr=subprocess.STDOUT,
|
|
|
|
stderr=subprocess.STDOUT,
|
|
|
|
text=True,
|
|
|
|
text=True,
|
|
|
|
bufsize=1,
|
|
|
|
bufsize=1,
|
|
|
|
|
|
|
|
env=_launch_env(),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
assert proc.stdout is not None
|
|
|
|
assert proc.stdout is not None
|
|
|
|
for line in proc.stdout:
|
|
|
|
for line in proc.stdout:
|
|
|
|