Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/src/pkgrepo.in
diff options
context:
space:
mode:
authorLevente Polyak <anthraxx@archlinux.org>2022-09-11 22:17:09 +0200
committerLevente Polyak <anthraxx@archlinux.org>2023-05-19 22:27:12 +0200
commit3d3176beb6eb0319809be386cd903fa03bdabc73 (patch)
treeb25c4c6612f71cd07a5773e04bc466fcf09b565a /src/pkgrepo.in
parent6aa42e1f6e913fd8706bd809f784f6c492762a20 (diff)
pkgrepo: rename archco as a general purpose tool for packaging repos
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
Diffstat (limited to 'src/pkgrepo.in')
-rw-r--r--src/pkgrepo.in260
1 files changed, 260 insertions, 0 deletions
diff --git a/src/pkgrepo.in b/src/pkgrepo.in
new file mode 100644
index 0000000..2804cba
--- /dev/null
+++ b/src/pkgrepo.in
@@ -0,0 +1,260 @@
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+m4_include(lib/common.sh)
+
+source /usr/share/makepkg/util/config.sh
+source /usr/share/makepkg/util/message.sh
+
+set -e
+
+
+usage() {
+ cat <<- _EOF_
+ Usage: ${BASH_SOURCE[0]##*/} [COMMAND] [OPTIONS]
+
+ Manage Git packaging repositories and helps with their configuration
+ according to distro specs.
+
+ Git author information and the used signing key is set up from
+ makepkg.conf read from any valid location like /etc or XDG_CONFIG_HOME.
+ The configure command can be used to synchronize the distro specs and
+ makepkg.conf settings for previously cloned repositories.
+
+ The unprivileged option can be used for cloning packaging repositories
+ without SSH access using read-only HTTPS.
+
+ COMMANDS
+ clone Clone a package repository
+ configure Configure a clone according to distro specs
+
+ OPTIONS
+ -h, --help Show this help text
+_EOF_
+}
+
+usage_clone() {
+ cat <<- _EOF_
+ Usage: ${BASH_SOURCE[0]##*/} clone [OPTIONS] [PKGNAME...]
+
+ Clone Git packaging repositories from the canonical namespace.
+
+ The configure command is subsequently invoked to synchronize the distro
+ specs and makepkg.conf settings. The unprivileged option can be used
+ for cloning packaging repositories without SSH access using read-only
+ HTTPS.
+
+ OPTIONS
+ -m, --maintainer=NAME Clone all packages of the named maintainer
+ -u, --unprivileged Clone package with read-only access and without
+ packager info as Git author.
+ -h, --help Show this help text
+_EOF_
+}
+
+usage_configure() {
+ cat <<- _EOF_
+ Usage: ${BASH_SOURCE[0]##*/} configure [OPTIONS] [PATH...]
+
+ Configure Git packaging repositories according to distro specs and
+ makepkg.conf settings.
+
+ Git author information and the used signing key is set up from
+ makepkg.conf read from any valid location like /etc or XDG_CONFIG_HOME.
+ The unprivileged option can be used for cloning packaging repositories
+ without SSH access using read-only HTTPS.
+
+ OPTIONS
+ -u, --unprivileged Configure read-only repo without packager info as Git author.
+ -h, --help Show this help text
+_EOF_
+}
+
+if (( $# < 1 )); then
+ usage
+ exit 1
+fi
+
+# commands
+CLONE=0
+CONFIGURE=0
+
+# options
+GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH}
+UNPRIVILEGED=0
+MAINTAINER=
+PACKAGER_NAME=
+PACKAGER_EMAIL=
+
+# command checking
+while (( $# )); do
+ case $1 in
+ -h|--help)
+ usage
+ exit 0
+ ;;
+ clone)
+ CLONE=1
+ CONFIGURE=1
+ shift
+ break
+ ;;
+ configure)
+ CONFIGURE=1
+ shift
+ break
+ ;;
+ *)
+ die "invalid argument: %s" "$1"
+ ;;
+ esac
+done
+
+if (( CLONE )); then
+ # option checking
+ if (( $# < 1 )); then
+ usage_clone
+ exit 1
+ fi
+ while (( $# )); do
+ case $1 in
+ -h|--help)
+ usage_clone
+ exit 0
+ ;;
+ -u|--unprivileged)
+ GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS}
+ UNPRIVILEGED=1
+ shift
+ ;;
+ -m|--maintainer)
+ (( $# <= 1 )) && die "missing argument for %s" "$1"
+ MAINTAINER="$2"
+ shift 2
+ ;;
+ --maintainer=*)
+ MAINTAINER="${1#*=}"
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ die "invalid argument: %s" "$1"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ done
+elif (( CONFIGURE )); then
+ # option checking
+ if (( $# < 1 )); then
+ usage_configure
+ exit 1
+ fi
+ while (( $# )); do
+ case $1 in
+ -h|--help)
+ usage_configure
+ exit 0
+ ;;
+ -u|--unprivileged)
+ GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS}
+ UNPRIVILEGED=1
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ die "invalid argument: %s" "$1"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ done
+fi
+
+pkgbases=("$@")
+
+# Load makepkg.conf variables to be available
+load_makepkg_config
+
+# Check official packaging identity before setting Git author
+if (( ! UNPRIVILEGED )); then
+ if [[ $PACKAGER == *"Unknown Packager"* ]]; then
+ die "Packager must be set in makepkg.conf"
+ fi
+ packager_pattern="(.+) <(.+@.+)>"
+ if [[ ! $PACKAGER =~ $packager_pattern ]]; then
+ die "Invalid Packager format '${PACKAGER}' in makepkg.conf"
+ fi
+
+ PACKAGER_NAME=$(echo "${PACKAGER}"|sed -E "s/${packager_pattern}/\1/")
+ PACKAGER_EMAIL=$(echo "${PACKAGER}"|sed -E "s/${packager_pattern}/\2/")
+
+ if [[ ! $PACKAGER_EMAIL =~ .+@archlinux.org ]]; then
+ die "Packager email '${PACKAGER_EMAIL}' is not an @archlinux.org address"
+ fi
+fi
+
+# Query packages of a maintainer
+if [[ -n ${MAINTAINER} ]]; then
+ stat_busy "Query packages for ${MAINTAINER}"
+ max_pages=$(curl --silent --location --fail --retry 3 --retry-delay 3 "https://archlinux.org/packages/search/json/?sort=name&maintainer=${MAINTAINER}" | jq -r '.num_pages')
+ mapfile -t pkgbases < <(for page in $(seq "${max_pages}"); do
+ curl --silent --location --fail --retry 3 --retry-delay 3 "https://archlinux.org/packages/search/json/?sort=name&maintainer=${MAINTAINER}&page=${page}" | jq -r '.results[].pkgbase'
+ stat_progress
+ done | sort --unique)
+ stat_done
+fi
+
+for pkgbase in "${pkgbases[@]}"; do
+ if (( CLONE )); then
+ if [[ ! -d ${pkgbase} ]]; then
+ msg "Cloning ${pkgbase} ..."
+ remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git"
+ git clone --origin origin "${remote_url}"
+ else
+ warning "Skip cloning ${pkgbase}: Directory exists"
+ fi
+ fi
+
+ if (( CONFIGURE )); then
+ msg "Configuring $(basename "${pkgbase}") ..."
+ path=${pkgbase}
+ if [[ ! -d "${path}/.git" ]]; then
+ error "Not a Git repository: ${path}"
+ continue
+ fi
+
+ giturl=$(git -C "${path}" remote get-url origin)
+ if [[ ${giturl} != *${GIT_PACKAGING_NAMESPACE}* ]]; then
+ error "Not a packaging repository: ${path}"
+ continue
+ fi
+
+ pkgbase=$(basename "${giturl}")
+ pkgbase=${pkgbase%.git}
+ remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git"
+
+ git -C "${path}" remote set-url origin "${remote_url}"
+ git -C "${path}" config devtools.version "${GIT_REPO_SPEC_VERSION}"
+ git -C "${path}" config commit.gpgsign true
+ git -C "${path}" config pull.rebase true
+ git -C "${path}" config branch.main.rebase true
+
+ if (( ! UNPRIVILEGED )); then
+ git -C "${path}" config user.name "${PACKAGER_NAME}"
+ git -C "${path}" config user.email "${PACKAGER_EMAIL}"
+ if [[ -n $GPGKEY ]]; then
+ git -C "${path}" config user.signingKey "${GPGKEY}"
+ fi
+ fi
+ fi
+done