Skip to content
This repository was archived by the owner on Apr 22, 2026. It is now read-only.

Commit 462f6ed

Browse files
committed
fix: resolve ruff lint errors in TUI modules
1 parent 9cfbc29 commit 462f6ed

4 files changed

Lines changed: 28 additions & 20 deletions

File tree

fuzzforge-cli/src/fuzzforge_cli/tui/app.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,14 @@ class SingleClickDataTable(DataTable):
4646
class RowClicked(Message):
4747
"""Fired on every single mouse click on a data row."""
4848

49-
def __init__(self, data_table: "SingleClickDataTable", cursor_row: int) -> None:
49+
def __init__(self, data_table: SingleClickDataTable, cursor_row: int) -> None:
5050
self.data_table = data_table
5151
self.cursor_row = cursor_row
5252
super().__init__()
5353

5454
@property
55-
def control(self) -> "SingleClickDataTable":
55+
def control(self) -> SingleClickDataTable:
56+
"""Return the data table that fired this event."""
5657
return self.data_table
5758

5859
async def _on_click(self, event: events.Click) -> None: # type: ignore[override]
@@ -471,7 +472,6 @@ def _on_build_confirmed(self, confirmed: bool, server_name: str, image: str, hub
471472
@work(thread=True)
472473
def _run_build(self, server_name: str, image: str, hub_name: str) -> None:
473474
"""Build a Docker/Podman image in a background thread."""
474-
import subprocess
475475
from fuzzforge_cli.tui.helpers import build_image, find_dockerfile_for_server
476476

477477
logs = self._build_logs.setdefault(image, [])
@@ -481,7 +481,7 @@ def _run_build(self, server_name: str, image: str, hub_name: str) -> None:
481481
logs.append(f"ERROR: Dockerfile not found for '{server_name}' in hub '{hub_name}'")
482482
self._build_results[image] = False
483483
self._active_builds.pop(image, None)
484-
self.call_from_thread(self._on_build_done, image, False)
484+
self.call_from_thread(self._on_build_done, image, success=False)
485485
return
486486

487487
logs.append(f"Building {image} from {dockerfile.parent}")
@@ -493,24 +493,25 @@ def _run_build(self, server_name: str, image: str, hub_name: str) -> None:
493493
logs.append(f"ERROR: {exc}")
494494
self._build_results[image] = False
495495
self._active_builds.pop(image, None)
496-
self.call_from_thread(self._on_build_done, image, False)
496+
self.call_from_thread(self._on_build_done, image, success=False)
497497
return
498498

499499
self._active_builds[image] = proc # replace pending marker with actual process
500500
self.call_from_thread(self._refresh_hub) # show ⏳ in table
501501

502-
assert proc.stdout is not None
502+
if proc.stdout is None:
503+
return
503504
for line in proc.stdout:
504505
logs.append(line.rstrip())
505506

506507
proc.wait()
507508
self._active_builds.pop(image, None)
508509
success = proc.returncode == 0
509510
self._build_results[image] = success
510-
self.call_from_thread(self._on_build_done, image, success)
511+
self.call_from_thread(self._on_build_done, image, success=success)
511512

512-
def _on_build_done(self, image: str, success: bool) -> None:
513-
"""Called on the main thread when a background build finishes."""
513+
def _on_build_done(self, image: str, *, success: bool) -> None:
514+
"""Handle completion of a background build on the main thread."""
514515
self._refresh_hub()
515516
if success:
516517
self.notify(f"✓ {image} built successfully", severity="information")

fuzzforge-cli/src/fuzzforge_cli/tui/helpers.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
from __future__ import annotations
1010

11+
import contextlib
1112
import json
1213
import os
1314
import subprocess
@@ -301,9 +302,10 @@ def _discover_hub_dirs() -> list[Path]:
301302
candidates: list[Path] = []
302303
for base in (get_fuzzforge_user_dir() / "hubs", get_fuzzforge_dir() / "hubs"):
303304
if base.is_dir():
304-
for entry in base.iterdir():
305-
if entry.is_dir() and (entry / ".git").is_dir():
306-
candidates.append(entry)
305+
candidates.extend(
306+
entry for entry in base.iterdir()
307+
if entry.is_dir() and (entry / ".git").is_dir()
308+
)
307309
return candidates
308310

309311

@@ -356,10 +358,8 @@ def load_hubs_registry() -> dict[str, Any]:
356358

357359
registry: dict[str, Any] = {"hubs": hubs}
358360
# Persist so we don't re-scan on every load
359-
try:
361+
with contextlib.suppress(OSError):
360362
save_hubs_registry(registry)
361-
except OSError:
362-
pass
363363
return registry
364364

365365

fuzzforge-cli/src/fuzzforge_cli/tui/screens/build_image.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def __init__(self, server_name: str, image: str, hub_name: str) -> None:
3030
self._hub_name = hub_name
3131

3232
def compose(self) -> ComposeResult:
33+
"""Build the confirmation dialog UI."""
3334
with Vertical(id="build-dialog"):
3435
yield Label(f"Build {self._image}", classes="dialog-title")
3536
yield Label(
@@ -38,18 +39,20 @@ def compose(self) -> ComposeResult:
3839
)
3940
yield Label(
4041
"The image will be built in the background.\n"
41-
"You\'ll receive a notification when it\'s done.",
42+
"You'll receive a notification when it's done.",
4243
id="confirm-text",
4344
)
4445
with Horizontal(classes="dialog-buttons"):
4546
yield _NoFocusButton("Build", variant="primary", id="btn-build")
4647
yield _NoFocusButton("Cancel", variant="default", id="btn-cancel")
4748

4849
def on_button_pressed(self, event: Button.Pressed) -> None:
50+
"""Handle Build or Cancel button clicks."""
4951
if event.button.id == "btn-build":
50-
self.dismiss(True)
52+
self.dismiss(result=True)
5153
elif event.button.id == "btn-cancel":
52-
self.dismiss(False)
54+
self.dismiss(result=False)
5355

5456
def action_cancel(self) -> None:
55-
self.dismiss(False)
57+
"""Dismiss the dialog when Escape is pressed."""
58+
self.dismiss(result=False)

fuzzforge-cli/src/fuzzforge_cli/tui/screens/build_log.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def __init__(self, image: str) -> None:
2929
self._last_line: int = 0
3030

3131
def compose(self) -> ComposeResult:
32+
"""Build the log viewer UI."""
3233
with Vertical(id="build-dialog"):
3334
yield Label(f"Build log — {self._image}", classes="dialog-title")
3435
yield Label("", id="build-status")
@@ -37,6 +38,7 @@ def compose(self) -> ComposeResult:
3738
yield _NoFocusButton("Close", variant="default", id="btn-close")
3839

3940
def on_mount(self) -> None:
41+
"""Initialize log polling when the screen is mounted."""
4042
self._flush_log()
4143
self.set_interval(0.5, self._poll_log)
4244

@@ -63,12 +65,14 @@ def _flush_log(self) -> None:
6365
status.update(f"[red]✗ {self._image} build failed[/red]")
6466

6567
def _poll_log(self) -> None:
66-
"""Called every 500 ms by set_interval."""
68+
"""Poll for new log lines periodically."""
6769
self._flush_log()
6870

6971
def on_button_pressed(self, event: Button.Pressed) -> None:
72+
"""Handle Close button click."""
7073
if event.button.id == "btn-close":
7174
self.dismiss(None)
7275

7376
def action_close(self) -> None:
77+
"""Dismiss the dialog when Escape is pressed."""
7478
self.dismiss(None)

0 commit comments

Comments
 (0)