#!/usr/bin/env bash # shellcheck disable=SC2034 # CLI parsing — paru-like short option clusters # Globals set by parse_args OP= # S Q R G B P D F T U none interactive OP_REFRESH=0 # y OP_UPGRADE=0 # u OP_SEARCH=0 # s (count) OP_INFO=0 # i OP_CLEAN=0 # c OP_AUR_ONLY=0 # a (with S/Q) OP_PRINT=0 # -p for -G OP_BUILD_INSTALL=0 # -i for -B TARGETS=() PACMAN_EXTRA=() # leftover short flags for pacman passthrough DO_PASSTHRU=0 print_help() { cat <<'EOF' Usage: miaur miaur [...] miaur miaur is a pure-shell AUR helper with paru-like everyday commands. Pacman operations extended with AUR support: miaur {-h --help} miaur {-V --version} miaur {-Q --query} [options] [packages] miaur {-R --remove} [options] miaur {-S --sync} [options] [packages] miaur {-U --upgrade} [options] Additional operations: miaur {-G --getpkgbuild} [packages] miaur {-B --build} [directories] miaur self-update Update miaur from Git With no arguments, miaur runs 'miaur -Syu'. Common commands: miaur -Syu Upgrade repository and AUR packages miaur -Sua Upgrade AUR packages only miaur -S Install from a repository or the AUR miaur -Ss Search packages miaur -Si Show package information miaur -Qua List available AUR upgrades miaur -G Download a PKGBUILD miaur -Gp Print a PKGBUILD miaur -Bi . Build and install a local PKGBUILD miaur self-update Update miaur itself Options: -a, --aur Assume targets are from the AUR --repo Assume targets are from repositories --skipreview Skip PKGBUILD review --cleanafter Remove build sources after installation --[no]removemake Remove make dependencies after installation --bottomup Show AUR results first --topdown Show repository results first (default) --clonedir Set the PKGBUILD clone directory --mflags Pass additional flags to makepkg --sudoloop Keep sudo credentials alive (default) --nosudoloop Disable the sudo keep-alive loop --noconfirm Bypass any confirmation prompts --self-update Same as: miaur self-update EOF } # Strip miaur-only options so the remainder can be forwarded to pacman. # Prints one argument per line (safe for mapfile with typical package names). strip_miaur_opts() { local -a raw=("$@") local i=0 while ((i < ${#raw[@]})); do local arg=${raw[$i]} case "$arg" in --aur | --repo | --skipreview | --review | --cleanafter | --nocleanafter | \ --removemake | --noremovemake | --noremovermake | --bottomup | --topdown | \ --sudoloop | --nosudoloop | --noconfirm | --self-update) ;; --clonedir | --mflags | --mode) i=$((i + 1)) ;; --clonedir=* | --mflags=* | --mode=* | --repo-url=* | --branch=*) ;; --repo-url | --branch) i=$((i + 1)) ;; *) printf '%s\n' "$arg" ;; esac i=$((i + 1)) done } parse_args() { if [[ $# -eq 0 ]]; then OP=S OP_REFRESH=1 OP_UPGRADE=1 return 0 fi # Subcommand: self-update [--noconfirm] [--repo-url URL] [--branch NAME] if [[ $1 == self-update || $1 == --self-update ]]; then OP=selfupdate local -a raw=("$@") local i=1 while ((i < ${#raw[@]})); do local arg=${raw[$i]} case "$arg" in --noconfirm) MIAUR_NOCONFIRM=1 ;; --repo-url) i=$((i + 1)) MIAUR_REPO=${raw[$i]:-} [[ -n $MIAUR_REPO ]] || die "--repo-url requires a URL" ;; --repo-url=*) MIAUR_REPO=${arg#*=} ;; --branch) i=$((i + 1)) MIAUR_BRANCH=${raw[$i]:-} [[ -n $MIAUR_BRANCH ]] || die "--branch requires a name" ;; --branch=*) MIAUR_BRANCH=${arg#*=} ;; -h | --help) print_help exit 0 ;; *) die "unknown self-update option: $arg" ;; esac i=$((i + 1)) done return 0 fi # No leading dash → interactive search if [[ $1 != -* ]]; then OP=interactive TARGETS=("$@") return 0 fi local -a raw=("$@") local i=0 while ((i < ${#raw[@]})); do local arg=${raw[$i]} case "$arg" in -h | --help) print_help exit 0 ;; -V | --version) printf 'miaur v%s\n' "$MIAUR_VERSION" exit 0 ;; --self-update) OP=selfupdate ;; --aur) OP_AUR_ONLY=1 MIAUR_MODE=aur ;; --repo) MIAUR_MODE=repo ;; --skipreview) MIAUR_SKIPREVIEW=1 ;; --review) MIAUR_SKIPREVIEW=0 ;; --cleanafter) MIAUR_CLEANAFTER=1 ;; --nocleanafter) MIAUR_CLEANAFTER=0 ;; --removemake) MIAUR_REMOVEMAKE=1 ;; --noremovemake) MIAUR_REMOVEMAKE=0 ;; # Typo alias kept for compatibility with older docs/scripts --noremovermake) MIAUR_REMOVEMAKE=0 ;; --bottomup) MIAUR_BOTTOMUP=1 ;; --topdown) MIAUR_BOTTOMUP=0 ;; --sudoloop) MIAUR_SUDOLOOP=1 ;; --nosudoloop) MIAUR_SUDOLOOP=0 ;; --noconfirm) MIAUR_NOCONFIRM=1 ;; --clonedir) i=$((i + 1)) MIAUR_CLONEDIR=${raw[$i]:-} [[ -n $MIAUR_CLONEDIR ]] || die "--clonedir requires a path" ;; --clonedir=*) MIAUR_CLONEDIR=${arg#*=} ;; --mflags) i=$((i + 1)) MIAUR_MFLAGS=${raw[$i]:-} ;; --mflags=*) MIAUR_MFLAGS=${arg#*=} ;; --mode) i=$((i + 1)) MIAUR_MODE=${raw[$i]:-} ;; --mode=*) MIAUR_MODE=${arg#*=} ;; --repo-url) i=$((i + 1)) MIAUR_REPO=${raw[$i]:-} [[ -n $MIAUR_REPO ]] || die "--repo-url requires a URL" ;; --repo-url=*) MIAUR_REPO=${arg#*=} ;; --branch) i=$((i + 1)) MIAUR_BRANCH=${raw[$i]:-} [[ -n $MIAUR_BRANCH ]] || die "--branch requires a name" ;; --branch=*) MIAUR_BRANCH=${arg#*=} ;; --sync) OP=S ;; --query) OP=Q ;; --remove) OP=R DO_PASSTHRU=1 ;; --getpkgbuild) OP=G ;; --build) OP=B ;; --database) OP=D DO_PASSTHRU=1 ;; --files) OP=F DO_PASSTHRU=1 ;; --deptest) OP=T DO_PASSTHRU=1 ;; --upgrade) OP=U DO_PASSTHRU=1 ;; --) i=$((i + 1)) while ((i < ${#raw[@]})); do TARGETS+=("${raw[$i]}") i=$((i + 1)) done break ;; --*) # Unknown long option: keep for pacman passthrough (e.g. --ignore) PACMAN_EXTRA+=("$arg") DO_PASSTHRU=1 ;; -*) local cluster=${arg:1} local j c for ((j = 0; j < ${#cluster}; j++)); do c=${cluster:j:1} case "$c" in S) OP=S ;; Q) OP=Q ;; R) OP=R DO_PASSTHRU=1 ;; G) OP=G ;; B) OP=B ;; D) OP=D DO_PASSTHRU=1 ;; F) OP=F DO_PASSTHRU=1 ;; T) OP=T DO_PASSTHRU=1 ;; U) OP=U DO_PASSTHRU=1 ;; y) OP_REFRESH=1 ;; u) OP_UPGRADE=1 ;; s) OP_SEARCH=$((OP_SEARCH + 1)) ;; i) if [[ $OP == B ]]; then OP_BUILD_INSTALL=1 else OP_INFO=1 fi ;; c) OP_CLEAN=1 ;; a) OP_AUR_ONLY=1 MIAUR_MODE=aur ;; p) if [[ $OP == G ]]; then OP_PRINT=1 else PACMAN_EXTRA+=("$c") fi ;; h) print_help exit 0 ;; V) printf 'miaur v%s\n' "$MIAUR_VERSION" exit 0 ;; *) PACMAN_EXTRA+=("$c") ;; esac done ;; *) TARGETS+=("$arg") ;; esac i=$((i + 1)) done }