Files
Cursor AgentandFrank Vitrano a4f4767c47 Add self-update command to refresh miaur from Git
Introduce `miaur self-update` / `--self-update` that clones RepoUrl@Branch,
detects user vs system install prefix, and reinstalls in place. Configurable
via conf/env; supports --noconfirm, --repo-url, and --branch.

Co-authored-by: Frank Vitrano <WHC2006@users.noreply.github.com>
2026-07-23 14:44:24 +00:00

308 lines
7.7 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 && $OP != selfupdate ]]; then
die "internal error: passthrough should be handled in main"
fi
case "$OP" in
selfupdate)
need_cmd git
cmd_self_update
;;
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
}