summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
authorAndreas Grapentin <andreas@grapentin.org>2018-03-29 23:33:02 +0200
committerAndreas Grapentin <andreas@grapentin.org>2018-03-29 23:33:02 +0200
commitc1fced40c2f37f844eb810216eb0a1da1a436aa8 (patch)
tree205d4971dd3e2498d8c78b42ff1320f3603957e5 /src/shared
parent0cdff36d43aea7dc5415e6a4d58d1e10c68e2965 (diff)
major restructure, builds ok up to end of stage2
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/checks.sh153
-rw-r--r--src/shared/common.sh127
-rw-r--r--src/shared/deptree.sh103
-rw-r--r--src/shared/feedback.sh76
-rw-r--r--src/shared/pacman.sh81
-rw-r--r--src/shared/srcinfo.sh57
-rw-r--r--src/shared/upstream.sh93
7 files changed, 592 insertions, 98 deletions
diff --git a/src/shared/checks.sh b/src/shared/checks.sh
new file mode 100644
index 0000000..57bb646
--- /dev/null
+++ b/src/shared/checks.sh
@@ -0,0 +1,153 @@
+#!/bin/bash
+ ##############################################################################
+ # parabola-riscv64-bootstrap #
+ # #
+ # Copyright (C) 2018 Andreas Grapentin #
+ # #
+ # This program is free software: you can redistribute it and/or modify #
+ # it under the terms of the GNU General Public License as published by #
+ # the Free Software Foundation, either version 3 of the License, or #
+ # (at your option) any later version. #
+ # #
+ # This program is distributed in the hope that it will be useful, #
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+ # GNU General Public License for more details. #
+ # #
+ # You should have received a copy of the GNU General Public License #
+ # along with this program. If not, see <http://www.gnu.org/licenses/>. #
+ ##############################################################################
+
+check_exe() {
+ local OPTIND o r=
+ while getopts "r" o; do
+ case "$o" in
+ r) r=yes ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] program ..." ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ local v res=0
+ for v in "$@"; do
+ echo -n "checking for $v in \$PATH ... "
+
+ local have_exe=yes
+ type -p "$v" >/dev/null || have_exe=no
+ echo $have_exe
+
+ if [ "x$have_exe" != "xyes" ]; then
+ [ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing $v in \$PATH"
+ res="$ERROR_MISSING"
+ fi
+ done
+
+ return "$res"
+}
+
+check_file() {
+ local OPTIND o r=
+ while getopts "r" o; do
+ case "$o" in
+ r) r=yes ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] file ..." ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ local v res=0
+ for v in "$@"; do
+ echo -n "checking for $v ... "
+
+ local have_file=yes
+ [ -f "$v" ] || have_file=no
+ echo $have_file
+
+ if [ "x$have_file" != "xyes" ]; then
+ [ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing $v in filesystem"
+ res="$ERROR_MISSING"
+ fi
+ done
+
+ return "$res"
+}
+
+check_gpgkey() {
+ local OPTIND o r=
+ while getopts "r" o; do
+ case "$o" in
+ r) r=yes ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] key" ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ local v res=0
+ for v in "$@"; do
+ echo -n "checking for key $v ... "
+
+ local have_key=yes
+ sudo -u "$SUDO_USER" gpg --list-keys "$v" &>/dev/null || have_key=no
+ echo $have_key
+
+ if [ "x$have_key" != "xyes" ]; then
+ [ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing $v in keyring"
+ res="$ERROR_MISSING"
+ fi
+ done
+
+ return "$res"
+}
+
+check_pkgfile() {
+ local OPTIND o r=
+ while getopts "r" o; do
+ case "$o" in
+ r) r=yes ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] key" ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ echo -n "checking for built package $2 ... "
+
+ local pkgfile have_pkgfile=yes
+ pkgfile=$(find "$1" -regex "^.*/$2-[^-]*-[^-]*-[^-]*\\.pkg\\.tar\\.xz\$")
+ [ -n "$pkgfile" ] || have_pkgfile=no
+ echo $have_pkgfile
+
+ if [ "x$have_pkgfile" != "xyes" ]; then
+ [ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing package $2 in $1"
+ return "$ERROR_MISSING"
+ fi
+}
+
+check_repo() {
+ local OPTIND o r=
+ while getopts "r" o; do
+ case "$o" in
+ r) r=yes ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-r] repo ..." ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ local path="$1"
+ shift
+
+ local v res=0
+ for v in "$@"; do
+ echo -n "checking for repo $v ... "
+
+ local have_repo=yes
+ [ -e "$path/$v.db" ] || have_repo=no
+ echo $have_repo
+
+ if [ "x$have_repo" != "xyes" ]; then
+ [ "x$r" == "xyes" ] && die -e "$ERROR_MISSING" "missing [$v] in $path"
+ res="$ERROR_MISSING"
+ fi
+ done
+
+ return "$res"
+}
diff --git a/src/shared/common.sh b/src/shared/common.sh
index 46ba6ca..0a11251 100644
--- a/src/shared/common.sh
+++ b/src/shared/common.sh
@@ -18,90 +18,75 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
##############################################################################
-set -euo pipefail
+# shellcheck source=src/shared/feedback.sh
+. "$TOPSRCDIR"/shared/feedback.sh
+# shellcheck source=src/shared/checks.sh
+. "$TOPSRCDIR"/shared/checks.sh
+# shellcheck source=src/shared/srcinfo.sh
+. "$TOPSRCDIR"/shared/srcinfo.sh
+# shellcheck source=src/shared/pacman.sh
+. "$TOPSRCDIR"/shared/pacman.sh
+# shellcheck source=src/shared/upstream.sh
+. "$TOPSRCDIR"/shared/upstream.sh
+# shellcheck source=src/shared/deptree.sh
+. "$TOPSRCDIR"/shared/deptree.sh
retry() {
- for i in $(seq $(expr $1 - 1)); do
- "${@:3}" && return 0 || sleep $2;
+ local OPTIND o n=5 s=60
+ while getopts "n:s:" o; do
+ case "$o" in
+ n) n="$OPTARG" ;;
+ s) s="$OPTARG" ;;
+ *) die -e $ERROR_INVOCATION "Usage: ${FUNCNAME[0]} [-n tries] [-s delay] cmd ..." ;;
+ esac
done
- "${@:3}" || return;
-}
-
-import_keys() {
- local keys="$(source ${1:-PKGBUILD} && echo "${validpgpkeys[@]}")"
- if [ -n "$keys" ]; then
- local key
- for key in $keys; do
- echo -n "checking for key $key ... "
- sudo -u $SUDO_USER gpg --list-keys $key &>/dev/null && _have_key=yes || _have_key=no
- echo $_have_key
- if [ "x$_have_key" == "xno" ]; then
- retry 5 60 sudo -u $SUDO_USER gpg --recv-keys $key \
- || die "failed to import key $key"
- fi
- done
- fi
-}
+ shift $((OPTIND-1))
-_fetch_pkgfiles_from() {
- curl -sL $url | grep -iq 'not found' && return 1
- local src=$(curl -sL $url | grep -i 'source files' | cut -d'"' -f2 | sed 's#/tree/#/plain/#')
- for link in $(curl -sL $src | grep '^ <li><a href' | cut -d"'" -f2 \
- | sed "s#^#$(echo $src | awk -F/ '{print $3}')#"); do
- wget -q $link -O $(basename ${link%\?*});
+ for _ in $(seq "$((n - 1))"); do
+ "$@" && return 0
+ sleep "$s"
done
- [ -f PKGBUILD ] || return 1
+ "$@" || return
}
-fetch_pkgfiles() {
- # acquire the pkgbuild and auxiliary files
- local url=https://www.parabola.nu/packages/libre/x86_64/$1/
- _fetch_pkgfiles_from $url && echo "libre" > .REPO && return
+prepare_makepkgdir() {
+ rm -rf "$1"
+ mkdir -p "$1"
+ chown -R "$SUDO_USER" "$1"
- local repo
- for repo in core extra community; do
- url=https://www.archlinux.org/packages/$repo/x86_64/$1/
- _fetch_pkgfiles_from $url && echo "$repo" > .REPO && return
- done
- die "$1: failed to fetch pkgfiles"
+ pushd "$1" >/dev/null || return 1
}
-prepare_makepkgdir() {
- rm -rf "$_makepkgdir"/$_pkgname
- mkdir -p "$_makepkgdir"/$_pkgname
- pushd "$_makepkgdir"/$_pkgname >/dev/null
- chown -R $SUDO_USER "$_makepkgdir"/$_pkgname
+find_lastlog() {
+ local log
+ # shellcheck disable=SC2010
+ log=$(ls -t "$1" | grep -P "^$2(-[^-]*){3}-(pkgver|prepare|build|package)" | head -n1)
+ [ -n "$log" ] && echo "$log"
}
-failed_build() {
- _log=$(find "$_logdest" -type f -iname "$1-*" -printf "%T@ %p\n" \
- | sort -n | tail -n1 | cut -d' ' -f2-)
- set +o pipefail
- _phase=""
- [ -z "$_log" ] || _phase=$(cat $_log | grep '==>.*occurred in' \
- | awk '{print $7}' | sed 's/().*//')
- set -o pipefail
- if [ -n "${_phase:-}" ]; then
- notify -c error "$_pkgname: error in $_phase()" -h string:document:"$_log"
- else
- notify -c error "$_pkgname: error in makepkg"
- fi
- [ "x$KEEP_GOING" == "xyes" ] || die "error building $_pkgname"
- _build_failed=yes
+binfmt_enable() {
+ echo 1 > /proc/sys/fs/binfmt_misc/status
}
-make_realdep() {
- local dep
-
- dep="$1"
- _realdep=$(pacman --noconfirm -Sddw "$dep" \
- | grep '^Packages' | awk '{print $3}')
- [ -n "$_realdep" ] && _realdep="${_realdep%-*-*}" && return 0
+binfmt_disable() {
+ echo 0 > /proc/sys/fs/binfmt_misc/status
+}
- dep="$(echo "$dep" | sed 's/[<>=].*//')"
- _realdep=$(pacman --noconfirm -Sddw "$dep" \
- | grep '^Packages' | awk '{print $3}')
- [ -n "$_realdep" ] && _realdep="${_realdep%-*-*}" && return 0
+#failed_build() {
+# # FIXME
+# _log=$(find "$_logdest" -type f -iname "$1-*" -printf "%T@ %p\n" \
+# | sort -n | tail -n1 | cut -d' ' -f2-)
+# set +o pipefail
+# _phase=""
+# [ -z "$_log" ] || _phase=$(cat $_log | grep '==>.*occurred in' \
+# | awk '{print $7}' | sed 's/().*//')
+# set -o pipefail
+# if [ -n "${_phase:-}" ]; then
+# notify -c error "$_pkgname: error in $_phase()" -h string:document:"$_log"
+# else
+# notify -c error "$_pkgname: error in makepkg"
+# fi
+# [ "x$KEEP_GOING" == "xyes" ] || die "error building $_pkgname"
+# _build_failed=yes
+#}
- return 0
-}
diff --git a/src/shared/deptree.sh b/src/shared/deptree.sh
new file mode 100644
index 0000000..ffc0af8
--- /dev/null
+++ b/src/shared/deptree.sh
@@ -0,0 +1,103 @@
+#!/bin/bash
+ ##############################################################################
+ # parabola-riscv64-bootstrap #
+ # #
+ # Copyright (C) 2018 Andreas Grapentin #
+ # #
+ # This program is free software: you can redistribute it and/or modify #
+ # it under the terms of the GNU General Public License as published by #
+ # the Free Software Foundation, either version 3 of the License, or #
+ # (at your option) any later version. #
+ # #
+ # This program is distributed in the hope that it will be useful, #
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+ # GNU General Public License for more details. #
+ # #
+ # You should have received a copy of the GNU General Public License #
+ # along with this program. If not, see <http://www.gnu.org/licenses/>. #
+ ##############################################################################
+
+check_deptree() {
+ echo -n "checking for complete deptree ... "
+
+ local have_deptree=yes
+ [ -f "$DEPTREE".FULL ] || have_deptree=no
+ echo $have_deptree
+
+ [ "x$have_deptree" == "xyes" ] || return "$ERROR_MISSING"
+}
+
+build_deptree() {
+ check_exe ed pacman sed || return
+
+ # create empty deptree
+ truncate -s0 "$DEPTREE".FULL
+
+ # add the packages listed in the given groups
+ local g p r
+ for g in "$@"; do
+ for p in $(pacman -Sg "$g" | awk '{print $2}'); do
+ r=$(make_realpkg "$p") || return "$ERROR_MISSING"
+
+ if ! grep -q "^$r :" "$DEPTREE".FULL; then
+ echo "$r : [ ] # $g" >> "$DEPTREE".FULL
+ else
+ sed -i "s/^$r : \\[.*/&, $g/" "$DEPTREE".FULL
+ fi
+ done
+ done
+}
+
+prepare_deptree() {
+ check_deptree || build_deptree "$@" || return
+
+ [ -f "$DEPTREE" ] || cp "$DEPTREE"{.FULL,}
+ chown "$SUDO_USER" "$DEPTREE"{,.FULL}
+}
+
+deptree_next() {
+ local pkg
+ pkg=$(grep '\[ *\]' "$DEPTREE" | tail -n1 | awk '{print $1}')
+ [ -n "$pkg" ] || return "$ERROR_MISSING"
+ echo "$pkg"
+}
+
+deptree_remove() {
+ sed -i "/^$1 :/d; s/ / /g; s/ $1 / /g; s/ */ /g" "$DEPTREE"
+}
+
+deptree_check_depends() {
+ local OPTIND o needed=yes
+ while getopts "n" o; do
+ case "$o" in
+ n) needed=no ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-p] deptree pkgname depend" ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ local pkg="$1"
+ shift
+
+ local dep r res=0
+ # shellcheck disable=SC2068
+ for dep in $@; do
+ r=$(make_realpkg "$dep") || { res="$ERROR_MISSING"; continue; }
+
+ local have_pkg=yes
+ check_pkgfile "$PKGDEST" "$r" || have_pkg=no
+
+ if ! grep -q "^$r :" "$DEPTREE".FULL; then
+ echo "$r : [ ] # $pkg" >> "$DEPTREE".FULL
+ echo "$r : [ ] # $pkg" >> "$DEPTREE"
+ else
+ sed -i "/#.* $pkg\\(\\$\\|[ ,]\\)/! s/^$r : \\[.*/&, $pkg/" "$DEPTREE"{,.FULL}
+ fi
+ if [ "x$needed" == "xyes" ] && [ "x$have_pkg" == "xno" ]; then
+ sed -i "s/^$pkg : \\[/& $r/" "$DEPTREE"{,.FULL}
+ fi
+ done
+
+ return "$res"
+}
diff --git a/src/shared/feedback.sh b/src/shared/feedback.sh
index 6b766ff..39e0a0c 100644
--- a/src/shared/feedback.sh
+++ b/src/shared/feedback.sh
@@ -18,45 +18,67 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
##############################################################################
-set -euo pipefail
-
-# output formatting
-export BO=$(tput bold)
-export NO=$(tput sgr0)
-export RE=$(tput setf 4)
-export GR=$(tput setf 2)
-export WH=$(tput setf 7)
+# error codes
+export ERROR_UNSPECIFIED=1
+export ERROR_INVOCATION=2
+export ERROR_MISSING=3
+export ERROR_BUILDFAIL=4
+export ERROR_KEYFAIL=5
# messaging functions
notify() {
# useful if running notify_telegram
- local recipient=-211578786
+ local recipient=260151125
+ #local recipient=-211578786
if type -p notify-send >/dev/null; then
- machinectl -q shell --uid=$SUDO_USER .host \
- $(which notify-send) -h string:recipient:$recipient "$@" >/dev/null
+ machinectl -q shell --uid="$SUDO_USER" .host \
+ "$(which notify-send)" -h string:recipient:$recipient "$@" >/dev/null
fi
}
-die() {
- echo "$BO$RE==> ERROR:$WH $*$NO" 1>&2
- notify -c error *Error:* "$(caller): $*"
- trap - ERR
- exit 1;
-}
-
msg() {
- echo "$BO$GR==>$WH $*$NO";
+ local OPTIND o n='' d=()
+ while getopts "d:n" o; do
+ case "$o" in
+ n) n=yes ;;
+ d) d=(-h string:document:"$OPTARG") ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-n] [-d file] msg ..." ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ [ "x$n" == "xyes" ] && notify "${d[@]}" "$*"
+ echo "$(tput bold)$(tput setf 2)==>$(tput setf 7) $*$(tput sgr0)";
}
-trap "die unknown error" ERR
+error() {
+ local OPTIND o n='' d=()
+ while getopts "d:n" o; do
+ case "$o" in
+ n) n=yes ;;
+ d) d=(-h string:document:"$OPTARG") ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-n] [-d file] msg ..." ;;
+ esac
+ done
+ shift $((OPTIND-1))
-# host system check helpers
-check_exe() {
- echo -n "checking for $1 ... "
- type -p $1 >/dev/null && echo yes || (echo no && die "missing ${2:-$1} in \$PATH")
+ [ "x$n" == "xyes" ] && notify -c error "${d[@]}" "$*"
+ echo "$(tput bold)$(tput setf 4)==> ERROR:$(tput setf 7) $*$(tput sgr0)" 1>&2
}
-check_file() {
- echo -n "checking for $1 ... "
- [ -f "$1" ] && echo yes || (echo no && die "missing ${2:-$1} in filesystem")
+die() {
+ local OPTIND o e="$ERROR_UNSPECIFIED" d=()
+ while getopts "e:d:" o; do
+ case "$o" in
+ e) e="$OPTARG" ;;
+ d) d=(-d "$OPTARG") ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-e status] [-d file] msg ..." ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ error -n "${d[@]}" "$*"
+ trap - ERR
+ exit "$e"
}
+trap 'die "unknown error"' ERR
diff --git a/src/shared/pacman.sh b/src/shared/pacman.sh
new file mode 100644
index 0000000..fde78e7
--- /dev/null
+++ b/src/shared/pacman.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+ ##############################################################################
+ # parabola-riscv64-bootstrap #
+ # #
+ # Copyright (C) 2018 Andreas Grapentin #
+ # #
+ # This program is free software: you can redistribute it and/or modify #
+ # it under the terms of the GNU General Public License as published by #
+ # the Free Software Foundation, either version 3 of the License, or #
+ # (at your option) any later version. #
+ # #
+ # This program is distributed in the hope that it will be useful, #
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+ # GNU General Public License for more details. #
+ # #
+ # You should have received a copy of the GNU General Public License #
+ # along with this program. If not, see <http://www.gnu.org/licenses/>. #
+ ##############################################################################
+
+import_keys() {
+ local keys k
+ keys="$(srcinfo_validpgpkeys)"
+ for k in $keys; do
+ check_gpgkey "$k" && continue
+ if ! retry -n 5 -s 60 sudo -u "$SUDO_USER" gpg --recv-keys "$k"; then
+ error -n "failed to import key '$k'"
+ return "$ERROR_KEYFAIL"
+ fi
+ done
+}
+
+pkgdeps() {
+ pacman -Si "$1" | grep '^Depends' | cut -d':' -f2 | sed 's/None//'
+}
+
+pkgarch() {
+ local pkgarch
+ pkgarch=$(pacman -Si "$1" | grep '^Architecture' | awk '{print $3}') || return
+ [ -n "$pkgarch" ] || return
+
+ # set arch to $CARCH, unless it is any
+ [ "x$pkgarch" == "xany" ] || pkgarch="$CARCH"
+ echo "$pkgarch"
+}
+
+pkgver() {
+ local pkgver
+ pkgver=$(pacman -Si "$1" | grep '^Version' | awk '{print $3}') || return
+ [ -n "$pkgver" ] || return
+ echo "$pkgver"
+}
+
+make_realpkg() {
+ local dep realpkg
+
+ dep="$1"
+ realpkg=$(pacman --noconfirm -Sddw "$dep" | grep '^Packages' | awk '{print $3}')
+ [ -n "$realpkg" ] && echo "${realpkg%-*-*}" && return 0
+
+ dep="$(sed 's/[<>=].*//' <<< "$dep")"
+ realpkg=$(pacman --noconfirm -Sddw "$dep" | grep '^Packages' | awk '{print $3}')
+ [ -n "$realpkg" ] && echo "${realpkg%-*-*}" && return 0
+
+ return "$ERROR_MISSING"
+}
+
+make_repo() {
+ local path=$1
+ shift
+
+ mkdir -p "$path" || return
+
+ local v
+ for v in "$@"; do
+ tar -czf "$path"/"$v".db.tar.gz -T /dev/null
+ tar -czf "$path"/"$v".files.tar.gz -T /dev/null
+ ln -s "$v".db.tar.gz "$path"/"$v".db
+ ln -s "$v".files.tar.gz "$path"/"$v".files
+ done
+}
diff --git a/src/shared/srcinfo.sh b/src/shared/srcinfo.sh
new file mode 100644
index 0000000..906ce9d
--- /dev/null
+++ b/src/shared/srcinfo.sh
@@ -0,0 +1,57 @@
+#!/bin/bash
+ ##############################################################################
+ # parabola-riscv64-bootstrap #
+ # #
+ # Copyright (C) 2018 Andreas Grapentin #
+ # #
+ # This program is free software: you can redistribute it and/or modify #
+ # it under the terms of the GNU General Public License as published by #
+ # the Free Software Foundation, either version 3 of the License, or #
+ # (at your option) any later version. #
+ # #
+ # This program is distributed in the hope that it will be useful, #
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+ # GNU General Public License for more details. #
+ # #
+ # You should have received a copy of the GNU General Public License #
+ # along with this program. If not, see <http://www.gnu.org/licenses/>. #
+ ##############################################################################
+
+makesrcinfo() {
+ if [ ! -f .SRCINFO ] || [ .SRCINFO -ot PKGBUILD ]; then
+ (sudo -u "$SUDO_USER" makepkg --printsrcinfo) > .SRCINFO
+ fi
+}
+
+srcinfo_validpgpkeys() {
+ makesrcinfo
+ grep 'validpgpkeys =' .SRCINFO | awk '{print $3}'
+}
+
+srcinfo_pkgbase() {
+ makesrcinfo
+ grep '^pkgbase =' .SRCINFO | awk '{print $3}'
+}
+
+srcinfo_builddeps() {
+ local OPTIND o n='check\|' m='make\|'
+ while getopts "nm" o; do
+ case "$o" in
+ n) n='' ;;
+ m) m='' ;;
+ *) die -e "$ERROR_INVOCATION" "Usage: ${FUNCNAME[0]} [-n]" ;;
+ esac
+ done
+ shift $((OPTIND-1))
+
+ makesrcinfo
+ awk '/^pkgbase = /,/^$/{print}' < .SRCINFO \
+ | grep " \\($m$n\\)depends =" | awk '{print $3}'
+}
+
+srcinfo_rundeps() {
+ makesrcinfo
+ awk '/^pkgname = '"$1"'$/,/^$/{print}' < .SRCINFO \
+ | grep ' depends =' | awk '{print $3}'
+}
diff --git a/src/shared/upstream.sh b/src/shared/upstream.sh
new file mode 100644
index 0000000..d310be7
--- /dev/null
+++ b/src/shared/upstream.sh
@@ -0,0 +1,93 @@
+#!/bin/bash
+ ##############################################################################
+ # parabola-riscv64-bootstrap #
+ # #
+ # Copyright (C) 2018 Andreas Grapentin #
+ # #
+ # This program is free software: you can redistribute it and/or modify #
+ # it under the terms of the GNU General Public License as published by #
+ # the Free Software Foundation, either version 3 of the License, or #
+ # (at your option) any later version. #
+ # #
+ # This program is distributed in the hope that it will be useful, #
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+ # GNU General Public License for more details. #
+ # #
+ # You should have received a copy of the GNU General Public License #
+ # along with this program. If not, see <http://www.gnu.org/licenses/>. #
+ ##############################################################################
+
+package_get_upstream_repo() {
+ local repo url response target=
+ for repo in core extra community; do
+ url=https://www.archlinux.org/packages/$repo/x86_64/$1/
+ response=$(retry -n 5 -s 60 curl -sL "$url") || die "failed to retrieve url $url"
+ grep -iq "Arch Linux - $1" <<< "$response" || continue
+
+ target=$repo
+ break
+ done
+ [ -z "$target" ] || target=libre
+ echo $target
+}
+
+package_fetch_upstream_pkgfiles() {
+ # fetch upstream pkgbuilds from arch
+ local repo repoinfo pkgbase
+ repoinfo=$(asp list-repos "$1") || repoinfo=""
+ repo=$(grep -P '^(core|extra|community)' <<< "$repoinfo" | head -n1)
+ pkgbase=$(grep -o 'part of package .*' <<< "$repoinfo" | awk '{print $4}')
+
+ [ -z "$repo" ] && repo=libre
+ [ -z "$pkgbase" ] && pkgbase="$1"
+
+ mkdir -p .arch
+ asp export "$repo/$1" >/dev/null
+ mv "$pkgbase"/* .arch/
+ rm -rf "$pkgbase"
+
+ # fetch upstream pkgbuilds from parabola
+ mkdir -p .parabola
+ local src url=https://www.parabola.nu/packages/libre/x86_64/$1/
+ if ! curl -sL "$url" | grep -iq 'not found'; then
+ src=$(curl -sL "$url" | grep -i 'source files' | cut -d'"' -f2 | sed 's#/tree/#/plain/#')
+ for link in $(curl -sL "$src" | grep '^ <li><a href' | cut -d"'" -f2 \
+ | sed "s#^#$(echo "$src" | awk -F/ '{print $3}')#"); do
+ wget -q "$link" -O .parabola/"$(basename "${link%\?*}")";
+ done
+ fi
+
+ if [ -f .parabola/PKGBUILD ]; then
+ cp -v .parabola/* .
+ elif [ -f .arch/PKGBUILD ]; then
+ cp -v .arch/* .
+ else
+ return "$ERROR_MISSING"
+ fi
+}
+
+#package_fetch_upstream_pkgfiles() {
+# FIXME
+# # acquire the pkgbuild and auxiliary files
+# local url=https://www.parabola.nu/packages/libre/x86_64/$1/
+# _fetch_pkgfiles_from $url && echo "libre" > .REPO && return
+#
+# local repo
+# for repo in core extra community; do
+# url=https://www.archlinux.org/packages/$repo/x86_64/$1/
+# _fetch_pkgfiles_from $url && echo "$repo" > .REPO && return
+# done
+# die "$1: failed to fetch pkgfiles"
+#}
+#
+#_fetch_pkgfiles_from() {
+# curl -sL $url | grep -iq 'not found' && return 1
+# local src=$(curl -sL $url | grep -i 'source files' | cut -d'"' -f2 | sed 's#/tree/#/plain/#')
+# for link in $(curl -sL $src | grep '^ <li><a href' | cut -d"'" -f2 \
+# | sed "s#^#$(echo $src | awk -F/ '{print $3}')#"); do
+# wget -q $link -O $(basename ${link%\?*});
+# done
+# [ -f PKGBUILD ] || return 1
+#}
+