Repository navigation
feat/0.13.0: add metadata checkbox to TUI + metadata tests #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5ea558c
baa25f5
69f455f
4f138da
ea290ff
8ff9e61
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,11 +2,9 @@ | |
|
|
||
| from __future__ import annotations | ||
|
|
||
| from typing import Any | ||
|
|
||
| from textual.app import App, ComposeResult | ||
| from textual.containers import Container, Horizontal, Vertical | ||
| from textual.widgets import Button, Footer, Header, Input, Log, Select, Static | ||
| from textual.widgets import Button, Checkbox, Footer, Header, Input, Log, Select, Static | ||
|
|
||
|
|
||
| class MaximizerApp(App): | ||
|
|
@@ -38,6 +36,7 @@ def compose(self) -> ComposeResult: | |
| value="greedy", | ||
| id="solver", | ||
| ) | ||
| yield Checkbox("Load metadata", id="metadata") | ||
| yield Button("Run", id="run") | ||
| with Vertical(id="results"): | ||
| yield Static("Results will appear here.", id="result_text") | ||
|
|
@@ -49,6 +48,7 @@ def on_button_pressed(self, event: Button.Pressed) -> None: | |
| return | ||
| packages_text = self.query_one("#packages", Input).value | ||
| solver = self.query_one("#solver", Select).value | ||
| metadata = self.query_one("#metadata", Checkbox).value | ||
| log = self.query_one("#log_output", Log) | ||
| result_text = self.query_one("#result_text", Static) | ||
|
|
||
|
|
@@ -64,6 +64,21 @@ def on_button_pressed(self, event: Button.Pressed) -> None: | |
|
|
||
| maximizer = PackageMaximizer(manager="apt", solver=solver or "greedy") | ||
| pkg_objs = [Package(name=p) for p in packages] | ||
| if metadata: | ||
| from package_maximizer.adapters import get_adapter | ||
|
|
||
| adapter = get_adapter("apt") | ||
| if adapter is not None: | ||
| for pkg in pkg_objs: | ||
| meta = adapter.fetch(pkg.name) | ||
| if meta and meta.name: | ||
| if meta.depends: | ||
| pkg.depends = meta.depends | ||
| if meta.conflicts: | ||
| pkg.conflicts = meta.conflicts | ||
| log.write_line(f"Loaded metadata for {len(packages)} packages.") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Report the number of successful metadata fetches.
Proposed fix+ loaded_count = 0
for pkg in pkg_objs:
meta = adapter.fetch(pkg.name)
if meta and meta.name:
+ loaded_count += 1
if meta.depends:
pkg.depends = meta.depends
if meta.conflicts:
pkg.conflicts = meta.conflicts
- log.write_line(f"Loaded metadata for {len(packages)} packages.")
+ log.write_line(f"Loaded metadata for {loaded_count} packages.")🤖 Prompt for AI Agents |
||
| else: | ||
| log.write_line("No adapter for metadata; continuing without it.") | ||
| selected = maximizer.maximize(pkg_objs) | ||
| selected_names = [p.name for p in selected] | ||
| result_text.update( | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,8 @@ | |
|
|
||
| import pytest | ||
|
|
||
| textual = pytest.importorskip("textual") # noqa: E402 | ||
|
|
||
| from package_maximizer.tui.app import MaximizerApp | ||
|
|
||
|
|
||
|
|
@@ -74,6 +76,24 @@ def test_button_run_with_solver_z3(): | |
| assert "Selected" in out or "No selection" in out | ||
|
|
||
|
|
||
| def test_metadata_checkbox_present(): | ||
| """Metadata checkbox exists in the widget tree.""" | ||
|
|
||
| async def _check(): | ||
| app = MaximizerApp() | ||
| async with app.run_test() as pilot: | ||
| await pilot.pause() | ||
| assert app.query_one("#metadata") is not None | ||
|
|
||
| asyncio.run(_check()) | ||
|
|
||
|
|
||
| def test_run_with_metadata_flag(): | ||
| """Metadata path does not crash when checkbox is enabled.""" | ||
| out = _run_app("vim,nano", "greedy") | ||
| assert isinstance(out, str) | ||
|
Comment on lines
+93
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Enable and validate the metadata path in this test. The test suite installs the TUI dependency and runs 🤖 Prompt for AI Agents |
||
|
|
||
|
|
||
| def test_non_run_button_ignored(): | ||
| """Buttons other than #run do not trigger solving.""" | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: dominicusin/package-maximizer
Length of output: 19023
🏁 Script executed:
Repository: dominicusin/package-maximizer
Length of output: 16834
Move APT metadata loading to a Textual worker.
on_button_pressedcallsAPTMetadataAdapter.fetchsynchronously for each package. The method runssubprocess.run(..., timeout=10), so the UI event loop can block for up to 10 seconds per package. Run the metadata loop in a Textual worker before updating the UI.🤖 Prompt for AI Agents