summaryrefslogtreecommitdiff
path: root/src/commitpkg.in
diff options
context:
space:
mode:
Diffstat (limited to 'src/commitpkg.in')
-rw-r--r--src/commitpkg.in241
1 files changed, 241 insertions, 0 deletions
diff --git a/src/commitpkg.in b/src/commitpkg.in
new file mode 100644
index 0000000..31adcd6
--- /dev/null
+++ b/src/commitpkg.in
@@ -0,0 +1,241 @@
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+m4_include(lib/common.sh)
+
+# Source makepkg.conf; fail if it is not found
+if [[ -r '/etc/makepkg.conf' ]]; then
+ # shellcheck source=config/makepkg/x86_64.conf
+ source '/etc/makepkg.conf'
+else
+ die '/etc/makepkg.conf not found!'
+fi
+
+# Source user-specific makepkg.conf overrides
+if [[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf" ]]; then
+ # shellcheck source=/dev/null
+ source "${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf"
+elif [[ -r "$HOME/.makepkg.conf" ]]; then
+ # shellcheck source=/dev/null
+ source "$HOME/.makepkg.conf"
+fi
+
+cmd=${0##*/}
+
+if [[ ! -f PKGBUILD ]]; then
+ die 'No PKGBUILD file'
+fi
+
+source=()
+# shellcheck source=PKGBUILD.proto
+. ./PKGBUILD
+pkgbase=${pkgbase:-$pkgname}
+
+case "$cmd" in
+ commitpkg)
+ if (( $# == 0 )); then
+ die 'Usage: commitpkg <reponame> [-f] [-s server] [-l limit] [-a arch] [commit message]'
+ fi
+ repo="$1"
+ shift
+ ;;
+ *pkg)
+ repo="${cmd%pkg}"
+ ;;
+ *)
+ die 'Usage: commitpkg <reponame> [-f] [-s server] [-l limit] [-a arch] [commit message]'
+ ;;
+esac
+
+
+if (( ${#validpgpkeys[@]} != 0 )); then
+ if [[ -d keys ]]; then
+ for key in "${validpgpkeys[@]}"; do
+ if [[ ! -f keys/pgp/$key.asc ]]; then
+ export-pkgbuild-keys || die 'Failed to export valid PGP keys for source files'
+ fi
+ done
+ else
+ export-pkgbuild-keys || die 'Failed to export valid PGP keys for source files'
+ fi
+
+ svn add --parents --force keys/pgp/*
+fi
+
+# find files which should be under source control
+needsversioning=()
+for s in "${source[@]}"; do
+ [[ $s != *://* ]] && needsversioning+=("$s")
+done
+for i in 'changelog' 'install'; do
+ while read -r file; do
+ # evaluate any bash variables used
+ eval "file=\"$(sed "s/^\(['\"]\)\(.*\)\1\$/\2/" <<< "$file")\""
+ needsversioning+=("$file")
+ done < <(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD)
+done
+for key in "${validpgpkeys[@]}"; do
+ needsversioning+=("keys/pgp/$key.asc")
+done
+
+# assert that they really are controlled by SVN
+if (( ${#needsversioning[*]} )); then
+ # svn status's output is only two columns when the status is unknown
+ while read -r status filename; do
+ [[ $status = '?' ]] && unversioned+=("$filename")
+ done < <(svn status -v "${needsversioning[@]}")
+ (( ${#unversioned[*]} )) && die "%s is not under version control" "${unversioned[@]}"
+fi
+
+rsyncopts=(-e ssh -p '--chmod=ug=rw,o=r' -c -h -L --progress --partial -y)
+archreleaseopts=()
+while getopts ':l:a:s:f' flag; do
+ case $flag in
+ f) archreleaseopts+=('-f') ;;
+ s) server=$OPTARG ;;
+ l) rsyncopts+=("--bwlimit=$OPTARG") ;;
+ a) commit_arch=$OPTARG ;;
+ :) die "Option requires an argument -- '%s'" "$OPTARG" ;;
+ \?) die "Invalid option -- '%s'" "$OPTARG" ;;
+ esac
+done
+shift $(( OPTIND - 1 ))
+
+# check packages for validity
+for _arch in "${arch[@]}"; do
+ if [[ -n $commit_arch && ${_arch} != "$commit_arch" ]]; then
+ continue
+ fi
+ for _pkgname in "${pkgname[@]}"; do
+ fullver=$(get_full_version "$_pkgname")
+
+ if pkgfile=$(find_cached_package "$_pkgname" "$fullver" "$_arch"); then
+ check_package_validity "$pkgfile"
+ fi
+ done
+
+ fullver=$(get_full_version "$pkgbase")
+ if pkgfile=$(find_cached_package "$pkgbase-debug" "$fullver" "$_arch"); then
+ check_package_validity "$pkgfile"
+ fi
+done
+
+if [[ -z $server ]]; then
+ server='repos.archlinux.org'
+fi
+
+if [[ -n $(svn status -q) ]]; then
+ msgtemplate="upgpkg: $pkgbase $(get_full_version)"
+ if [[ -n $1 ]]; then
+ stat_busy 'Committing changes to trunk'
+ svn commit -q -m "${msgtemplate}: ${1}" || die
+ stat_done
+ else
+ msgfile="$(mktemp)"
+ echo "$msgtemplate" > "$msgfile"
+ if [[ -n $SVN_EDITOR ]]; then
+ $SVN_EDITOR "$msgfile"
+ elif [[ -n $VISUAL ]]; then
+ $VISUAL "$msgfile"
+ elif [[ -n $EDITOR ]]; then
+ $EDITOR "$msgfile"
+ else
+ vi "$msgfile"
+ fi
+ [[ -s $msgfile ]] || die
+ stat_busy 'Committing changes to trunk'
+ svn commit -q -F "$msgfile" || die
+ unlink "$msgfile"
+ stat_done
+ fi
+fi
+
+declare -a uploads
+declare -a commit_arches
+declare -a skip_arches
+
+for _arch in "${arch[@]}"; do
+ if [[ -n $commit_arch && ${_arch} != "$commit_arch" ]]; then
+ skip_arches+=("$_arch")
+ continue
+ fi
+
+ for _pkgname in "${pkgname[@]}"; do
+ fullver=$(get_full_version "$_pkgname")
+ if ! pkgfile=$(find_cached_package "$_pkgname" "$fullver" "${_arch}"); then
+ warning "Skipping %s: failed to locate package file" "$_pkgname-$fullver-$_arch"
+ skip_arches+=("$_arch")
+ continue 2
+ fi
+ uploads+=("$pkgfile")
+ done
+
+ fullver=$(get_full_version "$pkgbase")
+ if ! pkgfile=$(find_cached_package "$pkgbase-debug" "$fullver" "$_arch"); then
+ continue
+ fi
+ if ! is_debug_package "$pkgfile"; then
+ continue
+ fi
+ uploads+=("$pkgfile")
+done
+
+for pkgfile in "${uploads[@]}"; do
+ sigfile="${pkgfile}.sig"
+ if [[ ! -f $sigfile ]]; then
+ msg "Signing package %s..." "${pkgfile}"
+ if [[ -n $GPGKEY ]]; then
+ SIGNWITHKEY=(-u "${GPGKEY}")
+ fi
+ gpg --detach-sign --use-agent --no-armor "${SIGNWITHKEY[@]}" "${pkgfile}" || die
+ fi
+ if ! gpg --verify "$sigfile" "$pkgfile" >/dev/null 2>&1; then
+ die "Signature %s is incorrect!" "$sigfile"
+ fi
+ uploads+=("$sigfile")
+done
+
+for _arch in "${arch[@]}"; do
+ if ! in_array "$_arch" "${skip_arches[@]}"; then
+ commit_arches+=("$_arch")
+ fi
+done
+
+if [[ ${#commit_arches[*]} -gt 0 ]]; then
+ archrelease "${archreleaseopts[@]}" "${commit_arches[@]/#/$repo-}" || die
+fi
+
+if [[ ${#uploads[*]} -gt 0 ]]; then
+ new_uploads=()
+
+ # convert to absolute paths so rsync can work with colons (epoch)
+ while read -r -d '' upload; do
+ new_uploads+=("$upload")
+ done < <(realpath -z "${uploads[@]}")
+
+ uploads=("${new_uploads[@]}")
+ unset new_uploads
+ msg 'Uploading all package and signature files'
+ rsync "${rsyncopts[@]}" "${uploads[@]}" "$server:staging/$repo/" || die
+fi
+
+if [[ "${arch[*]}" == 'any' ]]; then
+ if [[ -d ../repos/$repo-x86_64 ]]; then
+ pushd ../repos/ >/dev/null
+ stat_busy "Removing %s" "$repo-x86_64"
+ svn rm -q "$repo-x86_64"
+ svn commit -q -m "Removed $repo-x86_64 for $pkgname"
+ stat_done
+ popd >/dev/null
+ fi
+else
+ if [[ -d ../repos/$repo-any ]]; then
+ pushd ../repos/ >/dev/null
+ stat_busy "Removing %s" "$repo-any"
+ svn rm -q "$repo-any"
+ svn commit -q -m "Removed $repo-any for $pkgname"
+ stat_done
+ popd >/dev/null
+ fi
+fi