Files
skeptical-updater/tests/unit/fakes/zypper/zypper
T
bryanpedini 71d7f87aa3 feat(info): show the install reason and drop the indentation
N? and `info PKG` now print three lines, none indented:

    PKG: <description>
    reason: explicitly installed | installed as a dependency | unknown | not installed
    required by: <installed dependents, comma separated> | nothing

The reason comes from a new <be>_reason backend function: apt-mark
showauto / showmanual (dpkg decides for a package in neither list), the
Install Reason of pacman -Qi, dnf repoquery --installed %{reason} (dnf4
and dnf5 words) and the Installed line of zypper info (rpm plus libzypp's
AutoInstalled when zypper is locked). A row whose old version is "-" is
not installed and the backend is not asked. The "(installed)" qualifier
moves to --help, README and DESIGN.

The rpm E2E fixture and e2e_reset now also mark su-dummy-a and su-dummy-c
as user-installed on dnf, which records plain rpm installs as "unknown",
so 1? and 2? show both reasons on all 12 distros. The verified commands
are recorded in discovery/{apt,pacman,rpm}.md.
2026-10-10 13:32:42 +02:00

113 lines
3.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2026 Bryan Joshua Pedini
# fake zypper (unit tests). FAKE_ZYPPER_LU=fixture|real|none picks the list-updates XML,
# FAKE_ZYPPER_DUP=fixture|empty|removes the `dist-upgrade --dry-run` plan (data/zypper/dup-*.xml).
# addlock writes real zypp lock entries into the locksfile.path of $ZYPP_CONF (default
# /etc/zypp/locks is never touched: the fake refuses); update/dist-upgrade log that file.
# info replays data/zypper/info-NAME.txt (exit 104 without one); FAKE_ZYPPER_INFO_RC=7 makes it fail
# like a zypp lock held by another process.
# shellcheck source=../fakelib.bash
. "${BASH_SOURCE[0]%/*}/../fakelib.bash"
fake_log "${ZYPP_CONF:+ZYPP_CONF=$ZYPP_CONF }$*"
D=$FAKE_DATA/zypper
locksfile() {
local f=${ZYPP_CONF:-} line l=
[[ -n $f && -r $f ]] || return 1
while IFS= read -r line; do
[[ $line =~ ^[[:space:]]*locksfile\.path[[:space:]]*=[[:space:]]*(.*)$ ]] && l=${BASH_REMATCH[1]}
done <"$f"
[[ -n $l ]] || return 1
printf '%s' "$l"
}
pos=()
for a in "$@"; do case $a in -*) ;; *) pos+=("$a") ;; esac; done
verb=${pos[0]:-}
args=("${pos[@]:1}")
xml_remove() { # the install-summary of `remove --dry-run` for the given names
local n
printf "<?xml version='1.0'?>\n<stream>\n<install-summary download-size=\"0\" space-usage-diff=\"-30\" packages-to-change=\"%s\">\n<to-remove>\n" "$#"
for n in "$@"; do printf '<solvable type="package" name="%s" edition="1.0-1" arch="noarch" repository="@System" summary="dummy %s"><description>d</description></solvable>\n' "$n" "$n"; done
printf '</to-remove>\n</install-summary>\n</stream>\n'
}
dry=0
case " $* " in *' --dry-run '*) dry=1 ;; esac
case $verb in
refresh)
rc=$(fake_rc FAKE_ZYPPER_REFRESH_RC 0)
((rc == 0)) || echo "Could not refresh the repositories because of errors." >&2
exit "$rc"
;;
list-updates) cat "$D/lu-${FAKE_ZYPPER_LU:-fixture}.xml" ;;
info)
p=${args[-1]}
if [[ -n ${FAKE_ZYPPER_INFO_RC:-} ]]; then
echo "System management is locked by the application with pid 4242 (zypper)."
echo "Close this application before trying again."
exit "$FAKE_ZYPPER_INFO_RC"
fi
if [[ -f $D/info-$p.txt ]]; then cat "$D/info-$p.txt"; else
echo "package '$p' not found."
exit 104
fi
;;
addlock)
l=$(locksfile) || {
echo "fake zypper: addlock without a private ZYPP_CONF/locksfile.path" >&2
exit 98
}
for p in "${args[@]}"; do printf '\ntype: package\nmatch_type: glob\ncase_sensitive: on\nsolvable_name: %s\n\n' "$p" >>"$l"; done
;;
dist-upgrade | dup | update)
if ((dry)); then
cat "$D/dup-${FAKE_ZYPPER_DUP:-fixture}.xml"
exit 0
fi
if l=$(locksfile); then { echo "--- locks seen by $verb:"; cat "$l"; echo "--- end"; } >>"$FAKE_LOG"; fi
if [[ -n ${ZYPP_CONF:-} && -n ${SKEPTICAL_UPDATER_STATE_DIR:-} && -e $SKEPTICAL_UPDATER_STATE_DIR/zypper.lock ]]; then
if flock -n "$SKEPTICAL_UPDATER_STATE_DIR/zypper.lock" true; then l=free; else l=held; fi
echo "zypper.lock during $verb: $l" >>"$FAKE_LOG"
fi
if [[ -n ${FAKE_ZYPPER_UPGRADE_KILL:-} ]]; then
kill -s "$FAKE_ZYPPER_UPGRADE_KILL" "$PPID"
sleep 0.2
fi
exit "$(fake_rc FAKE_ZYPPER_UPGRADE_RC 0)"
;;
remove)
if ((dry)); then
set -- "${args[@]}"
# FAKE_ZYPPER_CLEAN="pkg:dep" (unneeded dependency) / FAKE_ZYPPER_EXTRA="pkg:other" join the plan
more=()
for r in ${FAKE_ZYPPER_CLEAN:-} ${FAKE_ZYPPER_EXTRA:-}; do [[ ${r%%:*} == "${1:-}" ]] && more+=("${r#*:}"); done
case ${1:-} in
su-dummy-b) xml_remove su-dummy-a su-dummy-b "${more[@]}" ;;
su-dummy-*) xml_remove "$1" "${more[@]}" ;;
*)
echo "'$1' not found in package names. Trying capabilities."
echo "No provider of '$1' found."
exit 104
;;
esac
exit 0
fi
for p in "${args[@]}"; do
case $p in su-dummy-*) ;; *)
echo "'$p' not found in package names. Trying capabilities."
echo "No provider of '$p' found."
exit 104
;;
esac
done
fake_mark_purged "${args[@]}"
;;
*)
echo "fake zypper: unhandled: $*" >&2
exit 99
;;
esac