diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-20 11:16:44 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-20 11:16:44 +0200 |
| commit | cc8ea76af30a9e285d3784d5de51f6d1a85afbd5 (patch) | |
| tree | 3caab2bf22cf7231e21012440b18ab66b1a90fd1 /docs/superpowers | |
| parent | bafab248a348e861511c8a984bdafa48fc32215f (diff) | |
| download | sb-builder-cc8ea76af30a9e285d3784d5de51f6d1a85afbd5.tar.gz sb-builder-cc8ea76af30a9e285d3784d5de51f6d1a85afbd5.zip | |
Document the Hints screen; phase 4 spec from the implementation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'docs/superpowers')
| -rw-r--r-- | docs/superpowers/specs/2026-10-20-sb-builder-phase4-design.md | 132 |
1 files changed, 78 insertions, 54 deletions
diff --git a/docs/superpowers/specs/2026-10-20-sb-builder-phase4-design.md b/docs/superpowers/specs/2026-10-20-sb-builder-phase4-design.md index df360eb..c45c720 100644 --- a/docs/superpowers/specs/2026-10-20-sb-builder-phase4-design.md +++ b/docs/superpowers/specs/2026-10-20-sb-builder-phase4-design.md @@ -1,15 +1,15 @@ # sb-builder phase 4: hints Date: 2026-10-20 -Status: draft +Status: approved Builds on: `2026-10-19-sb-builder-phase1-design.md` (helper, job model, GUI shell), `2026-10-19-sb-builder-phase2-design.md` (inventory, hint view, slackrepo jobs) ## Goal Manage slackrepo hint files from sb-builder: check upstream versions, update -version hints, create and delete hints, sweep `DELREQUIRES` for -current -phantom deps, and see a diff of every change with a way to revert it. +version hints, create and delete hints, and see a diff of every change +with a way to revert it. Direction set by the user: the repo is run from the desktop, the VM shell is for upgrading Slackware only. The VM-side tools were built for a terminal; a @@ -23,9 +23,11 @@ Verified on the VM, in the mkhint source (`~/Programming/GIT/mkhintfile/mkhint`, 1.4.0, 2291 lines) and in slackrepo (`../GITHUB/slackrepo`): - The VM has 607 hints, all in `hintdir`, none in subdirectories and none in - the SBo tree. 594 carry `DELREQUIRES` (from `mkhint -F`), 13 carry + the SBo tree. 594 carry only `DELREQUIRES`, 13 carry `VERSION` + `ARCH` + `DOWNLOAD` + `MD5SUM`, one carries `OPTIONS`. No hint - carries `NODOWNLOAD` or a `DOWNLOAD_x86_64`/`MD5SUM_x86_64` line. + carries `NODOWNLOAD`. Pinned hints carry `DOWNLOAD_x86_64`/`MD5SUM_x86_64` + lines, mostly empty (`claude-code`: `DOWNLOAD="UNSUPPORTED"` with the URL in + `DOWNLOAD_x86_64`), and `ARCH="x86_64"`. - slackrepo reads `DOWNLOAD="no"` as "no download" and ignores `NODOWNLOAD`. `DOWNLOAD_$ARCH` replaces `DOWNLOAD` when set (`libexec/functions.d/parsefunctions.sh:457`), so `DOWNLOAD="no"` next to a @@ -44,12 +46,24 @@ Verified on the VM, in the mkhint source (`~/Programming/GIT/mkhintfile/mkhint`, - mkhint's `-F`: for every `.info` in the repo whose `REQUIRES` contains a phantom dep, merge those deps into the hint's `DELREQUIRES` (union, first seen order, `.bak` only when something changes, minimal hint created when - absent). -- The VM's nvchecker config has 65 stanzas named after the packages, plus a + absent). It edits only the `DELREQUIRES` line. sbshadow + (slackrepo_setup) runs it after every sync: that is where the 594 + DELREQUIRES-only hints come from, and why they exist (slackrepo must not + build deps -current does not need). Until now sbshadow ran it on `--no` + previews too. +- The VM's nvchecker config has 64 stanzas named after the packages, plus a `[__config__]` with oldver, newver and keyfile. nvchecker v2.22 is installed on the desktop, with a GitHub token in - `~/.config/nvchecker/keys.toml`. Its newver file is - `{"version": 2, "data": {"<name>": {"version": "..."}, ...}}`. + `~/.config/nvchecker/keys.toml`. With `--logger json` it prints one JSON + object per line on stdout: `{"name", "version", "event": "updated"}` per + result, `{"name", "error", "level": "error"}` per failure; it exits 0 when + entries fail and needs no oldver or newver to run. +- A DELREQUIRES-only hint has no `VERSION`; mkhint's update cannot bump it. + Updating one pins it from the `.info` first; the next `mkhint -F` keeps the + pin. A package with a phantom dep always has such a hint, so `hint-new` + never sees one. +- slackrepo `update <item>` builds an item that exists, built or not + (`update_command` calls `build_command`). - The phantom deps list on the VM (`/root/.config/mkhint/phantom-deps`) has 18 entries. - Two packages use bundled-dep manifests: neovim (url mode) and openvino @@ -57,33 +71,37 @@ Verified on the VM, in the mkhint source (`~/Programming/GIT/mkhintfile/mkhint`, ## Scope -In: upstream check, version update, new hint, delete hint, fix-current, +In: upstream check, version update, new hint, delete hint, `--no-dl` as `DOWNLOAD="no"`, diff and revert. Out, for good (the Hints screen covers them): mkhint `--list`, `--versions`, `--review`, `--strip-version`, `--info`, `--clean`. -Out, later: bundled-dep reconcile for neovim and openvino (phase 4b, which -then removes mkhint and nvchecker from the VM), generating nvchecker stanzas +Out, later (phase 4b, which then removes mkhint and nvchecker from the VM): +bundled-dep reconcile for neovim and openvino, and a helper `fix-current` +that sbshadow calls in place of `mkhint -F`, with the phantom deps list +moved into the helper config as its single source. Also out: generating nvchecker stanzas for new packages (add them to `nvchecker.toml` by hand), free text hint editing, migration of `NODOWNLOAD=yes` lines (none exist). ## Part 1: upstream check, on the desktop -- `nvchecker.toml` in the repo root: the VM's 65 stanzas, without +- `nvchecker.toml` in the repo root: the VM's 64 stanzas, without `[__config__]`. Stanza name = package name. Git-tracked, edited by hand. - `sb_builder/upstream.py` runs nvchecker through `QProcess` (as `remote.py` - runs `virsh`) with a fixed argv: `nvchecker -c <tmp>/nvchecker.toml`. The - temp dir holds a generated config: a `[__config__]` with `keyfile` (from - the GUI config) and `newver = "<tmp>/new.json"`, followed by the repo - file's text. No oldver, no `nvtake`: the comparison is against the hints. -- Result: `{pkg: version}` from the newver file. Failure: the exit status and - stderr, shown as a `nvchecker error` state. + runs `virsh`) with a fixed argv: `nvchecker -c <tmp>/nvchecker.toml + --logger json`. The temp dir holds a generated config: a `[__config__]` + with `keyfile` (from the GUI config, when the file exists), followed by the + repo file's text. No oldver, newver or `nvtake`: the comparison is against + the hints. +- Result: `{pkg: version}` and `{pkg: error}` from the JSON log. A package + without a result, or a failed run (exit status, stderr), shows as + `nvchecker error` with the reason in the tooltip. - A package is outdated when its upstream version differs from the hint `VERSION`, or from the `.info` `VERSION` when the hint has none. Versions are compared as strings; no ordering is attempted. -GUI config gains `nvchecker_keyfile`, default +GUI config gains `[hints] nvchecker_keyfile`, default `~/.config/nvchecker/keys.toml` (expanded). A missing keyfile is not an error: nvchecker runs without a token. @@ -91,8 +109,7 @@ error: nvchecker runs without a token. ### Config -New key `phantom_deps`, list of strings, default `[]`. The VM config gets -the 18 entries at deploy. `remote/config.example.toml` shows the key. +New key `manifest_packages` (below). `remote/config.example.toml` shows it. ### Arguments @@ -108,27 +125,36 @@ the 18 entries at deploy. `remote/config.example.toml` shows the key. ### Job kinds -- `hint-update <pkg>=<ver>... [--no-dl]`: per package, in order: back up the - hint to `.bak`, apply the version (below), write atomically. A failure - restores the hint from the `.bak` it just wrote, logs `<pkg>: failed: <why>` - and continues with the next package. The last log line is - `SBB-RESULT {"ok": [...], "failed": [...]}`. Exit status 1 when any - package failed. +- `hint-update <pkg>=<ver>... [--no-dl]`: per package, in order: compute the + new text (apply the version, below), then back the hint up to `.bak` and + write atomically. A failure (download, missing `.info` VERSION) leaves the + hint and its old `.bak` untouched, logs `<pkg>: failed: <why>` and + continues with the next package. A package without a hint gets a new one + built as `hint-new` does. The last log line is + `SBB-RESULT {"ok": [pkg...], "failed": [[pkg, why]...]}`. Exit status 1 + when any package failed. - `hint-new <pkg> [<ver>] [--no-dl]`: refuses when the hint exists. Builds - the hint from the `.info` as mkhint does, phantom deps from - `phantom_deps`, then applies the version when given. No `.bak` (nothing to - back up); revert means delete. -- `fix-current`: mkhint's `-F` with `phantom_deps`. Logs one line per - changed hint, then `SBB-RESULT {"ok": [...], "failed": []}`. + the hint from the `.info` as mkhint does, without phantom deps (see the + facts), then applies the version when given. No `.bak` (a stale + one is removed); revert means delete. -These jobs never sign, so they do not check the signing key. +These jobs never sign, so they do not check the signing key. Their argv is +the helper itself: `python3 sbb-remote _hint <kind> <args>`, validated again +there. Job ids now allow a hyphenated kind (`...-hint-update`). + +`job-result <id>`: the last `SBB-RESULT` object of a job's log. ### Applying a version -1. Old version = hint `VERSION`, else `.info` `VERSION`. -2. Replace old by new everywhere in the file. When either contains `_`, also - the `-` forms. When old contains `.`, also its dotless form inside URLs, - as a whole number (no digit before or after), so md5 hex is untouched. +1. A hint without `VERSION` is first pinned from the `.info`: its + `VERSION`, `DOWNLOAD*` and `MD5SUM*` lines, plus `ARCH="x86_64"` when the + hint has no `ARCH`, are put in front of the hint's text. Old version = the + hint's `VERSION`. With no version given (`hint-new <pkg>`), steps 2 and 3 + are skipped. +2. Replace old by new everywhere in the file except inside `MD5SUM*` + values. When either contains `_`, also the `-` forms. When old contains + `.`, also its dotless form inside URLs, as a whole number (no digit before + or after). 3. Without `--no-dl`: for `DOWNLOAD`/`MD5SUM` and `DOWNLOAD_x86_64`/`MD5SUM_x86_64`, split the values on whitespace (hint values may continue over lines with `\`). Skip a pair whose value is empty, @@ -141,9 +167,8 @@ These jobs never sign, so they do not check the signing key. written, because `DOWNLOAD_$ARCH` would override it. Hint text is edited as text, not regenerated, so comments, order and other -keys stay as they are. Assignments are located with the rules the helper's -`parse_assignments` already uses (`KEY="..."` at line start, values may span -lines inside the quotes). +keys stay as they are. An assignment is `KEY="..."` (the value may span +lines inside the quotes) or `KEY=word`, at line start. ### Commands (answer at once, not jobs) @@ -177,22 +202,21 @@ convention. - **Update selected**: starts `hint-update pkg=ver ...` for the checked rows that have an upstream version; a **No download** checkbox adds `--no-dl`. - - **Fix current**: starts `fix-current`. - **Delete hint**: confirm dialog, then `hint-delete` for the current row. - Jobs go through the Jobs tab like every other job. ### After a hint job -When a `hint-update`, `hint-new` or `fix-current` job ends, the GUI reads +When a `hint-update` or `hint-new` job ends, the GUI reads its `SBB-RESULT` line and opens a dialog with one entry per changed package: a unified diff (`difflib`) of `hint-diff`, and a **Revert** button per package. Failed packages are listed with their reason. The dialog ends with -**Build these**, which starts the usual slackrepo preview for the changed -packages (`update` when built, `build` otherwise, as the Packages tab -decides), and **Close**. After Revert or Delete the inventory is reloaded. +**Build these**, which starts `slackrepo update --preview` for the changed +packages that were not reverted (update builds unbuilt items too), and +**Close**. Revert is offered once per package: a second one would delete +the restored hint. After Revert or Delete the inventory is reloaded. -For `fix-current` the dialog lists the packages without opening every diff -(it can touch hundreds); clicking one shows its diff. +Each diff is fetched when its package is selected. ### Packages detail pane @@ -219,13 +243,13 @@ For `fix-current` the dialog lists the packages without opening every diff touched), multi-line `DOWNLOAD`/`MD5SUM` with continuation md5s kept, `UNSUPPORTED` skipped, `--no-dl` removing `DOWNLOAD_x86_64` and writing `DOWNLOAD="no"`, a download failure restoring the hint while the next - package still updates, `SBB-RESULT` contents, `hint-new` from `.info` - with phantom deps, `fix-current` merge and idempotence (second run - changes nothing and writes no `.bak`), new -> revert, update -> diff -> + package still updates, `SBB-RESULT` contents, `hint-new` from `.info`, + a DELREQUIRES-only hint pinned from the `.info`, new -> revert, update -> diff -> revert, delete -> revert, manifest package refusal, unmanaged hint path refusal, bad version and package rejection. -- `test_upstream.py`: generated config text, newver parsing from a fixture, - outdated comparison (hint version, `.info` fallback). No network. +- `test_upstream.py`: generated config, JSON log parsing, states (hint + version, `.info` fallback), the repo file has no `[__config__]`, `Checker` + against a fake `nvchecker` on `PATH` and a missing one. No network. - `test_gui.py`: Hints screen with a fake remote and injected upstream results (states, checked rows, Update selected argv), diff dialog Revert call. @@ -233,6 +257,6 @@ For `fix-current` the dialog lists the packages without opening every diff ## Deploy (asks first) 1. `./install.sh --remote` with helper 0.5.0. -2. Add `phantom_deps` (the VM's 18 entries) to `/etc/sb-builder/config.toml`. +2. slackrepo_setup's sbshadow, which no longer runs `mkhint -F` on `--no`. 3. mkhint, nvchecker and `/root/.config/{mkhint,nvchecker}` stay on the VM until phase 4b. |
