#!/bin/bash # License: Unspecified m4_include(lib/common.sh) # Source makepkg.conf; fail if it is not found if [[ -r '/etc/makepkg.conf' ]]; then # shellcheck source=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 [-f] [-s server] [-l limit] [-a arch] [commit message]' fi repo="$1" shift ;; *pkg) repo="${cmd%pkg}" ;; *) die 'Usage: commitpkg [-f] [-s server] [-l limit] [-a arch] [commit message]' ;; esac # 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 # 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 have the packager field set 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" "$_arch" "$fullver"); then if grep -q "packager = Unknown Packager" <(bsdtar -xOqf "$pkgfile" .PKGINFO); then die "PACKAGER was not set when building package" fi fi done done if [[ -z $server ]]; then server='repos.archlinux.org' fi if [[ -n $(svn status -q) ]]; then msgtemplate="upgpkg: $pkgbase $(get_full_version)"$'\n\n' 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") 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" >/dev/null 2>&1; then die "Signature %s.sig is incorrect!" "$pkgfile" fi uploads+=("$sigfile") done 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-i686 && -d ../repos/$repo-x86_64 ]]; then pushd ../repos/ >/dev/null stat_busy "Removing %s and %s" "$repo-i686" "$repo-x86_64" svn rm -q "$repo-i686" svn rm -q "$repo-x86_64" svn commit -q -m "Removed $repo-i686 and $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