summaryrefslogtreecommitdiffstats
path: root/CLAUDE.md
diff options
context:
space:
mode:
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md153
1 files changed, 153 insertions, 0 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..9d4cd5f
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,153 @@
+# sbo-dockerbuild
+
+Docker-based toolchain for test-building [SlackBuilds.org (SBo)](https://slackbuilds.org)
+packages on Slackware, on both `-current` and `15.0`, in throwaway containers.
+
+Extracted from the `.extras/` dir of the **sbo-slackbuilds** package repo (danix's
+SBo maintenance mirror) once it grew from a helper into a standalone tool. Git
+history starts fresh here; the original 41-commit log is preserved in
+[HISTORY.md](HISTORY.md) (those hashes refer to sbo-slackbuilds, not this repo).
+
+## What this repo is (and is not)
+
+This is the **tooling**, not packages. It builds and consumes docker images to
+verify that a SlackBuild still builds; it does not itself contain SlackBuilds.
+The packages live in the maintenance repo (sbo-slackbuilds) and other repos.
+
+Two cooperating tools, one shared set of images:
+
+- **`test-build`** — verify a single SlackBuild builds cleanly in a container.
+- **`image-builder/`** — build the images `test-build` consumes.
+
+## Layout
+
+```
+test-build the test-build tool (single bash script)
+install.sh copy test-build into ~/bin (BINDIR= to override)
+test-logic.sh pure-logic self-check for test-build (no docker)
+test-build-config.example copy to ~/.config/sbo-testbuild/config and edit
+overrides.example current-vs-stable dep overrides (optional)
+image-builder/ bootstrap.sh, build-full-image.sh,
+ build-sbo-testbuild.sh, lib.sh, config,
+ test-image-builder.sh, README
+docs/specs, docs/plans design specs and implementation plans
+```
+
+Everything is at the repo root (flat), not under `.extras/` — that nesting was a
+sbo-slackbuilds convention and does not apply here.
+
+## test-build
+
+Resolves and builds a SlackBuild in a disposable Slackware container, then lints
+it. The **target** is the local SlackBuild under edit; its **dependencies** come
+from a configured SBo tree. These are two different sources — do not conflate
+them (an earlier bug resolved the target from the tree, testing the published
+version instead of the edit).
+
+### Target resolution (`resolve_target_dir`)
+
+Repo-agnostic, driven by where you are:
+
+- a **path** (absolute, `./x`, or containing `/`): that directory
+- a **bare name**: `./<name>/` under CWD, else CWD itself if it *is* `<name>/`
+
+So `cd pkgdir && test-build <name>`, `test-build /path/to/pkg`, and
+`test-build ./pkg` all work.
+
+### Dependency resolution
+
+Deps are resolved from the SBo tree in the config (`SBO_TREE_CURRENT` /
+`SBO_TREE_STABLE`), topologically sorted, cycle-checked. A dep is satisfied by:
+
+1. building it from the tree (recursively), or
+2. `installed_in_base` — already present in the full-install image (queried once
+ per run from the image's `/var/log/packages`), or
+3. an override (see below).
+
+Deps build first and are cached; the target always rebuilds (that is the test).
+
+### current-vs-stable overrides
+
+`~/.config/sbo-testbuild/overrides` (see `overrides.example`), applied **only on
+-current** (15.0 is the SBo baseline). Verbs:
+
+- `drop: <dep>` — a 15.0-only SBo dep whose payload the -current base already
+ ships (e.g. `rust-opt`, `google-go-lang`, `cmake-opt`, `llvm-opt`,
+ `python3-installer`, `python3-build`). Satisfied at resolution: not built, not
+ UNMET.
+- `rename: <old> -> <new>` — dep renamed on -current.
+- `fetch: <prog>` — dep removed from the -current tree; built via `sbopkg` in
+ the container.
+
+### The build container
+
+One `docker run --rm -i` per package (the `-i` is required — without it `bash -s`
+gets no stdin and the heredoc is silently discarded). Inside, as root:
+installs already-built deps, sources `/etc/profile.d/*.sh` (so dep-provided env
+like google-go-lang's `GOROOT`/`PATH` is live in the non-login shell), builds the
+SlackBuild, `installpkg`s it, and runs `sbopkglint` **in-container** (it shells
+out to sudo, which only works as root here; never lint on the host). The host
+reads a `LINT-CLEAN`/`LINT-FINDINGS` marker from the log.
+
+### Dep cache
+
+Host dir (`PKG_CACHE`), namespaced `<variant>-<image-digest>/`. An image rebuild
+changes the digest and self-invalidates the cache. Each run prunes superseded
+digests **of the same variant only**, so a `--current` run does not wipe the
+`15.0` cache (both live caches survive; testing both trees back-to-back reuses
+built deps). Only **deps** are cached, never the target.
+
+### Flags
+
+`--stable` (15.0), `--dry-run`, `--yes`, `--no-cache`, `--keep` (copy the built
+target `.txz` to `<data>/kept/` so it can be installed on the host, e.g. to
+regenerate post-install artifacts), `--no-color`.
+
+## image-builder
+
+Three chained scripts build the images, each self-gated so an unchanged night is
+a cheap no-op:
+
+- `bootstrap.sh` → `sbo-base:{ver}` FROM scratch (gated on the mirror's
+ `ChangeLog.txt` hash)
+- `build-full-image.sh` → `sbo-full:{ver}` all series (gated on base digest;
+ `--force` prunes the build cache first)
+- `build-sbo-testbuild.sh` → `sbo-testbuild:{ver}` + sbopkg + maintainer-tools
+ (gated on full digest + tools `.txz` hash)
+
+All settings in `image-builder/config`. Full setup (NFS mirror mounts, LAN
+registry, prebuilt pkgs, cron) is in `image-builder/README`.
+
+**Main-loop gotcha:** each script runs its `build_variant` in an `if ! (...)`
+condition, which suppresses `set -e` inside the subshell. So `docker build` /
+`docker push` failures are caught with **explicit** `if ! ...; return 1` checks,
+not by relying on `set -e`. Keep that pattern when editing.
+
+## Testing
+
+Pure-logic self-checks, no docker, no network:
+
+```bash
+bash test-logic.sh # test-build resolver/overrides/cache
+bash image-builder/test-image-builder.sh # image-builder lib.sh logic
+```
+
+Non-trivial logic changes get a check here. The docker build path itself is
+verified by running `test-build` against a real image.
+
+## Conventions
+
+- Plain bash, single-file scripts where practical, minimal dependencies.
+- `set -euo pipefail` in executables; guard `set -e` around subshell conditions
+ (see the image-builder gotcha).
+- GPLv2-only. Every source file carries a short GPL header notice.
+- No em dashes in prose.
+
+## Deployment
+
+The image-builder scripts run on the docker host VM (`docker.noland.dnx`,
+reached via the `docker` SSH host alias, root login), deployed under
+`/opt/sbo-testbuild/image-builder/`. A nightly cron rebuilds both variants after
+the repo syncs. Treat the VM as outward-facing: confirm before deploying, and
+inspect a target before overwriting it. After editing a script here, sync it to
+the VM so the cron runs the current version.