feat(build): consolidate repo flags in build and release subcommand

Previously the behavior was inconsistent and not fully fulfilling its
purpose of only using --repo once when initially pushing a new and
unknown package to the official repositories.

Consolidate the behavior by only allowing to use --repo during the
initial packaging and disallow any subsequent usage. The expected user
experience is to subsequently use --testing or --staging to influence
the auto-detection of the build target. This avoids any kind of human
error which leads to releasing core packages to extra-testing by
accident.

Furthermore, allow the build subcommand to automatically fallback to
extra as the default stable repository target which greatly improves the
usability for AUR or local override builds.

Fixes #193
Fixes #191

Component: pkgctl build
Component: pkgctl release
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
This commit is contained in:
Levente Polyak 2024-02-06 21:59:11 +01:00
parent 5042dcaeb4
commit 3ecba314fc
No known key found for this signature in database
GPG Key ID: FC1B547C8D8172C8
6 changed files with 53 additions and 29 deletions

View File

@ -91,7 +91,7 @@ _pkgctl_db_update_args=(
_pkgctl_release_args=(
'(-m --message=)'{-m,--message=}"[Use the given <msg> as the commit message]:message:"
'(-r --repo=)'{-r,--repo=}"[Specify a target repository (disables auto-detection)]:repo:($DEVTOOLS_VALID_REPOS[*])"
'(-r --repo=)'{-r,--repo=}"[Specify a target repository for new packages]:repo:($DEVTOOLS_VALID_REPOS[*])"
'(-s --staging)'{-s,--staging}'[Release to the staging counterpart of the auto-detected repo]'
'(-t --testing)'{-t,--testing}'[Release to the testing counterpart of the auto-detected repo]'
'(-u --db-update)'{-u,--db-update}'[Automatically update the pacman database after uploading]'

View File

@ -21,7 +21,10 @@ Build Options
Specify architectures to build for (disables auto-detection)
*--repo* 'REPO'::
Specify a target repository (disables auto-detection)
Specify target repository for new packages not in any official repo.
Fallback to `'extra'` when building packages that are not present in any
official repository yet. Using this option is disallowed if the package is
already released, as it would circumvent the auto-detection safeguard.
*-s, --staging*::
Build against the staging counterpart of the auto-detected repo

View File

@ -27,7 +27,9 @@ Options
Use the given <msg> as the commit message
*-r, --repo* 'REPO'::
Specify a target repository (disables auto-detection)
Specify target repository for new packages not in any official repo.
Using this option is disallowed if the package is already released, as it
would circumvent the auto-detection safeguard.
*-s, --staging*::
Build against the staging counterpart of the auto-detected repo

View File

@ -49,7 +49,7 @@ pkgctl_build_usage() {
BUILD OPTIONS
--arch ARCH Specify architectures to build for (disables auto-detection)
--repo REPO Specify a target repository (disables auto-detection)
--repo REPO Specify target repository for new packages not in any official repo
-s, --staging Build against the staging counterpart of the auto-detected repo
-t, --testing Build against the testing counterpart of the auto-detected repo
-o, --offload Build on a remote server and transfer artifacts afterwards
@ -89,8 +89,7 @@ pkgctl_build_check_option_group_repo() {
local repo=$2
local testing=$3
local staging=$4
if ( (( testing )) && (( staging )) ) ||
( [[ $repo =~ ^.*-(staging|testing)$ ]] && ( (( testing )) || (( staging )) )); then
if [[ -n "${repo}" ]] || (( testing )) || (( staging )); then
die "The argument '%s' cannot be used with one or more of the other specified arguments" "${option}"
exit 1
fi
@ -153,8 +152,8 @@ pkgctl_build() {
;;
--repo)
(( $# <= 1 )) && die "missing argument for %s" "$1"
REPO="${2}"
pkgctl_build_check_option_group_repo '--repo' "${REPO}" "${TESTING}" "${STAGING}"
REPO="${2}"
shift 2
;;
--arch)
@ -203,13 +202,13 @@ pkgctl_build() {
shift
;;
-s|--staging)
STAGING=1
pkgctl_build_check_option_group_repo '--staging' "${REPO}" "${TESTING}" "${STAGING}"
STAGING=1
shift
;;
-t|--testing)
TESTING=1
pkgctl_build_check_option_group_repo '--testing' "${REPO}" "${TESTING}" "${STAGING}"
TESTING=1
shift
;;
-c|--clean)
@ -331,14 +330,22 @@ pkgctl_build() {
pkgbuild_checksum=$(b2sum PKGBUILD | awk '{print $1}')
msg "Building ${pkgbase}"
# auto-detection of build target
if [[ -z ${pkgrepo} ]]; then
if ! pkgrepo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then
die 'failed to get pacman repo'
fi
if [[ -z "${pkgrepo}" ]]; then
die 'unknown repo, specify --repo for packages not currently in any official repo'
fi
# auto-detect target repository
if ! repo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then
die 'Failed to query pacman repo'
fi
# fail if an existing package specifies --repo
if [[ -n "${repo}" ]] && [[ -n ${pkgrepo} ]]; then
die 'Using --repo for packages that exist in official repositories is disallowed'
fi
# assign auto-detected target repository
if [[ -n ${repo} ]]; then
pkgrepo=${repo}
# fallback to extra for unreleased packages
elif [[ -z ${pkgrepo} ]]; then
pkgrepo=extra
fi
# special cases to resolve final build target

View File

@ -35,7 +35,7 @@ pkgctl_release_usage() {
OPTIONS
-m, --message MSG Use the given <msg> as the commit message
-r, --repo REPO Specify a target repository (disables auto-detection)
-r, --repo REPO Specify target repository for new packages not in any official repo
-s, --staging Release to the staging counterpart of the auto-detected repo
-t, --testing Release to the testing counterpart of the auto-detected repo
-u, --db-update Automatically update the pacman database after uploading
@ -43,8 +43,8 @@ pkgctl_release_usage() {
EXAMPLES
$ ${COMMAND}
$ ${COMMAND} --repo core-testing --message 'libyay 0.42 rebuild' libfoo libbar
$ ${COMMAND} --staging --db-update libfoo
$ ${COMMAND} --staging --message 'libyay 0.42 rebuild' libfoo libbar
$ ${COMMAND} --repo extra --db-update new-package
_EOF_
}
@ -134,15 +134,22 @@ pkgctl_release() {
pushd "${path}" >/dev/null
pkgbase=$(basename "${path}")
if [[ -n ${REPO} ]]; then
# auto-detect target repository
if ! repo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then
die 'Failed to query pacman repo'
fi
# fail if an existing package specifies --repo
if [[ -n "${repo}" ]] && [[ -n ${REPO} ]]; then
die 'Using --repo for packages that exist in official repositories is disallowed'
fi
# fail if a new package does not specify --repo
if [[ -z "${repo}" ]]; then
if [[ -z ${REPO} ]]; then
die 'Specify --repo for packages that do not yet exist in official repositories'
fi
repo=${REPO}
else
if ! repo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then
die 'Failed to get pacman repo'
fi
if [[ -z "${repo}" ]]; then
die 'Unknown repo, please specify --repo for new packages'
fi
fi
if (( TESTING )); then

View File

@ -38,6 +38,11 @@ get_pacman_repo_from_pkgbuild() {
return
fi
# update the pacman repo cache if it doesn't exist yet
if [[ ! -d "${_DEVTOOLS_PACMAN_CACHE_DIR}" ]]; then
update_pacman_repo_cache
fi
slock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache"
# query repo of passed pkgname, specify --nodeps twice to skip all dependency checks
mapfile -t repos < <(pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/multilib.conf" \
@ -47,7 +52,7 @@ get_pacman_repo_from_pkgbuild() {
--nodeps \
--print \
--print-format '%n %r' \
"${pkgnames[0]}" | awk '$1=="'"${pkgnames[0]}"'"{print $2}'
"${pkgnames[0]}" 2>/dev/null | awk '$1=="'"${pkgnames[0]}"'"{print $2}'
)
lock_close 10