mirror of
https://github.com/FuzzingLabs/fuzzforge_ai.git
synced 2026-03-13 13:57:36 +00:00
fix: resolve ruff lint errors in TUI modules
This commit is contained in:
@@ -46,13 +46,14 @@ class SingleClickDataTable(DataTable):
|
||||
class RowClicked(Message):
|
||||
"""Fired on every single mouse click on a data row."""
|
||||
|
||||
def __init__(self, data_table: "SingleClickDataTable", cursor_row: int) -> None:
|
||||
def __init__(self, data_table: SingleClickDataTable, cursor_row: int) -> None:
|
||||
self.data_table = data_table
|
||||
self.cursor_row = cursor_row
|
||||
super().__init__()
|
||||
|
||||
@property
|
||||
def control(self) -> "SingleClickDataTable":
|
||||
def control(self) -> SingleClickDataTable:
|
||||
"""Return the data table that fired this event."""
|
||||
return self.data_table
|
||||
|
||||
async def _on_click(self, event: events.Click) -> None: # type: ignore[override]
|
||||
@@ -471,7 +472,6 @@ class FuzzForgeApp(App[None]):
|
||||
@work(thread=True)
|
||||
def _run_build(self, server_name: str, image: str, hub_name: str) -> None:
|
||||
"""Build a Docker/Podman image in a background thread."""
|
||||
import subprocess
|
||||
from fuzzforge_cli.tui.helpers import build_image, find_dockerfile_for_server
|
||||
|
||||
logs = self._build_logs.setdefault(image, [])
|
||||
@@ -481,7 +481,7 @@ class FuzzForgeApp(App[None]):
|
||||
logs.append(f"ERROR: Dockerfile not found for '{server_name}' in hub '{hub_name}'")
|
||||
self._build_results[image] = False
|
||||
self._active_builds.pop(image, None)
|
||||
self.call_from_thread(self._on_build_done, image, False)
|
||||
self.call_from_thread(self._on_build_done, image, success=False)
|
||||
return
|
||||
|
||||
logs.append(f"Building {image} from {dockerfile.parent}")
|
||||
@@ -493,13 +493,14 @@ class FuzzForgeApp(App[None]):
|
||||
logs.append(f"ERROR: {exc}")
|
||||
self._build_results[image] = False
|
||||
self._active_builds.pop(image, None)
|
||||
self.call_from_thread(self._on_build_done, image, False)
|
||||
self.call_from_thread(self._on_build_done, image, success=False)
|
||||
return
|
||||
|
||||
self._active_builds[image] = proc # replace pending marker with actual process
|
||||
self.call_from_thread(self._refresh_hub) # show ⏳ in table
|
||||
|
||||
assert proc.stdout is not None
|
||||
if proc.stdout is None:
|
||||
return
|
||||
for line in proc.stdout:
|
||||
logs.append(line.rstrip())
|
||||
|
||||
@@ -507,10 +508,10 @@ class FuzzForgeApp(App[None]):
|
||||
self._active_builds.pop(image, None)
|
||||
success = proc.returncode == 0
|
||||
self._build_results[image] = success
|
||||
self.call_from_thread(self._on_build_done, image, success)
|
||||
self.call_from_thread(self._on_build_done, image, success=success)
|
||||
|
||||
def _on_build_done(self, image: str, success: bool) -> None:
|
||||
"""Called on the main thread when a background build finishes."""
|
||||
def _on_build_done(self, image: str, *, success: bool) -> None:
|
||||
"""Handle completion of a background build on the main thread."""
|
||||
self._refresh_hub()
|
||||
if success:
|
||||
self.notify(f"✓ {image} built successfully", severity="information")
|
||||
|
||||
@@ -8,6 +8,7 @@ and managing linked MCP hub repositories.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
@@ -301,9 +302,10 @@ def _discover_hub_dirs() -> list[Path]:
|
||||
candidates: list[Path] = []
|
||||
for base in (get_fuzzforge_user_dir() / "hubs", get_fuzzforge_dir() / "hubs"):
|
||||
if base.is_dir():
|
||||
for entry in base.iterdir():
|
||||
if entry.is_dir() and (entry / ".git").is_dir():
|
||||
candidates.append(entry)
|
||||
candidates.extend(
|
||||
entry for entry in base.iterdir()
|
||||
if entry.is_dir() and (entry / ".git").is_dir()
|
||||
)
|
||||
return candidates
|
||||
|
||||
|
||||
@@ -356,10 +358,8 @@ def load_hubs_registry() -> dict[str, Any]:
|
||||
|
||||
registry: dict[str, Any] = {"hubs": hubs}
|
||||
# Persist so we don't re-scan on every load
|
||||
try:
|
||||
with contextlib.suppress(OSError):
|
||||
save_hubs_registry(registry)
|
||||
except OSError:
|
||||
pass
|
||||
return registry
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ class BuildImageScreen(ModalScreen[bool]):
|
||||
self._hub_name = hub_name
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
"""Build the confirmation dialog UI."""
|
||||
with Vertical(id="build-dialog"):
|
||||
yield Label(f"Build {self._image}", classes="dialog-title")
|
||||
yield Label(
|
||||
@@ -38,7 +39,7 @@ class BuildImageScreen(ModalScreen[bool]):
|
||||
)
|
||||
yield Label(
|
||||
"The image will be built in the background.\n"
|
||||
"You\'ll receive a notification when it\'s done.",
|
||||
"You'll receive a notification when it's done.",
|
||||
id="confirm-text",
|
||||
)
|
||||
with Horizontal(classes="dialog-buttons"):
|
||||
@@ -46,10 +47,12 @@ class BuildImageScreen(ModalScreen[bool]):
|
||||
yield _NoFocusButton("Cancel", variant="default", id="btn-cancel")
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
"""Handle Build or Cancel button clicks."""
|
||||
if event.button.id == "btn-build":
|
||||
self.dismiss(True)
|
||||
self.dismiss(result=True)
|
||||
elif event.button.id == "btn-cancel":
|
||||
self.dismiss(False)
|
||||
self.dismiss(result=False)
|
||||
|
||||
def action_cancel(self) -> None:
|
||||
self.dismiss(False)
|
||||
"""Dismiss the dialog when Escape is pressed."""
|
||||
self.dismiss(result=False)
|
||||
|
||||
@@ -29,6 +29,7 @@ class BuildLogScreen(ModalScreen[None]):
|
||||
self._last_line: int = 0
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
"""Build the log viewer UI."""
|
||||
with Vertical(id="build-dialog"):
|
||||
yield Label(f"Build log — {self._image}", classes="dialog-title")
|
||||
yield Label("", id="build-status")
|
||||
@@ -37,6 +38,7 @@ class BuildLogScreen(ModalScreen[None]):
|
||||
yield _NoFocusButton("Close", variant="default", id="btn-close")
|
||||
|
||||
def on_mount(self) -> None:
|
||||
"""Initialize log polling when the screen is mounted."""
|
||||
self._flush_log()
|
||||
self.set_interval(0.5, self._poll_log)
|
||||
|
||||
@@ -63,12 +65,14 @@ class BuildLogScreen(ModalScreen[None]):
|
||||
status.update(f"[red]✗ {self._image} build failed[/red]")
|
||||
|
||||
def _poll_log(self) -> None:
|
||||
"""Called every 500 ms by set_interval."""
|
||||
"""Poll for new log lines periodically."""
|
||||
self._flush_log()
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
"""Handle Close button click."""
|
||||
if event.button.id == "btn-close":
|
||||
self.dismiss(None)
|
||||
|
||||
def action_close(self) -> None:
|
||||
"""Dismiss the dialog when Escape is pressed."""
|
||||
self.dismiss(None)
|
||||
|
||||
Reference in New Issue
Block a user