Skip to content

Instantly share code, notes, and snippets.

@AladW
Created February 25, 2020 23:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AladW/5d25ab4518d056112fa02e3955b0f33c to your computer and use it in GitHub Desktop.
Save AladW/5d25ab4518d056112fa02e3955b0f33c to your computer and use it in GitHub Desktop.
WIP
#!/bin/bash
# aur-fetch - retrieve build files from the AUR
[[ -v AUR_DEBUG ]] && set -o xtrace
argv0=fetch
AUR_LOCATION=${AUR_LOCATION:-https://aur.archlinux.org}
XDG_CONFIG_HOME=${XDG_CONFIG_HOME:-$HOME/.config}
PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[1]}(): }'
# default options
verbose=0 recurse=0 results=0 sync=no log_fmt=diff
usage() {
cat <<! | base64 -d
ICAgICAgICAgICAgIC4tLX5+LF9fCjotLi4uLiwtLS0tLS0tYH5+Jy5fLicKIGAtLCwsICAs
XyAgICAgIDsnflUnCiAgXywtJyAsJ2AtX187ICctLS4KIChfLyd+fiAgICAgICcnJycoOwoK
!
plain >&2 'usage: %s [-rSv] pkgname...' "$argv0"
exit 1
}
source /usr/share/makepkg/util/message.sh
source /usr/share/makepkg/util/parseopts.sh
if [[ ! -v NO_COLOR ]] && [[ ! -v AUR_DEBUG ]]; then
[[ -t 2 ]] && colorize
fi
opt_short='H:rSv'
opt_long=('recurse' 'verbose' 'sync:' 'results:' 'format:' 'prev-head:' 'write-log:')
opt_hidden=('dump-options')
if ! parseopts "$opt_short" "${opt_long[@]}" "${opt_hidden[@]}" -- "$@"; then
usage
fi
set -- "${OPTRET[@]}"
unset log_dir log_rev results_file
while true; do
case "$1" in
-r|--recurse)
recurse=1 ;;
-v|--verbose)
verbose=1 ;;
-S)
sync=auto ;;
--write-log)
shift; log_dir=$1 ;;
--results)
shift; results_file=$1 ;;
--format)
case $1 in
log|diff)
shift; log_fmt=$1 ;;
*)
error '%s: invalid --format option: %s' "$argv0" "$1"
usage ;;
esac ;;
--sync)
case $1 in
auto|reset|rebase|no)
shift; sync=$1 ;;
*)
error '%s: invalid --sync option: %s' "$argv0" "$1"
usage ;;
esac ;;
--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
if [[ -v log_dir ]] && [[ ! -d $log_dir ]]; then
error '%s: %s: not a directory' "$argv0" "$log_dir"
exit 20
fi
if ! (( $# )); then
error '%s: no targets specified' "$argv0"
exit 1
fi
if [[ -v results_file ]]; then
: >"$results_file" || exit 1 # truncate file
results=1
fi
# Default to showing PKGBUILD first in patch (#399)
mkdir -p "$XDG_CONFIG_HOME/aurutils/$argv0"
orderfile=$XDG_CONFIG_HOME/aurutils/$argv0/orderfile
if [[ ! -s $orderfile ]]; then
printf 'PKGBUILD\n' > "$orderfile"
fi
if (( recurse )); then
aur depends --pkgbase "$@"
else
printf '%s\n' "$@"
fi | while read -r pkg; do
unset GIT_DIR GIT_WORK_TREE
# Check if git object is existing, print name on success
aur_rev() {
git rev-parse --quiet --verify "$1"
}
# Reset/rebase if we are on valid repo
if [[ -d $pkg/.git ]]; then
# Avoid issues with filesystem boundaries (#274)
export GIT_DIR=$pkg/.git GIT_WORK_TREE=$pkg
if ! git fetch --verbose; then
exit 1
fi
# head before rebase or reset
prev_head=$(aur_rev 'HEAD')
if (( results )); then
printf 'fetch:%s:%s:file://%s\n' "$prev_head" "$(aur_rev 'FETCH_HEAD')" "$PWD/$pkg" | tee -a "$results_file"
fi
# set sync to rebase or reset depending on aurutils.rebase configuration
if [[ $sync == 'auto' ]]; then
if [[ $(git config --get --type=bool aurutils.rebase) == 'true' ]]; then
plain >&2 'aurutils.rebase is set for %s' "$pkg"
if ! git merge-base --is-ancestor 'HEAD@{upstream}' 'HEAD'; then
sync=rebase
fi
elif [[ $prev_head != $(aur_rev 'HEAD@{upstream}') ]]; then
sync=reset
fi
fi
if [[ $sync == 'rebase' ]]; then
if ! { git stash && git reset --hard 'HEAD' && git rebase --verbose; }; then
error '%s: failed to rebase repository %s' "$argv0" "$pkg"
exit 1
elif (( results )); then
printf 'rebase:%s:%s:file://%s\n' "$prev_head" "$(aur_rev 'HEAD')" "$PWD/$pkg" | tee -a "$results_file"
fi
elif [[ $sync == 'reset' ]]; then
if ! { git stash && git reset --hard 'HEAD@{upstream}'; }; then
error '%s: failed to reset repository %s' "$argv0" "$pkg"
exit 1
elif (( results )); then
printf 'reset:%s:%s:file://%s\n' "$prev_head" "$(aur_rev 'HEAD')" "$PWD/$pkg" | tee -a "$results_file"
fi
fi
# Print changes from rebase/reset, if available
write_log() {
git --no-pager "$log_fmt" --patch --stat "$1..HEAD"
}
if [[ $prev_head != "$(aur_rev 'HEAD')" ]]; then
if (( verbose )); then
write_log "$prev_head" >/dev/stdout
fi
if [[ $log_dir ]]; then
write_log "$prev_head" >"$log_dir/$pkg.$log_fmt"
fi
fi
# Otherwise, try to clone anew
elif git clone "$AUR_LOCATION/$pkg" "$pkg"; then
export GIT_DIR=$pkg/.git GIT_WORK_TREE=$pkg
# Show PKGBUILDs first. (#399)
git config diff.orderFile "$orderfile"
# Update results file (clone)
if (( results )); then
printf 'clone:%d:%s:file://%s\n' 0 "$(aur_rev 'HEAD')" "$PWD/$pkg" | tee -a "$results_file"
fi
else
error '%s: %s: failed to clone repository' "$argv0" "$pkg"
exit 1
fi
done
# vim: set et sw=4 sts=4 ft=sh:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment