aboutsummaryrefslogtreecommitdiffstats
path: root/docs/design/2026-10-21-sb-builder-repository-design.md
blob: 45dc9a670207e51f19bdeed2b78c018d4d40ac1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# sb-builder: version compare, hint column, Repository tab

Date: 2026-10-21
Status: approved
Builds on: `2026-10-19-sb-builder-phase2-design.md`, `2026-10-20-sb-builder-ui-design.md`

## Goal

Three gaps found browsing the Packages tab:

- A package's hint is visible only after selecting it: nothing in the list
  says whether it has one, or whether it pins a version or only drops
  shadowed deps.
- `outdated` is `built_version != version`. A package built at 1.4.5 whose
  target is now 1.4.2 (a pin dropped from its hint) shows as `outdated`,
  and Update would downgrade it.
- Nothing shows what slackrepo produced: the built package repository.

## Facts

- The inventory already carries `hint_path` and the parsed `hints` of each
  row: the hint column needs no helper change.
- slackrepo's `PKGREPO` is `/repo` on the VM (virtiofs). The desktop sees
  the same tree at the same path, `/repo` (a link to an NFS mount). It holds
  `<category>/<pkg>/<pkg>-<version>-<arch>-<build>.txz`, plus the
  gen_repos_files output at the top: `PACKAGES.TXT` (first line
  `PACKAGES.TXT;  <date>`, then per package `PACKAGE NAME`, `PACKAGE
  LOCATION`, both `PACKAGE SIZE` lines in K, `PACKAGE DESCRIPTION` with
  `<pkg>:` lines) and `ChangeLog.txt` (entries separated by
  `+--------------------------+`, a date line, then
  `<category>/<pkg>/<file>.txz: <text>` items, continuation lines
  indented). On 2026-10-21: 546 packages, 4.8G.

## Packages tab

### Version compare

`vercmp(a, b)` in `packages.py` returns -1, 0 or 1 (stdlib has no version
compare, `packaging` is third-party):

- split each version into runs of digits and runs of letters; `.`, `_`,
  `-`, `+` and `~` separate and are dropped;
- compare run by run: two digit runs numerically, two letter runs as
  lower-cased strings, a digit run beats a letter run;
- when one side runs out: if the other continues with a pre-release word
  (`alpha`, `beta`, `pre`, `rc`, `dev`) it is the older one
  (`1.0rc1 < 1.0`), otherwise it is the newer one (`1.0.1 > 1.0`,
  `4.3.5b > 4.3.5`);
- `ponytail:` comment: single-letter pre-releases (`1.0b1`) count as newer
  than the release; snapshot versions (`20240101_ab12cd`) order by date,
  their hash part orders arbitrarily.

`status(row)`: `never` and `failed` as today, then by `vercmp(built,
version)`: `ok` (0), `outdated` (built older), `newer` (built newer than the
target). `STATUSES` gains `newer` with its own chip and colour.

### Hint column

New column `hint` after `built`, one word from the row's `hints`:

- `skip`: `SKIP` set and not `no`;
- `pin`: `VERSION` set;
- `deps`: only `DELREQUIRES` and/or `ADDREQUIRES` (shadowed dep removal,
  phantom deps);
- `other`: a hint with none of the above (ARCH, options...);
- empty: no hint.

First match wins in that order. The cell tooltip lists the hint's keys. The
query gains a `hint:` prefix matching that word, plus `hint:none` for rows
without a hint.

## Repository tab (`sb_builder/repository.py`)

Local only, no ssh: works while the VM is off.

- Config: `[repository] path`, default `/repo`. A missing or unreadable
  path shows a one-line message in the tab, never a warning dialog.
- Loads on first show and on Refresh, off the GUI thread (NFS can be slow):
  - walk `<path>/*/*/*.t?z`: category, then name, version, arch and build
    from the file name (the last three `-` fields are version, arch, build),
    size and mtime from `stat`;
  - `PACKAGES.TXT`: per `PACKAGE LOCATION`/`PACKAGE NAME`, the description
    and the uncompressed size; its first line is the last publish time;
  - `ChangeLog.txt`: entries per `category/pkg`, with their dates.
- Stats line above the table: packages, size on disk (sum of the `.txz`),
  uncompressed total, last publish, counts per overlay (personal,
  pentesting, upstream as in Packages), unpublished (a `.txz` on disk with
  no matching `PACKAGE NAME` in `PACKAGES.TXT`).
- Table: name, version, build, category, size, date, published. Search
  field (name and description), overlay chips and an `unpublished` chip, as
  in Packages. No tick boxes: the tab has no change actions.
- Detail pane: description, both sizes, file path, the package's ChangeLog
  entries newest first, and an "Open in Packages" link (navigation, as
  "Open in Hints" is in Packages).
- Ribbon: no actions (Publish stays in Packages). View actions: Refresh.

## Testing

- `vercmp`: equal, numeric runs (`1.4.10 > 1.4.9`), pre-release
  (`1.0rc1 < 1.0`), longer release (`1.0.1 > 1.0`), letter suffix
  (`4.3.5b > 4.3.5`); `status` gives `newer` for built 1.4.5, target 1.4.2.
- Hint word for each case, `hint:` filter.
- Repository parsing against a temp tree with two `.txz`, a two-entry
  `PACKAGES.TXT` (one listed, one not) and a short `ChangeLog.txt`: names,
  versions, sizes, unpublished count, changelog entries. GUI test loads the
  tab offscreen from that tree; a missing path shows the message.

## Out

Stale `.txz` whose SlackBuild left the repo, several versions of one
package side by side, file lists (`FILELIST.TXT`, `MANIFEST.bz2`), reading
the repository through the helper.