diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-21 09:57:21 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-21 09:57:21 +0200 |
| commit | 45c7a3f4ac550be4bb4cf4c3a7786dfbbff02859 (patch) | |
| tree | 58b1e8428e471bd7ebf4fea8adca78b003a726ee | |
| parent | cdbf53d4f6ed8009b4d5ac55f65208efb2fe7b1b (diff) | |
| download | sb-builder-45c7a3f4ac550be4bb4cf4c3a7786dfbbff02859.tar.gz sb-builder-45c7a3f4ac550be4bb4cf4c3a7786dfbbff02859.zip | |
Packages: hint column, hint: query prefix
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| -rw-r--r-- | sb_builder/packages.py | 34 | ||||
| -rw-r--r-- | tests/test_gui.py | 13 |
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:")]) |
