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
|
# CLAUDE.md
Working notes for Claude Code on this project. Read before editing.
## What this is
`sbo-batch-test`: a single self-contained bash script that batch-tests
SlackBuilds against a clean Slackware 15.0 overlay chroot. The user is an SBo
(SlackBuilds.org) maintainer on Slackware64-current who needs to verify builds
against 15.0 stable without booting a VM.
Full spec lives in `claude-code-prompt-sbo-batch-tester.txt`. Reference mount
machinery in `overlay-chroot.sh` (Jeremy Hansen / bassmadrigal). User-facing
docs in `README.md`.
## Conventions (the user cares about these)
- **No em dash character** in any prose, comments, README, or commit messages.
Use commas or periods. This is a hard rule.
- This session runs with ponytail (laziest working solution) and caveman
(terse replies) modes. Code stays normal; chat is terse.
- Build incrementally. The user wants to review the dep resolver and the
mount/teardown core before trusting the rest. Do not balloon scope.
- Do NOT default to agreement. If a choice is fragile or wrong, say so and
propose better with reasoning.
## Hard constraints (do not violate)
- **Resolution is LOCAL-tree-only.** Never add network/sbopkg resolution. The
local SBo tree is the single source of truth (contains unpublished
personal/pentesting packages). Settled, not open for revisiting.
- **overlay lowerdir must be LOCAL.** `SLACKWARE_BASE` is a local fs path.
`LOCAL_MIRROR_15` is NFS and is a package SOURCE only. overlayfs over NFS
lowerdir is fragile. The script guards against pointing base under the mirror.
- **Do not wrap/drive slackrepo.** Separate pipeline, keep independent.
- **Shares host kernel.** No kernel-module testing claims.
- Runs as root only (overlay + chroot).
- Per-target disposable overlay: each category target tests against pristine
15.0. Built packages are throwaway.
## Architecture (single file: sbo-batch-test)
Top-to-bottom layout:
1. **CONFIG block** - `SLACKWARE_BASE`, `LOCAL_MIRROR_15`, `SBO_TREE_ROOTS[]`,
`CHROOT_LOCATION`, `LOG_ROOT`, `VERSION`. Currently placeholder paths (we are
not in the VM, no real values yet). User fills these in.
2. **Globals / flags** - `USE_COLOR DRY_RUN WITH_X JOBS`, status maps
(`ST_STATUS ST_REASON ST_TIME ST_README`), `ACTIVE_MOUNTS[]`.
3. **usage / init_color / parse_args / validate_env** - fail-fast startup
checks with copy-pasteable hints.
4. **init_base** - `--init-base` mode only. First-time populate: `installpkg
--root` the full `slackware64/*/*.t?z` set into `SLACKWARE_BASE`, seed the
`last-base-update` marker, exit. Runs its own checks (root, NFS reachable,
not under mirror) since the base does not exist yet; refuses to clobber a
populated base. Wired in `main` before `validate_env`, exits 0.
**update_base** - patches local base from mirror's `patches/packages/` when
ChangeLog head differs (reused from reference script).
5. **SBo tree lookup** - `find_slackbuild_dir`, `category_of`, `pkg_key`,
`read_requires`.
6. **Dependency resolution** - `resolve_target` -> `_resolve_visit` (DFS topo
sort + cycle detection). Outputs `RESOLVED_ORDER[]`, records `UNMET[]`,
`CYCLES[]`, `HAS_README[]`. `installed_in_base` checks base package db.
7. **Overlay lifecycle** - `setup_overlay` (echoes tmpdir, mounts overlay +
binds), `teardown_overlay` (idempotent, correct reverse order), `cleanup_trap`
(EXIT/INT/TERM, unwinds all live overlays).
8. **build_one** - copies SlackBuild into overlay, runs download/md5/build/
installpkg INSIDE the chroot non-interactively via heredoc, reads back a
status token file, sets status maps. Logs resolved .info env up front and
the installed file list (from /var/log/packages) after installpkg, so the
overlay is fully disposable.
9. **run_target** - fresh overlay per target, builds resolved chain in order,
marks `BLOCKED-BY-DEP` on dependents of failures, tears down.
10. **print_summary** - color screen recap + plain `summary.log`.
11. **main** - parse, validate, make `RUN_DIR`, update base, collect targets
(single-package or category-folder), run each.
## Teardown order (do not reorder)
pts -> dev/proc/sys -> resolv.conf -> dbus machine-id -> overlay last.
Matches the reference script. Idempotent (mountpoint-guarded), trap-registered
so a mid-target abort still unwinds. `ACTIVE_MOUNTS[]` tracks live overlays.
## Status values
`SUCCESS DOWNLOAD-FAILED MD5-MISMATCH BUILD-FAILED INSTALL-FAILED
BLOCKED-BY-DEP UNMET-DEP`. `%README%` recorded separately as a reminder flag,
not a status.
## What is verified vs not
- **Verified by self-check** (`test-logic.sh` in repo, `bash test-logic.sh`, no
VM needed): topo order, `%README%` recording, unmet-dep, cycle detection, and
BLOCKED-BY-DEP propagation (`depends_on_failed`, including the transitive
one-hop cascade). The check builds a fake SBo tree and sources the script with
config overridden AFTER sourcing (sourcing re-runs the CONFIG block, so test
vars must be set after the `source`). Gotchas baked in: do not name the dead
list `failed` (collides with `depends_on_failed`'s `local -n failed`), and
`ok`/`bad` must `return 0` (`((x++))` returns nonzero when x was 0).
- **NOT runnable-tested** (needs the VM): overlay mounts, chroot build flow,
base patching, `--init-base` populate, installpkg. Logic mirrors the
reference script / the prior manual populate hint.
## Known shortcuts (ponytail: comments in source)
- `depends_on_failed`: direct-REQUIRES check only. Transitive blocking still
works because the loop runs in topo order, so a failure propagates one hop per
package.
## Open items / TODO
- **`--keep` removed (resolved).** No keep-overlay option. Overlay is always
torn down. Rationale: per-package logs now capture full build/install output,
resolved `.info` env, and the installed file list, so the overlay holds
nothing worth retaining. Do not re-add `--keep` without a reason logs cannot
cover.
- **Package-output cache** (deferred, user wants it next): keep built `.tgz`
outside the overlay, `installpkg` a cached dep instead of rebuilding. Fixes
the "shared deps rebuilt per target" cost in category mode. Likely shape: a
per-run stash in `$RUN_DIR/pkgcache` keyed `prog-version`, reused across
targets within one run. NOT implemented yet.
- **"all" mode**: build every package across all SBo roots. Extension point in
`main` where `targets` is populated. TODO marker in source.
- **queue/list-file mode**: build a named list. Same extension point.
- **`-j` parallelism**: flag parsed, currently no-op. TODO marker in source.
## How to run the self-check
```sh
bash test-logic.sh
```
Covers resolution + BLOCKED-BY-DEP. Extend it (not /tmp scratch files) when
adding logic. Anything VM-dependent (overlay, chroot, installpkg) is out of its
reach by design.
|