aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sb_builder/packages.py34
-rw-r--r--tests/test_gui.py13
2 files changed, 40 insertions, 7 deletions
diff --git a/sb_builder/packages.py b/sb_builder/packages.py
index 0a669bb..60e0425 100644
--- a/sb_builder/packages.py
+++ b/sb_builder/packages.py
@@ -31,10 +31,11 @@ from .ui import SP, action, chip, enable, group_label, search_field
OVERLAYS = ("personal", "pentesting")
STATUSES = ("ok", "failed", "never", "outdated", "newer")
-COLUMNS = ("", "name", "category", "version", "built", "status", "maintainer")
+COLUMNS = ("", "name", "category", "version", "built", "hint", "status", "maintainer")
STATUS_COLOR = {"ok": STATUS["ok"], "failed": STATUS["failed"], "outdated": STATUS["aborted"],
"newer": STATUS["bad"]}
-FIELDS = {"cat": "category", "maint": "maintainer", "req": "requires", "status": "status"}
+FIELDS = {"cat": "category", "maint": "maintainer", "req": "requires", "status": "status",
+ "hint": "hint"}
PRE_RELEASE = ("alpha", "beta", "pre", "rc", "dev")
@@ -63,6 +64,20 @@ def vercmp(a, b):
return -sign if nxt in PRE_RELEASE else sign
+def hint_kind(hints):
+ """One word for the Packages hint column: skip, pin, deps, other; "" without a hint."""
+ if hints is None:
+ return ""
+ skip = hintlib._raw(hints.get("SKIP", "no"))
+ if skip.lower() != "no":
+ return "skip"
+ if "VERSION" in hints:
+ return "pin"
+ if hints and set(hints) <= {"DELREQUIRES", "ADDREQUIRES"}:
+ return "deps"
+ return "other"
+
+
def status(row):
# ponytail: compares versions only; slackrepo also rebuilds on SlackBuild
# or dependency changes, which its preview shows
@@ -109,6 +124,8 @@ def matches(row, terms, overlays=(), statuses=(), orphans=False):
hay = f"{row['name']} {row['summary'] or ''}"
elif field == "requires":
hay = " ".join(row["requires"])
+ elif field == "hint":
+ hay = row["hint"] or "none"
else:
hay = row[field] or ""
if term not in hay.lower():
@@ -122,6 +139,7 @@ def load_rows(inventory):
row = dict(zip(inventory["columns"], values))
row["category"], row["name"] = row["path"].split("/", 1)
row["status"] = status(row)
+ row["hint"] = hint_kind(row["hints"])
rows.append(row)
return rows
@@ -169,9 +187,11 @@ class Model(QAbstractTableModel):
if role == Qt.ItemDataRole.CheckStateRole and col == 0:
return Qt.CheckState.Checked if row["name"] in self.checked else Qt.CheckState.Unchecked
if role == Qt.ItemDataRole.DisplayRole:
- return (None, row["name"], row["category"], row["version"],
- row["built_version"] or "", row["status"], row["maintainer"] or "")[col]
- if role == Qt.ItemDataRole.ForegroundRole and col == 5 and row["status"] in STATUS_COLOR:
+ return (None, row["name"], row["category"], row["version"], row["built_version"] or "",
+ row["hint"], row["status"], row["maintainer"] or "")[col]
+ if role == Qt.ItemDataRole.ToolTipRole and col == 5 and row["hints"]:
+ return ", ".join(sorted(row["hints"]))
+ if role == Qt.ItemDataRole.ForegroundRole and col == 6 and row["status"] in STATUS_COLOR:
return QColor(STATUS_COLOR[row["status"]])
if role == Qt.ItemDataRole.UserRole:
return row
@@ -255,7 +275,7 @@ class PackagesTab(QWidget):
self.proxy = Filter()
self.proxy.setSourceModel(self.model)
- self.query = search_field("search (cat: maint: req: status:)")
+ self.query = search_field("search (cat: maint: req: status: hint:)")
self.query.textChanged.connect(self.refilter)
self.chips = {}
chips = QHBoxLayout()
@@ -275,7 +295,7 @@ class PackagesTab(QWidget):
self.table.setSelectionMode(QTableView.SelectionMode.SingleSelection)
self.table.verticalHeader().hide()
self.table.horizontalHeader().setStretchLastSection(True)
- for col, width in enumerate((28, 220, 110, 120, 120, 80)):
+ for col, width in enumerate((28, 220, 110, 120, 120, 60, 80)):
self.table.setColumnWidth(col, width)
self.table.selectionModel().currentRowChanged.connect(self.show_detail)
self.table.clicked.connect(self._toggle)
diff --git a/tests/test_gui.py b/tests/test_gui.py
index eef9c5d..8ffb65d 100644
--- a/tests/test_gui.py
+++ b/tests/test_gui.py
@@ -256,6 +256,19 @@ class FilterTest(unittest.TestCase):
self.assertEqual(pk.vercmp(a, b), want, (a, b))
self.assertEqual(pk.vercmp(b, a), -want, (b, a))
+ def test_hint_kind(self):
+ for hints, want in ((None, ""), ({"SKIP": "yes", "VERSION": "2"}, "skip"),
+ ({"SKIP": "no", "VERSION": "2"}, "pin"),
+ ({"DELREQUIRES": "x", "ADDREQUIRES": "y"}, "deps"),
+ ({"ARCH": "x86_64"}, "other"), ({}, "other"),
+ ({"VERSION": {"value": "$V", "shell": True}}, "pin")):
+ self.assertEqual(pk.hint_kind(hints), want, hints)
+
+ def test_hint_query(self):
+ self.assertEqual(self.names("hint:deps"), ["foo"])
+ self.assertEqual(self.names("hint:none"), ["borgbackup", "curl", "nmap", "nuclei"])
+ self.assertEqual(self.rows["foo"]["hint"], "deps")
+
def test_query(self):
self.assertEqual(pk.parse_query("Nuc cat:misc bogus:x status:"),
[(None, "nuc"), ("category", "misc"), (None, "bogus:x"), (None, "status:")])