Drop default --noconfirm (opt-in via --noconfirm), fix --noremovemake, forward pacman argv intact for -R/-D/-F/-T/-U, deepen PKGBUILD review, show an install plan before building, and add shellcheck CI plus unit tests. Co-authored-by: Frank Vitrano <WHC2006@users.noreply.github.com>
304 lines
7.6 KiB
Bash
304 lines
7.6 KiB
Bash
#!/usr/bin/env bash
|
|
# Dispatch handlers for miaur operations
|
|
|
|
# Reconstruct pacman argv from OP + PACMAN_EXTRA + targets for passthrough
|
|
pacman_passthru() {
|
|
local -a args=("$@")
|
|
as_root ${MIAUR_PACMAN} "${args[@]}"
|
|
}
|
|
|
|
# Search repo + AUR
|
|
cmd_search() {
|
|
local -a terms=("$@")
|
|
[[ ${#terms[@]} -eq 0 ]] && die "specify a search query"
|
|
local query="${terms[*]}"
|
|
|
|
local -a repo_lines=() aur_lines=()
|
|
|
|
if [[ ${MIAUR_MODE:-} != aur ]]; then
|
|
mapfile -t repo_lines < <(${MIAUR_PACMAN} -Ss "$query" 2>/dev/null || true)
|
|
fi
|
|
|
|
if [[ ${MIAUR_MODE:-} != repo ]]; then
|
|
local line name ver votes pop desc
|
|
while IFS='|' read -r name ver votes pop desc; do
|
|
[[ -z $name ]] && continue
|
|
aur_lines+=("$(aur_format_search_line "$name" "$ver" "$votes" "$pop" "$desc")")
|
|
done < <(aur_search "$query" || true)
|
|
fi
|
|
|
|
if [[ ${MIAUR_BOTTOMUP:-0} -eq 1 ]]; then
|
|
local l
|
|
for l in "${aur_lines[@]}"; do printf '%b\n' "$l"; done
|
|
[[ ${#repo_lines[@]} -gt 0 && ${#aur_lines[@]} -gt 0 ]] && echo
|
|
local r
|
|
for r in "${repo_lines[@]}"; do printf '%s\n' "$r"; done
|
|
else
|
|
local r
|
|
for r in "${repo_lines[@]}"; do printf '%s\n' "$r"; done
|
|
[[ ${#repo_lines[@]} -gt 0 && ${#aur_lines[@]} -gt 0 ]] && echo
|
|
local l
|
|
for l in "${aur_lines[@]}"; do printf '%b\n' "$l"; done
|
|
fi
|
|
}
|
|
|
|
# Interactive search + install (like `paru foo`)
|
|
cmd_interactive() {
|
|
local query="$*"
|
|
[[ -z $query ]] && die "specify a search query"
|
|
|
|
local -a entries=() # type|name
|
|
local -a display=()
|
|
|
|
# Repo results
|
|
if [[ ${MIAUR_MODE:-} != aur ]]; then
|
|
local line repo name rest
|
|
while IFS= read -r line; do
|
|
[[ $line =~ ^([a-z0-9_-]+)/([^[:space:]]+) ]] || continue
|
|
repo=${BASH_REMATCH[1]}
|
|
name=${BASH_REMATCH[2]}
|
|
entries+=("repo|$name")
|
|
display+=("${C_BOLD}${C_BLUE}${repo}/${name}${C_RESET}")
|
|
done < <(${MIAUR_PACMAN} -Ss "$query" 2>/dev/null | grep -E '^[a-z0-9_-]+/' || true)
|
|
fi
|
|
|
|
# AUR results
|
|
if [[ ${MIAUR_MODE:-} != repo ]]; then
|
|
local name ver votes pop desc
|
|
while IFS='|' read -r name ver votes pop desc; do
|
|
[[ -z $name ]] && continue
|
|
entries+=("aur|$name")
|
|
display+=("${C_BOLD}${C_CYAN}aur/${name}${C_RESET} ${ver} (${votes})")
|
|
done < <(aur_search "$query" || true)
|
|
fi
|
|
|
|
[[ ${#entries[@]} -eq 0 ]] && die "no matches found: $query"
|
|
|
|
local i
|
|
if [[ ${MIAUR_BOTTOMUP:-0} -eq 1 ]]; then
|
|
for ((i = ${#display[@]} - 1; i >= 0; i--)); do
|
|
printf '%s%3d%s %b\n' "${C_DIM}" "$((i + 1))" "${C_RESET}" "${display[$i]}"
|
|
done
|
|
else
|
|
for ((i = 0; i < ${#display[@]}; i++)); do
|
|
printf '%s%3d%s %b\n' "${C_DIM}" "$((i + 1))" "${C_RESET}" "${display[$i]}"
|
|
done
|
|
fi
|
|
|
|
printf '%s::%s Select packages (for example: 1 3; leave empty to cancel): ' \
|
|
"${C_BOLD}${C_BLUE}" "${C_RESET}"
|
|
local sel=
|
|
read -r sel || exit 1
|
|
[[ -z $sel ]] && { msg "Cancelled"; return 0; }
|
|
|
|
local -a repo_pkgs=() aur_pkgs=()
|
|
local tok
|
|
for tok in $sel; do
|
|
if [[ $tok =~ ^[0-9]+$ ]]; then
|
|
local idx=$((tok - 1))
|
|
((idx >= 0 && idx < ${#entries[@]})) || die "invalid number: $tok"
|
|
local e=${entries[$idx]}
|
|
case "$e" in
|
|
repo\|*) repo_pkgs+=("${e#repo|}") ;;
|
|
aur\|*) aur_pkgs+=("${e#aur|}") ;;
|
|
esac
|
|
else
|
|
die "invalid selection: $tok"
|
|
fi
|
|
done
|
|
|
|
if [[ ${#repo_pkgs[@]} -gt 0 ]]; then
|
|
local -a conf=()
|
|
mapfile -t conf < <(pac_noconfirm_args)
|
|
as_root ${MIAUR_PACMAN} -S --needed "${conf[@]}" "${repo_pkgs[@]}"
|
|
fi
|
|
if [[ ${#aur_pkgs[@]} -gt 0 ]]; then
|
|
install_aur_packages "${aur_pkgs[@]}"
|
|
fi
|
|
}
|
|
|
|
cmd_info() {
|
|
local -a pkgs=("$@")
|
|
[[ ${#pkgs[@]} -eq 0 ]] && die "specify at least one package"
|
|
local p found
|
|
for p in "${pkgs[@]}"; do
|
|
found=0
|
|
if [[ ${MIAUR_MODE:-} != aur ]] && ${MIAUR_PACMAN} -Si "$p" 2>/dev/null; then
|
|
found=1
|
|
fi
|
|
if [[ ${MIAUR_MODE:-} != repo ]]; then
|
|
if aur_print_info "$p" 2>/dev/null; then
|
|
found=1
|
|
fi
|
|
fi
|
|
[[ $found -eq 1 ]] || error "package not found: $p"
|
|
done
|
|
}
|
|
|
|
cmd_sync_install() {
|
|
local -a pkgs=("$@")
|
|
[[ ${#pkgs[@]} -eq 0 ]] && die "specify at least one package"
|
|
|
|
local -a repo_pkgs=() aur_pkgs=()
|
|
local p
|
|
for p in "${pkgs[@]}"; do
|
|
if [[ ${MIAUR_MODE:-} == aur ]]; then
|
|
aur_pkgs+=("$p")
|
|
elif [[ ${MIAUR_MODE:-} == repo ]]; then
|
|
repo_pkgs+=("$p")
|
|
elif repo_has_pkg "$p"; then
|
|
repo_pkgs+=("$p")
|
|
elif aur_exists "$p"; then
|
|
aur_pkgs+=("$p")
|
|
else
|
|
die "package not found: $p"
|
|
fi
|
|
done
|
|
|
|
if [[ ${#repo_pkgs[@]} -gt 0 ]]; then
|
|
local -a conf=()
|
|
mapfile -t conf < <(pac_noconfirm_args)
|
|
as_root ${MIAUR_PACMAN} -S --needed "${conf[@]}" "${repo_pkgs[@]}"
|
|
fi
|
|
if [[ ${#aur_pkgs[@]} -gt 0 ]]; then
|
|
install_aur_packages "${aur_pkgs[@]}"
|
|
fi
|
|
}
|
|
|
|
cmd_getpkgbuild() {
|
|
local -a pkgs=("$@")
|
|
[[ ${#pkgs[@]} -eq 0 ]] && die "specify at least one package"
|
|
local p dir
|
|
for p in "${pkgs[@]}"; do
|
|
if [[ $OP_PRINT -eq 1 ]]; then
|
|
dir=$(aur_clone "$p")
|
|
cat "$dir/PKGBUILD"
|
|
else
|
|
dir=$(aur_clone "$p")
|
|
# Copy to cwd like paru -G
|
|
if [[ -e ./$p ]]; then
|
|
warn "./$p already exists; replacing it"
|
|
rm -rf "./$p"
|
|
fi
|
|
cp -a "$dir" "./$p"
|
|
msg "Downloaded to ./$p"
|
|
fi
|
|
done
|
|
}
|
|
|
|
cmd_clean() {
|
|
# -Sc: clean pacman cache + AUR clone cache
|
|
if [[ ${MIAUR_MODE:-} != aur ]]; then
|
|
local -a conf=()
|
|
mapfile -t conf < <(pac_noconfirm_args)
|
|
as_root ${MIAUR_PACMAN} -Sc "${conf[@]}" || true
|
|
fi
|
|
aur_clean_cache
|
|
}
|
|
|
|
dispatch() {
|
|
# Passthrough for R/D/F/T/U is handled in main() via strip_miaur_opts.
|
|
# Keep a reconstruction fallback only if somehow reached without orig argv.
|
|
if [[ $DO_PASSTHRU -eq 1 && $OP != S && $OP != Q && $OP != G && $OP != B && $OP != interactive ]]; then
|
|
die "internal error: passthrough should be handled in main"
|
|
fi
|
|
|
|
case "$OP" in
|
|
interactive)
|
|
need_cmd curl jq
|
|
cmd_interactive "${TARGETS[@]}"
|
|
;;
|
|
S)
|
|
if [[ $OP_CLEAN -eq 1 ]]; then
|
|
cmd_clean
|
|
return
|
|
fi
|
|
if [[ $OP_SEARCH -gt 0 ]]; then
|
|
need_cmd curl jq
|
|
cmd_search "${TARGETS[@]}"
|
|
return
|
|
fi
|
|
if [[ $OP_INFO -eq 1 ]]; then
|
|
need_cmd curl jq
|
|
cmd_info "${TARGETS[@]}"
|
|
return
|
|
fi
|
|
if [[ $OP_UPGRADE -eq 1 ]]; then
|
|
need_cmd curl jq
|
|
local -a conf=()
|
|
mapfile -t conf < <(pac_noconfirm_args)
|
|
if [[ $OP_AUR_ONLY -eq 1 ]]; then
|
|
# -Sua or -Su --aur
|
|
[[ $OP_REFRESH -eq 1 ]] && as_root ${MIAUR_PACMAN} -Sy "${conf[@]}"
|
|
cmd_upgrade_aur
|
|
else
|
|
cmd_upgrade_all "$OP_REFRESH"
|
|
fi
|
|
return
|
|
fi
|
|
if [[ $OP_REFRESH -eq 1 && ${#TARGETS[@]} -eq 0 ]]; then
|
|
local -a conf=()
|
|
mapfile -t conf < <(pac_noconfirm_args)
|
|
as_root ${MIAUR_PACMAN} -Sy "${conf[@]}"
|
|
return
|
|
fi
|
|
# Install packages; optionally refresh first
|
|
if [[ $OP_REFRESH -eq 1 ]]; then
|
|
local -a conf=()
|
|
mapfile -t conf < <(pac_noconfirm_args)
|
|
as_root ${MIAUR_PACMAN} -Sy "${conf[@]}"
|
|
fi
|
|
need_cmd curl jq
|
|
cmd_sync_install "${TARGETS[@]}"
|
|
;;
|
|
Q)
|
|
if [[ $OP_UPGRADE -eq 1 && $OP_AUR_ONLY -eq 1 ]]; then
|
|
need_cmd curl jq
|
|
cmd_query_aur_upgrades
|
|
return
|
|
fi
|
|
if [[ $OP_UPGRADE -eq 1 ]]; then
|
|
# -Qu: repo + AUR
|
|
${MIAUR_PACMAN} -Qu || true
|
|
need_cmd curl jq
|
|
cmd_query_aur_upgrades || true
|
|
return
|
|
fi
|
|
# Default query passthrough
|
|
local -a qargs=(-Q)
|
|
local c
|
|
for c in "${PACMAN_EXTRA[@]}"; do
|
|
# Long options like --explicit may land in PACMAN_EXTRA as full tokens
|
|
if [[ $c == --* ]]; then
|
|
qargs+=("$c")
|
|
else
|
|
qargs+=("-$c")
|
|
fi
|
|
done
|
|
[[ $OP_AUR_ONLY -eq 1 ]] && qargs+=(-m)
|
|
[[ $OP_SEARCH -gt 0 ]] && qargs+=(-s)
|
|
[[ $OP_INFO -eq 1 ]] && qargs+=(-i)
|
|
qargs+=("${TARGETS[@]}")
|
|
${MIAUR_PACMAN} "${qargs[@]}"
|
|
;;
|
|
G)
|
|
need_cmd curl jq git
|
|
cmd_getpkgbuild "${TARGETS[@]}"
|
|
;;
|
|
B)
|
|
[[ ${#TARGETS[@]} -eq 0 ]] && TARGETS=(.)
|
|
need_cmd git makepkg
|
|
build_local_dirs "$OP_BUILD_INSTALL" "${TARGETS[@]}"
|
|
;;
|
|
"")
|
|
if [[ $DO_PASSTHRU -eq 1 ]]; then
|
|
die "unable to parse operation; use pacman directly or see --help"
|
|
fi
|
|
die "no operation specified"
|
|
;;
|
|
*)
|
|
die "unsupported operation: $OP"
|
|
;;
|
|
esac
|
|
}
|