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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# sb-builder: named builds and per-package results
Date: 2026-10-21
Status: approved
## Goal
Three fixes to how slackrepo jobs run:
1. A never-built package can be built from the GUI by name.
2. A job that builds several packages says which ones failed, and its status
reflects that.
3. Packages whose SlackBuild is gone can be removed without an Update all.
One job keeps running every package given to it. Splitting into one job per
package was considered and rejected: slackrepo already orders deps across
the whole set, builds a shared dep once and goes on past a failed item.
Splitting would add one preview, one gpg unlock and one publish per package,
for nothing but the ability to cancel a single package.
## 1. Named packages run `build`, not `update`
slackrepo looks up the items named to `update` in its package database only
(`find_items -p`, `parsefunctions.sh`), so a package never built before
ends `bad: No matches found for update command`. Deps of named items use
`-ps` (database, then the SlackBuild tree) and are found.
`build` on named items does what `update` would: `build_command` sets an
outdated item to `update` and rebuilds it, a new one to `add` and builds it,
an up-to-date one to `ok` and skips it. The one thing only `update` does is
remove the packages of an item whose SlackBuild is gone (e.g. moved to the
official tree). That cannot happen for a named item: `kind_slackrepo`
accepts only names with a SlackBuild dir, and the Packages tab lists only
those.
Changes (GUI only, the helper is unchanged):
- `HintResultDialog.build_requested` (`mainwindow.py`) starts
`slackrepo build --preview <pkgs>` instead of `update`.
- The Packages tab drops its per-row **Update** action: **Build** now does
the same thing.
- **Update all** stays `slackrepo update` with no items. It still removes
packages whose SlackBuild is gone, but that is no longer the only way:
see section 3.
## 2. Per-package results of a job
slackrepo exits 0 after a full run whatever its items did. It exits non-zero
only on setup errors. Today a run where some packages failed shows as `ok`.
slackrepo records each item's outcome in its database:
`buildresults(itemid, time, result)`, `time` in epoch seconds, one row per
item (insert or replace), written by `log_itemfinish` for build, rebuild and
update. Results: `ok`, `skipped`, `unsupported`, `failed`, `aborted`
(skipped because a dep failed), `bad`, `removed`.
### Helper (`sbb-remote`)
In `cmd_run`, after a real slackrepo job ends (`signs(kind, args)`, i.e. not
`--preview`), read the rows with `time >= meta["start"]` from
`slackrepo_db` (read-only, as `cmd_results`) into
`meta["results"] = {itemid: result}`. If any result is `failed`, `aborted`
or `bad` and the exit was 0, the job's status is `failed`. A database error
leaves `results` unset and the status as the exit code says: the build
already happened, a missing summary must not lose it.
No new job status: `failed` is already handled everywhere (Jobs tab,
notifications, badge). `job-list` carries `results` with the rest of the
meta. The flock serializes jobs, so rows newer than the job's start are
this job's.
`rebuild-tree` does not touch `buildresults` and is unaffected. `publish`
is a separate job and keeps its own exit status.
### GUI
- Jobs tab: a slackrepo job with `results` shows a one-line count in its
details, e.g. `3 ok, 1 failed, 1 aborted`.
- Notification body (`fmt.outcome`): the same count, plus the names of the
failed items, so a failed build says what failed without opening the app.
- Next step (UI guideline 5): when a real slackrepo job started this
session ends with any non-`ok` result, a non-modal `BuildResultDialog`
lists every item with its result chip. Per row: **Log** opens the
existing `results.LogViewer` (`build-log <item>`). Bottom: **Retry
failed** starts `slackrepo build --preview` on the `failed` and `aborted`
items (not `bad`: those need a fix first), **Close**. It can be reopened
from the Jobs tab ribbon for the highlighted job, like a preview's next
step.
## 3. Prune: remove built packages whose SlackBuild is gone
When SBo drops a SlackBuild (e.g. the package moved to the official tree),
the built package stays in the repository until an Update all removes it.
Prune does just that removal, without building anything.
### Helper
- New slackrepo action `prune` (`slackrepo prune [--preview]`). It takes
no package names: the helper computes the list itself, so no name crosses
the trust boundary. Items: `select distinct itemid from packages` in
`slackrepo_db` (read-only), keeping those with no
`<repo_dir>/<itemid>/<pkg>.SlackBuild`. argv:
`slackrepo --repo=... remove [--preview] <itemid>...`. slackrepo's
`remove` looks items up in the same `packages` table (`find_items -p`) and
honours `--preview`.
- An empty list is an error at `job-start` ("nothing to prune"): no job.
- `stats` gains `prunable`, the length of that list, for the GUI to enable
the action.
- `signs()`: a real prune ends in `gen_repos_files.sh` like any slackrepo
run, so it signs: `kind == "slackrepo"` already covers it.
### GUI
- Packages tab ribbon: **Prune** after **Update all**, disabled with reason
"no built package lost its SlackBuild" when `prunable` is 0. It starts
`slackrepo prune --preview`. The preview lists what would be removed; the
NextStep runs `slackrepo prune` for real (the helper recomputes the list,
same result unless the tree changed in between).
- The Dashboard's Built tile shows `N to prune` in its detail when
`prunable` is non-zero.
## Tests
- `test_remote.py`: `cmd_run` on a fake slackrepo that writes rows to a
temp `buildresults` db and exits 0: `results` filled; status `failed` when
one row is `failed`, `ok` when all are `ok`; rows older than the job's
start ignored; a preview job gets no `results`.
- `test_remote.py`: `kind_slackrepo(["prune"])` on a temp db with one item
whose SlackBuild dir exists and one whose dir is gone: argv names only the
gone one; `--preview` passes through; package names are rejected; an
empty list raises.
- `test_gui.py`: Packages tab has no Update action; the hint result's build
request starts `build`; a finished job with a failed result opens
`BuildResultDialog`, and Retry failed starts `build --preview` on the
failed and aborted items only.
|