4043787a58
- DU-H1: flags are parsed wherever they sit, so `install --unattended` and `--unattended install` are the same run; any unknown flag, word, or subcommand exits 2 to stderr before a package manager is touched. - DU-H2: every download lands in one private mktemp -d (mode 700) workdir per run, is checked non-empty before sudo tar sees it, and an EXIT/INT/TERM trap cleans up. No fixed /tmp paths remain. - BUG-1: ^t is now toggle-shown — it ticks only the rows the active filter is showing, and @needs expansion stops at the first invasive row, so an invasive package can never be ticked off-screen. - BUG-2: ^t journals what it added, so a second ^t over the same shown set unticks exactly that set; the bind no longer clears the query. - lab: the type verb polls fzf's reported query to a deadline instead of a fixed sleep; marks_settled retries within its deadline. Suite 256/0 host, 214/0 docker (ubuntu:24.04), mutations 24/24 killed (six new mutants re-introduce each bug and all die), lab 6/6 green.
110 lines
4.8 KiB
Bash
Executable File
110 lines
4.8 KiB
Bash
Executable File
#!/bin/sh
|
|
# Build a SEALED bin directory: the whole of $PATH for a run under test.
|
|
#
|
|
# sh seal.sh <dir> [--with name ...] [--without name ...]
|
|
#
|
|
# The old harness prepended .tests/fakebin to the caller's $PATH. That fails
|
|
# OPEN: a package manager with no fake here simply fell through to the real one,
|
|
# and an audit of this suite invoked the host's actual `brew`. The seal fails
|
|
# CLOSED. It holds exactly two kinds of thing --
|
|
#
|
|
# REAL pure, local, side-effect-free tools dotup is entitled to use: awk,
|
|
# sed, install, sha256sum, tar. Faking these would weaken the test;
|
|
# `sha256sum` in particular has to be the real one or the checksum
|
|
# comparison is checking a fixture against itself.
|
|
# FAKE anything that installs, downloads, or needs root. Symlinks to _fake.
|
|
#
|
|
# -- and nothing else. A tool that is neither is command-not-found, which is a
|
|
# visible failure rather than a silent hand-off to the machine.
|
|
#
|
|
# One hole cannot be closed from here and is reported rather than hidden:
|
|
# find_tool probes /usr/local/bin, /usr/local/go/bin, /home/linuxbrew/... and
|
|
# /opt/homebrew/bin by ABSOLUTE path, so on a developer box those directories
|
|
# can satisfy a lookup no matter what PATH says. The seal therefore ships a fake
|
|
# for every name that is shadowed there -- `command -v` is tried first, so the
|
|
# fake wins -- and writes the shadow list to <dir>/.shadowed so a test that
|
|
# needs a tool to be genuinely ABSENT can say so instead of quietly passing.
|
|
set -eu
|
|
|
|
# gzip is here because tar shells out to it: without it `tar xz` dies with
|
|
# "gzip: not found" -- which is the seal working, and is how it was found.
|
|
REAL='sh awk grep sed sort cut tr head tail id uname mkdir cp mv rm cat
|
|
dirname basename chmod mktemp find install sha256sum stty tar gzip ln
|
|
touch true false env expr wc stat'
|
|
# Deliberately NOT here by default, each for a reason a test depends on:
|
|
# sudo absent means SUDO='' and apt-get is invoked directly, which is the
|
|
# only way FAKE_FAIL=apt-get can reach the installer at all.
|
|
# fzf absent is what makes ensure_fzf actually fetch one.
|
|
# bws absent is what makes the private tier actually install it.
|
|
FAKE='curl apt-get apt-cache brew npm uv snap flatpak xcode-select
|
|
git dpkg unzip chezmoi'
|
|
OPTIONAL='sudo fzf bws nvim go node'
|
|
|
|
dir=${1:?usage: seal.sh <dir> [--with name ...] [--without name ...]}; shift
|
|
# Everything the seal KNOWS about, fixed before --without takes anything out: a
|
|
# hole punched on purpose is still an accounted-for tool, and must not trip the
|
|
# coverage audit below.
|
|
KNOWN="$REAL $FAKE $OPTIONAL"
|
|
mode=
|
|
for a in "$@"; do
|
|
case $a in
|
|
--with) mode=with ;;
|
|
--without) mode=without ;;
|
|
*) case $mode in
|
|
with) FAKE="$FAKE $a"; KNOWN="$KNOWN $a" ;;
|
|
without) FAKE=$(printf '%s\n' $FAKE | grep -vx "$a" | tr '\n' ' ') ;;
|
|
*) echo "seal.sh: stray argument $a" >&2; exit 2 ;;
|
|
esac ;;
|
|
esac
|
|
done
|
|
|
|
here=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
FB=$here/fakebin
|
|
[ -x "$FB/_fake" ] || { echo "seal.sh: no $FB/_fake" >&2; exit 1; }
|
|
|
|
rm -rf "$dir"; mkdir -p "$dir"
|
|
ln -s "$FB/_fake" "$dir/_fake"
|
|
ln -s "$FB/_curl" "$dir/_curl"
|
|
|
|
# Resolved by looking, not by `command -v`: an interactive shell reports
|
|
# aliases and functions, and a symlink to a bare name is a loop.
|
|
miss=
|
|
for t in $REAL; do
|
|
found=
|
|
for bd in /usr/bin /bin /usr/local/bin /sbin /usr/sbin; do
|
|
[ -x "$bd/$t" ] && { ln -sf "$bd/$t" "$dir/$t"; found=1; break; }
|
|
done
|
|
[ -n "$found" ] || miss="$miss $t"
|
|
done
|
|
[ -z "$miss" ] || { echo "seal.sh: host is missing real tools:$miss" >&2; exit 1; }
|
|
|
|
for t in $FAKE; do ln -sf "$dir/_fake" "$dir/$t"; done
|
|
|
|
# ------------------------------------------------------------- the audits ---
|
|
# 1. Anything dotup probes for must be accounted for. A new `have foo` with no
|
|
# fake would otherwise fall through to the host the moment someone adds one.
|
|
D=${DOTUP_SEAL_TARGET:-$here/../dot_local/bin/executable_dotup}
|
|
probes=$(grep -v '^[[:space:]]*#' "$D" \
|
|
| grep -oE '\b(have|find_tool) [a-z][a-z0-9-]*' \
|
|
| awk '{print $2}' | sort -u || :)
|
|
unknown=
|
|
for p in $probes; do
|
|
case " $KNOWN " in *" $p "*) ;; *) unknown="$unknown $p" ;; esac
|
|
done
|
|
[ -z "$unknown" ] || {
|
|
echo "seal.sh: dotup probes for tools the seal has never heard of:$unknown" >&2
|
|
echo " add them to REAL, FAKE or OPTIONAL -- do not let them fall through" >&2
|
|
exit 1; }
|
|
|
|
# 2. The absolute-path hole, reported rather than papered over. $KNOWN, not
|
|
# $FAKE: a name taken out with --without is exactly the name a test wants to
|
|
# be absent, so it is the one that most needs checking.
|
|
: > "$dir/.shadowed"
|
|
for t in $KNOWN; do
|
|
for bd in /usr/local/bin /usr/local/go/bin /home/linuxbrew/.linuxbrew/bin /opt/homebrew/bin; do
|
|
[ -x "$bd/$t" ] || continue
|
|
[ -e "$dir/$t" ] || printf '%s\t%s\n' "$t" "$bd/$t" >> "$dir/.shadowed"
|
|
done
|
|
done
|
|
printf '%s\n' "$dir"
|