1
0
Fork 0

Gentoo user-packages: skip package if binary exists but not in portage

Some packages on tadbit have binaries installed OUTSIDE portage
(bat was installed by cargo earlier; eza/fd from a previous run
that the script didn't track). qlist -I correctly reports them as
not-in-portage, but command -v <bin> finds them on PATH.

Without this guard, every apply would re-emerge these packages,
causing spurious failures (e.g. 'there are no ebuilds to satisfy
app-text/bat' even though /usr/bin/bat works fine).

The detection now does:
  1. If qlist reports the package is in portage: skip
  2. If the binary is on PATH: log + skip
  3. Otherwise: add to MISSING_PKGS

Same fix applied to the GURU_MISSING detection.
This commit is contained in:
Rain 2026-06-23 16:55:16 -04:00
parent 94d3c0ebaf
commit 03338d1f39

View file

@ -94,21 +94,37 @@ GENTOO_PKGS=(
# check for our purposes is `qlist -I <pkg>` — returns 0 if the # check for our purposes is `qlist -I <pkg>` — returns 0 if the
# package is in the installed-db, 1 if not. But qlist is from # package is in the installed-db, 1 if not. But qlist is from
# gentoolkit and may not be available. Fall back to `equery`. # gentoolkit and may not be available. Fall back to `equery`.
#
# A package may also be installed OUTSIDE portage (e.g. cargo install
# or a tarball extract that landed a binary at /usr/bin/<name>). In
# that case qlist reports missing but the binary exists. To avoid
# re-installing these, also check for the binary on PATH and skip
# the package if it's there.
MISSING_PKGS=() MISSING_PKGS=()
for p in "${GENTOO_PKGS[@]}"; do for p in "${GENTOO_PKGS[@]}"; do
bin_name=$(basename "$p")
bin_on_path=0
command -v "$bin_name" >/dev/null 2>&1 && bin_on_path=1
if command -v qlist >/dev/null 2>&1; then if command -v qlist >/dev/null 2>&1; then
if ! qlist -I "$p" >/dev/null 2>&1; then if qlist -I "$p" >/dev/null 2>&1; then
: # installed via portage
elif (( bin_on_path )); then
log "$p: not in portage, but $bin_name found on PATH (skipped)"
else
MISSING_PKGS+=("$p") MISSING_PKGS+=("$p")
fi fi
elif command -v equery >/dev/null 2>&1; then elif command -v equery >/dev/null 2>&1; then
if ! equery -q list "$p" 2>/dev/null | grep -q "^$p"; then if equery -q list "$p" 2>/dev/null | grep -q "^$p"; then
: # installed via portage
elif (( bin_on_path )); then
log "$p: not in portage, but $bin_name found on PATH (skipped)"
else
MISSING_PKGS+=("$p") MISSING_PKGS+=("$p")
fi fi
else else
# Last resort: try a few common binary names per package # Last resort: just check the binary on PATH
# (most have one matching the basename) if ! (( bin_on_path )); then
bin_name=$(basename "$p")
if ! command -v "$bin_name" >/dev/null 2>&1; then
MISSING_PKGS+=("$p") MISSING_PKGS+=("$p")
fi fi
fi fi
@ -143,8 +159,21 @@ GURU_PKGS=(
GURU_MISSING=() GURU_MISSING=()
for p in "${GURU_PKGS[@]}"; do for p in "${GURU_PKGS[@]}"; do
bin_name=$(basename "$p") bin_name=$(basename "$p")
if ! command -v "$bin_name" >/dev/null 2>&1; then bin_on_path=0
GURU_MISSING+=("$p") command -v "$bin_name" >/dev/null 2>&1 && bin_on_path=1
if command -v qlist >/dev/null 2>&1; then
if qlist -I "$p" >/dev/null 2>&1; then
: # already in portage
elif (( bin_on_path )); then
log "$p: not in portage, but $bin_name found on PATH (skipped)"
else
GURU_MISSING+=("$p")
fi
else
if ! (( bin_on_path )); then
GURU_MISSING+=("$p")
fi
fi fi
done done