Files
command-center/scripts/lib/manifest.sh
Frank 06f45e83c1 refactor(packages): one manifest parser, so a name means one thing to both tools
install.sh and pkg-inventory.sh carried byte-identical copies of read_manifest.
That is the duplicated-code half of the problem; the worse half is untested —
neither script had any test for the grammar that decides what gets installed.

- scripts/lib/manifest.sh is the parser; both scripts source it
- tests/manifest-parser.bats writes the contract first (comments, CRLF, first
  field only, unreadable file fails loudly instead of yielding "nothing desired")
- an unreadable manifest now fails inside the helper rather than depending on
  whichever `set` options the caller happens to run under
- install.sh check mode verified end to end against a stubbed pacman: a CRLF
  manifest with trailing comments resolves to bare names, installed names drop

Refs #60
2026-10-21 00:54:31 -07:00

24 lines
1.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# scripts/lib/manifest.sh — the one parser for packages/*.pkgs
#
# install.sh walks desired → installed; pkg-inventory.sh walks installed → declared. Both read the
# same hand-written manifests, so both must agree on what a line MEANS: if one forgives an inline
# comment and the other does not, the same name is simultaneously "desired" and "drift", and the
# pair stops being a check on the machine. Source it — do not paste the body into a caller again
# (Refs #60: it was pasted twice, in install.sh and in pkg-inventory.sh).
#
# Contract, and tests/manifest-parser.bats is that contract:
# name first field of a line, emitted as one bare token — callers hand it to pacman
# comment `#` and everything after it is dropped, whole-line or trailing
# CRLF stripped (the manifests are edited on more than one box)
# blank empty and whitespace-only rows vanish
# unreadable non-zero exit, no names: a silent empty list reads as "nothing desired", and a
# rebuild would then install nothing while reporting success
#
# Sourced, never executed; callers own `set -euo pipefail`.
read_manifest() { # $1 = manifest path; prints one package name per line
[[ -r "$1" ]] || { printf 'read_manifest: cannot read %s\n' "$1" >&2; return 2; }
sed 's/#.*//' "$1" | tr -d '\r' | awk '{if ($1) print $1}'
}