From fd8bd321018097e3bfe1d4ffaa7bf9c9c9c283b5 Mon Sep 17 00:00:00 2001 From: Taeyeon Mori Date: Sun, 6 Mar 2016 19:18:03 +0100 Subject: [PATCH] aur.sh: Big update adding advanced metadata processing using cower --- bin/aur.sh | 177 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 150 insertions(+), 27 deletions(-) diff --git a/bin/aur.sh b/bin/aur.sh index ea61d27..708fcc0 100755 --- a/bin/aur.sh +++ b/bin/aur.sh @@ -11,10 +11,6 @@ function throw { exit $1 } -# Figure out build directory -tmpbuild=${TMPDIR-/tmp}/aur.sh.$$ -build="${BUILDDIR:-$tmpbuild}" -test -d "$build" || mkdir -p "$build" || exit 1 # ------------------------------------------------------------------------------ # Parse commandline: anything prefixed with - is a makepkg option, others are package names @@ -24,62 +20,125 @@ makepkg_args=() aur_get=aur_get_aur4 DL_ONLY=false ASK=false +AUR_HOST="https://aur.archlinux.org/" +ADD_UPDATES=false +RECURSE_DEPS=false +NEED_COWER=false +LIST_ONLY=false add_makepkg_arg() { makepkg_args=("${makepkg_args[@]}" "$1") } _proxy_args=0 -for cx in "$@"; do +_next_arg= +process_arg() { + local cx="$1" if [ $_proxy_args -gt 0 ]; then add_makepkg_arg "$cx" _proxy_args=$[$_proxy_args - 1] continue fi + if [ -n "$_next_arg" ]; then + case "$_next_arg" in + --aur-host) + AUR_HOST="$cx";; + esac + _next_arg= + continue + fi case "$cx" in + # aur.sh options --old-aur) - warn "[AUR] Using old AUR (--old-aur)" + warn "[AUR] Using old AUR methods (--old-aur)" aur_get=aur_get_old;; -X|--download-only) warn "[AUR] Building was disabled (-X)" DL_ONLY=true;; --ask) ASK=true;; + --aur-host) # need more args + _next_arg="$cx";; + -u|--update) + [ -n "$MODE" ] && throw 255 "Can only use one flag from the 'aur.sh command' category" + NEED_COWER=true + ADD_UPDATES=true;; + -S|--recurse-deps) + NEED_COWER=true + RECURSE_DEPS=true + add_makepkg_arg -is;; + -L|--list-only) + LIST_ONLY=true;; -h|--help) - echo "Usage $0 [-h] [-X] [makepkg options] " + echo "Usage $0 [-h|-u] [-S] [-L|-X] [makepkg options] " echo "Taeyeon's aur.sh (c) 2014-2015 Taeyeon Mori (not related to http://aur.sh)" echo echo "A simple AUR client realized in bash/zsh" echo echo "aur.sh options:" echo " -h, --help Display this message" + echo " -u, --update Build all updated AUR packages [c]" + echo " -S, --recurse-deps" + echo " Recursively build & install all dependencies [c]" + echo " Implies -is" + echo " -L, --list-only" + echo " Only list all affected packages" echo " -X, --download-only" - echo " Only download the PKGBUILDs from AUR, don't build" - echo " --old-aur Use the old (non-git) AUR" + echo " Only download the PKGBUILDs from AUR, don't build." + echo " --aur-host " + echo " Use a different AUR server. default: https://aur.archlinux.org/" + echo " --old-aur Use the old (non-git) AUR methods" echo " --ask Ask before installing packages (removes --noconfirm)" echo echo "Useful makepkg options:" echo " -i Install package after building it" echo " -s Install dependencies from official repos" echo " --pkg Only build selected packages (when working with split packages)" + echo + echo "NOTE: options marked [c] require cower to be installed (\$ aur.sh -is cower)" + echo " However, certain cower-only features are automatically enabled when cower is found." exit 0 ;; + # Makepkg args --pkg|--key|--config) # These take an additional value _proxy_args=1 add_makepkg_arg "$cx";; -*) add_makepkg_arg "$cx";; + # Package names *) packages=("${packages[@]}" "$cx");; esac +} + +for cx in "$@"; do + case "$cx" in + --*) + process_arg "$cx";; + -*) + for c in `echo "${cx:1}" | grep -o .`; do + process_arg "-$c" + done;; + *) + process_arg "$cx";; + esac done +if cower --version >/dev/null; then + NEED_COWER=true # Auto-enable cower support if installed. +elif $NEED_COWER; then + throw 31 "Options requiring cower have been selected but cower was not found." +else + warn "Could not detect cower on the system. Not all features are available without it." + warn "Specifically, split packages cannot be detected without cower." +fi + # ------------------------------------------------------------------------- # aur functions aur_get_old() { [ -d "$1/.git" ] && err "Local copy of $1 is a Git clone from AUR v4. Don't use --old-aur with it!" && return 32 - curl "https://aur.archlinux.org/packages/${1:0:2}/$1/$1.tar.gz" | tar xz + curl "$AUR_HOST/packages/${1:0:2}/$1/$1.tar.gz" | tar xz } aur_get_aur4() { @@ -94,7 +153,7 @@ aur_get_aur4() { [ "$ans" = "y" ] || [ "$ans" = "yes" ] || [ "$ans" = "Y" ] || return 32 rm -rf "$1" fi - git clone "https://aur4.archlinux.org/$1.git/" "$1" + git clone "$AUR_HOST/$1.git" "$1" fi } @@ -102,19 +161,72 @@ aur_get_aur4() { # Actual work starts here # Print some info msg "[AUR] AURDIR=$AURDIR; PKGDEST=$PKGDEST" -test "$build" = "$PWD" || \ - msg "[AUR] Working in $build." -msg "[AUR] Building packages: $packages" -if ! $ASK && ! $DL_ONLY; then - msg "[AUR] Updating sudo timestamp" - sudo -v +# Figure out build directory +if ! $DL_ONLY && ! $LIST_ONLY; then + tmpbuild=${TMPDIR-/tmp}/aur.sh.$$ + build="${BUILDDIR:-$tmpbuild}" + test -d "$build" || mkdir -p "$build" || throw 1 "Couldn't create build directory" + + test "$build" = "$PWD" || \ + msg "[AUR] Working in $build." + msg "[AUR] Building packages: $packages" + + if ! $ASK; then + msg "[AUR] Updating sudo timestamp" + sudo -v - add_makepkg_arg "--noconfirm" + add_makepkg_arg "--noconfirm" + fi fi -# Process packages -for p in "${packages[@]}"; do +if $ADD_UPDATES; then + [ -n "$packages" ] && throw 31 "You cannot specify package names when using --update" + OFS="$IFS" + IFS=$'\n' + for update in `cower -u`; do + packages=("${packages[@]}" "`echo $update | cut -d' ' -f1`") + done + IFS="$OFS" +fi + + +AFFECTED_PKGS=() + +# Package processing +build_package() { + local p="$1" # package name + local COWER_INFO="$2" + + if $NEED_COWER; then + [ -z "$COWER_INFO" ] && COWER_INFO=`cower -i $p` + + info_grep() { + echo "$COWER_INFO" | grep "$@" | cut -d: -f2 + } + + local PACKBASE=`info_grep PackageBase | sed -e 's/^\s*//' -e 's/\s*$//'` + if [ -n "$PACKBASE" ]; then + color 35 echo "$p: Is a split package. Selecting base package '$PACKBASE' instead." + warn "Operations on specific sub-packages require the base package to be specified along with --pkg." + build_package "$PACKBASE" "`echo "$COWER_INFO" | grep -v PackageBase`" + return $? + fi + + local DEPENDS=`info_grep -i depends` + if $RECURSE_DEPS; then + for dep in `echo $DEPENDS`; do + if ! pacman -Qi "$dep" >/dev/null 2>&1 && cower -i "$dep" >/dev/null 2>&1; then # Check if it's an (un-installed) aur package + color 35 echo "$p: Building AUR dependency '$dep'..." + build_package "$dep" + fi + done + fi + fi + + AFFECTED_PKGS=("${AFFECTED_PKGS[@]}" "$p") + + $LIST_ONLY && return # First, download the PKGBUILD from AUR, to $AURDEST cd "$AURDEST" @@ -127,10 +239,10 @@ for p in "${packages[@]}"; do } || \ $aur_get "$p" || throw 2 "[AUR] $p: Couldn't download package" - if $DL_ONLY; then continue; fi + $DL_ONLY && return # Copy it to the build directory $build and change there - cp -r "$p" "$build" + cp -Lr "$p" "$build" cd "$build/$p" # Update timestamp, but don't ask for pw if it expired @@ -142,13 +254,24 @@ for p in "${packages[@]}"; do throw 1 "[AUR] $p: Makepkg failed!" msg "[AUR] $p: Done!" +} + +# Process packages +for p in "${packages[@]}"; do + build_package "$p" done -msg "[AUR] All Done!" +if $LIST_ONLY; then + echo "Affected Packages: `echo "${AFFECTED_PKGS[@]}" | sed 's/ /\n/g' | awk '!_[$0]++{printf "%s ",$0}'`" +else + msg "[AUR] All Done!" +fi # Remove the builddir if we previously created it. -cd "$AURDEST" -[ "$build" = "$tmpbuild" ] && \ - warn "[AUR] Removing temporary directory $tmpbuild" && \ - rm -rf "$tmpbuild" +if ! $DL_ONLY && ! $LIST_ONLY; then + cd "$AURDEST" + [ "$build" = "$tmpbuild" ] && \ + warn "[AUR] Removing temporary directory $tmpbuild" && \ + rm -rf "$tmpbuild" +fi