Skip to main content

max / alloy

image: settle the package list and guard the console build The cache-split cleanup in the rust-build stage was an unasserted glob. `rm -f target/release/deps/alloy-*` is the only thing keeping cargo from finding the stub `fn main() {}` fresh and uplifting it, and rm exits 0 when a glob matches nothing. If cargo ever changes artifact naming, the image ships a console where every subcommand is a no-op, including `alloy install`, which is the ISO's whole purpose. Remove the fingerprint directory too, and assert the built binary answers --version, the way the makeover themes glob a few lines below is already asserted. distrobox was pinned to `1.8.2.5*`, one build rather than a line. Fedora's updates repo keeps only the newest build and dnf5 install is fatal on an argument that matches nothing, so the day 1.8.3 lands the image stops building with no local change. The pin exists to exclude the v2 Go rewrite, so pin the v1 line. fzf is added for the two TUI menus that land next. foot is removed: it arrives as a weak dependency of sway-config-upstream, whose config binds it as sway's default terminal, and nothing in Alloy invokes it.
Co-Authored-By
Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-22 21:12 UTC
Signed with PGP, not checked
Commit: 773e0831bef9639cbd9f19d1a496446e94264bd5
Parent: 8f0baaf
1 file changed, +45 insertions, -3 deletions
M Containerfile +45 -3
@@ -39,13 +39,31 @@
39 39 RUN mkdir -p crates/alloy/src \
40 40 && echo 'fn main() {}' > crates/alloy/src/main.rs \
41 41 && cargo build --release --locked \
42 - && rm -f target/release/alloy target/release/deps/alloy-*
42 + && rm -rf target/release/alloy target/release/deps/alloy-* \
43 + target/release/.fingerprint/alloy-*
43 44
44 45 # Then the real source. The removals above are what make cargo rebuild
45 46 # the binary rather than find the stub's artifact already in place.
46 47 COPY crates/ crates/
47 48 RUN cargo build --release --locked
48 49
50 + # Assert the stub is gone rather than trusting the glob that removed it.
51 + #
52 + # Those `rm` patterns are the only thing standing between this stage and
53 + # shipping `fn main() {}` as the console: if cargo ever changes artifact
54 + # naming, the glob matches nothing, `rm` still exits 0, cargo finds the unit
55 + # fresh, and the stub is uplifted and copied into the image. Every subcommand
56 + # would then be a silent no-op, including `alloy install`, which is the ISO's
57 + # entire purpose, failing by doing nothing on a machine that was about to be
58 + # repartitioned.
59 + #
60 + # clap's `version` gives the real binary a `--version` that prints its name;
61 + # the stub prints nothing and exits 0. That is the whole difference, so that is
62 + # what gets checked. The makeover themes glob below is asserted for the same
63 + # reason: silently copying nothing rebuilds exactly the failure it fixes.
64 + RUN /src/target/release/alloy --version | grep -q '^alloy ' \
65 + || { echo "built console is the stub; the cache-split cleanup matched nothing" >&2; exit 1; }
66 +
49 67 # The console's themes, staged at a path the runtime stage can name.
50 68 #
51 69 # theme.rs has no built-in palette on purpose (docs/TOKENS.md: no hex in
@@ -199,6 +217,14 @@
199 217 dua-cli \
200 218 # Wayland session glue
201 219 cliphist \
220 + # The fuzzy picker behind both TUI menus in usr/bin: alloy-menu
221 + # ($mod+d, the launcher) and alloy-clipmenu ($mod+Shift+v, the read
222 + # half of the clipboard history). docs/STACK.md rejects graphical
223 + # launchers on thesis and names a terminal fuzzy picker in both
224 + # places; one package is the whole of that, and without it the
225 + # cliphist watchers the sway config has always run had nothing that
226 + # could read them back.
227 + fzf \
202 228 # Lock + idle. swaylock is the adopted lock surface per
203 229 # docs/STACK.md#lock. A session-lock surface is graphical and
204 230 # cannot be a TUI, so Alloy adopts rather than authors it. The
@@ -285,8 +311,15 @@
285 311 # distrobox is pinned. v2 is a Go rewrite, at rc.3 as of 2026-06-29, and
286 312 # upstream's own announcement says v1 stays the production recommendation
287 313 # and that exported binaries and apps must be re-exported after
288 - # upgrading. Fedora's 1.8.2.5 is the pin; moving it wants a release note.
289 - RUN dnf install -y 'distrobox-1.8.2.5*' \
314 + # upgrading. So the pin excludes v2, and nothing narrower.
315 + #
316 + # The v1 *line*, not a build. This read `distrobox-1.8.2.5*` and would have
317 + # hard-failed the whole image build on an upstream event: Fedora's updates
318 + # repo keeps only the newest build, and dnf5 `install` is fatal on an argument
319 + # that matches nothing, so the day 1.8.3 lands the build stops with no local
320 + # change. Moving off the 1.8 line wants a release note; moving within it does
321 + # not, and should not break the build.
322 + RUN dnf install -y 'distrobox-1.8*' \
290 323 && dnf clean all
291 324
292 325 # =====================================================================
@@ -299,6 +332,15 @@
299 332 gdm \
300 333 gnome-shell \
301 334 gnome-session \
335 + # foot, a second terminal nothing in Alloy invokes. It arrives as a
336 + # weak dependency of sway-config-upstream, whose config binds it as
337 + # sway's default terminal; Alloy ships its own config and binds rio
338 + # (docs/STACK.md#terminal), so nothing here ever launches it. Left in,
339 + # it puts three of the eleven entries in the new launcher (Foot, Foot
340 + # Client, Foot Server), which is how an unused package stops being
341 + # merely 0.8 MB of dead weight. Recommends are not requirements, so
342 + # this does not disturb sway-config-upstream itself.
343 + foot \
302 344 || true
303 345
304 346 # =====================================================================