Created
February 25, 2020 23:37
-
-
Save AladW/5d25ab4518d056112fa02e3955b0f33c to your computer and use it in GitHub Desktop.
WIP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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