#!/bin/bash
# aur-srcver - update and print package revisions
[[ -v AUR_DEBUG ]] && set -o xtrace
shopt -s nullglob
argv0=srcver
PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'

# default arguments
makepkg_args=('--nobuild' '--nodeps' '--skipinteg')
num_procs=$(( "$(nproc)" + 2 ))

# shellcheck disable=SC2154
get_full_version() {
    if (( epoch > 0 )); then
        printf "%s\n" "$epoch:$pkgver-$pkgrel"
    else
        printf "%s\n" "$pkgver-$pkgrel"
    fi
}

trap_exit() {
    if [[ ! -v AUR_DEBUG ]]; then
        rm -rf -- "$tmp"
    else
        printf >&2 'AUR_DEBUG: %s: temporary files at %s\n' "$argv0" "$tmp"
    fi
}

usage() {
    printf >&2 'usage: %s [--no-prepare] <pkgbase> [<pkgbase> ...]\n' "$argv0"
    exit 1
}

source /usr/share/makepkg/util/parseopts.sh

opt_short=j:
opt_long=('no-prepare' 'jobs:' 'buildscript:')
opt_hidden=('dump-options' 'noprepare')

if ! parseopts "$opt_short" "${opt_long[@]}" "${opt_hidden[@]}" -- "$@"; then
    usage
fi
set -- "${OPTRET[@]}"

unset buildscript
while true; do
    case "$1" in
        --noprepare|--no-prepare)
            makepkg_args+=(--noprepare) ;;
        -j|--jobs)
            shift; num_procs=$1 ;;
        --buildscript)
            shift; buildscript=$1
            makepkg_args+=(-p "$1") ;;
        --dump-options)
            printf -- '--%s\n' "${opt_long[@]}" ${AUR_DEBUG+"${opt_hidden[@]}"}
            printf -- '%s' "${opt_short}" | sed 's/.:\?/-&\n/g'
            exit ;;
        --)
            shift; break ;;
    esac
    shift
done

# Single hyphen to denote input taken from stdin
stdin=0
if (( $# == 1 )) && [[ $1 == "-" || $1 == "/dev/stdin" ]]; then
    stdin=1
fi

if (( ! $# )); then
    usage
fi

# shellcheck disable=SC2174
mkdir -pm 0700 "${TMPDIR:-/tmp}/aurutils-$UID"
tmp=$(mktemp -d --tmpdir "aurutils-$UID/$argv0.XXXXXXXX") || exit
trap 'trap_exit' EXIT

# A pipeline `foo | bar &` causes `bar` to detach from the script. In
# this case, aur-srcver returns immediately with `makepkg` processes
# still running in the background. Read all input into an array to
# avoid this. (cf. aur-view, #958)
if (( stdin )); then
    mapfile -t packages
else
    packages=("$@")
    set --
fi

i=0 # package counter
for n in "${packages[@]}"; do
    if (( i++ >= num_procs )); then
        wait -n
    fi

    { mkdir -p "$tmp/$n"

      if ! env -C "$n" nice -n 20 makepkg "${makepkg_args[@]}" >"$tmp/$n"/log 2>&1; then
          echo $? >"$tmp/$n"/failed
      fi
    } &
done
wait

failed=()
for d in "$tmp"/*/; do # iterate over directories
    n=$(basename "$d")

    if [[ -e $tmp/$n/failed ]]; then
        failed+=("$n")
    else
        # Precautions when sourcing the PKGBUILD have no effect here,
        # because makepkg already sourced the PKGBUILD above.
        # shellcheck disable=SC1090
        ( source "$n/${buildscript-PKGBUILD}"

          fullver=$(get_full_version)
          printf '%s\t%s\n' "${pkgbase:-$pkgname}" "$fullver"
        )
    fi
done

if (( ${#failed[@]} )); then
    printf >&2 '8<----\n'
fi

for f in "${failed[@]}"; do
    printf >&2 '%s: makepkg %s failed for package %s\n' "$argv0" "${makepkg_args[*]}" "$f"

    cat "$tmp/$f"/log >&2
    printf >&2 '8<----\n'
done

# vim: set et sw=4 sts=4 ft=sh:
