aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md3
-rwxr-xr-xremote/sbb-remote4
-rw-r--r--sb_builder/__init__.py2
-rw-r--r--sb_builder/dashboard.py2
-rw-r--r--sb_builder/mainwindow.py17
-rw-r--r--tests/test_gui.py9
-rw-r--r--tests/test_remote.py2
7 files changed, 30 insertions, 9 deletions
diff --git a/README.md b/README.md
index c3737a3..67e820f 100644
--- a/README.md
+++ b/README.md
@@ -90,7 +90,8 @@ reopens it.
- **Dashboard**: VM load, uptime and free disk, package counts, slackrepo
build results, last overlay pull, SBo orphans, recent jobs. Refreshes while
visible. The tiles open Packages (the orphans tile with only the orphaned
- filter on), Results (one result kind) and Jobs.
+ filter on), Results (one result kind) and Jobs; Built lists the packages
+ to prune (built, SlackBuild gone).
- **Packages**: every package of the repository, with built version, hint
and status (`ok`, `failed`, `never`, `outdated`, `newer`: built newer than
the target, e.g. after a pin left its hint, so a build would downgrade). The
diff --git a/remote/sbb-remote b/remote/sbb-remote
index 15c0fec..d075f38 100755
--- a/remote/sbb-remote
+++ b/remote/sbb-remote
@@ -41,7 +41,7 @@ import time
import tomllib
import urllib.request
-VERSION = "0.12.0"
+VERSION = "0.12.1"
DEFAULTS = {
"state_dir": "/var/lib/sb-builder",
"repo_dir": "/var/lib/sbopkg/SBo-danix",
@@ -537,7 +537,7 @@ def cmd_stats(cfg):
"slackpkg": _slackpkg(),
"packages": _try(lambda: _packages(cfg)),
"orphans": _try(lambda: _orphans(cfg)),
- "prunable": _try(lambda: len(_prunable(cfg))),
+ "prunable": _try(lambda: _prunable(cfg)),
"sync": {o: _try(lambda o=o: int(_git(cfg, "log", "-1", "--format=%ct", "--", o + "/")))
for o in cfg["overlays"]},
"slackrepo": _try(lambda: _slackrepo(cfg)),
diff --git a/sb_builder/__init__.py b/sb_builder/__init__.py
index 99d4de6..22beac6 100644
--- a/sb_builder/__init__.py
+++ b/sb_builder/__init__.py
@@ -16,4 +16,4 @@
"""sb-builder: Qt6 GUI driving the SlackBuild tooling on a build VM."""
-VERSION = "0.12.0" # must match remote/sbb-remote VERSION
+VERSION = "0.12.1" # must match remote/sbb-remote VERSION
diff --git a/sb_builder/dashboard.py b/sb_builder/dashboard.py
index c70258c..f4ea687 100644
--- a/sb_builder/dashboard.py
+++ b/sb_builder/dashboard.py
@@ -328,7 +328,7 @@ class Dashboard(QWidget):
else:
never = "" if p is None else f" · {num(p['total'] - sr['built'])} never built"
if s.get("prunable"):
- never += f" · {num(s['prunable'])} to prune"
+ never += f" · {num(len(s['prunable']))} to prune"
t["Built"].set(num(sr["built"]), f"of {num(p and p['total'])}{never}")
known = [ts for ts in sync.values() if ts is not None]
t["Last pull"].set(fmt_age(min(known)) if known else NA,
diff --git a/sb_builder/mainwindow.py b/sb_builder/mainwindow.py
index aab6093..cee984f 100644
--- a/sb_builder/mainwindow.py
+++ b/sb_builder/mainwindow.py
@@ -115,6 +115,8 @@ class MainWindow(QMainWindow):
self.dashboard.tiles["Packages"].link(self.open_packages)
self.dashboard.orphans.link(lambda: self.open_packages().filter_to("orphaned"))
self.dashboard.jobs.link(self.open_jobs)
+ self.prunable = []
+ self.dashboard.tiles["Built"].link(self.show_prunable)
self.dashboard.result_clicked.connect(self.open_results)
self.jobs_tab = JobsTab(self.remote)
self.jobs_tab.refresh_requested.connect(self.poll_jobs)
@@ -222,7 +224,8 @@ class MainWindow(QMainWindow):
if err:
return self._failed(err)
self.dashboard.show_stats(data)
- self.packages_tab.set_prunable(data.get("prunable"))
+ self.prunable = data.get("prunable") or []
+ self.packages_tab.set_prunable(len(self.prunable))
def _got_version(self, data, err):
if err:
@@ -352,6 +355,18 @@ class MainWindow(QMainWindow):
else:
d.show()
+ def show_prunable(self):
+ """The built packages whose SlackBuild is gone, readable while a job runs."""
+ if not self.prunable:
+ return
+ box = QMessageBox(QMessageBox.Icon.Information, "To prune",
+ "Built, but their SlackBuild is gone from the tree. "
+ "Packages, Prune removes them.", parent=self)
+ box.setDetailedText("\n".join(self.prunable))
+ box.setModal(False)
+ box.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
+ box.show()
+
def show_build_result(self, job):
"""A slackrepo run's per-package results: logs, Retry failed."""
if job["id"] in self.next_steps:
diff --git a/tests/test_gui.py b/tests/test_gui.py
index f5894de..496061a 100644
--- a/tests/test_gui.py
+++ b/tests/test_gui.py
@@ -32,7 +32,7 @@ sys.path.insert(0, ROOT)
from PyQt6.QtCore import QObject, QPointF, QProcess, pyqtSignal # noqa: E402
from PyQt6.QtGui import QColor # noqa: E402
-from PyQt6.QtWidgets import QApplication # noqa: E402
+from PyQt6.QtWidgets import QApplication, QMessageBox # noqa: E402
from sb_builder import VERSION, config # noqa: E402
from sb_builder import hints as hintlib # noqa: E402
@@ -486,10 +486,15 @@ class SmokeTest(unittest.TestCase):
self.assertIn(("job-start", "slackrepo", "build", "--preview", "b", "c"), remote.calls)
def test_prunable_enables_prune(self):
- w, _ = self.window(stats=(dict(STATS, prunable=3, slackrepo={"results": {}, "built": 5}), None))
+ gone = ["a/x", "b/y", "c/z"]
+ w, _ = self.window(stats=(dict(STATS, prunable=gone, slackrepo={"results": {}, "built": 5}), None))
w.poll_jobs()
self.assertTrue(w.packages_tab.act_prune.isEnabled())
self.assertIn("3 to prune", w.dashboard.tiles["Built"].detail.text())
+ w.dashboard.tiles["Built"].clicked.emit()
+ box = w.findChild(QMessageBox)
+ self.assertFalse(box.isModal())
+ self.assertEqual(box.detailedText(), "a/x\nb/y\nc/z")
def test_slackpkg_dot(self):
old = dict(STATS, slackpkg={"update": None, "upgrade": 1})
diff --git a/tests/test_remote.py b/tests/test_remote.py
index 9f28701..f9e541f 100644
--- a/tests/test_remote.py
+++ b/tests/test_remote.py
@@ -185,7 +185,7 @@ class KindsTest(Base):
kind = sbb.KINDS["slackrepo"]
self.assertEqual(kind(self.cfg, ["prune", "--preview"]),
(["slackrepo", "--repo=SBo-danix", "remove", "--preview", "misc/gone"], {}))
- self.assertEqual(sbb.cmd_stats(self.cfg)["prunable"], 1)
+ self.assertEqual(sbb.cmd_stats(self.cfg)["prunable"], ["misc/gone"])
with self.assertRaises(sbb.Error):
kind(self.cfg, ["prune", "kept"])
self.make_pkg("misc/gone")