#!/bin/sh -eu
usage() {
printf "%s\n\n" "Usage: $0 [command...] [flags...] [args...]"
printf "%s\n" "$0 add-repo [-s] <name> <key>"
printf "\t%s\n" "Trusts <key> and adds the local repo to /etc/apk/repositories"
printf "\t%s\n\n" "-s: set this key as default in abuild.conf"
printf "%s\n" "$0 build [-cu] [-v <pkgver>] <packages...>"
printf "\t%s\n" "Builds packages"
printf "\t%s\n" "-c: update checksums"
printf "\t%s\n" "-u: update pkgrel"
printf "\t%s\n\n" "-v <pkgver>: update pkgver"
printf "%s\n" "$0 pkgver"
printf "\t%s\n\n" "Prints the suggested package ver for this directory"
printf "%s\n" "$0 upload <ssh server> <remote path> <packages...>"
printf "\t%s\n" "Uploads packages via rsync and updates remote APKINDEX"
}
get_pkgvar() (
var="$1"
set +u
. APKBUILD
eval 'printf "%s\n" "$'"$var"'"'
)
find_repos() (
find . -maxdepth 1 -type d -not -name . -not -name .git
)
find_pkg_repo() (
pkg=$1
for repo in $(find_repos)
do
if [ -d "$repo"/"$pkg" ]
then
echo "$repo"
return 0
fi
done
return 1
)
update_pkgrel() (
pkg="$1"
pkgver="$(get_pkgvar pkgver)"
prev_ver=$(apk search -x "$pkg" | cut -c$((${#pkg}+2))-)
prev_pkgver=$(printf "%s" "$prev_ver" | cut -d'-' -f1)
prev_pkgrel=$(printf "%s" "$prev_ver" | cut -d'-' -f2 | cut -d'r' -f2-)
if [ "$prev_pkgver" == "$pkgver" ]
then
pkgrel=$((prev_pkgrel + 1))
sed -e "s/pkgrel=.*/pkgrel=$pkgrel/" -i APKBUILD
fi
)
update_pkgver() {
pkgver="$1"
prev_pkgver=$(apk search -x ${project} | cut -d '-' -f2)
sed -e "s/pkgver=.*/pkgver=$pkgver/" -i APKBUILD
if [ "$prev_pkgver" != "$pkgver" ]
then
sed -e "s/pkgrel=.*/pkgrel=0/" -i APKBUILD
fi
}
add_repo() {
set_default=0
while getopts s flag
do
case $flag in
s) set_default=1 ;;
*) usage && exit 1 ;;
esac
done
shift $((OPTIND-1))
echo "$@"
if [ $# -ne 2 ]
then
usage
exit 1
fi
repo="$1"
key="$2"
mkdir -p ~/packages/$repo
echo ~/packages/$repo | cat - /etc/apk/repositories > /tmp/repositories
sudo mv /tmp/repositories /etc/apk/repositories
if ! [ -f "$key" ]
then
echo "Warning: generating new abuild key"
key="$HOME/.abuild/abuild.rsa"
mkdir -p $HOME/.abuild
(
umask 0007
openssl genrsa -out "$key" 2048
)
fi
sudo openssl rsa -in $key -pubout \
-out /etc/apk/keys/$(basename "$key").pub
if [ $set_default -eq 1 ]
then
echo "PACKAGER_PRIVKEY="'"'$key'"' >> \
~/.abuild/abuild.conf
fi
}
build() (
builddeps=0
checksum=0
updpkgrel=0
pkgver=""
# Disable progress on abuild-apk
cat <<-"EOF" | sudo tee /usr/local/bin/abuild-apk
#!/bin/sh
exec /usr/bin/abuild-apk --no-progress $@
EOF
sudo chmod +x /usr/local/bin/abuild-apk
export PATH=/usr/local/bin:$PATH
while getopts Rcuv: flag
do
case $flag in
R) builddeps=1 ;;
c) checksum=1 ;;
u) updpkgrel=1 ;;
v) pkgver="$OPTARG" ;;
*) usage && exit 1 ;;
esac
done
shift $((OPTIND-1))
if [ $# -eq 0 ]
then
echo "No packages specified."
exit 1
fi
for pkg in $@
do
repo="$(find_pkg_repo "$pkg")"
(
cd "$repo"/"$pkg"
if [ -n "$pkgver" ]
then
update_pkgver "$pkgver"
fi
if [ $updpkgrel -eq 1 ]
then
update_pkgrel "$pkg"
fi
if [ $checksum -eq 1 ]
then
abuild checksum
fi
if [ $builddeps -eq 1 ]
then
abuild -R
else
abuild -r
fi
)
done
)
print_pkgver() {
if [ $# -ne 0 ]
then
usage
exit 1
fi
if [ -d .git ]
then
set +e
pkgver=$(git describe --abbrev=0 2>/dev/null)
if [ $? -ne 0 ]
then
pkgver=0
fi
set -e
if ! git describe --exact-match HEAD >/dev/null 2>&1
then
cdate=$(git show -s -1 --format='%ci' HEAD)
cdate=$(echo "$cdate" | cut -d' ' -f1 | sed -e 's/-//g')
pkgver="${pkgver}_git${cdate}"
fi
elif [ -d .hg ]
then
pkgver=$(hg id -T '{latesttag}')
if [ "$(hg id -T '{latesttagdistance}')" -ne 0 ]
then
pkgver="$(hg id -T '{latesttag}_hg{sub("-", "", date|shortdate)}')"
fi
else
pkgver=unknown_0000
fi
echo "$pkgver"
}
mirror_ver() (
mirror="$1"
pkg="$2"
apk policy "$pkg" | while read -r line
do
case "$line" in
*:)
ver="${line%:}"
ver="${ver## }"
;;
*$mirror*)
echo "$ver"
;;
esac
done
)
get_aver() {
aver="${REPOSITORY:-}"
if [ ${#aver} -eq 0 ]
then
. /etc/os-release
aver="v$(printf "%s" "$VERSION_ID" | cut -d. -f1-2)"
fi
echo "$aver"
}
upload_pkg() (
repo="$1"
pkg="$2"
arch="$(uname -m)"
aver="$(get_aver)"
set -x
path="$remote_path/$aver/$repo/$arch"
ssh "$remote" mkdir -p "$path"
url=$(echo "$remote" | cut -d@ -f2)
prev_ver=$(mirror_ver "$url" "$pkg")
for ver in $prev_ver
do
if [ "$prev_ver" != "none" ]
then
ssh "$remote" rm -f "$path/$pkg-$ver.apk"
fi
done
pkgver="$(get_pkgvar pkgver)"
pkgrel="$(get_pkgvar pkgrel)"
rsync --blocking-io -rsP \
~/packages/"$repo/$arch/$pkg-$pkgver-r$pkgrel.apk" "$remote":"$path/"
set +x
)
update_index() (
repo="$1"
arch="$(uname -m)"
. /etc/os-release
aver="$(get_aver)"
path="$remote_path/$aver/$repo/$arch"
set -x
ssh "$remote" \
find "$path" -type f -name '*.apk' -print0 |
ssh "$remote" xargs -0 apk index \
--rewrite-arch "$(uname -m)" \
-x "$path"/APKINDEX.tar.gz \
-o "$path"/APKINDEX.unsigned.tar.gz
rsync --blocking-io -rP \
"$remote:$path/APKINDEX.unsigned.tar.gz" \
/tmp/APKINDEX.tar.gz
abuild-sign /tmp/APKINDEX.tar.gz
rsync --blocking-io -rP /tmp/APKINDEX.tar.gz "$remote:$path/"
set +x
)
upload() (
if [ $# -lt 2 ]
then
usage
exit 1
fi
remote="$1"
remote_path="$2"
shift 2
if [ $# -eq 0 ]
then
echo "No packages specified"
exit 1
fi
repos=""
for pkg in $@
do
repo=$(find_pkg_repo "$pkg")
if ! echo "$repos" | grep "$repo" >/dev/null
then
repos="$repo $repos"
fi
(
cd "$repo"/"$pkg"
arch="$(get_pkgvar arch)"
subpkgs="$pkg:_:$arch $(get_pkgvar subpackages)"
for subpkg in $subpkgs
do
name="$(echo "$subpkg" | cut -d':' -f1)"
upload_pkg "$repo" "$name"
done
)
done
for repo in $repos
do
update_index $repo
done
)
if [ $# -lt 1 ]
then
usage
exit 1
fi
cmd="$1"
shift
case "$cmd" in
add-repo)
add_repo "$@"
;;
build)
build "$@"
;;
pkgver)
print_pkgver "$@"
;;
upload)
upload "$@"
;;
help|-h)
usage
;;
esac