5.2 KiB
SteamCMD Install Logging & Buffering Fix Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Improve live feedback during the install operation by adding step markers to SteamInstaller and fixing Python subprocess buffering so output streams immediately.
Architecture: Modifies l4d2host/process.py and l4d2web/services/host_commands.py to add flush=True to print() statements for immediate pipeline throughput. Modifies l4d2host/steam_install.py to use _emit_step to log platform payload downloads.
Tech Stack: Python, subprocess
Task 1: Fix process output buffering
Files:
-
Modify:
l4d2host/process.py -
Modify:
l4d2web/services/host_commands.py -
Step 1: Check existing test suite No failing test is required here because we are only modifying the
flushparameter ofprint()inside existing pass-through functions, which are thoroughly covered by integration tests but unit-testing the buffering ofprintis notoriously flaky across OSes. We will just modify the code and run the existing suite. -
Step 2: Add flush to l4d2host process
Modify emit_stderr_message and pump inside run_command in l4d2host/process.py:
def emit_stderr_message(line: str) -> None:
stderr_lines.append(line)
if on_stderr is not None:
on_stderr(line)
if passthrough:
print(line, file=sys.stderr, flush=True)
# ... inside pump ...
if passthrough:
print(line, file=output_stream, flush=True)
- Step 3: Add flush to l4d2web host_commands
Modify emit_stderr_message and pump inside run_command in l4d2web/services/host_commands.py:
def emit_stderr_message(line: str) -> None:
stderr_lines.append(line)
if on_stderr is not None:
on_stderr(line)
if passthrough:
print(line, file=sys.stderr, flush=True)
# ... inside pump ...
if passthrough:
print(line, file=output_stream, flush=True)
- Step 4: Run test to verify it passes
Run: pytest l4d2host/tests l4d2web/tests -q
Expected: PASS
- Step 5: Commit
git add l4d2host/process.py l4d2web/services/host_commands.py
git commit -m "fix(host): enforce flush=True to prevent pipeline block buffering"
Task 2: Add step logging to SteamInstaller
Files:
-
Modify:
l4d2host/steam_install.py -
Modify:
l4d2host/tests/test_install.py -
Step 1: Write failing test
In l4d2host/tests/test_install.py, add a test to verify SteamInstaller logs steps:
def test_steam_installer_emits_steps(tmp_path: Path, monkeypatch) -> None:
monkeypatch.setenv("LEFT4ME_ROOT", str(tmp_path))
monkeypatch.setattr("l4d2host.steam_install.run_command", lambda cmd, **kwargs: None)
steps: list[str] = []
from l4d2host.steam_install import SteamInstaller
SteamInstaller().install_or_update(on_stdout=steps.append)
assert steps == [
"Step: downloading windows platform payload...",
"Step: downloading linux platform payload...",
"Step: installation complete."
]
- Step 2: Run test to verify it fails
Run: pytest l4d2host/tests/test_install.py -k test_steam_installer_emits_steps -q
Expected: FAIL because steps is empty.
- Step 3: Add step logs to SteamInstaller
In l4d2host/steam_install.py, import _emit_step:
from l4d2host.instances import _emit_step
Modify install_or_update:
def install_or_update(
self,
*,
on_stdout: Callable[[str], None] | None = None,
on_stderr: Callable[[str], None] | None = None,
passthrough: bool = False,
should_cancel: Callable[[], bool] | None = None,
) -> None:
for platform in ("windows", "linux"):
_emit_step(f"downloading {platform} platform payload...", on_stdout, passthrough)
run_command(
[
self.steamcmd,
"+force_install_dir",
str(self.install_dir),
"+login",
"anonymous",
"+@sSteamCmdForcePlatformType",
platform,
"+app_update",
"222860",
"validate",
"+quit",
],
on_stdout=on_stdout,
on_stderr=on_stderr,
passthrough=passthrough,
should_cancel=should_cancel,
)
_emit_step("installation complete.", on_stdout, passthrough)
- Step 4: Run test to verify it passes
Run: pytest l4d2host/tests/test_install.py -k test_steam_installer_emits_steps -q
Expected: PASS
- Step 5: Run full suite
Run: pytest l4d2host/tests l4d2web/tests -q
Expected: PASS
- Step 6: Commit
git add l4d2host/steam_install.py l4d2host/tests/test_install.py
git commit -m "feat(host): add step logging to steam_install"