aboutsummaryrefslogtreecommitdiffstats
path: root/sb_builder
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-21 10:03:31 +0200
committerDanilo M. <danix@danix.xyz>2026-10-21 10:03:31 +0200
commit6b0f67655b40fef221f9c84cfb6c0bcedf34e3bb (patch)
treeb4f66f2e0f327d9da5c40566518225606a517135 /sb_builder
parent8a63cde8346c6ff30dd79cf7862e28ce6dff56fc (diff)
downloadsb-builder-6b0f67655b40fef221f9c84cfb6c0bcedf34e3bb.tar.gz
sb-builder-6b0f67655b40fef221f9c84cfb6c0bcedf34e3bb.zip
Repository, Packages: no stale detail pane; scan survives races
A reload or filter that drops the current row left its pane and link up, and the link then crashed on current() being None (Packages had the same). A .txz slackrepo replaces between glob and stat is skipped, and any exception in the scan thread reaches the stats line instead of leaving it at loading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'sb_builder')
-rw-r--r--sb_builder/packages.py5
-rw-r--r--sb_builder/repository.py10
2 files changed, 10 insertions, 5 deletions
diff --git a/sb_builder/packages.py b/sb_builder/packages.py
index 60e0425..a3d7126 100644
--- a/sb_builder/packages.py
+++ b/sb_builder/packages.py
@@ -50,7 +50,7 @@ def vercmp(a, b):
letter. Past the shorter version, a pre-release word makes the longer one
older (1.0rc1 < 1.0), anything else newer (1.0.1, 4.3.5b > their base).
"""
- # ponytail: single-letter pre-releases (1.0b1) count as newer than 1.0;
+ # ponytail: single-letter pre-releases (1.0b1) and 1.0.0 count as newer than 1.0;
# snapshots (20240101_ab12cd) order by date, their hash part arbitrarily
ra, rb = _runs(a), _runs(b)
for x, y in zip(ra, rb):
@@ -364,7 +364,7 @@ class PackagesTab(QWidget):
self.count.setText(f"inventory failed: {err}")
return
self.model.set_rows(load_rows(data))
- self.update_count()
+ self.refilter()
def filter_to(self, name):
"""Show only one chip's packages (from a Dashboard click)."""
@@ -379,6 +379,7 @@ class PackagesTab(QWidget):
self.proxy.update(self.query.text(), on - set(STATUSES) - {"orphaned"}, on & set(STATUSES),
"orphaned" in on)
self.update_count()
+ self.show_detail(self.table.currentIndex(), None) # a reset or filter can drop it
def update_count(self):
self.count.setText(f"{self.proxy.rowCount():,} shown · {len(self.model.checked)} selected")
diff --git a/sb_builder/repository.py b/sb_builder/repository.py
index 29f4291..38c6ecc 100644
--- a/sb_builder/repository.py
+++ b/sb_builder/repository.py
@@ -106,7 +106,10 @@ def scan(path):
m = PKGFILE.match(os.path.basename(f))
if not m:
continue
- st = os.stat(f)
+ try:
+ st = os.stat(f)
+ except FileNotFoundError:
+ continue # slackrepo replaced it since the glob
item = os.path.relpath(os.path.dirname(f), path) # category/pkg
info = meta.get(os.path.basename(f))
rows.append({**m.groupdict(), "category": item.split("/")[0], "file": f,
@@ -283,7 +286,7 @@ class RepositoryTab(QWidget):
def work():
try:
self.scanned.emit(gen, scan(path), "")
- except OSError as e:
+ except Exception as e: # the thread's boundary: never stuck at loading
self.scanned.emit(gen, None, str(e))
threading.Thread(target=work, daemon=True).start()
@@ -292,12 +295,13 @@ class RepositoryTab(QWidget):
return # an older Refresh, overtaken
self.model.set_rows(data["rows"] if data else [])
self.stats.setText(err or summary(data))
- self.update_count()
+ self.refilter()
def refilter(self):
on = {n for n, b in self.chips.items() if b.isChecked()}
self.proxy.update(self.query.text(), on - {"unpublished"}, "unpublished" in on)
self.update_count()
+ self.show_detail(self.table.currentIndex(), None) # a reset or filter can drop it
def update_count(self):
self.count.setText(f"{self.proxy.rowCount():,} shown")