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
This commit is contained in:
1 parent
40b9725433
commit
06f45e83c1
4 files changed
+86
-8
No files matched your search
+3
-4
@@ -17,7 +17,8 @@
|
||||
# otherwise sudo prompts normally. The value is never stored in this repo.
|
||||
set -euo pipefail
|
||||
|
||||
REPO="$(git -C "$(dirname "$(realpath "$0")")" rev-parse --show-toplevel 2>/dev/null || true)"
|
||||
HERE="$(dirname "$(realpath "$0")")"
|
||||
REPO="$(git -C "$HERE" rev-parse --show-toplevel 2>/dev/null || true)"
|
||||
REPO="${INSTALL_REPO:-$REPO}"
|
||||
[ -n "$REPO" ] && [ -d "$REPO/packages" ] || { echo "install.sh: no packages/ under ${REPO:-<repo>}" >&2; exit 1; }
|
||||
|
||||
@@ -36,9 +37,7 @@ SUDO() {
|
||||
else sudo "$@"; fi
|
||||
}
|
||||
|
||||
read_manifest() { # $1 = manifest path; emits package names, strips comments/blanks
|
||||
sed 's/#.*//' "$1" | tr -d '\r' | awk '{if ($1) print $1}'
|
||||
}
|
||||
source "$HERE/lib/manifest.sh" # the same parser pkg-inventory.sh reads with
|
||||
# ---- desired-minus-installed delta ------------------------------------------
|
||||
PKGS=()
|
||||
for m in common.pkgs "$HOST.pkgs"; do
|
||||
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/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}'
|
||||
}
|
||||
Reference in new issue
Block a user