<feed xmlns='http://www.w3.org/2005/Atom'>
<title>archangel/Makefile, branch main</title>
<subtitle>Arch Linux installer ISO — ZFS-on-root or BTRFS, doubles as rescue disk
</subtitle>
<id>https://git.cjennings.net/archangel/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/archangel/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/'/>
<updated>2026-06-10T04:37:07+00:00</updated>
<entry>
<title>feat(build): add AUR local-repo build helpers</title>
<updated>2026-06-10T04:37:07+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-10T04:37:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=5e43d8c4ad8685e88331ac78641ca84666cb9e7a'/>
<id>urn:sha1:5e43d8c4ad8685e88331ac78641ca84666cb9e7a</id>
<content type='text'>
Add build-aur.sh, sourced by build.sh, that builds the v1 genuine-AUR set into a local pacman repo and emits an auditable manifest. The pure helpers carry the testable surface: the package sets (one source of truth for the build array and the package-list append), the [aur] stanza renderer, the TSV manifest header/row, the package-file locator, the staged repo replacement, and the build-environment preflight.

makepkg refuses to run as root, so the orchestrator drops to $SUDO_USER for the clone and build. It stages on the same filesystem and swaps in with mv -T on full success, so a failure ships no repo and leaves no stale one. On any failure error() names the package, the phase, and the log path.

The orchestrator and manifest-append need root, network, and makepkg, so they stay out of bats and are covered by the build integration test and the manual checklist instead. Eighteen unit tests cover the pure helpers across Normal, Boundary, and Error.
</content>
</entry>
<entry>
<title>feat: consolidate zfssnapshot and zfsrollback into one subcommand-driven script</title>
<updated>2026-04-27T23:33:03+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-27T23:33:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=422d1098cd89beaeed81cc40488252233e2ca0ad'/>
<id>urn:sha1:422d1098cd89beaeed81cc40488252233e2ca0ad</id>
<content type='text'>
Problem: zfssnapshot and zfsrollback were two separate scripts with overlapping pre-flight checks (zfs / fzf / root) and parallel UX patterns (description sanitization in one, fzf selection in the other). Users had to remember which script was for which operation, and a "list" view meant typing the raw `zfs list -t snapshot` command. There was no path to destroy individual snapshots short of `zfs destroy` directly, which is dangerous without a confirmation flow.

Solution: rewrite zfssnapshot as a single multi-subcommand script (list, create, rollback, delete). Drop installer/zfsrollback. The new script uses a source-guard at the bottom (`if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then main "$@"; fi`) so bats can source it without triggering the install-time pre-flight checks, matching the pattern in installer/archangel.

Pure helpers (sanitize_description, validate_description, format_snapshot_name) get extracted as named functions so they're testable in isolation. The destructive flows (rollback, delete) keep the explicit "yes" confirmation prompt, the genesis-snapshot warning, and the recursive-rollback-destroys-newer-snapshots warning. Delete uses fzf --multi so the user can pick several snapshot names at once.

Updated build.sh to copy only the consolidated script. Dropped the zfsrollback profiledef permission line. Updated Makefile, README, scripts/sanity-test.sh, and testing-strategy.org to reflect the single-script layout.

Bats: 147 → 168 (+21). Coverage spans sanitize_description (normal / boundary / error), validate_description (alphanumerics, hyphens, underscores accepted; spaces, slashes, shell metacharacters, empty rejected), format_snapshot_name (timestamp + description composition), and main subcommand dispatch (list / create / rollback / delete / help / unknown). Lint clean. The zfs-, fzf-, and arch-chroot-shelling subcommand bodies stay VM-tested per testing-strategy.org.
</content>
</entry>
<entry>
<title>fix: don't mask test-install exit codes through tee</title>
<updated>2026-04-22T01:25:21+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-22T01:25:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=5d677360721ec3ea0f3624ca2a2f20e7241bfba8'/>
<id>urn:sha1:5d677360721ec3ea0f3624ca2a2f20e7241bfba8</id>
<content type='text'>
The Makefile let failures slip through silently when the caller piped
output: `make test-install 2&gt;&amp;1 | tee log` returned 0 even when the
inner build or VM run failed, because tee's zero exit masked the
pipeline. This happened today during an ISO rebuild — the first
attempt failed on corrupted pacman cache but the task notification
reported exit 0.

Two changes:

1. Set the recipe shell flags to enable pipefail (`SHELL := /bin/bash`
   + `.SHELLFLAGS := -o pipefail -c`). Any intra-recipe pipeline now
   propagates the first non-zero exit instead of the last. Safe to
   add — no existing recipe uses intra-recipe pipes today.

2. Bake tee into the test-install recipe itself. Output writes to
   `test-logs/make-test-install-YYYY-MM-DD-HHMM.log` so callers never
   need to pipe through tee externally. With SHELLFLAGS pipefail in
   place, the test script's exit code propagates through the baked-in
   tee back to the caller cleanly.

Verified with a repro: a recipe shaped like `failing-cmd | tee log`
returns non-zero; the 71-test bats suite still passes.
</content>
</entry>
<entry>
<title>test: add bats unit tests for common.sh and config.sh</title>
<updated>2026-04-13T03:48:14+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-04-13T03:48:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=863ceeac8fdb10258a58d35bcee6874097fffc88'/>
<id>urn:sha1:863ceeac8fdb10258a58d35bcee6874097fffc88</id>
<content type='text'>
23 bats tests covering the pure logic in installer/lib/common.sh
(command_exists, require_command, info/warn/error, enable_color,
require_root, log) and installer/lib/config.sh (parse_args, load_config,
validate_config, check_config). Makefile adds a 'bats' target; 'test'
now runs lint + bats (VM integration tests remain under test-install).
</content>
</entry>
<entry>
<title>refactor: rename vm-* Makefile targets to test-* for discoverability</title>
<updated>2026-02-24T13:58:15+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-24T13:58:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=cbe5c9d237f2ced2ea7bc91c213b25810b2fc2b0'/>
<id>urn:sha1:cbe5c9d237f2ced2ea7bc91c213b25810b2fc2b0</id>
<content type='text'>
</content>
</entry>
<entry>
<title>feat: add Makefile targets for manual VM testing</title>
<updated>2026-02-24T13:57:34+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-24T13:57:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=25513d9631c182a9b5df5b19cb9450b671e67d39'/>
<id>urn:sha1:25513d9631c182a9b5df5b19cb9450b671e67d39</id>
<content type='text'>
Add vm, vm-multi, vm-multi3, vm-boot, and vm-clean targets. Update
README to reference make targets instead of raw script invocations.
</content>
</entry>
<entry>
<title>chore: remove default Makefile target, update README overview</title>
<updated>2026-02-23T21:33:43+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-23T21:33:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=0c0d6009c0590facbaab8c79cbb27954c5ec2ae6'/>
<id>urn:sha1:0c0d6009c0590facbaab8c79cbb27954c5ec2ae6</id>
<content type='text'>
</content>
</entry>
<entry>
<title>refactor: rename custom/ to installer/ for clarity</title>
<updated>2026-02-23T17:54:25+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-23T17:54:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=fd2ea796b20bcbebea19c43978fb08e3cd6754ed'/>
<id>urn:sha1:fd2ea796b20bcbebea19c43978fb08e3cd6754ed</id>
<content type='text'>
The custom/ directory name was an archiso implementation detail. Renamed
to installer/ which clearly communicates that this directory contains the
installer scripts and utilities that ship on the ISO.

Updated all references in build.sh, Makefile, test-install.sh, and README.
</content>
</entry>
<entry>
<title>chore: standardize shebangs, fix lint target, add .editorconfig</title>
<updated>2026-02-23T11:27:27+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-23T11:27:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=a171caf0b0a5541246f994155406e840b28390de'/>
<id>urn:sha1:a171caf0b0a5541246f994155406e840b28390de</id>
<content type='text'>
- Change all script shebangs to #!/usr/bin/env bash for portability
  (heredocs writing to installed systems keep #!/bin/bash)
- Remove || true from Makefile lint target so shellcheck errors fail the build
- Add .editorconfig for consistent formatting across editors
</content>
</entry>
<entry>
<title>remove skeleton archsetup-zfs script</title>
<updated>2026-02-23T05:22:26+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-02-23T05:22:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/archangel/commit/?id=b8f4bf5e9caae747345dfab05ef9e5c2b2cb6de6'/>
<id>urn:sha1:b8f4bf5e9caae747345dfab05ef9e5c2b2cb6de6</id>
<content type='text'>
Non-functional stub that printed "this is a skeleton" — worse than
not having it. Removed from build.sh, Makefile, and file permissions.
</content>
</entry>
</feed>
