summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/completion/zsh/_devtools.in40
-rw-r--r--lib/common.sh9
-rw-r--r--src/archco.in238
3 files changed, 273 insertions, 14 deletions
diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in
index 707e3fa..1dc112f 100644
--- a/contrib/completion/zsh/_devtools.in
+++ b/contrib/completion/zsh/_devtools.in
@@ -15,10 +15,24 @@ _archbuild_args=(
'--[Introduce makechrootpkg options]:*::makechrootpkg options:= _dispatch makechrootpkg makechrootpkg'
)
-_archco_args=(
+_archco_cmds=(
+ "archco command"
+ "clone[Clone a package repository]"
+ "configure[Configure a clone according to distro specs]"
+)
+
+_archco_clone_args=(
+ '(-u --unprivileged)'{-u,--unprivileged}'[Read-only access without packager info as Git author]'
+ '(-h --help)'{-h,--help}'[Display usage]'
'*:packages:_devtools_completions_all_packages'
)
+_archco_configure_args=(
+ '(-u --unprivileged)'{-u,--unprivileged}'[Configure read-only repo without packager info as Git author]'
+ '(-h --help)'{-h,--help}'[Display usage]'
+ '*:git_dir:_files -/'
+)
+
_arch_nspawn_args=(
'-C[Location of a pacman config file]:pacman_config:_files -g "*.conf(.)"'
'-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"'
@@ -128,8 +142,30 @@ _devtools_completions_all_packages() {
}
_devtools() {
- local argname="_${service//-/_}_args[@]"
+ local service_func=_${service//-/_}
+ local service_cmds=${service_func}_cmds
+ if typeset -p ${service_cmds} &> /dev/null; then
+ _arguments -C \
+ "1: :->cmds" \
+ '*::arg:->args'
+ case $state in
+ cmds)
+ local service_cmds_array=${service_cmds}[@]
+ _values "${(P)service_cmds_array}"
+ ;;
+ args)
+ local cmd_args_array=${service_func}_$line[1]_args
+ if typeset -p ${cmd_args_array} &> /dev/null; then
+ local cmd_args=${cmd_args_array}[@]
+ _arguments -s "${(P)cmd_args}"
+ fi
+ ;;
+ esac
+ return 0
+ fi
+ local argname="${service_func}_args[@]"
_arguments -s "${(P)argname}"
+
}
_devtools
diff --git a/lib/common.sh b/lib/common.sh
index 577bb6e..5f134ae 100644
--- a/lib/common.sh
+++ b/lib/common.sh
@@ -19,6 +19,15 @@ export LANG=C
export BUILDTOOL=devtools
export BUILDTOOLVER=m4_devtools_version
+# Set common properties
+export PACMAN_KEYRING_DIR=/etc/pacman.d/gnupg
+export GITLAB_HOST=gitlab.archlinux.org
+export GIT_REPO_SPEC_VERSION=1
+export GIT_PACKAGING_NAMESPACE=archlinux/packaging/packages
+export GIT_PACKAGING_NAMESPACE_ID=11323
+export GIT_PACKAGING_URL_SSH="ssh://git@${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}"
+export GIT_PACKAGING_URL_HTTPS="https://${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}"
+
# check if messages are to be printed using color
if [[ -t 2 && "$TERM" != dumb ]]; then
colorize
diff --git a/src/archco.in b/src/archco.in
index c569e52..b401c23 100644
--- a/src/archco.in
+++ b/src/archco.in
@@ -4,21 +4,235 @@
m4_include(lib/common.sh)
-scriptname=${0##*/}
+source /usr/share/makepkg/util/config.sh
+source /usr/share/makepkg/util/message.sh
-if [[ -z $1 ]]; then
- printf 'Usage: %s <package name>...\n' "$scriptname"
+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
+ -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
-case $scriptname in
- archco)
- GITURL="ssh://git@gitlab.archlinux.org:222/bot-test/packages";;
- *)
- die "Couldn't find Git url for %s" "$scriptname"
- ;;
-esac
+# 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
+ ;;
+ --)
+ 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
+
+# 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
+
+pkgbases=("$@")
+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
-for pkgbase in "$@"; do
- git clone --origin origin --config commit.gpgsign=true "${GITURL}/${pkgbase}.git"
+ 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