From b5d5402e439f5edfd642fb4f680d596f5992e874 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Mon, 10 Oct 2022 00:37:51 +0200 Subject: src: modularize repo layout into a library This will greatly help us to structure the functionality and commands in a more sane way. We will distribute the sources as actual libraries and reuse code with imports instead of processing everything with m4 and duplicating a lot of code. --- src/lib/archroot.sh | 62 ++++++++++ src/lib/common.sh | 289 ++++++++++++++++++++++++++++++++++++++++++++++ src/lib/repo.sh | 90 +++++++++++++++ src/lib/repo/clone.sh | 139 ++++++++++++++++++++++ src/lib/repo/configure.sh | 169 +++++++++++++++++++++++++++ src/lib/repo/web.sh | 84 ++++++++++++++ src/lib/valid-repos.sh | 32 +++++ src/lib/valid-tags.sh | 26 +++++ 8 files changed, 891 insertions(+) create mode 100644 src/lib/archroot.sh create mode 100644 src/lib/common.sh create mode 100644 src/lib/repo.sh create mode 100644 src/lib/repo/clone.sh create mode 100644 src/lib/repo/configure.sh create mode 100644 src/lib/repo/web.sh create mode 100644 src/lib/valid-repos.sh create mode 100644 src/lib/valid-tags.sh (limited to 'src/lib') diff --git a/src/lib/archroot.sh b/src/lib/archroot.sh new file mode 100644 index 0000000..d7917da --- /dev/null +++ b/src/lib/archroot.sh @@ -0,0 +1,62 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +: + +# shellcheck disable=2034 +CHROOT_VERSION='v4' + +## +# usage : check_root $keepenv +## +orig_argv=("${BASH_SOURCE[0]}" "$@") +check_root() { + local keepenv=$1 + + (( EUID == 0 )) && return + if type -P sudo >/dev/null; then + exec sudo --preserve-env=$keepenv -- "${orig_argv[@]}" + else + exec su root -c "$(printf ' %q' "${orig_argv[@]}")" + fi +} + +## +# usage : is_btrfs( $path ) +# return : whether $path is on a btrfs +## +is_btrfs() { + [[ -e "$1" && "$(stat -f -c %T "$1")" == btrfs ]] +} + +## +# usage : is_subvolume( $path ) +# return : whether $path is a the root of a btrfs subvolume (including +# the top-level subvolume). +## +is_subvolume() { + [[ -e "$1" && "$(stat -f -c %T "$1")" == btrfs && "$(stat -c %i "$1")" == 256 ]] +} + +## +# usage : subvolume_delete_recursive( $path ) +# +# Find all btrfs subvolumes under and including $path and delete them. +## +subvolume_delete_recursive() { + local subvol + + is_subvolume "$1" || return 0 + + while IFS= read -d $'\0' -r subvol; do + if ! subvolume_delete_recursive "$subvol"; then + return 1 + fi + done < <(find "$1" -mindepth 1 -xdev -depth -inum 256 -print0) + if ! btrfs subvolume delete "$1" &>/dev/null; then + error "Unable to delete subvolume %s" "$subvol" + return 1 + fi + + return 0 +} diff --git a/src/lib/common.sh b/src/lib/common.sh new file mode 100644 index 0000000..f977726 --- /dev/null +++ b/src/lib/common.sh @@ -0,0 +1,289 @@ +#!/hint/bash +# +# This may be included with or without `set -euE` +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_COMMON_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_COMMON_SH="$(set +o|grep nounset)" + +set +u +o posix +# shellcheck disable=1091 +. /usr/share/makepkg/util.sh +$DEVTOOLS_INCLUDE_COMMON_SH + +# Avoid any encoding problems +export LANG=C + +# Set buildtool properties +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}" +export PACKAGING_REPO_RELEASE_HOST=repos.archlinux.org + +# check if messages are to be printed using color +if [[ -t 2 && "$TERM" != dumb ]]; then + colorize +else + # shellcheck disable=2034 + declare -gr ALL_OFF='' BOLD='' BLUE='' GREEN='' RED='' YELLOW='' +fi + +stat_busy() { + local mesg=$1; shift + # shellcheck disable=2059 + printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}...${ALL_OFF}" "$@" >&2 +} + +stat_progress() { + # shellcheck disable=2059 + printf "${BOLD}.${ALL_OFF}" >&2 +} + +stat_done() { + # shellcheck disable=2059 + printf "${BOLD}done${ALL_OFF}\n" >&2 +} + +_setup_workdir=false +setup_workdir() { + [[ -z ${WORKDIR:-} ]] && WORKDIR=$(mktemp -d --tmpdir "${0##*/}.XXXXXXXXXX") + _setup_workdir=true + trap 'trap_abort' INT QUIT TERM HUP + trap 'trap_exit' EXIT +} + +cleanup() { + if [[ -n ${WORKDIR:-} ]] && $_setup_workdir; then + rm -rf "$WORKDIR" + fi + exit "${1:-0}" +} + +abort() { + error 'Aborting...' + cleanup 255 +} + +trap_abort() { + trap - EXIT INT QUIT TERM HUP + abort +} + +trap_exit() { + local r=$? + trap - EXIT INT QUIT TERM HUP + cleanup $r +} + +die() { + (( $# )) && error "$@" + cleanup 255 +} + +## +# usage : lock( $fd, $file, $message, [ $message_arguments... ] ) +## +lock() { + # Only reopen the FD if it wasn't handed to us + if ! [[ "/dev/fd/$1" -ef "$2" ]]; then + mkdir -p -- "$(dirname -- "$2")" + eval "exec $1>"'"$2"' + fi + + if ! flock -n "$1"; then + stat_busy "${@:3}" + flock "$1" + stat_done + fi +} + +## +# usage : slock( $fd, $file, $message, [ $message_arguments... ] ) +## +slock() { + # Only reopen the FD if it wasn't handed to us + if ! [[ "/dev/fd/$1" -ef "$2" ]]; then + mkdir -p -- "$(dirname -- "$2")" + eval "exec $1>"'"$2"' + fi + + if ! flock -sn "$1"; then + stat_busy "${@:3}" + flock -s "$1" + stat_done + fi +} + +## +# usage : lock_close( $fd ) +## +lock_close() { + local fd=$1 + # https://github.com/koalaman/shellcheck/issues/862 + # shellcheck disable=2034 + exec {fd}>&- +} + +## +# usage: pkgver_equal( $pkgver1, $pkgver2 ) +## +pkgver_equal() { + if [[ $1 = *-* && $2 = *-* ]]; then + # if both versions have a pkgrel, then they must be an exact match + [[ $1 = "$2" ]] + else + # otherwise, trim any pkgrel and compare the bare version. + [[ ${1%%-*} = "${2%%-*}" ]] + fi +} + +## +# usage: find_cached_package( $pkgname, $pkgver, $arch ) +# +# $pkgver can be supplied with or without a pkgrel appended. +# If not supplied, any pkgrel will be matched. +## +shopt -s extglob +find_cached_package() { + local searchdirs=("$PWD" "$PKGDEST") results=() + local targetname=$1 targetver=$2 targetarch=$3 + local dir pkg packages pkgbasename name ver rel arch r results + + for dir in "${searchdirs[@]}"; do + [[ -d $dir ]] || continue + + shopt -s extglob nullglob + mapfile -t packages < <(printf "%s\n" "$dir"/"${targetname}"-"${targetver}"-*"${targetarch}".pkg.tar?(.!(sig|*.*))) + shopt -u extglob nullglob + + for pkg in "${packages[@]}"; do + [[ -f $pkg ]] || continue + + # avoid adding duplicates of the same inode + for r in "${results[@]}"; do + [[ $r -ef $pkg ]] && continue 2 + done + + # split apart package filename into parts + pkgbasename=${pkg##*/} + pkgbasename=${pkgbasename%.pkg.tar*} + + arch=${pkgbasename##*-} + pkgbasename=${pkgbasename%-"$arch"} + + rel=${pkgbasename##*-} + pkgbasename=${pkgbasename%-"$rel"} + + ver=${pkgbasename##*-} + name=${pkgbasename%-"$ver"} + + if [[ $targetname = "$name" && $targetarch = "$arch" ]] && + pkgver_equal "$targetver" "$ver-$rel"; then + results+=("$pkg") + fi + done + done + + case ${#results[*]} in + 0) + return 1 + ;; + 1) + printf '%s\n' "${results[0]}" + return 0 + ;; + *) + error 'Multiple packages found:' + printf '\t%s\n' "${results[@]}" >&2 + return 1 + esac +} +shopt -u extglob + +check_package_validity(){ + local pkgfile=$1 + if grep -q "packager = Unknown Packager" <(bsdtar -xOqf "$pkgfile" .PKGINFO); then + die "PACKAGER was not set when building package" + fi + hashsum=sha256sum + pkgbuild_hash=$(awk -v"hashsum=$hashsum" -F' = ' '$1 == "pkgbuild_"hashsum {print $2}' <(bsdtar -xOqf "$pkgfile" .BUILDINFO)) + if [[ "$pkgbuild_hash" != "$($hashsum PKGBUILD|cut -d' ' -f1)" ]]; then + die "PKGBUILD $hashsum mismatch: expected $pkgbuild_hash" + fi +} + + +# usage: grep_pkginfo pkgfile pattern +grep_pkginfo() { + local _ret=() + mapfile -t _ret < <(bsdtar -xOqf "$1" ".PKGINFO" | grep "^${2} = ") + printf '%s\n' "${_ret[@]#${2} = }" +} + + +# Get the package name +getpkgname() { + local _name + + _name="$(grep_pkginfo "$1" "pkgname")" + if [[ -z $_name ]]; then + error "Package '%s' has no pkgname in the PKGINFO. Fail!" "$1" + exit 1 + fi + + echo "$_name" +} + + +# Get the package base or name as fallback +getpkgbase() { + local _base + + _base="$(grep_pkginfo "$1" "pkgbase")" + if [[ -z $_base ]]; then + getpkgname "$1" + else + echo "$_base" + fi +} + + +getpkgdesc() { + local _desc + + _desc="$(grep_pkginfo "$1" "pkgdesc")" + if [[ -z $_desc ]]; then + error "Package '%s' has no pkgdesc in the PKGINFO. Fail!" "$1" + exit 1 + fi + + echo "$_desc" +} + + +get_tag_from_pkgver() { + local pkgver=$1 + local tag=${pkgver} + + tag=${tag/:/-} + tag=${tag//~/.} + echo "${tag}" +} + + +is_debug_package() { + local pkgfile=${1} pkgbase pkgname pkgdesc + pkgbase="$(getpkgbase "${pkgfile}")" + pkgname="$(getpkgname "${pkgfile}")" + pkgdesc="$(getpkgdesc "${pkgfile}")" + [[ ${pkgdesc} == "Detached debugging symbols for "* && ${pkgbase}-debug = "${pkgname}" ]] +} diff --git a/src/lib/repo.sh b/src/lib/repo.sh new file mode 100644 index 0000000..8b8df11 --- /dev/null +++ b/src/lib/repo.sh @@ -0,0 +1,90 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_REPO_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_REPO_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + +set -e + + +pkgctl_repo_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [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 + web Open the packaging repository's website + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} clone libfoo linux libbar + $ ${COMMAND} clone --maintainer mynickname + $ ${COMMAND} configure * + $ ${COMMAND} web linux +_EOF_ +} + +pkgctl_repo() { + if (( $# < 1 )); then + pkgctl_repo_usage + exit 0 + fi + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_repo_usage + exit 0 + ;; + clone) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/repo/clone.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/clone.sh + pkgctl_repo_clone "$@" + exit 0 + ;; + configure) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/repo/configure.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/configure.sh + pkgctl_repo_configure "$@" + exit 0 + ;; + web) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/repo/web.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/web.sh + pkgctl_repo_web "$@" + exit 0 + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + die "invalid command: %s" "$1" + ;; + esac + done +} diff --git a/src/lib/repo/clone.sh b/src/lib/repo/clone.sh new file mode 100644 index 0000000..42dc383 --- /dev/null +++ b/src/lib/repo/clone.sh @@ -0,0 +1,139 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_REPO_CLONE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_REPO_CLONE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/api/gitlab.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh +# shellcheck source=src/lib/repo/configure.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/configure.sh + +source /usr/share/makepkg/util/message.sh + +set -e + + +pkgctl_repo_clone_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PKGBASE]... + + 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 + --universe Clone all existing packages, useful for cache warming + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} libfoo linux libbar + $ ${COMMAND} --maintainer mynickname +_EOF_ +} + +pkgctl_repo_clone() { + if (( $# < 1 )); then + pkgctl_repo_clone_usage + exit 0 + fi + + # options + local GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} + local CLONE_ALL=0 + local MAINTAINER= + local CONFIGURE_OPTIONS=() + local pkgbases + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_repo_clone_usage + exit 0 + ;; + -u|--unprivileged) + GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS} + CONFIGURE_OPTIONS+=("$1") + shift + ;; + -m|--maintainer) + (( $# <= 1 )) && die "missing argument for %s" "$1" + MAINTAINER="$2" + shift 2 + ;; + --maintainer=*) + MAINTAINER="${1#*=}" + shift + ;; + --universe) + CLONE_ALL=1 + shift + ;; + --) + shift + break + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + pkgbases=("$@") + break + ;; + esac + done + + # Query packages of a maintainer + if [[ -n ${MAINTAINER} ]]; then + stat_busy "Query packages" + 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') + if [[ ! ${max_pages} =~ ([[:digit:]]) ]]; then + stat_done + warning "found no packages for maintainer ${MAINTAINER}" + exit 0 + fi + 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 + + # Query all released packages + if (( CLONE_ALL )); then + stat_busy "Query all released packages" + max_pages=$(curl --silent --location --fail --retry 3 --retry-delay 3 "https://archlinux.org/packages/search/json/?sort=name" | jq -r '.num_pages') + if [[ ! ${max_pages} =~ ([[:digit:]]) ]]; then + stat_done + die "failed to query packages" + fi + 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&page=${page}" | jq -r '.results[].pkgbase' + stat_progress + done | sort --unique) + stat_done + fi + + for pkgbase in "${pkgbases[@]}"; do + if [[ ! -d ${pkgbase} ]]; then + msg "Cloning ${pkgbase} ..." + remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git" + git clone --origin origin "${remote_url}" "${pkgbase}" + else + warning "Skip cloning ${pkgbase}: Directory exists" + fi + + pkgctl_repo_configure "${CONFIGURE_OPTIONS[@]}" "${pkgbase}" + done +} diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh new file mode 100644 index 0000000..5c99562 --- /dev/null +++ b/src/lib/repo/configure.sh @@ -0,0 +1,169 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_REPO_CONFIGURE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_REPO_CONFIGURE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/api/gitlab.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh + +source /usr/share/makepkg/util/config.sh +source /usr/share/makepkg/util/message.sh + +set -e + + +pkgctl_repo_configure_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [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 + + EXAMPLES + $ ${COMMAND} configure * +_EOF_ +} + +pkgctl_repo_configure() { + # options + local GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} + local UNPRIVILEGED=0 + local PACKAGER_NAME= + local PACKAGER_EMAIL= + local paths=() + + # variables + local path realpath pkgbase remote_url + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_repo_configure_usage + exit 0 + ;; + -u|--unprivileged) + GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS} + UNPRIVILEGED=1 + shift + ;; + --) + shift + break + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + paths=("$@") + break + ;; + esac + done + + # check if invoked without any path from within a packaging repo + if (( ${#paths[@]} == 0 )); then + if [[ -f PKGBUILD ]]; then + paths=(".") + else + pkgctl_repo_configure_usage + exit 1 + fi + fi + + # Load makepkg.conf variables to be available + # shellcheck disable=2119 + 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 + + msg "Collected packager settings" + msg2 "name : ${PACKAGER_NAME}" + msg2 "email : ${PACKAGER_EMAIL}" + msg2 "gpg-key : ${GPGKEY:-undefined}" + + # TODO: print which protocol got auto detected, ssh https + + for path in "${paths[@]}"; do + if ! realpath=$(realpath -e "${path}"); then + error "No such directory: ${path}" + continue + fi + + pkgbase=$(basename "${realpath}") + pkgbase=${pkgbase%.git} + msg "Configuring ${pkgbase}" + + if [[ ! -d "${path}/.git" ]]; then + error "Not a Git repository: ${path}" + continue + fi + + remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git" + if ! git -C "${path}" remote add origin "${remote_url}" &>/dev/null; then + git -C "${path}" remote set-url origin "${remote_url}" + fi + + # move the master branch to main + if [[ $(git -C "${path}" symbolic-ref --short HEAD) == master ]]; then + git -C "${path}" branch --move main + git -C "${path}" config branch.main.merge refs/heads/main + fi + + git -C "${path}" config devtools.version "${GIT_REPO_SPEC_VERSION}" + git -C "${path}" config pull.rebase true + git -C "${path}" config branch.autoSetupRebase always + git -C "${path}" config branch.main.remote origin + git -C "${path}" config branch.main.rebase true + + git -C "${path}" config transfer.fsckobjects true + git -C "${path}" config fetch.fsckobjects true + git -C "${path}" config receive.fsckobjects true + + if (( ! UNPRIVILEGED )); then + git -C "${path}" config user.name "${PACKAGER_NAME}" + git -C "${path}" config user.email "${PACKAGER_EMAIL}" + git -C "${path}" config commit.gpgsign true + if [[ -n $GPGKEY ]]; then + git -C "${path}" config user.signingKey "${GPGKEY}" + else + warning "Missing makepkg.conf configuration: GPGKEY" + fi + fi + + if ! git ls-remote origin &>/dev/null; then + warning "configured remote origin may not exist, run:" + msg2 "pkgctl repo create ${pkgbase}" + fi + done +} diff --git a/src/lib/repo/web.sh b/src/lib/repo/web.sh new file mode 100644 index 0000000..3fa214d --- /dev/null +++ b/src/lib/repo/web.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_REPO_WEB_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_REPO_WEB_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/api/gitlab.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh + +set -e + + +pkgctl_repo_web_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PKGBASE]... + + Open the packaging repository's website via xdg-open. If called with + no arguments, open the package cloned in the current working directory. + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} web linux +_EOF_ +} + +pkgctl_repo_web() { + local pkgbases=() + local path giturl pkgbase + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_repo_web_usage + exit 0 + ;; + --) + shift + break + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + pkgbases=("$@") + break + ;; + esac + done + + # Check if web mode has xdg-open + if ! command -v xdg-open &>/dev/null; then + die "The web command requires 'xdg-open'" + fi + + # Check if used without pkgnames in a packaging directory + if (( ! $# )); then + path=${PWD} + if [[ ! -d "${path}/.git" ]]; then + die "Not a Git repository: ${path}" + fi + + giturl=$(git -C "${path}" remote get-url origin) + if [[ ${giturl} != *${GIT_PACKAGING_NAMESPACE}* ]]; then + die "Not a packaging repository: ${path}" + fi + + pkgbase=$(basename "${giturl}") + pkgbase=${pkgbase%.git} + pkgbases=("${pkgbase}") + fi + + for pkgbase in "${pkgbases[@]}"; do + path=$(gitlab_project_name_to_path "${pkgbase}") + xdg-open "${GIT_PACKAGING_URL_HTTPS}/${path}" + done +} diff --git a/src/lib/valid-repos.sh b/src/lib/valid-repos.sh new file mode 100644 index 0000000..9ac9639 --- /dev/null +++ b/src/lib/valid-repos.sh @@ -0,0 +1,32 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +: + +# shellcheck disable=2034 +_repos=( + staging + testing + core + extra + community-staging + community-testing + community + multilib-staging + multilib-testing + multilib + gnome-unstable + kde-unstable +) + +# shellcheck disable=2034 +_build_repos=( + staging + testing + extra + multilib-staging + multilib-testing + multilib + gnome-unstable + kde-unstable +) diff --git a/src/lib/valid-tags.sh b/src/lib/valid-tags.sh new file mode 100644 index 0000000..d628fd1 --- /dev/null +++ b/src/lib/valid-tags.sh @@ -0,0 +1,26 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +: + +# shellcheck disable=2034 +_arch=( + x86_64 + any +) + +# shellcheck disable=2034 +_tags=( + core-x86_64 core-any + extra-x86_64 extra-any + multilib-x86_64 + staging-x86_64 staging-any + testing-x86_64 testing-any + multilib-testing-x86_64 + multilib-staging-x86_64 + community-x86_64 community-any + community-staging-x86_64 community-staging-any + community-testing-x86_64 community-testing-any + kde-unstable-x86_64 kde-unstable-any + gnome-unstable-x86_64 gnome-unstable-any +) -- cgit v1.2.3-70-g09d2 From f63d343e40f7f07c7a900cbb7445bbefa0997259 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 22 Oct 2022 15:49:57 +0200 Subject: config: implemented simple config module to store token and settings --- src/lib/config.sh | 27 +++++++++++++++++++++++++++ src/pkgctl.in | 4 ++++ 2 files changed, 31 insertions(+) create mode 100644 src/lib/config.sh (limited to 'src/lib') diff --git a/src/lib/config.sh b/src/lib/config.sh new file mode 100644 index 0000000..5034c6e --- /dev/null +++ b/src/lib/config.sh @@ -0,0 +1,27 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_CONFIG_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_CONFIG_SH=1 + +set -e + +readonly XDG_DEVTOOLS_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/devtools" +readonly XDG_DEVTOOLS_GITLAB_CONFIG="${XDG_DEVTOOLS_DIR}/gitlab.conf" + +# default config variables +export GITLAB_TOKEN="" + +load_devtools_config() { + if [[ ! -f "${XDG_DEVTOOLS_GITLAB_CONFIG}" ]]; then + GITLAB_TOKEN="" + return + fi + GITLAB_TOKEN=$(grep GITLAB_TOKEN "${XDG_DEVTOOLS_GITLAB_CONFIG}"|cut -d= -f2|cut -d\" -f2) +} + +save_devtools_config() { + mkdir -p "${XDG_DEVTOOLS_DIR}" + printf 'GITLAB_TOKEN="%s"\n' "${GITLAB_TOKEN}" > "${XDG_DEVTOOLS_GITLAB_CONFIG}" +} diff --git a/src/pkgctl.in b/src/pkgctl.in index 64d9bcd..35305c1 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -5,6 +5,8 @@ _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} # shellcheck source=src/lib/common.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/config.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/config.sh set -e @@ -32,6 +34,8 @@ fi export _DEVTOOLS_COMMAND='pkgctl' +load_devtools_config + # command checking while (( $# )); do case $1 in -- cgit v1.2.3-70-g09d2 From d2245b1943fd30ab0252e47d47871ac94e143339 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 22 Oct 2022 15:40:40 +0200 Subject: gitlab: implemented module for required API calls We need to use API calls as we can't create repositories in protected namespaces by simply pushing a none existing repository. For privacy reasons this is limited to private personal repositories in GitLab. --- src/lib/api/gitlab.sh | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/common.sh | 24 +++++++++++ 2 files changed, 132 insertions(+) create mode 100644 src/lib/api/gitlab.sh (limited to 'src/lib') diff --git a/src/lib/api/gitlab.sh b/src/lib/api/gitlab.sh new file mode 100644 index 0000000..649e205 --- /dev/null +++ b/src/lib/api/gitlab.sh @@ -0,0 +1,108 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_API_GITLAB_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_API_GITLAB_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/config.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/config.sh + +set -e + + +gitlab_api_call() { + local outfile=$1 + local request=$2 + local endpoint=$3 + local data=${4:-} + local error + + # empty token + if [[ -z "${GITLAB_TOKEN}" ]]; then + msg_error " api call failed: No token provided" + return 1 + fi + + if ! curl --request "${request}" \ + --url "https://${GITLAB_HOST}/api/v4/${endpoint}" \ + --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \ + --header "Content-Type: application/json" \ + --data "${data}" \ + --output "${outfile}" \ + --silent; then + msg_error " api call failed: $(cat "${outfile}")" + return 1 + fi + + # check for general purpose api error + if error=$(jq --raw-output --exit-status '.error' < "${outfile}"); then + msg_error " api call failed: ${error}" + return 1 + fi + + # check for api specific error messages + if ! jq --raw-output --exit-status '.id' < "${outfile}" >/dev/null; then + if jq --raw-output --exit-status '.message | keys[]' < "${outfile}" &>/dev/null; then + while read -r error; do + msg_error " api call failed: ${error}" + done < <(jq --raw-output --exit-status '.message|to_entries|map("\(.key) \(.value[])")[]' < "${outfile}") + elif error=$(jq --raw-output --exit-status '.message' < "${outfile}"); then + msg_error " api call failed: ${error}" + fi + return 1 + fi + + return 0 +} + +gitlab_api_get_user() { + local outfile username + + [[ -z ${WORKDIR:-} ]] && setup_workdir + outfile=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api.XXXXXXXXXX) + + # query user details + if ! gitlab_api_call "${outfile}" GET "user/"; then + msg_warn " Invalid token provided?" + exit 1 + fi + + # extract username from details + if ! username=$(jq --raw-output --exit-status '.username' < "${outfile}"); then + msg_error " failed to query username: $(cat "${outfile}")" + return 1 + fi + + printf "%s" "${username}" + return 0 +} + +gitlab_api_create_project() { + local pkgbase=$1 + local outfile data path + + [[ -z ${WORKDIR:-} ]] && setup_workdir + outfile=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api.XXXXXXXXXX) + + # create GitLab project + data='{ + "name": "'"${pkgbase}"'", + "namespace_id": "'"${GIT_PACKAGING_NAMESPACE_ID}"'", + "request_access_enabled": "false" + }' + if ! gitlab_api_call "${outfile}" POST "projects/" "${data}"; then + return 1 + fi + + if ! path=$(jq --raw-output --exit-status '.path' < "${outfile}"); then + msg_error " failed to query path: $(cat "${outfile}")" + return 1 + fi + + printf "%s" "${path}" + return 0 +} diff --git a/src/lib/common.sh b/src/lib/common.sh index f977726..1fe396c 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -53,6 +53,30 @@ stat_done() { printf "${BOLD}done${ALL_OFF}\n" >&2 } +msg_success() { + local msg=$1 + local padding + padding=$(echo "${msg}"|sed -E 's/( *).*/\1/') + msg=$(echo "${msg}"|sed -E 's/ *(.*)/\1/') + printf "%s %s\n" "${padding}${GREEN}✓${ALL_OFF}" "${msg}" >&2 +} + +msg_error() { + local msg=$1 + local padding + padding=$(echo "${msg}"|sed -E 's/( *).*/\1/') + msg=$(echo "${msg}"|sed -E 's/ *(.*)/\1/') + printf "%s %s\n" "${padding}${RED}x${ALL_OFF}" "${msg}" >&2 +} + +msg_warn() { + local msg=$1 + local padding + padding=$(echo "${msg}"|sed -E 's/( *).*/\1/') + msg=$(echo "${msg}"|sed -E 's/ *(.*)/\1/') + printf "%s %s\n" "${padding}${YELLOW}!${ALL_OFF}" "${msg}" >&2 +} + _setup_workdir=false setup_workdir() { [[ -z ${WORKDIR:-} ]] && WORKDIR=$(mktemp -d --tmpdir "${0##*/}.XXXXXXXXXX") -- cgit v1.2.3-70-g09d2 From 77d800eab2419b334cafd94b2e986351919def77 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 23 Oct 2022 20:42:34 +0200 Subject: auth: implemented module to authenticate against our GitLab This helps to have a convenient way to manage and test our personal GitLab tokens. Those are used for certain API calls like creating new repositories. prefill the access token web view as per https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#prefill-personal-access-token-name-and-scopes Signed-off-by: Levente Polyak --- contrib/completion/zsh/_devtools.in | 17 +++++++ doc/man/pkgctl-auth-login.1.asciidoc | 33 +++++++++++++ doc/man/pkgctl-auth-status.1.asciidoc | 32 ++++++++++++ doc/man/pkgctl-auth.1.asciidoc | 38 ++++++++++++++ doc/man/pkgctl.1.asciidoc | 4 ++ src/lib/auth.sh | 72 +++++++++++++++++++++++++++ src/lib/auth/login.sh | 93 +++++++++++++++++++++++++++++++++++ src/lib/auth/status.sh | 69 ++++++++++++++++++++++++++ src/pkgctl.in | 9 ++++ 9 files changed, 367 insertions(+) create mode 100644 doc/man/pkgctl-auth-login.1.asciidoc create mode 100644 doc/man/pkgctl-auth-status.1.asciidoc create mode 100644 doc/man/pkgctl-auth.1.asciidoc create mode 100644 src/lib/auth.sh create mode 100644 src/lib/auth/login.sh create mode 100644 src/lib/auth/status.sh (limited to 'src/lib') diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index b210378..6ff6cad 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -18,6 +18,22 @@ _archbuild_args=( '--[Introduce makechrootpkg options]:*::makechrootpkg options:= _dispatch makechrootpkg makechrootpkg' ) +_pkgctl_auth_cmds=( + "pkgctl auth command" + "login[Authenticate with the GitLab instance]" + "status[View authentication status]" +) + +_pkgctl_auth_login_args=( + '(-g --gen-access-token)'{-g,--gen-access-token}'[Open the URL to generate a new personal access token]' + '(-h --help)'{-h,--help}'[Display usage]' +) + +_pkgctl_auth_status_args=( + '(-t --show-token)'{-t,--show-token}'[Display the auth token]' + '(-h --help)'{-h,--help}'[Display usage]' +) + _pkgctl_repo_cmds=( "pkgctl repo command" "clone[Clone a package repository]" @@ -154,6 +170,7 @@ _devtools_completions_all_packages() { _pkgctl_cmds=( "pkgctl command" + "auth[Authenticate with services like GitLab]" "diff[Compare package files using different modes]" "repo[Manage Git packaging repositories and their configuration]" ) diff --git a/doc/man/pkgctl-auth-login.1.asciidoc b/doc/man/pkgctl-auth-login.1.asciidoc new file mode 100644 index 0000000..9c32ab2 --- /dev/null +++ b/doc/man/pkgctl-auth-login.1.asciidoc @@ -0,0 +1,33 @@ +pkgctl-auth-login(1) +==================== + +Name +---- +pkgctl-auth-login - Authenticate with the GitLab instance + +Synopsis +-------- +pkgctl auth login [OPTIONS] + +Description +----------- + +Interactively authenticate with the GitLab instance. + +The minimum required scopes for the token are: 'api', 'write_repository'. + +Options +------- + +*-g, --gen-access-token*:: + Open the URL to generate a new personal access token + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-auth-status[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-auth-status.1.asciidoc b/doc/man/pkgctl-auth-status.1.asciidoc new file mode 100644 index 0000000..e23ee2e --- /dev/null +++ b/doc/man/pkgctl-auth-status.1.asciidoc @@ -0,0 +1,32 @@ +pkgctl-auth-status(1) +===================== + +Name +---- +pkgctl-auth-status - View authentication status + +Synopsis +-------- +pkgctl auth status [OPTIONS] + +Description +----------- + +Verifies and displays information about your authentication state of +services like the GitLab instance and reports issues if any. + +Options +------- + +*-t, --show-token*:: + Display the auth token + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-auth-login[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-auth.1.asciidoc b/doc/man/pkgctl-auth.1.asciidoc new file mode 100644 index 0000000..4912b02 --- /dev/null +++ b/doc/man/pkgctl-auth.1.asciidoc @@ -0,0 +1,38 @@ +pkgctl-auth(1) +============== + +Name +---- +pkgctl-auth - Authenticate with serivces like GitLab. + +Synopsis +-------- +pkgctl auth [OPTIONS] [SUBCOMMAND] + +Description +----------- + +Manage the authorization for the GitLab instance and show its current status. + +Options +------- + +*-h, --help*:: + Show a help text + +Subcommands +----------- + +pkgctl auth login:: + Authenticate with the GitLab instance + +pkgctl auth status:: + View authentication status + +See Also +-------- + +linkman:pkgctl-auth-login[1] +linkman:pkgctl-auth-status[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 0455074..45d5187 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -17,6 +17,9 @@ TODO Subcommands ----------- +pkgctl auth:: + Authenticate with services like GitLab + pkgctl diff:: Compare package files using different modes @@ -26,6 +29,7 @@ pkgctl repo:: See Also -------- +linkman:pkgctl-auth[1] linkman:pkgctl-diff[1] linkman:pkgctl-repo[1] diff --git a/src/lib/auth.sh b/src/lib/auth.sh new file mode 100644 index 0000000..77d6a90 --- /dev/null +++ b/src/lib/auth.sh @@ -0,0 +1,72 @@ +#!/hint/bash +# +# This may be included with or without `set -euE` +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_AUTH_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_AUTH_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + +set -e + + +pkgctl_auth_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [COMMAND] [OPTIONS] + + Authenticate with services like GitLab. + + COMMANDS + login Authenticate with the GitLab instance + status View authentication status + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} login --gen-access-token + $ ${COMMAND} status +_EOF_ +} + +pkgctl_auth() { + if (( $# < 1 )); then + pkgctl_auth_usage + exit 0 + fi + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_auth_usage + exit 0 + ;; + login) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/auth/login.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/auth/login.sh + pkgctl_auth_login "$@" + exit 0 + ;; + status) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/auth/status.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/auth/status.sh + pkgctl_auth_status "$@" + exit 0 + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + die "invalid command: %s" "$1" + ;; + esac + done +} diff --git a/src/lib/auth/login.sh b/src/lib/auth/login.sh new file mode 100644 index 0000000..083e80a --- /dev/null +++ b/src/lib/auth/login.sh @@ -0,0 +1,93 @@ +#!/hint/bash +# +# This may be included with or without `set -euE` +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_AUTH_LOGIN_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_AUTH_LOGIN_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/config.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/config.sh +# shellcheck source=src/lib/api/gitlab.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh + +set -e + + +pkgctl_auth_login_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] + + Interactively authenticate with the GitLab instance. + + The minimum required scopes for the token are: 'api', 'write_repository'. + + OPTIONS + -g, --gen-access-token Open the URL to generate a new personal access token + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} + $ ${COMMAND} --gen-access-token +_EOF_ +} + + +pkgctl_auth_login() { + local token personal_access_token_url + local GEN_ACESS_TOKEN=0 + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_auth_login_usage + exit 0 + ;; + -g|--gen-access-token) + GEN_ACESS_TOKEN=1 + shift + ;; + *) + die "invalid argument: %s" "$1" + ;; + esac + done + + personal_access_token_url="https://${GITLAB_HOST}/-/profile/personal_access_tokens?name=pkgctl+token&scopes=api,write_repository" + + cat <<- _EOF_ + Logging into ${BOLD}${GITLAB_HOST}${ALL_OFF} + + Tip: you can generate a Personal Access Token here ${personal_access_token_url} + The minimum required scopes are 'api' and 'write_repository'. +_EOF_ + + if (( GEN_ACESS_TOKEN )); then + xdg-open "${personal_access_token_url}" 2>/dev/null + fi + + # read token from stdin + read -s -r -p "${GREEN}?${ALL_OFF} ${BOLD}Paste your authentication token:${ALL_OFF} " token + echo + + if [[ -z ${token} ]]; then + msg_error " No token provided" + exit 1 + fi + + # check if the passed token works + GITLAB_TOKEN="${token}" + if ! result=$(gitlab_api_get_user); then + printf "%s\n" "$result" + exit 1 + fi + + msg_success " Logged in as ${BOLD}${result}${ALL_OFF}" + save_devtools_config +} diff --git a/src/lib/auth/status.sh b/src/lib/auth/status.sh new file mode 100644 index 0000000..6cbaab1 --- /dev/null +++ b/src/lib/auth/status.sh @@ -0,0 +1,69 @@ +#!/hint/bash +# +# This may be included with or without `set -euE` +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_AUTH_STATUS_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_AUTH_STATUS_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/api/gitlab.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh + +set -e + + +pkgctl_auth_status_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] + + Verifies and displays information about your authentication state of + services like the GitLab instance and reports issues if any. + + OPTIONS + -t, --show-token Display the auth token + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} + $ ${COMMAND} --show-token +_EOF_ +} + +pkgctl_auth_status() { + local SHOW_TOKEN=0 + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_auth_status_usage + exit 0 + ;; + -t|--show-token) + SHOW_TOKEN=1 + shift + ;; + *) + die "invalid argument: %s" "$1" + ;; + esac + done + + printf "%s\n" "${BOLD}${GITLAB_HOST}${ALL_OFF}" + # shellcheck disable=2119 + if ! username=$(gitlab_api_get_user); then + printf "%s\n" "${username}" + exit 1 + fi + + msg_success " Logged in as ${BOLD}${username}${ALL_OFF}" + if (( SHOW_TOKEN )); then + msg_success " Token: ${GITLAB_TOKEN}" + else + msg_success " Token: **************************" + fi +} diff --git a/src/pkgctl.in b/src/pkgctl.in index 35305c1..e024d1f 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -19,6 +19,7 @@ usage() { Unified command-line frontend for devtools. COMMANDS + auth Authenticate with services like GitLab diff Compare package files using different modes repo Manage Git packaging repositories and their configuration @@ -51,6 +52,14 @@ while (( $# )); do pkgctl_repo "$@" exit 0 ;; + auth) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/auth.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/auth.sh + pkgctl_auth "$@" + exit 0 + ;; diff) _DEVTOOLS_COMMAND+=" $1" shift -- cgit v1.2.3-70-g09d2 From 2a59c32bf4ff117bd02d58a4e3f322b709259f1e Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 30 Oct 2022 14:44:06 +0100 Subject: repo: added command to create a new packaging repository --- contrib/completion/zsh/_devtools.in | 7 +++ doc/man/pkgctl-repo-create.1.asciidoc | 40 ++++++++++++ doc/man/pkgctl-repo.1.asciidoc | 4 ++ src/lib/repo.sh | 10 +++ src/lib/repo/create.sh | 113 ++++++++++++++++++++++++++++++++++ 5 files changed, 174 insertions(+) create mode 100644 doc/man/pkgctl-repo-create.1.asciidoc create mode 100644 src/lib/repo/create.sh (limited to 'src/lib') diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 6ff6cad..3395338 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -38,6 +38,7 @@ _pkgctl_repo_cmds=( "pkgctl repo command" "clone[Clone a package repository]" "configure[Configure a clone according to distro specs]" + "create[Create a new GitLab package repository]" "web[Open the packaging repository's website]" ) @@ -55,6 +56,12 @@ _pkgctl_repo_configure_args=( '*:git_dir:_files -/' ) +_pkgctl_repo_create_args=( + '(-c --clone)'{-c,--clone}'[Clone the Git repository after creation]' + '(-h --help)'{-h,--help}'[Display usage]' + '1:pkgbase' +) + _pkgctl_repo_web_args=( '(-h --help)'{-h,--help}'[Display usage]' '*:git_dir:_files -/' diff --git a/doc/man/pkgctl-repo-create.1.asciidoc b/doc/man/pkgctl-repo-create.1.asciidoc new file mode 100644 index 0000000..b9d980b --- /dev/null +++ b/doc/man/pkgctl-repo-create.1.asciidoc @@ -0,0 +1,40 @@ +pkgctl-repo-create(1) +====================== + +Name +---- +pkgctl-repo-create - Create a new GitLab package repository + +Synopsis +-------- +pkgctl repo create [OPTIONS] [PKGBASE...] + +Description +----------- + +Create a new Git packaging repository in the canonical GitLab namespace. + +This command requires a valid GitLab API authentication. To setup a new +GitLab token or check the currently configured one please consult the +'auth' subcommand for further instructions. + +If invoked without a parameter, try to create a packaging repository +based on the 'PKGBUILD' from the current working directory. + +Options +------- + +*-c, --clone*:: + Clone the Git repository after creation + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-auth[1] +linkman:pkgctl-repo-clone[1] +linkman:pkgctl-repo-configure[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-repo.1.asciidoc b/doc/man/pkgctl-repo.1.asciidoc index 564679a..630afd8 100644 --- a/doc/man/pkgctl-repo.1.asciidoc +++ b/doc/man/pkgctl-repo.1.asciidoc @@ -38,6 +38,9 @@ pkgctl repo clone:: pkgctl repo configure:: Configure a clone according to distro specs +pkgctl repo create:: + Create a new GitLab package repository + pkgctl repo web:: Open the packaging repository's website @@ -46,6 +49,7 @@ See Also linkman:pkgctl-repo-clone[1] linkman:pkgctl-repo-configure[1] +linkman:pkgctl-repo-create[1] linkman:pkgctl-repo-web[1] include::include/footer.asciidoc[] diff --git a/src/lib/repo.sh b/src/lib/repo.sh index 8b8df11..6b3817a 100644 --- a/src/lib/repo.sh +++ b/src/lib/repo.sh @@ -29,6 +29,7 @@ pkgctl_repo_usage() { COMMANDS clone Clone a package repository configure Configure a clone according to distro specs + create Create a new GitLab package repository web Open the packaging repository's website OPTIONS @@ -38,6 +39,7 @@ pkgctl_repo_usage() { $ ${COMMAND} clone libfoo linux libbar $ ${COMMAND} clone --maintainer mynickname $ ${COMMAND} configure * + $ ${COMMAND} create libfoo $ ${COMMAND} web linux _EOF_ } @@ -71,6 +73,14 @@ pkgctl_repo() { pkgctl_repo_configure "$@" exit 0 ;; + create) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/repo/create.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/create.sh + pkgctl_repo_create "$@" + exit 0 + ;; web) _DEVTOOLS_COMMAND+=" $1" shift diff --git a/src/lib/repo/create.sh b/src/lib/repo/create.sh new file mode 100644 index 0000000..31b46e1 --- /dev/null +++ b/src/lib/repo/create.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_REPO_CREATE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_REPO_CREATE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/api/gitlab.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh +# shellcheck source=src/lib/repo/clone.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/clone.sh +# shellcheck source=src/lib/repo/configure.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/configure.sh + +set -e + + +pkgctl_repo_create_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PKGBASE]... + + Create a new Git packaging repository in the canonical GitLab namespace. + + This command requires a valid GitLab API authentication. To setup a new + GitLab token or check the currently configured one please consult the + 'auth' subcommand for further instructions. + + If invoked without a parameter, try to create a packaging repository + based on the PKGBUILD from the current working directory and configure + the local repository afterwards. + + OPTIONS + -c, --clone Clone the Git repository after creation + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} libfoo +_EOF_ +} + +pkgctl_repo_create() { + # options + local pkgbases=() + local pkgbase + local clone=0 + local configure=0 + + # variables + local path + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_repo_create_usage + exit 0 + ;; + -c|--clone) + clone=1 + shift + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + pkgbases=("$@") + break + ;; + esac + done + + # check if invoked without any path from within a packaging repo + if (( ${#pkgbases[@]} == 0 )); then + if [[ -f PKGBUILD ]]; then + if ! path=$(realpath -e .); then + die "failed to read path from current directory" + fi + pkgbases=("$(basename "${path}")") + clone=0 + configure=1 + else + pkgctl_repo_create_usage + exit 1 + fi + fi + + # create projects + for pkgbase in "${pkgbases[@]}"; do + if ! gitlab_api_create_project "${pkgbase}" >/dev/null; then + die "failed to create project: ${pkgbase}" + fi + msg_success "Successfully created ${pkgbase}" + if (( clone )); then + pkgctl_repo_clone "${pkgbase}" + elif (( configure )); then + pkgctl_repo_configure + fi + done + + # some convenience hints if not in auto clone/configure mode + if (( ! clone )) && (( ! configure )); then + cat <<- _EOF_ + + For new clones: + $(msg2 "pkgctl repo clone ${pkgbases[*]}") + For existing clones: + $(msg2 "pkgctl repo configure ${pkgbases[*]}") + _EOF_ + fi +} -- cgit v1.2.3-70-g09d2 From f834fc4700053cb9a83956c98835b0a158cc054c Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 11 Dec 2022 16:16:16 +0100 Subject: db: command for Pacman database modification like update, move etc --- contrib/completion/zsh/_devtools.in | 26 ++++++++++++ doc/man/pkgctl-db-move.1.asciidoc | 24 +++++++++++ doc/man/pkgctl-db-remove.1.asciidoc | 26 ++++++++++++ doc/man/pkgctl-db-update.1.asciidoc | 23 +++++++++++ doc/man/pkgctl.1.asciidoc | 4 ++ src/lib/db.sh | 80 +++++++++++++++++++++++++++++++++++++ src/lib/db/move.sh | 64 +++++++++++++++++++++++++++++ src/lib/db/remove.sh | 69 ++++++++++++++++++++++++++++++++ src/lib/db/update.sh | 46 +++++++++++++++++++++ src/pkgctl.in | 9 +++++ 10 files changed, 371 insertions(+) create mode 100644 doc/man/pkgctl-db-move.1.asciidoc create mode 100644 doc/man/pkgctl-db-remove.1.asciidoc create mode 100644 doc/man/pkgctl-db-update.1.asciidoc create mode 100644 src/lib/db.sh create mode 100644 src/lib/db/move.sh create mode 100644 src/lib/db/remove.sh create mode 100644 src/lib/db/update.sh (limited to 'src/lib') diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 3395338..62d9fea 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -34,6 +34,31 @@ _pkgctl_auth_status_args=( '(-h --help)'{-h,--help}'[Display usage]' ) +_pkgctl_db_cmds=( + "pkgctl db command" + "move[Move packages between pacman repositories]" + "remove[Remove packages from pacman repositories]" + "update[Update the pacman database as final release step]" +) + +_pkgctl_db_move_args=( + '(-h --help)'{-h,--help}'[Display usage]' + "1:src-repo:($_repos[*])" + "2:target-repo:($_repos[*])" + '*:pkgbase:_devtools_completions_all_packages' +) + +_pkgctl_db_remove_args=( + '(-a --arch=)'{-a,--arch=}"[Override the architecture (disables auto-detection)]:arch:($_arch[*])" + '(-h --help)'{-h,--help}'[Display usage]' + "1:repo:($_repos[*])" + '*:pkgbase:_devtools_completions_all_packages' +) + +_pkgctl_db_update_args=( + '(-h --help)'{-h,--help}'[Display usage]' +) + _pkgctl_repo_cmds=( "pkgctl repo command" "clone[Clone a package repository]" @@ -178,6 +203,7 @@ _devtools_completions_all_packages() { _pkgctl_cmds=( "pkgctl command" "auth[Authenticate with services like GitLab]" + "db[Pacman database modification for packge update, move etc]" "diff[Compare package files using different modes]" "repo[Manage Git packaging repositories and their configuration]" ) diff --git a/doc/man/pkgctl-db-move.1.asciidoc b/doc/man/pkgctl-db-move.1.asciidoc new file mode 100644 index 0000000..1ee02f8 --- /dev/null +++ b/doc/man/pkgctl-db-move.1.asciidoc @@ -0,0 +1,24 @@ +pkgctl-db-move(1) +================= + +Name +---- +pkgctl-db-update - Update the binary repository as final release step + +Synopsis +-------- +pkgctl db update [OPTIONS] + +Description +----------- + +Update the pacman database as final release step for packages that +have been transfered and staged on 'repos.archlinux.org'. + +Options +------- + +*-h, --help*:: + Show a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-db-remove.1.asciidoc b/doc/man/pkgctl-db-remove.1.asciidoc new file mode 100644 index 0000000..a95766d --- /dev/null +++ b/doc/man/pkgctl-db-remove.1.asciidoc @@ -0,0 +1,26 @@ +pkgctl-db-remove(1) +=================== + +Name +---- +pkgctl-db-remove - Remove packages from binary repositories + +Synopsis +-------- +pkgctl db remove [OPTIONS] [REPO] [PKGBASE]... + +Description +----------- + +Remove packages from pacman repositories. + +Options +------- + +*-a, --arch* 'ARCH':: + Override the architecture (disables auto-detection) + +*-h, --help*:: + Show a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-db-update.1.asciidoc b/doc/man/pkgctl-db-update.1.asciidoc new file mode 100644 index 0000000..fa7205e --- /dev/null +++ b/doc/man/pkgctl-db-update.1.asciidoc @@ -0,0 +1,23 @@ +pkgctl-db-move(1) +================= + +Name +---- +pkgctl-db-move - Move packages between binary repositories + +Synopsis +-------- +pkgctl db move [OPTIONS] [SOURCE_REPO] [TARGET_REPO] [PKGBASE]... + +Description +----------- + +Move packages between pacman repositories. + +Options +------- + +*-h, --help*:: + Show a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 45d5187..93fed5b 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -20,6 +20,9 @@ Subcommands pkgctl auth:: Authenticate with services like GitLab +pkgctl db:: + Pacman database modification for packge update, move etc + pkgctl diff:: Compare package files using different modes @@ -30,6 +33,7 @@ See Also -------- linkman:pkgctl-auth[1] +linkman:pkgctl-db[1] linkman:pkgctl-diff[1] linkman:pkgctl-repo[1] diff --git a/src/lib/db.sh b/src/lib/db.sh new file mode 100644 index 0000000..397ff0d --- /dev/null +++ b/src/lib/db.sh @@ -0,0 +1,80 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_DB_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_DB_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + +set -e + + +pkgctl_db_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [COMMAND] [OPTIONS] + + Pacman database modification for packge update, move etc + + COMMANDS + move Move packages between pacman repositories + remove Remove packages from pacman repositories + update Update the pacman database as final release step + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} move extra-staging extra-testing libfoo libbar + $ ${COMMAND} remove core-testing libfoo libbar + $ ${COMMAND} update +_EOF_ +} + +pkgctl_db() { + if (( $# < 1 )); then + pkgctl_db_usage + exit 0 + fi + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_db_usage + exit 0 + ;; + move) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/db/move.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/move.sh + pkgctl_db_move "$@" + exit 0 + ;; + remove) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/db/remove.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/remove.sh + pkgctl_db_remove "$@" + exit 0 + ;; + update) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/db/update.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/update.sh + pkgctl_db_update "$@" + exit 0 + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + die "invalid command: %s" "$1" + ;; + esac + done +} diff --git a/src/lib/db/move.sh b/src/lib/db/move.sh new file mode 100644 index 0000000..825b350 --- /dev/null +++ b/src/lib/db/move.sh @@ -0,0 +1,64 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_DB_MOVE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_DB_MOVE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +set -e + + +pkgctl_db_move_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [SOURCE_REPO] [TARGET_REPO] [PKGBASE]... + + Move packages between binary repositories. + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} extra-staging extra-testing libfoo libbar + $ ${COMMAND} extra core libfoo libbar +_EOF_ +} + +pkgctl_db_move() { + local SOURCE_REPO="" + local TARGET_REPO="" + local PKGBASES=() + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_db_move_usage + exit 0 + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + break + ;; + esac + done + + if (( $# < 3 )); then + pkgctl_db_move_usage + exit 1 + fi + + SOURCE_REPO=$1 + TARGET_REPO=$2 + shift 2 + PKGBASES+=("$@") + + # shellcheck disable=SC2029 + ssh "${PACKAGING_REPO_RELEASE_HOST}" db-move "${SOURCE_REPO}" "${TARGET_REPO}" "${PKGBASES[@]}" +} diff --git a/src/lib/db/remove.sh b/src/lib/db/remove.sh new file mode 100644 index 0000000..ba21c83 --- /dev/null +++ b/src/lib/db/remove.sh @@ -0,0 +1,69 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_DB_REMOVE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_DB_REMOVE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +set -e + + +pkgctl_db_remove_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [REPO] [PKGBASE]... + + Remove packages from binary repositories. + + OPTIONS + -a, --arch Override the architecture (disables auto-detection) + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} core-testing libfoo libbar + $ ${COMMAND} --arch x86_64 core libyay +_EOF_ +} + +pkgctl_db_remove() { + local REPO="" + local ARCH=any + local PKGBASES=() + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_db_remove_usage + exit 0 + ;; + -a|--arch) + (( $# <= 1 )) && die "missing argument for %s" "$1" + ARCH=$2 + shift 2 + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + break + ;; + esac + done + + if (( $# < 2 )); then + pkgctl_db_remove_usage + exit 1 + fi + + REPO=$1 + shift + PKGBASES+=("$@") + + # shellcheck disable=SC2029 + ssh "${PACKAGING_REPO_RELEASE_HOST}" db-remove "${REPO}" "${ARCH}" "${PKGBASES[@]}" +} diff --git a/src/lib/db/update.sh b/src/lib/db/update.sh new file mode 100644 index 0000000..269720d --- /dev/null +++ b/src/lib/db/update.sh @@ -0,0 +1,46 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_DB_UPDATE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_DB_UPDATE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +set -e + + +pkgctl_db_update_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] + + Update the binary repository as final release step for packages that + have been transfered and staged on ${PACKAGING_REPO_RELEASE_HOST}. + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} +_EOF_ +} + +pkgctl_db_update() { + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_db_update_usage + exit 0 + ;; + *) + die "invalid argument: %s" "$1" + ;; + esac + done + + ssh "${PACKAGING_REPO_RELEASE_HOST}" db-update +} diff --git a/src/pkgctl.in b/src/pkgctl.in index e024d1f..d9e1b4c 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -20,6 +20,7 @@ usage() { COMMANDS auth Authenticate with services like GitLab + db Pacman database modification for packge update, move etc diff Compare package files using different modes repo Manage Git packaging repositories and their configuration @@ -60,6 +61,14 @@ while (( $# )); do pkgctl_auth "$@" exit 0 ;; + db) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/auth.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db.sh + pkgctl_db "$@" + exit 0 + ;; diff) _DEVTOOLS_COMMAND+=" $1" shift -- cgit v1.2.3-70-g09d2 From b9db6160a2547a57d19308776a25223eb2130b6b Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Tue, 13 Dec 2022 20:41:37 +0100 Subject: git: convert repos and tags config to new repo layout --- Makefile | 9 ++++----- src/lib/valid-repos.sh | 21 +++++---------------- src/lib/valid-tags.sh | 9 ++++----- 3 files changed, 13 insertions(+), 26 deletions(-) (limited to 'src/lib') diff --git a/Makefile b/Makefile index f59ca26..89251f4 100644 --- a/Makefile +++ b/Makefile @@ -20,12 +20,11 @@ SETARCH_ALIASES = $(wildcard config/setarch-aliases.d/*) MANS = $(addprefix $(BUILDDIR)/,$(patsubst %.asciidoc,%,$(wildcard doc/man/*.asciidoc))) COMMITPKG_LINKS = \ + core-testingpkg \ + core-stagingpkg \ extrapkg \ - testingpkg \ - stagingpkg \ - communitypkg \ - community-testingpkg \ - community-stagingpkg \ + extra-testingpkg \ + extra-stagingpkg \ multilibpkg \ multilib-testingpkg \ multilib-stagingpkg \ diff --git a/src/lib/valid-repos.sh b/src/lib/valid-repos.sh index 9ac9639..1f823f4 100644 --- a/src/lib/valid-repos.sh +++ b/src/lib/valid-repos.sh @@ -5,28 +5,17 @@ # shellcheck disable=2034 _repos=( - staging - testing - core - extra - community-staging - community-testing - community - multilib-staging - multilib-testing - multilib + core core-staging core-testing + extra extra-staging extra-testing + multilib multilib-staging multilib-testing gnome-unstable kde-unstable ) # shellcheck disable=2034 _build_repos=( - staging - testing - extra - multilib-staging - multilib-testing - multilib + extra staging testing + multilib multilib-staging multilib-testing gnome-unstable kde-unstable ) diff --git a/src/lib/valid-tags.sh b/src/lib/valid-tags.sh index d628fd1..ca8d7d7 100644 --- a/src/lib/valid-tags.sh +++ b/src/lib/valid-tags.sh @@ -12,15 +12,14 @@ _arch=( # shellcheck disable=2034 _tags=( core-x86_64 core-any + core-staging-x86_64 core-staging-any + core-testing-x86_64 core-testing-any extra-x86_64 extra-any + extra-staging-x86_64 extra-staging-any + extra-testing-x86_64 extra-testing-any multilib-x86_64 - staging-x86_64 staging-any - testing-x86_64 testing-any multilib-testing-x86_64 multilib-staging-x86_64 - community-x86_64 community-any - community-staging-x86_64 community-staging-any - community-testing-x86_64 community-testing-any kde-unstable-x86_64 kde-unstable-any gnome-unstable-x86_64 gnome-unstable-any ) -- cgit v1.2.3-70-g09d2 From 5752488ef114513c8f75d753cf91d5b61dfa0660 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 17 Dec 2022 01:51:15 +0100 Subject: release: command to commit, tag and upload build artifacts This is a smart and more convenient invocation of the classical commitpkg and archrelease with auto-discovery for target repositories and a shorthand option to directly call db-update. --- contrib/completion/zsh/_devtools.in | 11 +++ doc/man/pkgctl-release.1.asciidoc | 49 +++++++++++ doc/man/pkgctl.1.asciidoc | 4 + src/lib/release.sh | 167 ++++++++++++++++++++++++++++++++++++ src/lib/util/pacman.sh | 52 +++++++++++ src/pkgctl.in | 9 ++ 6 files changed, 292 insertions(+) create mode 100644 doc/man/pkgctl-release.1.asciidoc create mode 100644 src/lib/release.sh create mode 100644 src/lib/util/pacman.sh (limited to 'src/lib') diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 62d9fea..2961f6f 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -59,6 +59,16 @@ _pkgctl_db_update_args=( '(-h --help)'{-h,--help}'[Display usage]' ) +_pkgctl_release_args=( + '(-m --message=)'{-m,--message=}"[Use the given as the commit message]:message:" + '(-r --repo=)'{-r,--repo=}"[Specify a target repository (disables auto-detection)]:repo:($_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]' + '(-h --help)'{-h,--help}'[Display usage]' + '*:git_dir:_files -/' +) + _pkgctl_repo_cmds=( "pkgctl repo command" "clone[Clone a package repository]" @@ -205,6 +215,7 @@ _pkgctl_cmds=( "auth[Authenticate with services like GitLab]" "db[Pacman database modification for packge update, move etc]" "diff[Compare package files using different modes]" + "release[Release step to commit, tag and upload build artifacts]" "repo[Manage Git packaging repositories and their configuration]" ) diff --git a/doc/man/pkgctl-release.1.asciidoc b/doc/man/pkgctl-release.1.asciidoc new file mode 100644 index 0000000..c991db4 --- /dev/null +++ b/doc/man/pkgctl-release.1.asciidoc @@ -0,0 +1,49 @@ +pkgctl-release(1) +================= + +Name +---- +pkgctl-release - Release step to commit, tag and upload build artifacts + +Synopsis +-------- +pkgctl release [OPTIONS] [PATH...] + +Description +----------- + +Modified version controlled files will first be staged for commit, +afterwards a Git tag matching the pkgver will be created and finally +all build artifacts will be uploaded. + +By default the target pacman repository will be auto-detected by querying +the repo it is currently released in. When initially adding a new package +to the repositories, the target repo must be specified manually. + +Options +------- + +*-m, --message* 'MSG':: + Use the given as the commit message + +*-r, --repo* 'REPO':: + Specify a target repository (disables auto-detection) + +*-s, --staging*:: + Build against the staging counterpart of the auto-detected repo + +*-t, --testing*:: + Build against the testing counterpart of the auto-detected repo + +*-u, --db-update*:: + Automatically update the pacman database after uploading + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-db-update[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 93fed5b..8da5d19 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -26,6 +26,9 @@ pkgctl db:: pkgctl diff:: Compare package files using different modes +pkgctl release:: + Release step to commit, tag and upload build artifacts + pkgctl repo:: Manage Git packaging repositories and their configuration @@ -35,6 +38,7 @@ See Also linkman:pkgctl-auth[1] linkman:pkgctl-db[1] linkman:pkgctl-diff[1] +linkman:pkgctl-release[1] linkman:pkgctl-repo[1] include::include/footer.asciidoc[] diff --git a/src/lib/release.sh b/src/lib/release.sh new file mode 100644 index 0000000..aabbd35 --- /dev/null +++ b/src/lib/release.sh @@ -0,0 +1,167 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_RELEASE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_RELEASE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/db/update.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/update.sh +# shellcheck source=src/lib/util/pacman.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh +# shellcheck source=src/lib/valid-repos.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh + +source /usr/share/makepkg/util/util.sh + +set -e + + +pkgctl_release_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PATH]... + + Release step to commit, tag and upload build artifacts + + Modified version controlled files will first be staged for commit, + afterwards a Git tag matching the pkgver will be created and finally + all build artifacts will be uploaded. + + By default the target pacman repository will be auto-detected by querying + the repo it is currently released in. When initially adding a new package + to the repositories, the target repo must be specified manually. + + OPTIONS + -m, --message MSG Use the given as the commit message + -r, --repo REPO Specify a target repository (disables auto-detection) + -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 + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} + $ ${COMMAND} --repo core-testing --message 'libyay 0.42 rebuild' libfoo libbar + $ ${COMMAND} --staging --db-update libfoo +_EOF_ +} + +pkgctl_release_check_option_group() { + local option=$1 + local repo=$2 + local testing=$3 + local staging=$4 + 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 + return 0 +} + +pkgctl_release() { + if (( $# < 1 )) && [[ ! -f PKGBUILD ]]; then + pkgctl_release_usage + exit 1 + fi + + local MESSAGE="" + local PKGBASES=() + local REPO="" + local TESTING=0 + local STAGING=0 + local DB_UPDATE=0 + + local path pkgbase pkgnames repo repos + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_release_usage + exit 0 + ;; + -m|--message) + (( $# <= 1 )) && die "missing argument for %s" "$1" + MESSAGE=$2 + shift 2 + ;; + -r|--repo) + (( $# <= 1 )) && die "missing argument for %s" "$1" + pkgctl_release_check_option_group '--repo' "${REPO}" "${TESTING}" "${STAGING}" + REPO=$2 + shift 2 + ;; + -s|--staging) + pkgctl_release_check_option_group '--staging' "${REPO}" "${TESTING}" "${STAGING}" + STAGING=1 + shift + ;; + -t|--testing) + pkgctl_release_check_option_group '--testing' "${REPO}" "${TESTING}" "${STAGING}" + TESTING=1 + shift + ;; + -u|--db-update) + DB_UPDATE=1 + shift + ;; + -*) + die "invalid option: %s" "$1" + ;; + *) + PKGBASES+=("$@") + break + ;; + esac + done + + # Resolve package from current working directory + if (( 0 == ${#PKGBASES[@]} )); then + PKGBASES=("$PWD") + fi + + # Update pacman cache for auto-detection + if [[ -z ${REPO} ]]; then + update_pacman_repo_cache + # Check valid repos if not resolved dynamically + elif ! in_array "${REPO}" "${_repos[@]}"; then + die "Invalid repository target: %s" "${REPO}" + fi + + for path in "${PKGBASES[@]}"; do + pushd "${path}" >/dev/null + pkgbase=$(basename "${path}") + + if [[ -n ${REPO} ]]; then + 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 + repo="${repo}-testing" + elif (( STAGING )); then + repo="${repo}-staging" + elif [[ $repo == core ]]; then + repo="${repo}-testing" + fi + + msg "Releasing ${pkgbase} to ${repo}" + commitpkg "${repo}" "${MESSAGE}" + + unset repo + popd >/dev/null + done + + if (( DB_UPDATE )); then + # shellcheck disable=2119 + pkgctl_db_update + fi +} diff --git a/src/lib/util/pacman.sh b/src/lib/util/pacman.sh new file mode 100644 index 0000000..f6c2d5f --- /dev/null +++ b/src/lib/util/pacman.sh @@ -0,0 +1,52 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_UTIL_PACMAN_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_UTIL_PACMAN_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +set -e + + +readonly _DEVTOOLS_PACMAN_CACHE_DIR=${XDG_CACHE_DIR:-$HOME/.cache}/devtools/pacman/db +readonly _DEVTOOLS_PACMAN_CONF_DIR=${_DEVTOOLS_LIBRARY_DIR}/pacman.conf.d +readonly _DEVTOOLS_MAKEPKG_CONF_DIR=${_DEVTOOLS_LIBRARY_DIR}/makepkg.conf.d + + +update_pacman_repo_cache() { + mkdir -p "${_DEVTOOLS_PACMAN_CACHE_DIR}" + msg "Updating pacman database cache" + lock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache" + fakeroot -- pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/multilib.conf" \ + --dbpath "${_DEVTOOLS_PACMAN_CACHE_DIR}" \ + -Sy + lock_close 10 +} + +get_pacman_repo_from_pkgbuild() { + local path=${1:-PKGBUILD} + + # shellcheck source=contrib/makepkg/PKGBUILD.proto + mapfile -t pkgnames < <(source "${path}"; printf "%s\n" "${pkgname[@]}") + + if (( ${#pkgnames[@]} == 0 )); then + die 'Failed to get pkgname from %s' "${path}" + return + fi + + slock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache" + mapfile -t repos < <(pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/multilib.conf" \ + --dbpath "${_DEVTOOLS_PACMAN_CACHE_DIR}" \ + -S \ + --print \ + --print-format '%n %r' \ + "${pkgnames[0]}" | grep -E "^${pkgnames[0]} " | awk '{print $2}' + ) + lock_close 10 + + printf "%s" "${repos[0]}" +} diff --git a/src/pkgctl.in b/src/pkgctl.in index d9e1b4c..47409de 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -22,6 +22,7 @@ usage() { auth Authenticate with services like GitLab db Pacman database modification for packge update, move etc diff Compare package files using different modes + release Release step to commit, tag and upload build artifacts repo Manage Git packaging repositories and their configuration OPTIONS @@ -75,6 +76,14 @@ while (( $# )); do diffpkg "$@" exit 0 ;; + release) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/release.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh + pkgctl_release "$@" + exit 0 + ;; *) die "invalid command: %s" "$1" ;; -- cgit v1.2.3-70-g09d2 From f1673c60adff196d9b1c7c97797c5775b3bdb56a Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Mon, 9 Jan 2023 21:40:45 +0100 Subject: build: replace m4 defines with sed scripts during build There is no reason anymore to use m4 since we got rid of the includes by using library files. Let's replace the last usage of m4 and completely red rid of it. Signed-off-by: Levente Polyak --- Makefile | 6 ++++-- src/lib/common.sh | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/lib') diff --git a/Makefile b/Makefile index 96a76f5..faac812 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,9 @@ ifneq ($(wildcard setarch-aliases.d/*),) endif -edit = sed -e "s|@pkgdatadir[@]|$(DATADIR)|g" +edit = sed \ + -e "s|@pkgdatadir[@]|$(DATADIR)|g" \ + -e "s|@buildtoolver[@]|$(BUILDTOOLVER)|g" GEN_MSG = @echo "GEN $(patsubst $(BUILDDIR)/%,%,$@)" define buildInScript @@ -76,7 +78,7 @@ $(1)/%: $(2)%$(3) $$(GEN_MSG) @mkdir -p $$(dir $$@) @$(RM) "$$@" - @{ echo -n 'm4_changequote([[[,]]])'; cat $$<; } | m4 -P --define=m4_devtools_version=$$(BUILDTOOLVER) | $(edit) >$$@ + @cat $$< | $(edit) >$$@ @chmod $(4) "$$@" @bash -O extglob -n "$$@" endef diff --git a/src/lib/common.sh b/src/lib/common.sh index 1fe396c..51ab2fd 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -17,7 +17,7 @@ export LANG=C # Set buildtool properties export BUILDTOOL=devtools -export BUILDTOOLVER=m4_devtools_version +export BUILDTOOLVER=@buildtoolver@ # Set common properties export PACMAN_KEYRING_DIR=/etc/pacman.d/gnupg -- cgit v1.2.3-70-g09d2 From 1d7f9972151b0a52297880c8f9e5f28a1d7fe597 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 14 Jan 2023 18:20:29 +0100 Subject: build: command to build packages inside a clean chroot --- .gitignore | 2 +- contrib/completion/zsh/_devtools.in | 20 ++ doc/man/pkgctl-build.1.asciidoc | 80 ++++++++ doc/man/pkgctl.1.asciidoc | 4 + src/lib/build/build.sh | 387 ++++++++++++++++++++++++++++++++++++ src/lib/util/git.sh | 24 +++ src/pkgctl.in | 9 + 7 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 doc/man/pkgctl-build.1.asciidoc create mode 100644 src/lib/build/build.sh create mode 100644 src/lib/util/git.sh (limited to 'src/lib') diff --git a/.gitignore b/.gitignore index f5d2d27..3e34a0c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ *~ devtools-*.tar.gz* -build/ +/build/ diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 2961f6f..c743667 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -34,6 +34,25 @@ _pkgctl_auth_status_args=( '(-h --help)'{-h,--help}'[Display usage]' ) +_pkgctl_build_args=( + "--arch=[Specify architectures to build for (disables auto-detection)]:arch:($_arch[*])" + "--repo=[Specify a target repository (disables auto-detection)]:repo:($_repos[*])" + '(-s --staging)'{-s,--staging}'[Build against the staging counterpart of the auto-detected repo]' + '(-t --testing)'{-t,--testing}'[Build against the testing counterpart of the auto-detected repo]' + '(-o --offload)'{-o,--offload}'[Build on a remote server and transfer artifacts afterwards]' + '(-c --clean)'{-c,--clean}'[Recreate the chroot before building]' + '(-I --install)'{-I,--install}'[Install a package into the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' + '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' + '--pkgrel=[Set pkgrel to a given value]:pkgrel:' + '--rebuild[Increment the pkgrel variable]' + '(-e --edit)'{-e,--edit}'[Edit the PKGBUILD before building]' + '(-r --release)'{-r,--release}'[Automatically commit, tag and release after building]' + '(-m --message=)'{-m,--message=}"[Use the given as the commit message]:message:" + '(-u --db-update)'{-u,--db-update}'[Automatically update the pacman database as last action]' + '(-h --help)'{-h,--help}'[Display usage]' + '*:git_dir:_files -/' +) + _pkgctl_db_cmds=( "pkgctl db command" "move[Move packages between pacman repositories]" @@ -213,6 +232,7 @@ _devtools_completions_all_packages() { _pkgctl_cmds=( "pkgctl command" "auth[Authenticate with services like GitLab]" + "build[Build packages inside a clean chroot]" "db[Pacman database modification for packge update, move etc]" "diff[Compare package files using different modes]" "release[Release step to commit, tag and upload build artifacts]" diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc new file mode 100644 index 0000000..132c0a4 --- /dev/null +++ b/doc/man/pkgctl-build.1.asciidoc @@ -0,0 +1,80 @@ +pkgctl-build(1) +=============== + +Name +---- +pkgctl-build - Build packages inside a clean chroot + +Synopsis +-------- +pkgctl build [OPTIONS] [PATH...] + +Description +----------- + +TODO + +Build Options +------------- + +*--arch* 'ARCH':: + Specify architectures to build for (disables auto-detection) + +*--repo* 'REPO':: + Specify a target repository (disables auto-detection) + +*-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 + +*-c, --clean*:: + Recreate the chroot before building + +*-I, --install* 'FILE':: + Install a package into the working copy of the chroot + +PKGBUILD Options +---------------- + +*--pkgver*='PKGVER':: + Set pkgver, reset pkgrel and update checksums + +*--pkgrel*='PKGREL':: + Set pkgrel to a given value + +*--rebuild*:: + Increment the current pkgrel variable + +*-e, --edit*:: + Edit the PKGBUILD before building + +Release Options +--------------- + +*-r, --release*:: + Automatically commit, tag and release after building + +*-m, --message* 'MSG':: + Use the given as the commit message + +*-u, --db-update*:: + Automatically update the pacman database as last action + +Options +------- + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-release[1] +linkman:pkgctl-db-update[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 8da5d19..c5a6174 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -20,6 +20,9 @@ Subcommands pkgctl auth:: Authenticate with services like GitLab +pkgctl build:: + Build packages inside a clean chroot + pkgctl db:: Pacman database modification for packge update, move etc @@ -36,6 +39,7 @@ See Also -------- linkman:pkgctl-auth[1] +linkman:pkgctl-build[1] linkman:pkgctl-db[1] linkman:pkgctl-diff[1] linkman:pkgctl-release[1] diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh new file mode 100644 index 0000000..e32c79f --- /dev/null +++ b/src/lib/build/build.sh @@ -0,0 +1,387 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_BUILD_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_BUILD_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/db/update.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/update.sh +# shellcheck source=src/lib/release.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh +# shellcheck source=src/lib/util/git.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/git.sh +# shellcheck source=src/lib/util/pacman.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh +# shellcheck source=src/lib/valid-repos.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh +# shellcheck source=src/lib/valid-tags.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh + +source /usr/share/makepkg/util/config.sh +source /usr/share/makepkg/util/message.sh + +set -e + + +pkgctl_build_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PATH]... + + Build packages inside a clean chroot + + When a new pkgver is set using the appropriate PKGBUILD options the + checksums are automatically updated. + + TODO + + BUILD OPTIONS + --arch ARCH Specify architectures to build for (disables auto-detection) + --repo REPO Specify a target repository (disables auto-detection) + -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 + -c, --clean Recreate the chroot before building + -I, --install FILE Install a package into the working copy of the chroot + + PKGBUILD OPTIONS + --pkgver=PKGVER Set pkgver, reset pkgrel and update checksums + --pkgrel=PKGREL Set pkgrel to a given value + --rebuild Increment the current pkgrel variable + -e, --edit Edit the PKGBUILD before building + + RELEASE OPTIONS + -r, --release Automatically commit, tag and release after building + -m, --message MSG Use the given as the commit message + -u, --db-update Automatically update the pacman database as last action + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} + $ ${COMMAND} --rebuild --staging --message 'libyay 0.42 rebuild' libfoo libbar + $ ${COMMAND} --pkgver 1.42 --release --db-update +_EOF_ +} + +pkgctl_build_check_option_group_repo() { + local option=$1 + local repo=$2 + local testing=$3 + local staging=$4 + if ( (( testing )) && (( staging )) ) || + ( [[ $repo =~ ^.*-(staging|testing)$ ]] && ( (( testing )) || (( staging )) )); then + die "The argument '%s' cannot be used with one or more of the other specified arguments" "${option}" + exit 1 + fi + return 0 +} + +pkgctl_build_check_option_group_ver() { + local option=$1 + local pkgver=$2 + local pkgrel=$3 + local rebuild=$4 + if [[ -n "${pkgver}" ]] || [[ -n "${pkgrel}" ]] || (( rebuild )); then + die "The argument '%s' cannot be used with one or more of the other specified arguments" "${option}" + exit 1 + fi + return 0 +} + +# TODO: import pgp keys +pkgctl_build() { + if (( $# < 1 )) && [[ ! -f PKGBUILD ]]; then + pkgctl_build_usage + exit 1 + fi + + local UPDPKGSUMS=0 + local EDIT=0 + local REBUILD=0 + local OFFLOAD=0 + local STAGING=0 + local TESTING=0 + local RELEASE=0 + local DB_UPDATE=0 + + local REPO= + local PKGVER= + local PKGREL= + local MESSAGE= + + local paths=() + local BUILD_ARCH=() + local BUILD_OPTIONS=() + local MAKECHROOT_OPTIONS=() + local RELEASE_OPTIONS=() + + local PTS + PTS="$(tty | sed 's|/dev/pts/||')" + local WORKER="${USER}-${PTS}" + + # variables + local path pkgbase pkgrepo source + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_build_usage + exit 0 + ;; + --repo) + (( $# <= 1 )) && die "missing argument for %s" "$1" + REPO="${2}" + pkgctl_build_check_option_group_repo '--repo' "${REPO}" "${TESTING}" "${STAGING}" + shift 2 + ;; + --arch) + (( $# <= 1 )) && die "missing argument for %s" "$1" + if [[ ${2} == all ]]; then + BUILD_ARCH=("${_arch[@]::${#_arch[@]}-1}") + elif [[ ${2} == any ]]; then + BUILD_ARCH=("${_arch[0]}") + elif ! in_array "${2}" "${BUILD_ARCH[@]}"; then + if ! in_array "${2}" "${_arch[@]}"; then + die 'invalid architecture: %s' "${2}" + fi + BUILD_ARCH+=("${2}") + fi + shift 2 + ;; + --pkgver=*) + pkgctl_build_check_option_group_ver '--pkgver' "${PKGVER}" "${PKGREL}" "${REBUILD}" + PKGVER="${1#*=}" + PKGREL=1 + UPDPKGSUMS=1 + shift + ;; + --pkgrel=*) + pkgctl_build_check_option_group_ver '--pkgrel' "${PKGVER}" "${PKGREL}" "${REBUILD}" + PKGREL="${1#*=}" + shift + ;; + --rebuild) + # shellcheck source=src/lib/util/git.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/git.sh + pkgctl_build_check_option_group_ver '--rebuild' "${PKGVER}" "${PKGREL}" "${REBUILD}" + REBUILD=1 + shift + ;; + -e|--edit) + EDIT=1 + shift + ;; + -o|--offload) + OFFLOAD=1 + shift + ;; + -s|--staging) + STAGING=1 + pkgctl_build_check_option_group_repo '--staging' "${REPO}" "${TESTING}" "${STAGING}" + shift + ;; + -t|--testing) + TESTING=1 + pkgctl_build_check_option_group_repo '--testing' "${REPO}" "${TESTING}" "${STAGING}" + shift + ;; + -c|--clean) + BUILD_OPTIONS+=("-c") + shift + ;; + -I|--install) + (( $# <= 1 )) && die "missing argument for %s" "$1" + MAKECHROOT_OPTIONS+=("-I" "$2") + warning 'installing packages into the chroot may break reproducible builds, use with caution!' + shift 2 + ;; + -r|--release) + # shellcheck source=src/lib/release.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh + RELEASE=1 + shift + ;; + -m|--message) + (( $# <= 1 )) && die "missing argument for %s" "$1" + MESSAGE=$2 + RELEASE_OPTIONS+=("--message" "${MESSAGE}") + shift 2 + ;; + -u|--db-update) + DB_UPDATE=1 + shift + ;; + --) + shift + break + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + paths=("$@") + break + ;; + esac + done + + # check if invoked without any path from within a packaging repo + if (( ${#paths[@]} == 0 )); then + if [[ -f PKGBUILD ]]; then + paths=(".") + else + pkgctl_build_usage + exit 1 + fi + fi + + # Update pacman cache for auto-detection + if [[ -z ${REPO} ]]; then + update_pacman_repo_cache + # Check valid repos if not resolved dynamically + elif ! in_array "${REPO}" "${_repos[@]}"; then + die "Invalid repository target: %s" "${REPO}" + fi + + for path in "${paths[@]}"; do + pushd "${path}" >/dev/null + + if [[ ! -f PKGBUILD ]]; then + die 'PKGBUILD not found in %s' "${path}" + fi + + source=() + # shellcheck source=contrib/makepkg/PKGBUILD.proto + . ./PKGBUILD + pkgbase=${pkgbase:-$pkgname} + pkgrepo=${REPO} + 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, please specify --repo for new packages' + fi + fi + + # special cases to resolve final build target + if (( TESTING )); then + pkgrepo="${pkgrepo}-testing" + elif (( STAGING )); then + pkgrepo="${pkgrepo}-staging" + elif [[ $pkgrepo == core ]]; then + pkgrepo="${pkgrepo}-testing" + fi + + # auto-detection of build architecture + if [[ $pkgrepo = multilib* ]]; then + BUILD_ARCH=("") + elif (( ${#BUILD_ARCH[@]} == 0 )); then + if in_array any "${arch[@]}"; then + BUILD_ARCH=("${_arch[0]}") + else + BUILD_ARCH+=("${arch[@]}") + fi + fi + + # print gathered build modes + msg2 "repo: ${pkgrepo}" + msg2 "arch: ${BUILD_ARCH[*]}" + + # increment pkgrel on rebuild + if (( REBUILD )); then + # try to figure out of pkgrel has been changed + if ! old_pkgrel=$(git_diff_tree HEAD PKGBUILD | grep --perl-regexp --only-matching --max-count=1 '^-pkgrel=\K\w+'); then + old_pkgrel=${pkgrel} + fi + # check if pkgrel conforms expectations + [[ ${pkgrel/.*} =~ ^[0-9]+$ ]] || die "Non-standard pkgrel declaration" + [[ ${old_pkgrel/.*} =~ ^[0-9]+$ ]] || die "Non-standard pkgrel declaration" + # increment pkgrel if it hasn't been changed yet + if [[ ${pkgrel} = "${old_pkgrel}" ]]; then + PKGREL=$((${pkgrel/.*}+1)) + else + warning 'ignoring --rebuild as pkgrel has already been incremented from %s to %s' "${old_pkgrel}" "${pkgrel}" + fi + fi + + # update pkgver + if [[ -n ${PKGVER} ]]; then + if [[ $(type -t pkgver) == function ]]; then + # TODO: check if die or warn, if we provide _commit _gitcommit setter maybe? + warning 'setting pkgver variable has no effect if the PKGBUILD has a pkgver() function' + fi + msg "Bumping pkgver to ${PKGVER}" + grep --extended-regexp --quiet --max-count=1 "^pkgver=${pkgver}$" PKGBUILD || die "Non-standard pkgver declaration" + sed --regexp-extended "s|^(pkgver=)${pkgver}$|\1${PKGVER}|g" -i PKGBUILD + fi + + # update pkgrel + if [[ -n ${PKGREL} ]]; then + msg "Bumping pkgrel to ${PKGREL}" + grep --extended-regexp --quiet --max-count=1 "^pkgrel=${pkgrel}$" PKGBUILD || die "Non-standard pkgrel declaration" + sed --regexp-extended "s|^(pkgrel=)${pkgrel}$|\1${PKGREL}|g" -i PKGBUILD + fi + + # edit PKGBUILD + if (( EDIT )); then + stat_busy 'Editing PKGBUILD' + if [[ -n $VISUAL ]]; then + $VISUAL PKGBUILD || die + elif [[ -n $EDITOR ]]; then + $EDITOR PKGBUILD || die + elif command -v vi &>/dev/null; then + vi PKGBUILD || die + else + die "need \$VISUAL or \$EDITOR to edit the PKGBUILD" + fi + stat_done + fi + + # update checksums if any sources are declared + if (( UPDPKGSUMS )) && (( ${#source[@]} >= 1 )); then + updpkgsums + fi + + # execute build + for arch in "${BUILD_ARCH[@]}"; do + if [[ -n $arch ]]; then + msg "Building ${pkgbase} for [${pkgrepo}] (${arch})" + BUILDTOOL="${pkgrepo}-${arch}-build" + else + msg "Building ${pkgbase} for [${pkgrepo}]" + BUILDTOOL="${pkgrepo}-build" + fi + + if (( OFFLOAD )); then + offload-build --repo "${pkgrepo}" -- "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" + else + "${BUILDTOOL}" "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" + fi + done + + # release the build + if (( RELEASE )); then + pkgctl_release --repo "${pkgrepo}" "${RELEASE_OPTIONS[@]}" + fi + + # reset common PKGBUILD variables + unset pkgbase pkgname arch pkgrepo source pkgver pkgrel validpgpkeys + popd >/dev/null + done + + # update the binary package repo db as last action + if (( RELEASE )) && (( DB_UPDATE )); then + # shellcheck disable=2119 + pkgctl_db_update + fi +} diff --git a/src/lib/util/git.sh b/src/lib/util/git.sh new file mode 100644 index 0000000..c4af662 --- /dev/null +++ b/src/lib/util/git.sh @@ -0,0 +1,24 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_UTIL_GIT_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_UTIL_GIT_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + + +git_diff_tree() { + local commit=$1 + local path=$2 + git \ + --no-pager \ + diff \ + --color=never \ + --color-moved=no \ + --unified=0 \ + --no-prefix \ + --no-ext-diff \ + "${commit}" \ + -- "${path}" +} diff --git a/src/pkgctl.in b/src/pkgctl.in index 47409de..40f9259 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -20,6 +20,7 @@ usage() { COMMANDS auth Authenticate with services like GitLab + build Build packages inside a clean chroot db Pacman database modification for packge update, move etc diff Compare package files using different modes release Release step to commit, tag and upload build artifacts @@ -46,6 +47,14 @@ while (( $# )); do usage exit 0 ;; + build) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/build/build.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/build/build.sh + pkgctl_build "$@" + exit 0 + ;; repo) _DEVTOOLS_COMMAND+=" $1" shift -- cgit v1.2.3-70-g09d2 From f669a71e847da88fefc1296dd2dd9ba82549a8c6 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 20 Jan 2023 18:03:31 +0100 Subject: repo-configure: automatically determine protocol from packager identity The remote protocol is automatically determined from the author email address by choosing SSH for all official packager identities and read-only HTTPS otherwise. Signed-off-by: Levente Polyak --- contrib/completion/zsh/_devtools.in | 2 - doc/man/pkgctl-repo-clone.1.asciidoc | 3 - doc/man/pkgctl-repo-configure.1.asciidoc | 9 +- src/lib/repo/clone.sh | 2 - src/lib/repo/configure.sh | 167 ++++++++++++++++++++----------- 5 files changed, 114 insertions(+), 69 deletions(-) (limited to 'src/lib') diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index c743667..5908bd6 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -98,14 +98,12 @@ _pkgctl_repo_cmds=( _pkgctl_repo_clone_args=( '(-m --maintainer=)'{-m,--maintainer=}'[Clone all packages of the named maintainer]:maintainer:' - '(-u --unprivileged)'{-u,--unprivileged}'[Read-only access without packager info as Git author]' '--universe[Clone all existing packages, useful for cache warming]' '(-h --help)'{-h,--help}'[Display usage]' '*:packages:_devtools_completions_all_packages' ) _pkgctl_repo_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 -/' ) diff --git a/doc/man/pkgctl-repo-clone.1.asciidoc b/doc/man/pkgctl-repo-clone.1.asciidoc index 9770ef8..a39fb37 100644 --- a/doc/man/pkgctl-repo-clone.1.asciidoc +++ b/doc/man/pkgctl-repo-clone.1.asciidoc @@ -25,9 +25,6 @@ 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 - *--universe*:: Clone all existing packages, useful for cache warming diff --git a/doc/man/pkgctl-repo-configure.1.asciidoc b/doc/man/pkgctl-repo-configure.1.asciidoc index c3a14de..4499ed6 100644 --- a/doc/man/pkgctl-repo-configure.1.asciidoc +++ b/doc/man/pkgctl-repo-configure.1.asciidoc @@ -17,15 +17,14 @@ Configure Git packaging repositories according to distro specs and 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. + +The remote protocol is automatically determined from the author email +address by choosing SSH for all official packager identities and +read-only HTTPS otherwise. Options ------- -*-u, --unprivileged*:: - Configure read-only repo without packager info as Git author - *-h, --help*:: Show a help text diff --git a/src/lib/repo/clone.sh b/src/lib/repo/clone.sh index 42dc383..4b26fcf 100644 --- a/src/lib/repo/clone.sh +++ b/src/lib/repo/clone.sh @@ -32,8 +32,6 @@ pkgctl_repo_clone_usage() { 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 --universe Clone all existing packages, useful for cache warming -h, --help Show this help text diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh index 5c99562..d6262b7 100644 --- a/src/lib/repo/configure.sh +++ b/src/lib/repo/configure.sh @@ -27,11 +27,12 @@ pkgctl_repo_configure_usage() { 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. + + The remote protocol is automatically determined from the author email + address by choosing SSH for all official packager identities and + read-only HTTPS otherwise. OPTIONS - -u, --unprivileged Configure read-only repo without packager info as Git author -h, --help Show this help text EXAMPLES @@ -39,16 +40,64 @@ pkgctl_repo_configure_usage() { _EOF_ } +get_packager_name() { + local packager=$1 + local packager_pattern="(.+) <(.+@.+)>" + local name + + if [[ ! $packager =~ $packager_pattern ]]; then + return 1 + fi + + name=$(echo "${packager}"|sed -E "s/${packager_pattern}/\1/") + printf "%s" "${name}" +} + +get_packager_email() { + local packager=$1 + local packager_pattern="(.+) <(.+@.+)>" + local email + + if [[ ! $packager =~ $packager_pattern ]]; then + return 1 + fi + + email=$(echo "${packager}"|sed -E "s/${packager_pattern}/\2/") + printf "%s" "${email}" +} + +is_packager_name_valid() { + local packager_name=$1 + if [[ -z ${packager_name} ]]; then + return 1 + elif [[ ${packager_name} == "John Doe" ]]; then + return 1 + elif [[ ${packager_name} == "Unknown Packager" ]]; then + return 1 + fi + return 0 +} + +is_packager_email_official() { + local packager_email=$1 + if [[ -z ${packager_email} ]]; then + return 1 + elif [[ $packager_email =~ .+@archlinux.org ]]; then + return 0 + fi + return 1 +} + pkgctl_repo_configure() { # options - local GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} - local UNPRIVILEGED=0 - local PACKAGER_NAME= - local PACKAGER_EMAIL= + local GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS} + local official=0 + local proto=https local paths=() # variables local path realpath pkgbase remote_url + local PACKAGER GPGKEY packager_name packager_email while (( $# )); do case $1 in @@ -56,11 +105,6 @@ pkgctl_repo_configure() { pkgctl_repo_configure_usage exit 0 ;; - -u|--unprivileged) - GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS} - UNPRIVILEGED=1 - shift - ;; --) shift break @@ -85,34 +129,33 @@ pkgctl_repo_configure() { fi fi - # Load makepkg.conf variables to be available + # Load makepkg.conf variables to be available for packager identity + msg "Collecting packager identity from makepkg.conf" # shellcheck disable=2119 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" + if [[ -n ${PACKAGER} ]]; then + if ! packager_name=$(get_packager_name "${PACKAGER}") || \ + ! packager_email=$(get_packager_email "${PACKAGER}"); then + die "invalid PACKAGER format '${PACKAGER}' in makepkg.conf" fi - packager_pattern="(.+) <(.+@.+)>" - if [[ ! $PACKAGER =~ $packager_pattern ]]; then - die "Invalid Packager format '${PACKAGER}' in makepkg.conf" + if ! is_packager_name_valid "${packager_name}"; then + die "invalid PACKAGER '${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" + if is_packager_email_official "${packager_email}"; then + official=1 + proto=ssh + GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} fi fi - msg "Collected packager settings" - msg2 "name : ${PACKAGER_NAME}" - msg2 "email : ${PACKAGER_EMAIL}" - msg2 "gpg-key : ${GPGKEY:-undefined}" - - # TODO: print which protocol got auto detected, ssh https + msg2 "name : ${packager_name:-${YELLOW}undefined${ALL_OFF}}" + msg2 "email : ${packager_email:-${YELLOW}undefined${ALL_OFF}}" + msg2 "gpg-key : ${GPGKEY:-${YELLOW}undefined${ALL_OFF}}" + if [[ ${proto} == ssh ]]; then + msg2 "protocol: ${GREEN}${proto}${ALL_OFF}" + else + msg2 "protocol: ${YELLOW}${proto}${ALL_OFF}" + fi for path in "${paths[@]}"; do if ! realpath=$(realpath -e "${path}"); then @@ -129,41 +172,51 @@ pkgctl_repo_configure() { continue fi + pushd "${path}" >/dev/null + remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git" - if ! git -C "${path}" remote add origin "${remote_url}" &>/dev/null; then - git -C "${path}" remote set-url origin "${remote_url}" + if ! git remote add origin "${remote_url}" &>/dev/null; then + git remote set-url origin "${remote_url}" fi # move the master branch to main - if [[ $(git -C "${path}" symbolic-ref --short HEAD) == master ]]; then - git -C "${path}" branch --move main - git -C "${path}" config branch.main.merge refs/heads/main + if [[ $(git symbolic-ref --quiet --short HEAD) == master ]]; then + git branch --move main + git config branch.main.merge refs/heads/main + fi + + git config devtools.version "${GIT_REPO_SPEC_VERSION}" + git config pull.rebase true + git config branch.autoSetupRebase always + git config branch.main.remote origin + git config branch.main.rebase true + + git config transfer.fsckobjects true + git config fetch.fsckobjects true + git config receive.fsckobjects true + + # setup author identity + if [[ -n ${packager_name} ]]; then + git config user.name "${packager_name}" + git config user.email "${packager_email}" + fi + + # force gpg for official packagers + if (( official )); then + git config commit.gpgsign true fi - git -C "${path}" config devtools.version "${GIT_REPO_SPEC_VERSION}" - git -C "${path}" config pull.rebase true - git -C "${path}" config branch.autoSetupRebase always - git -C "${path}" config branch.main.remote origin - git -C "${path}" config branch.main.rebase true - - git -C "${path}" config transfer.fsckobjects true - git -C "${path}" config fetch.fsckobjects true - git -C "${path}" config receive.fsckobjects true - - if (( ! UNPRIVILEGED )); then - git -C "${path}" config user.name "${PACKAGER_NAME}" - git -C "${path}" config user.email "${PACKAGER_EMAIL}" - git -C "${path}" config commit.gpgsign true - if [[ -n $GPGKEY ]]; then - git -C "${path}" config user.signingKey "${GPGKEY}" - else - warning "Missing makepkg.conf configuration: GPGKEY" - fi + # set custom pgp key from makepkg.conf + if [[ -n $GPGKEY ]]; then + git config commit.gpgsign true + git config user.signingKey "${GPGKEY}" fi if ! git ls-remote origin &>/dev/null; then warning "configured remote origin may not exist, run:" msg2 "pkgctl repo create ${pkgbase}" fi + + popd >/dev/null done } -- cgit v1.2.3-70-g09d2 From eda3a4aea00803d14400beff819d3b8be81774ce Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Mon, 30 Jan 2023 21:15:50 +0100 Subject: gitlab: add project path function to map special chars Automatic path conversion is limited to GitLab API v4 and will be removed in the future. It's expected that the caller does the path conversion on caller side and only passes a valid path to the API within its limitations. Hence convert project names to valid paths: 1. replace single '+' between word boundaries with '-' 2. replace any other '+' with literal 'plus' 3. replace any special chars other than '_', '-' and '.' with '-' 4. replace consecutive '_-' chars with a single '-' 5. replace 'tree' with 'unix-tree' due to GitLab reserved keyword Signed-off-by: Levente Polyak --- src/lib/api/gitlab.sh | 26 +++++++++++++++++++++++++- src/lib/repo/clone.sh | 6 +++++- src/lib/repo/configure.sh | 5 +++-- 3 files changed, 33 insertions(+), 4 deletions(-) (limited to 'src/lib') diff --git a/src/lib/api/gitlab.sh b/src/lib/api/gitlab.sh index 649e205..e5f4237 100644 --- a/src/lib/api/gitlab.sh +++ b/src/lib/api/gitlab.sh @@ -81,16 +81,40 @@ gitlab_api_get_user() { return 0 } +# Convert arbitrary project names to GitLab valid path names. +# +# GitLab has several limitations on project and group names and also maintains +# a list of reserved keywords as documented on their docs. +# https://docs.gitlab.com/ee/user/reserved_names.html +# +# 1. replace single '+' between word boundaries with '-' +# 2. replace any other '+' with literal 'plus' +# 3. replace any special chars other than '_', '-' and '.' with '-' +# 4. replace consecutive '_-' chars with a single '-' +# 5. replace 'tree' with 'unix-tree' due to GitLab reserved keyword +gitlab_project_name_to_path() { + local name=$1 + printf "%s" "${name}" \ + | sed -E 's/([a-zA-Z0-9]+)\+([a-zA-Z]+)/\1-\2/g' \ + | sed -E 's/\+/plus/g' \ + | sed -E 's/[^a-zA-Z0-9_\-\.]/-/g' \ + | sed -E 's/[_\-]{2,}/-/g' \ + | sed -E 's/^tree$/unix-tree/g' +} + gitlab_api_create_project() { local pkgbase=$1 - local outfile data path + local outfile data path project_path [[ -z ${WORKDIR:-} ]] && setup_workdir outfile=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api.XXXXXXXXXX) + project_path=$(gitlab_project_name_to_path "${pkgbase}") + # create GitLab project data='{ "name": "'"${pkgbase}"'", + "path": "'"${project_path}"'", "namespace_id": "'"${GIT_PACKAGING_NAMESPACE_ID}"'", "request_access_enabled": "false" }' diff --git a/src/lib/repo/clone.sh b/src/lib/repo/clone.sh index 4b26fcf..dee4870 100644 --- a/src/lib/repo/clone.sh +++ b/src/lib/repo/clone.sh @@ -54,6 +54,9 @@ pkgctl_repo_clone() { local CONFIGURE_OPTIONS=() local pkgbases + # variables + local project_path + while (( $# )); do case $1 in -h|--help) @@ -126,7 +129,8 @@ pkgctl_repo_clone() { for pkgbase in "${pkgbases[@]}"; do if [[ ! -d ${pkgbase} ]]; then msg "Cloning ${pkgbase} ..." - remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git" + project_path=$(gitlab_project_name_to_path "${pkgbase}") + remote_url="${GIT_REPO_BASE_URL}/${project_path}.git" git clone --origin origin "${remote_url}" "${pkgbase}" else warning "Skip cloning ${pkgbase}: Directory exists" diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh index d6262b7..942876a 100644 --- a/src/lib/repo/configure.sh +++ b/src/lib/repo/configure.sh @@ -96,7 +96,7 @@ pkgctl_repo_configure() { local paths=() # variables - local path realpath pkgbase remote_url + local path realpath pkgbase remote_url project_path local PACKAGER GPGKEY packager_name packager_email while (( $# )); do @@ -174,7 +174,8 @@ pkgctl_repo_configure() { pushd "${path}" >/dev/null - remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git" + project_path=$(gitlab_project_name_to_path "${pkgbase}") + remote_url="${GIT_REPO_BASE_URL}/${project_path}.git" if ! git remote add origin "${remote_url}" &>/dev/null; then git remote set-url origin "${remote_url}" fi -- cgit v1.2.3-70-g09d2 From a981ef40e84398475cfe04ac49b8118385249a96 Mon Sep 17 00:00:00 2001 From: Campbell Jones Date: Sat, 25 Mar 2023 17:53:27 -0400 Subject: edit: improve editor presence checking Adds a check for the configured Git editor (git config core.editor) in both commitpkg and build.sh. Additionally, instead of blindly executing vi when all other options are exhausted, remove it instead as it is a none standard installed editor anyway. Closes #106 Signed-off-by: Levente Polyak --- src/commitpkg.in | 4 +++- src/lib/build/build.sh | 11 +++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'src/lib') diff --git a/src/commitpkg.in b/src/commitpkg.in index 7573d9b..26117dc 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -198,8 +198,10 @@ if [[ -n $(git status --short --untracked-files=no) ]]; then $VISUAL "$msgfile" || die elif [[ -n $EDITOR ]]; then $EDITOR "$msgfile" || die + elif giteditor=$(git config --get core.editor); then + $giteditor "$msgfile" || die else - vi "$msgfile" || die + die "No usable editor found (tried \$GIT_EDITOR, \$VISUAL, \$EDITOR, git config [core.editor])." fi [[ -s $msgfile ]] || die stat_busy 'Committing changes' diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index e32c79f..72ee4fb 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -335,18 +335,21 @@ pkgctl_build() { # edit PKGBUILD if (( EDIT )); then stat_busy 'Editing PKGBUILD' - if [[ -n $VISUAL ]]; then + if [[ -n $GIT_EDITOR ]]; then + $GIT_EDITOR PKGBUILD || die + elif [[ -n $VISUAL ]]; then $VISUAL PKGBUILD || die elif [[ -n $EDITOR ]]; then $EDITOR PKGBUILD || die - elif command -v vi &>/dev/null; then - vi PKGBUILD || die + elif giteditor=$(git config --get core.editor); then + $giteditor PKGBUILD || die else - die "need \$VISUAL or \$EDITOR to edit the PKGBUILD" + die "No usable editor found (tried \$GIT_EDITOR, \$VISUAL, \$EDITOR, git config [core.editor])." fi stat_done fi + # update checksums if any sources are declared if (( UPDPKGSUMS )) && (( ${#source[@]} >= 1 )); then updpkgsums -- cgit v1.2.3-70-g09d2 From 5e22e4f81e61f4ad2228366439be00b691284894 Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Mon, 13 Feb 2023 14:58:42 +0100 Subject: config: allow suppying the gitlab token via env var This would allow to supply the gitlab tokens via the env var DEVTOOLS_GITLAB_TOKEN and therefore allow users to choose whatever program they want to fill this env var. Closes #113 Signed-off-by: Christian Heusel Signed-off-by: Levente Polyak --- doc/man/pkgctl-auth-login.1.asciidoc | 7 +++++++ src/lib/auth/login.sh | 8 ++++++++ src/lib/config.sh | 10 +++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) (limited to 'src/lib') diff --git a/doc/man/pkgctl-auth-login.1.asciidoc b/doc/man/pkgctl-auth-login.1.asciidoc index 9c32ab2..eeeec4e 100644 --- a/doc/man/pkgctl-auth-login.1.asciidoc +++ b/doc/man/pkgctl-auth-login.1.asciidoc @@ -16,6 +16,13 @@ Interactively authenticate with the GitLab instance. The minimum required scopes for the token are: 'api', 'write_repository'. +The GitLab API token can either be stored in a plaintext file in +'$XDG_CONFIG_HOME/devtools/gitlab.conf', or supplied via the +'DEVTOOLS_GITLAB_TOKEN' environment variable using any command (gpg, vault, +password manager) by declaring a shell alias: + + $ alias pkgctl='DEVTOOLS_GITLAB_TOKEN="$(command to obtain token)" pkgctl' + Options ------- diff --git a/src/lib/auth/login.sh b/src/lib/auth/login.sh index 083e80a..d427676 100644 --- a/src/lib/auth/login.sh +++ b/src/lib/auth/login.sh @@ -27,6 +27,10 @@ pkgctl_auth_login_usage() { The minimum required scopes for the token are: 'api', 'write_repository'. + The GitLab API token can either be stored in a plaintext file, or + supplied via the DEVTOOLS_GITLAB_TOKEN environment variable using a + vault, see pkgctl-auth-login(1) for details. + OPTIONS -g, --gen-access-token Open the URL to generate a new personal access token -h, --help Show this help text @@ -66,6 +70,10 @@ pkgctl_auth_login() { Tip: you can generate a Personal Access Token here ${personal_access_token_url} The minimum required scopes are 'api' and 'write_repository'. + + If you do not want to store the token in a plaintext file, you can abort + the following prompt and supply the token via the DEVTOOLS_GITLAB_TOKEN + environment variable using a vault, see pkgctl-auth-login(1) for details. _EOF_ if (( GEN_ACESS_TOKEN )); then diff --git a/src/lib/config.sh b/src/lib/config.sh index 5034c6e..ba6532e 100644 --- a/src/lib/config.sh +++ b/src/lib/config.sh @@ -14,11 +14,15 @@ readonly XDG_DEVTOOLS_GITLAB_CONFIG="${XDG_DEVTOOLS_DIR}/gitlab.conf" export GITLAB_TOKEN="" load_devtools_config() { - if [[ ! -f "${XDG_DEVTOOLS_GITLAB_CONFIG}" ]]; then - GITLAB_TOKEN="" + if [[ -n "${DEVTOOLS_GITLAB_TOKEN}" ]]; then + GITLAB_TOKEN="${DEVTOOLS_GITLAB_TOKEN}" return fi - GITLAB_TOKEN=$(grep GITLAB_TOKEN "${XDG_DEVTOOLS_GITLAB_CONFIG}"|cut -d= -f2|cut -d\" -f2) + if [[ -f "${XDG_DEVTOOLS_GITLAB_CONFIG}" ]]; then + GITLAB_TOKEN=$(grep GITLAB_TOKEN "${XDG_DEVTOOLS_GITLAB_CONFIG}"|cut -d= -f2|cut -d\" -f2) + return + fi + GITLAB_TOKEN="" } save_devtools_config() { -- cgit v1.2.3-70-g09d2 From f3518e248cc8be165009f2200ff3b6500bfc0476 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 1 Apr 2023 00:12:56 +0200 Subject: build: support nocheck for initial bootstrap builds Output a warning when this option is used to remind packagers to rebuild the packages with checks once the bootstrap cycle has been completed. --- contrib/completion/zsh/_devtools.in | 1 + doc/man/pkgctl-build.1.asciidoc | 3 +++ src/lib/build/build.sh | 11 +++++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 39e9ac0..e782fba 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -42,6 +42,7 @@ _pkgctl_build_args=( '(-o --offload)'{-o,--offload}'[Build on a remote server and transfer artifacts afterwards]' '(-c --clean)'{-c,--clean}'[Recreate the chroot before building]' '(-I --install)'{-I,--install}'[Install a package into the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' + '--nocheck[Do not run the check() function in the PKGBUILD]' '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' '--pkgrel=[Set pkgrel to a given value]:pkgrel:' '--rebuild[Increment the pkgrel variable]' diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index 132c0a4..6ae3872 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -38,6 +38,9 @@ Build Options *-I, --install* 'FILE':: Install a package into the working copy of the chroot +*--nocheck*:: + Do not run the check() function in the PKGBUILD + PKGBUILD Options ---------------- diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 72ee4fb..fff8125 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -47,6 +47,7 @@ pkgctl_build_usage() { -o, --offload Build on a remote server and transfer artifacts afterwards -c, --clean Recreate the chroot before building -I, --install FILE Install a package into the working copy of the chroot + --nocheck Do not run the check() function in the PKGBUILD PKGBUILD OPTIONS --pkgver=PKGVER Set pkgver, reset pkgrel and update checksums @@ -120,6 +121,7 @@ pkgctl_build() { local BUILD_OPTIONS=() local MAKECHROOT_OPTIONS=() local RELEASE_OPTIONS=() + local MAKEPKG_OPTIONS=() local PTS PTS="$(tty | sed 's|/dev/pts/||')" @@ -201,6 +203,11 @@ pkgctl_build() { warning 'installing packages into the chroot may break reproducible builds, use with caution!' shift 2 ;; + --nocheck) + MAKEPKG_OPTIONS+=("--nocheck") + warning 'not running checks is disallowed for official packages, except for bootstrapping. Please rebuild after bootstrapping is completed!' + shift + ;; -r|--release) # shellcheck source=src/lib/release.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh @@ -366,9 +373,9 @@ pkgctl_build() { fi if (( OFFLOAD )); then - offload-build --repo "${pkgrepo}" -- "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" + offload-build --repo "${pkgrepo}" -- "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" -- "${MAKEPKG_OPTIONS[@]}" else - "${BUILDTOOL}" "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" + "${BUILDTOOL}" "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" -- "${MAKEPKG_OPTIONS[@]}" fi done -- cgit v1.2.3-70-g09d2 From bc182032eb4a1cbae573c9f09bdd9f8338b20d23 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Wed, 5 Apr 2023 22:58:49 +0200 Subject: config: fixup file permissions to be more strict Normally the default in Arch is that all home directories are private. However, this may have been changed locally. To make sure we never expose secrets, lets use a umask of 0077 when writing the config. Additionally add some temporary fixup code to migrate the file and directory permissions of already existing paths. Signed-off-by: Levente Polyak --- src/lib/config.sh | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/config.sh b/src/lib/config.sh index ba6532e..b09479a 100644 --- a/src/lib/config.sh +++ b/src/lib/config.sh @@ -14,6 +14,13 @@ readonly XDG_DEVTOOLS_GITLAB_CONFIG="${XDG_DEVTOOLS_DIR}/gitlab.conf" export GITLAB_TOKEN="" load_devtools_config() { + # temporary permission fixup + if [[ -d "${XDG_DEVTOOLS_DIR}" ]]; then + chmod 700 "${XDG_DEVTOOLS_DIR}" + fi + if [[ -f "${XDG_DEVTOOLS_GITLAB_CONFIG}" ]]; then + chmod 600 "${XDG_DEVTOOLS_GITLAB_CONFIG}" + fi if [[ -n "${DEVTOOLS_GITLAB_TOKEN}" ]]; then GITLAB_TOKEN="${DEVTOOLS_GITLAB_TOKEN}" return @@ -26,6 +33,16 @@ load_devtools_config() { } save_devtools_config() { - mkdir -p "${XDG_DEVTOOLS_DIR}" - printf 'GITLAB_TOKEN="%s"\n' "${GITLAB_TOKEN}" > "${XDG_DEVTOOLS_GITLAB_CONFIG}" + # temporary permission fixup + if [[ -d "${XDG_DEVTOOLS_DIR}" ]]; then + chmod 700 "${XDG_DEVTOOLS_DIR}" + fi + if [[ -f "${XDG_DEVTOOLS_GITLAB_CONFIG}" ]]; then + chmod 600 "${XDG_DEVTOOLS_GITLAB_CONFIG}" + fi + ( + umask 0077 + mkdir -p "${XDG_DEVTOOLS_DIR}" + printf 'GITLAB_TOKEN="%s"\n' "${GITLAB_TOKEN}" > "${XDG_DEVTOOLS_GITLAB_CONFIG}" + ) } -- cgit v1.2.3-70-g09d2 From 645a5a9f047ada2fd76d6149ed24aa888547a52d Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Thu, 13 Apr 2023 17:44:48 +0200 Subject: pkgctl: introduce the version subcommand Related to https://gitlab.archlinux.org/archlinux/devtools/-/issues/125 Closes #125 Signed-off-by: Christian Heusel Co-Authored-By: Levente Polyak --- contrib/completion/zsh/_devtools.in | 6 +++++ doc/man/pkgctl-version.1.asciidoc | 23 ++++++++++++++++++ doc/man/pkgctl.1.asciidoc | 13 ++++++++++ src/lib/version/version.sh | 47 +++++++++++++++++++++++++++++++++++++ src/pkgctl.in | 9 +++++++ 5 files changed, 98 insertions(+) create mode 100644 doc/man/pkgctl-version.1.asciidoc create mode 100644 src/lib/version/version.sh (limited to 'src/lib') diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index cc8d5cf..20c37ce 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -231,9 +231,15 @@ _pkgctl_cmds=( "diff[Compare package files using different modes]" "release[Release step to commit, tag and upload build artifacts]" "repo[Manage Git packaging repositories and their configuration]" + "version[Show pkgctl version information]" ) _pkgctl_args=( + '(-V --version)'{-V,--version}'[Show pkgctl version information]' + '(-h --help)'{-h,--help}'[Display usage]' +) + +_pkgctl_version_args=( '(-h --help)'{-h,--help}'[Display usage]' ) diff --git a/doc/man/pkgctl-version.1.asciidoc b/doc/man/pkgctl-version.1.asciidoc new file mode 100644 index 0000000..9beebf5 --- /dev/null +++ b/doc/man/pkgctl-version.1.asciidoc @@ -0,0 +1,23 @@ +pkgctl-version(1) +================= + +Name +---- +pkgctl-version - Show pkgctl version information + +Synopsis +-------- +pkgctl version [OPTIONS] + +Description +----------- + +Shows the current version information of pkgctl. + +Options +------- + +*-h, --help*:: + Show a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index c5a6174..72cda1e 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -14,6 +14,15 @@ Description TODO +Options +------- + +*-V, --version*:: + Show pkgctl version information + +*-h, --help*:: + Show a help text + Subcommands ----------- @@ -35,6 +44,9 @@ pkgctl release:: pkgctl repo:: Manage Git packaging repositories and their configuration +pkgctl version:: + Show pkgctl version information + See Also -------- @@ -44,5 +56,6 @@ linkman:pkgctl-db[1] linkman:pkgctl-diff[1] linkman:pkgctl-release[1] linkman:pkgctl-repo[1] +linkman:pkgctl-version[1] include::include/footer.asciidoc[] diff --git a/src/lib/version/version.sh b/src/lib/version/version.sh new file mode 100644 index 0000000..d00a460 --- /dev/null +++ b/src/lib/version/version.sh @@ -0,0 +1,47 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_VERSION_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_VERSION_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + +source /usr/share/makepkg/util/message.sh + +set -e + + +pkgctl_version_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] + + Shows the current version information of pkgctl + + OPTIONS + -h, --help Show this help text +_EOF_ +} + +pkgctl_version_print() { + cat <<- _EOF_ + pkgctl @buildtoolver@ +_EOF_ +} + +pkgctl_version() { + while (( $# )); do + case $1 in + -h|--help) + pkgctl_version_usage + exit 0 + ;; + *) + die "invalid argument: %s" "$1" + ;; + esac + done + + pkgctl_version_print +} diff --git a/src/pkgctl.in b/src/pkgctl.in index 40f9259..1797b32 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -25,6 +25,7 @@ usage() { diff Compare package files using different modes release Release step to commit, tag and upload build artifacts repo Manage Git packaging repositories and their configuration + version Show pkgctl version information OPTIONS -h, --help Show this help text @@ -93,6 +94,14 @@ while (( $# )); do pkgctl_release "$@" exit 0 ;; + version|--version|-V) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/version/version.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/version.sh + pkgctl_version "$@" + exit 0 + ;; *) die "invalid command: %s" "$1" ;; -- cgit v1.2.3-70-g09d2 From ed966351410b39bfcec749df59dbc434a5dade1e Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Sat, 15 Apr 2023 19:44:22 +0200 Subject: pkgctl repo: introduce the switch subcommand Signed-off-by: Christian Heusel Co-Authored-By: Levente Polyak --- contrib/completion/bash/devtools.in | 19 ++++++ contrib/completion/zsh/_devtools.in | 8 +++ doc/man/pkgctl-repo-switch.1.asciidoc | 36 ++++++++++ doc/man/pkgctl-repo.1.asciidoc | 4 ++ src/lib/repo.sh | 10 +++ src/lib/repo/switch.sh | 119 ++++++++++++++++++++++++++++++++++ 6 files changed, 196 insertions(+) create mode 100644 doc/man/pkgctl-repo-switch.1.asciidoc create mode 100644 src/lib/repo/switch.sh (limited to 'src/lib') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index e3ae023..e79b862 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -255,6 +255,7 @@ _pkgctl_repo_cmds=( clone configure create + switch web ) @@ -282,6 +283,24 @@ _pkgctl_repo_create_args=( ) +_pkgctl_repo_switch_args=( + --discard-changes + -f --force + -h --help +) +_pkgctl_repo_switch_opts() { + local subcommand args + subcommand=(repo switch) + args=$(__pkgctl_word_count_after_subcommand "${subcommand[@]}") + + if (( args == 0 )); then + : + elif (( args >= 1 )); then + _filedir -d; + fi +} + + _pkgctl_repo_web_args=( -h --help ) diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 20c37ce..5760458 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -94,9 +94,17 @@ _pkgctl_repo_cmds=( "clone[Clone a package repository]" "configure[Configure a clone according to distro specs]" "create[Create a new GitLab package repository]" + "switch[Switch a package repository to a specified version]" "web[Open the packaging repository's website]" ) +_pkgctl_repo_switch_args=( + '(-f --force --discard-changes)'{-f,--force,--discard-changes}'[Discard changes if index or working tree is dirty]' + '(-h --help)'{-h,--help}'[Display usage]' + '1:version' + '*:git_dir:_files -/' +) + _pkgctl_repo_clone_args=( '(-m --maintainer=)'{-m,--maintainer=}'[Clone all packages of the named maintainer]:maintainer:' '--universe[Clone all existing packages, useful for cache warming]' diff --git a/doc/man/pkgctl-repo-switch.1.asciidoc b/doc/man/pkgctl-repo-switch.1.asciidoc new file mode 100644 index 0000000..ac12019 --- /dev/null +++ b/doc/man/pkgctl-repo-switch.1.asciidoc @@ -0,0 +1,36 @@ +pkgctl-repo-switch(1) +===================== + +Name +---- +pkgctl-repo-switch - Switch a package repository to a specified version + +Synopsis +-------- +pkgctl repo switch [OPTIONS] [VERSION] [PKGBASE]... + +Description +----------- + +Switch a package source repository to a specified version, tag or branch. +The working tree and the index are updated to match the specified ref. + +If a version identifier is specified in the pacman version format, that +identifier is automatically translated to the Git tag name accordingly. + +The current working directory is used if no PKGBASE is specified. + +Options +------- + +*--discard-changes*:: + Proceed even if the index or the working tree differs from HEAD. Both the + index and working tree are restored to match the switching target. + +*-f, --force*:: + An alias for '--discard-changes'. + +*-h, --help*:: + Show a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-repo.1.asciidoc b/doc/man/pkgctl-repo.1.asciidoc index 630afd8..713b474 100644 --- a/doc/man/pkgctl-repo.1.asciidoc +++ b/doc/man/pkgctl-repo.1.asciidoc @@ -41,6 +41,9 @@ pkgctl repo configure:: pkgctl repo create:: Create a new GitLab package repository +pkgctl repo switch:: + Switch a package repository to a specified version + pkgctl repo web:: Open the packaging repository's website @@ -50,6 +53,7 @@ See Also linkman:pkgctl-repo-clone[1] linkman:pkgctl-repo-configure[1] linkman:pkgctl-repo-create[1] +linkman:pkgctl-repo-switch[1] linkman:pkgctl-repo-web[1] include::include/footer.asciidoc[] diff --git a/src/lib/repo.sh b/src/lib/repo.sh index 6b3817a..9f545e9 100644 --- a/src/lib/repo.sh +++ b/src/lib/repo.sh @@ -30,6 +30,7 @@ pkgctl_repo_usage() { clone Clone a package repository configure Configure a clone according to distro specs create Create a new GitLab package repository + switch Switch a package repository to a specified version web Open the packaging repository's website OPTIONS @@ -40,6 +41,7 @@ pkgctl_repo_usage() { $ ${COMMAND} clone --maintainer mynickname $ ${COMMAND} configure * $ ${COMMAND} create libfoo + $ ${COMMAND} switch 2:1.19.5-1 libfoo $ ${COMMAND} web linux _EOF_ } @@ -81,6 +83,14 @@ pkgctl_repo() { pkgctl_repo_create "$@" exit 0 ;; + switch) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/repo/switch.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/switch.sh + pkgctl_repo_switch "$@" + exit 0 + ;; web) _DEVTOOLS_COMMAND+=" $1" shift diff --git a/src/lib/repo/switch.sh b/src/lib/repo/switch.sh new file mode 100644 index 0000000..f411ac2 --- /dev/null +++ b/src/lib/repo/switch.sh @@ -0,0 +1,119 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_REPO_SWITCH_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_REPO_SWITCH_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +source /usr/share/makepkg/util/message.sh + +set -e + + +pkgctl_repo_switch_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [VERSION] [PKGBASE]... + + Switch a package source repository to a specified version, tag or + branch. The working tree and the index are updated to match the + specified ref. + + If a version identifier is specified in the pacman version format, that + identifier is automatically translated to the Git tag name accordingly. + + The current working directory is used if no PKGBASE is specified. + + OPTIONS + --discard-changes Discard changes if index or working tree is dirty + -f, --force An alias for --discard-changes + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} 1.14.6-1 gopass gopass-jsonapi + $ ${COMMAND} --force 2:1.19.5-1 + $ ${COMMAND} main +_EOF_ +} + +pkgctl_repo_switch() { + if (( $# < 1 )); then + pkgctl_repo_switch_usage + exit 0 + fi + + # options + local VERSION + local GIT_REF + local GIT_CHECKOUT_OPTIONS=() + local paths path realpath pkgbase + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_repo_switch_usage + exit 0 + ;; + -f|--force|--discard-changes) + GIT_CHECKOUT_OPTIONS+=("--force") + shift + ;; + --) + shift + break + ;; + -*) + # - is special to switch back to previous version + if [[ $1 != - ]]; then + die "invalid argument: %s" "$1" + fi + ;;& + *) + if [[ -n ${VERSION} ]]; then + break + fi + VERSION=$1 + shift + ;; + esac + done + + if [[ -z ${VERSION} ]]; then + error "missing positional argument 'VERSION'" + pkgctl_repo_switch_usage + exit 1 + fi + + GIT_REF="$(get_tag_from_pkgver "${VERSION}")" + paths=("$@") + + # check if invoked without any path from within a packaging repo + if (( ${#paths[@]} == 0 )); then + if [[ -f PKGBUILD ]]; then + paths=(".") + else + die "Not a package repository: $(realpath -- .)" + fi + fi + + for path in "${paths[@]}"; do + if ! realpath=$(realpath -e -- "${path}"); then + die "No such directory: ${path}" + fi + pkgbase=$(basename "${realpath}") + + if [[ ! -d "${path}/.git" ]]; then + error "Not a Git repository: ${path}" + continue + fi + + if ! git -C "${path}" checkout "${GIT_CHECKOUT_OPTIONS[@]}" "${GIT_REF}"; then + die "Failed to switch ${pkgbase} to version ${VERSION}" + fi + msg "Successfully switched ${pkgbase} to version ${VERSION}" + done +} -- cgit v1.2.3-70-g09d2 From 4289be212b38cbd9a1676303224b6af5c00bd429 Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Tue, 18 Apr 2023 01:15:24 +0200 Subject: build: allow release options only in combination with --release It leads to weird expectations when using --db-update or --message without --release. Make the behavior more user friendly, by aborting the operation and explaining that release options only work in conjunction with the release option. Fixes #131 Signed-off-by: Christian Heusel --- doc/man/pkgctl-build.1.asciidoc | 4 +++- src/lib/build/build.sh | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index 6ae3872..489926e 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -60,7 +60,9 @@ Release Options --------------- *-r, --release*:: - Automatically commit, tag and release after building + Automatically commit, tag and release after building + + Specifying this option is required when using any of the following options + in this section *-m, --message* 'MSG':: Use the given as the commit message diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index fff8125..2153200 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -238,6 +238,16 @@ pkgctl_build() { esac done + # check if any release specific options were specified without releasing + if (( ! RELEASE )); then + if (( DB_UPDATE )); then + die "cannot use --db-update without --release" + fi + if [[ -n "${MESSAGE}" ]]; then + die "cannot use --message without --release" + fi + fi + # check if invoked without any path from within a packaging repo if (( ${#paths[@]} == 0 )); then if [[ -f PKGBUILD ]]; then -- cgit v1.2.3-70-g09d2 From 8e3b6bcc5b82b270f8d310865f14f2b0405eddd7 Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Fri, 14 Apr 2023 17:14:05 +0200 Subject: pkgctl repo clone: add option to switch working tree Add an option to call the switch command after clone. Switch to a specified version. The working tree and the index are updated to match the version. Signed-off-by: Christian Heusel Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 2 ++ contrib/completion/zsh/_devtools.in | 1 + doc/man/pkgctl-repo-clone.1.asciidoc | 5 +++++ src/lib/repo/clone.sh | 20 ++++++++++++++++++++ 4 files changed, 28 insertions(+) (limited to 'src/lib') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index e79b862..31269dd 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -262,12 +262,14 @@ _pkgctl_repo_cmds=( _pkgctl_repo_clone_args=( -m --maintainer + --switch -u --unprivileged --universe -h --help ) _pkgctl_repo_clone_args__maintainer_opts() { :; } _pkgctl_repo_clone_args_m_opts() { _pkgctl_repo_clone_args__maintainer_opts; } +_pkgctl_repo_clone_args__switch_opts() { :; } _pkgctl_repo_clone_opts() { _devtools_completions_all_packages; } diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 5760458..ed52a22 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -107,6 +107,7 @@ _pkgctl_repo_switch_args=( _pkgctl_repo_clone_args=( '(-m --maintainer=)'{-m,--maintainer=}'[Clone all packages of the named maintainer]:maintainer:' + '--switch=[Switch the current working tree to a specified version]' '--universe[Clone all existing packages, useful for cache warming]' '(-h --help)'{-h,--help}'[Display usage]' '*:packages:_devtools_completions_all_packages' diff --git a/doc/man/pkgctl-repo-clone.1.asciidoc b/doc/man/pkgctl-repo-clone.1.asciidoc index a39fb37..8f3aef7 100644 --- a/doc/man/pkgctl-repo-clone.1.asciidoc +++ b/doc/man/pkgctl-repo-clone.1.asciidoc @@ -28,6 +28,10 @@ Options *--universe*:: Clone all existing packages, useful for cache warming +*--switch* 'VERSION':: + Switch to a specified version. The working tree and the index are updated to + match the version. + *-h, --help*:: Show a help text @@ -35,5 +39,6 @@ See Also -------- linkman:pkgctl-repo-configure[1] +linkman:pkgctl-repo-switch[1] include::include/footer.asciidoc[] diff --git a/src/lib/repo/clone.sh b/src/lib/repo/clone.sh index dee4870..340aa69 100644 --- a/src/lib/repo/clone.sh +++ b/src/lib/repo/clone.sh @@ -32,12 +32,14 @@ pkgctl_repo_clone_usage() { OPTIONS -m, --maintainer=NAME Clone all packages of the named maintainer + --switch VERSION Switch the current working tree to a specified version --universe Clone all existing packages, useful for cache warming -h, --help Show this help text EXAMPLES $ ${COMMAND} libfoo linux libbar $ ${COMMAND} --maintainer mynickname + $ ${COMMAND} --switch 1:1.0-2 libfoo _EOF_ } @@ -51,6 +53,7 @@ pkgctl_repo_clone() { local GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} local CLONE_ALL=0 local MAINTAINER= + local VERSION= local CONFIGURE_OPTIONS=() local pkgbases @@ -77,6 +80,19 @@ pkgctl_repo_clone() { MAINTAINER="${1#*=}" shift ;; + --switch) + (( $# <= 1 )) && die "missing argument for %s" "$1" + # shellcheck source=src/lib/repo/switch.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/switch.sh + VERSION="$2" + shift 2 + ;; + --switch=*) + # shellcheck source=src/lib/repo/switch.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/switch.sh + VERSION="${1#*=}" + shift + ;; --universe) CLONE_ALL=1 shift @@ -137,5 +153,9 @@ pkgctl_repo_clone() { fi pkgctl_repo_configure "${CONFIGURE_OPTIONS[@]}" "${pkgbase}" + + if [[ -n "${VERSION}" ]]; then + pkgctl_repo_switch "${VERSION}" "${pkgbase}" + fi done } -- cgit v1.2.3-70-g09d2 From 830dcde2d8353dbcce1e831adb7c7e8f538210a3 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 5 May 2023 20:21:38 +0200 Subject: pkgctl build: support worker slots for none tty builds Allow overriding the worker slot with a dedicated option. Furthermore detect if the current tty is no pts and fall back to choosing a random worker slot between 1 and number of available processing units. Fixes #137 Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 3 +++ contrib/completion/zsh/_devtools.in | 1 + doc/man/pkgctl-build.1.asciidoc | 6 ++++++ src/lib/build/build.sh | 23 ++++++++++++++++++----- 4 files changed, 28 insertions(+), 5 deletions(-) (limited to 'src/lib') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 31269dd..b0a90e5 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -168,6 +168,7 @@ _pkgctl_build_args=( -t --testing -o --offload -c --clean + -w --worker --pkgver --pkgrel @@ -182,6 +183,8 @@ _pkgctl_build_args=( ) _pkgctl_build_args__arch_opts() { _devtools_completions_arch; } _pkgctl_build_args__repo_opts() { _devtools_completions_repo; } +_pkgctl_build_args__worker_opts() { :; } +_pkgctl_build_args_w_opts() { _pkgctl_build_args__worker_opts; } _pkgctl_build_args__pkgver_opts() { :; } _pkgctl_build_args__pkgrel_opts() { :; } _pkgctl_build_args__message_opts() { :; } diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index ed52a22..45ffde3 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -42,6 +42,7 @@ _pkgctl_build_args=( '(-o --offload)'{-o,--offload}'[Build on a remote server and transfer artifacts afterwards]' '(-c --clean)'{-c,--clean}'[Recreate the chroot before building]' '(-I --install)'{-I,--install}'[Install a package into the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' + '(-w --worker)'{-w,--worker}'[Name of the worker slot, useful for concurrent builds (disables auto-detection)]:slot:' '--nocheck[Do not run the check() function in the PKGBUILD]' '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' '--pkgrel=[Set pkgrel to a given value]:pkgrel:' diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index 489926e..f68e7cf 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -38,6 +38,12 @@ Build Options *-I, --install* 'FILE':: Install a package into the working copy of the chroot +*-w, --worker* 'SLOT':: + Name of the worker slot, useful for concurrent builds. By default the slot + is automatically assigned to the current tty pts number. In case the caller + is not a tty, choose a random slot between 1 and number of available + processing units. + *--nocheck*:: Do not run the check() function in the PKGBUILD diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 2153200..191fded 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -25,6 +25,7 @@ source /usr/share/makepkg/util/config.sh source /usr/share/makepkg/util/message.sh set -e +set -o pipefail pkgctl_build_usage() { @@ -47,6 +48,7 @@ pkgctl_build_usage() { -o, --offload Build on a remote server and transfer artifacts afterwards -c, --clean Recreate the chroot before building -I, --install FILE Install a package into the working copy of the chroot + -w, --worker SLOT Name of the worker slot, useful for concurrent builds (disables automatic names) --nocheck Do not run the check() function in the PKGBUILD PKGBUILD OPTIONS @@ -123,9 +125,8 @@ pkgctl_build() { local RELEASE_OPTIONS=() local MAKEPKG_OPTIONS=() - local PTS - PTS="$(tty | sed 's|/dev/pts/||')" - local WORKER="${USER}-${PTS}" + local WORKER= + local WORKER_SLOT= # variables local path pkgbase pkgrepo source @@ -224,6 +225,11 @@ pkgctl_build() { DB_UPDATE=1 shift ;; + -w|--worker) + (( $# <= 1 )) && die "missing argument for %s" "$1" + WORKER_SLOT=$2 + shift 2 + ;; --) shift break @@ -258,6 +264,12 @@ pkgctl_build() { fi fi + # assign default worker slot + if [[ -z ${WORKER_SLOT} ]] && ! WORKER_SLOT="$(tty | sed 's|/dev/pts/||')"; then + WORKER_SLOT=$(( RANDOM % $(nproc) + 1 )) + fi + WORKER="${USER}-${WORKER_SLOT}" + # Update pacman cache for auto-detection if [[ -z ${REPO} ]]; then update_pacman_repo_cache @@ -311,8 +323,9 @@ pkgctl_build() { fi # print gathered build modes - msg2 "repo: ${pkgrepo}" - msg2 "arch: ${BUILD_ARCH[*]}" + msg2 " repo: ${pkgrepo}" + msg2 " arch: ${BUILD_ARCH[*]}" + msg2 "worker: ${WORKER}" # increment pkgrel on rebuild if (( REBUILD )); then -- cgit v1.2.3-70-g09d2 From 41d4624879d01b1269d6af9c1440592a15ad7784 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 20 May 2023 00:20:41 +0200 Subject: fix(archroot): pass along the real command and argv by the caller Before modularizing the repo layout, we used m4_include to assemble together sources into a single file. Now, we properly use a library layout without assembling multiple files, which means we cannot anymore rely on BASH_SOURCE inside the library file. Hence, pass along the actual command and argv from the check_root caller. Fixes: src: modularize repo layout into a library Signed-off-by: Morten Linderud Signed-off-by: Levente Polyak --- src/arch-nspawn.in | 2 +- src/archbuild.in | 2 +- src/lib/archroot.sh | 5 +++-- src/makechrootpkg.in | 2 +- src/makerepropkg.in | 2 +- src/mkarchroot.in | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/lib') diff --git a/src/arch-nspawn.in b/src/arch-nspawn.in index 77a27ad..b692817 100644 --- a/src/arch-nspawn.in +++ b/src/arch-nspawn.in @@ -46,7 +46,7 @@ done shift $((OPTIND - 1)) (( $# < 1 )) && die 'You must specify a directory.' -check_root +check_root "" "${BASH_SOURCE[0]}" "$@" working_dir=$(readlink -f "$1") shift 1 diff --git a/src/archbuild.in b/src/archbuild.in index a7e4231..2f3faf9 100644 --- a/src/archbuild.in +++ b/src/archbuild.in @@ -74,7 +74,7 @@ while getopts 'hcr:' arg; do esac done -check_root SOURCE_DATE_EPOCH,SRCDEST,SRCPKGDEST,PKGDEST,LOGDEST,MAKEFLAGS,PACKAGER,GNUPGHOME +check_root SOURCE_DATE_EPOCH,SRCDEST,SRCPKGDEST,PKGDEST,LOGDEST,MAKEFLAGS,PACKAGER,GNUPGHOME "${BASH_SOURCE[0]}" "$@" # Pass all arguments after -- right to makepkg makechrootpkg_args+=("${@:$OPTIND}") diff --git a/src/lib/archroot.sh b/src/lib/archroot.sh index d7917da..3f48dc1 100644 --- a/src/lib/archroot.sh +++ b/src/lib/archroot.sh @@ -9,13 +9,14 @@ CHROOT_VERSION='v4' ## # usage : check_root $keepenv ## -orig_argv=("${BASH_SOURCE[0]}" "$@") check_root() { local keepenv=$1 + shift + local orig_argv=("$@") (( EUID == 0 )) && return if type -P sudo >/dev/null; then - exec sudo --preserve-env=$keepenv -- "${orig_argv[@]}" + exec sudo --preserve-env="${keepenv}" -- "${orig_argv[@]}" else exec su root -c "$(printf ' %q' "${orig_argv[@]}")" fi diff --git a/src/makechrootpkg.in b/src/makechrootpkg.in index 8d3d093..2cfd849 100644 --- a/src/makechrootpkg.in +++ b/src/makechrootpkg.in @@ -301,7 +301,7 @@ done [[ -n $makepkg_user && -z $(id -u "$makepkg_user") ]] && die 'Invalid makepkg user.' makepkg_user=${makepkg_user:-${SUDO_USER:-$USER}} -check_root SOURCE_DATE_EPOCH,BUILDTOOL,BUILDTOOLVER,GNUPGHOME,SRCDEST,SRCPKGDEST,PKGDEST,LOGDEST,MAKEFLAGS,PACKAGER +check_root SOURCE_DATE_EPOCH,BUILDTOOL,BUILDTOOLVER,GNUPGHOME,SRCDEST,SRCPKGDEST,PKGDEST,LOGDEST,MAKEFLAGS,PACKAGER "${BASH_SOURCE[0]}" "$@" # Canonicalize chrootdir, getting rid of trailing / chrootdir=$(readlink -e "$passeddir") diff --git a/src/makerepropkg.in b/src/makerepropkg.in index f310c69..61ee9db 100644 --- a/src/makerepropkg.in +++ b/src/makerepropkg.in @@ -137,7 +137,7 @@ while getopts 'dM:c:l:h' arg; do done shift $((OPTIND - 1)) -check_root +check_root "" "${BASH_SOURCE[0]}" "$@" [[ -f PKGBUILD ]] || { error "No PKGBUILD in current directory."; exit 1; } diff --git a/src/mkarchroot.in b/src/mkarchroot.in index 6c8d8a2..610de16 100644 --- a/src/mkarchroot.in +++ b/src/mkarchroot.in @@ -52,7 +52,7 @@ shift $((OPTIND - 1)) (( $# < 2 )) && die 'You must specify a directory and one or more packages.' -check_root +check_root "" "${BASH_SOURCE[0]}" "$@" working_dir="$(readlink -f "$1")" shift 1 -- cgit v1.2.3-70-g09d2 From 80a8cdcba22f1a567efad19a487cb8ce28353dab Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 20 May 2023 12:10:06 +0200 Subject: chore(git): use default ssh port 22 url scheme We only need to specifically use ssh:// protocol prefix if we want to specify a special port. As we moved to support pulling directly over port 22 from out GitLab instance we can change the url scheme to the simple variant. Signed-off-by: Levente Polyak --- src/lib/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/common.sh b/src/lib/common.sh index 51ab2fd..24479eb 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -25,7 +25,7 @@ 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_SSH="git@${GITLAB_HOST}:${GIT_PACKAGING_NAMESPACE}" export GIT_PACKAGING_URL_HTTPS="https://${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}" export PACKAGING_REPO_RELEASE_HOST=repos.archlinux.org -- cgit v1.2.3-70-g09d2 From bf61b8472a2e50a740229f007513dd663b9dddda Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 20 May 2023 14:55:46 +0200 Subject: chore(archroot): force build chroot recreation to adapt new configs Bumping the chroot version will result in the chroots checking against the local version and force recreation in case they do not match. Signed-off-by: Levente Polyak --- src/lib/archroot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/archroot.sh b/src/lib/archroot.sh index 3f48dc1..8386c6c 100644 --- a/src/lib/archroot.sh +++ b/src/lib/archroot.sh @@ -4,7 +4,7 @@ : # shellcheck disable=2034 -CHROOT_VERSION='v4' +CHROOT_VERSION='v5' ## # usage : check_root $keepenv -- cgit v1.2.3-70-g09d2 From 6ce666a1669235749c17d5c44d8a24dea4a135da Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 3 Feb 2023 00:58:59 +0100 Subject: feature(parallel): run up to N jobs in parallel for repo clone/configure Run up to N jobs in parallel. By default the number of jobs is equal to the number of available processing units. For sequential processing this option needs to be passed with 1. Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 6 ++++++ contrib/completion/zsh/_devtools.in | 2 ++ doc/man/pkgctl-repo-clone.1.asciidoc | 5 +++++ doc/man/pkgctl-repo-configure.1.asciidoc | 5 +++++ src/lib/common.sh | 2 +- src/lib/repo/clone.sh | 31 +++++++++++++++++++++++++++++-- src/lib/repo/configure.sh | 27 +++++++++++++++++++++++---- 7 files changed, 71 insertions(+), 7 deletions(-) (limited to 'src/lib') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index b0a90e5..17f863f 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -268,17 +268,23 @@ _pkgctl_repo_clone_args=( --switch -u --unprivileged --universe + -j --jobs -h --help ) _pkgctl_repo_clone_args__maintainer_opts() { :; } _pkgctl_repo_clone_args_m_opts() { _pkgctl_repo_clone_args__maintainer_opts; } _pkgctl_repo_clone_args__switch_opts() { :; } +_pkgctl_repo_clone_args__jobs_opts() { :; } +_pkgctl_repo_clone_args_j_opts() { _pkgctl_repo_clone_args__jobs_opts; } _pkgctl_repo_clone_opts() { _devtools_completions_all_packages; } _pkgctl_repo_configure_args=( + -j --jobs -h --help ) +_pkgctl_repo_configure_args__jobs_opts() { :; } +_pkgctl_repo_configure_args_j_opts() { _pkgctl_repo_clone_args__jobs_opts; } _pkgctl_repo_configure_opts() { _filedir -d; } diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 45ffde3..240f781 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -110,11 +110,13 @@ _pkgctl_repo_clone_args=( '(-m --maintainer=)'{-m,--maintainer=}'[Clone all packages of the named maintainer]:maintainer:' '--switch=[Switch the current working tree to a specified version]' '--universe[Clone all existing packages, useful for cache warming]' + '(-j --jobs)'{-j,--jobs}'[Run up to N jobs in parallel (default: number of processing units)]:jobs:' '(-h --help)'{-h,--help}'[Display usage]' '*:packages:_devtools_completions_all_packages' ) _pkgctl_repo_configure_args=( + '(-j --jobs)'{-j,--jobs}'[Run up to N jobs in parallel (default: number of processing units)]:jobs:' '(-h --help)'{-h,--help}'[Display usage]' '*:git_dir:_files -/' ) diff --git a/doc/man/pkgctl-repo-clone.1.asciidoc b/doc/man/pkgctl-repo-clone.1.asciidoc index 487ec35..d6da062 100644 --- a/doc/man/pkgctl-repo-clone.1.asciidoc +++ b/doc/man/pkgctl-repo-clone.1.asciidoc @@ -32,6 +32,11 @@ Options Switch to a specified version. The working tree and the index are updated to match the version. +*-j, --jobs* 'N':: + Run up to N jobs in parallel. By default the number of jobs is equal to the + number of available processing units. For sequential processing this option + needs to be passed with 1. + *-h, --help*:: Show a help text diff --git a/doc/man/pkgctl-repo-configure.1.asciidoc b/doc/man/pkgctl-repo-configure.1.asciidoc index 4499ed6..1b07dc7 100644 --- a/doc/man/pkgctl-repo-configure.1.asciidoc +++ b/doc/man/pkgctl-repo-configure.1.asciidoc @@ -25,6 +25,11 @@ read-only HTTPS otherwise. Options ------- +*-j, --jobs* 'N':: + Run up to N jobs in parallel. By default the number of jobs is equal to the + number of available processing units. For sequential processing this option + needs to be passed with 1. + *-h, --help*:: Show a help text diff --git a/src/lib/common.sh b/src/lib/common.sh index 24479eb..3d1ee56 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -30,7 +30,7 @@ export GIT_PACKAGING_URL_HTTPS="https://${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE export PACKAGING_REPO_RELEASE_HOST=repos.archlinux.org # check if messages are to be printed using color -if [[ -t 2 && "$TERM" != dumb ]]; then +if [[ -t 2 && "$TERM" != dumb ]] || [[ ${DEVTOOLS_COLOR} == always ]]; then colorize else # shellcheck disable=2034 diff --git a/src/lib/repo/clone.sh b/src/lib/repo/clone.sh index 340aa69..a02d799 100644 --- a/src/lib/repo/clone.sh +++ b/src/lib/repo/clone.sh @@ -34,6 +34,7 @@ pkgctl_repo_clone_usage() { -m, --maintainer=NAME Clone all packages of the named maintainer --switch VERSION Switch the current working tree to a specified version --universe Clone all existing packages, useful for cache warming + -j, --jobs N Run up to N jobs in parallel (default: $(nproc)) -h, --help Show this help text EXAMPLES @@ -55,9 +56,11 @@ pkgctl_repo_clone() { local MAINTAINER= local VERSION= local CONFIGURE_OPTIONS=() - local pkgbases + local jobs= + jobs=$(nproc) # variables + local command=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} local project_path while (( $# )); do @@ -97,6 +100,11 @@ pkgctl_repo_clone() { CLONE_ALL=1 shift ;; + -j|--jobs) + (( $# <= 1 )) && die "missing argument for %s" "$1" + jobs=$2 + shift 2 + ;; --) shift break @@ -142,12 +150,31 @@ pkgctl_repo_clone() { stat_done fi + # parallelization + if [[ ${jobs} != 1 ]] && (( ${#pkgbases[@]} > 1 )); then + # force colors in parallel if parent process is colorized + if [[ -n ${BOLD} ]]; then + export DEVTOOLS_COLOR=always + fi + # assign command options + if [[ -n "${VERSION}" ]]; then + command+=" --switch '${VERSION}'" + fi + if ! parallel --bar --jobs "${jobs}" "${command}" ::: "${pkgbases[@]}"; then + die 'Failed to clone some packages, please check the output' + exit 1 + fi + exit 0 + fi + for pkgbase in "${pkgbases[@]}"; do if [[ ! -d ${pkgbase} ]]; then msg "Cloning ${pkgbase} ..." project_path=$(gitlab_project_name_to_path "${pkgbase}") remote_url="${GIT_REPO_BASE_URL}/${project_path}.git" - git clone --origin origin "${remote_url}" "${pkgbase}" + if ! git clone --origin origin "${remote_url}" "${pkgbase}"; then + die 'failed to clone %s' "${pkgbase}" + fi else warning "Skip cloning ${pkgbase}: Directory exists" fi diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh index 942876a..a5708a0 100644 --- a/src/lib/repo/configure.sh +++ b/src/lib/repo/configure.sh @@ -33,6 +33,7 @@ pkgctl_repo_configure_usage() { read-only HTTPS otherwise. OPTIONS + -j, --jobs N Run up to N jobs in parallel (default: $(nproc)) -h, --help Show this help text EXAMPLES @@ -93,9 +94,12 @@ pkgctl_repo_configure() { local GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS} local official=0 local proto=https + local jobs= + jobs=$(nproc) local paths=() # variables + local -r command=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} local path realpath pkgbase remote_url project_path local PACKAGER GPGKEY packager_name packager_email @@ -105,6 +109,11 @@ pkgctl_repo_configure() { pkgctl_repo_configure_usage exit 0 ;; + -j|--jobs) + (( $# <= 1 )) && die "missing argument for %s" "$1" + jobs=$2 + shift 2 + ;; --) shift break @@ -157,10 +166,21 @@ pkgctl_repo_configure() { msg2 "protocol: ${YELLOW}${proto}${ALL_OFF}" fi + # parallelization + if [[ ${jobs} != 1 ]] && (( ${#paths[@]} > 1 )); then + if [[ -n ${BOLD} ]]; then + export DEVTOOLS_COLOR=always + fi + if ! parallel --bar --jobs "${jobs}" "${command}" ::: "${paths[@]}"; then + die 'Failed to configure some packages, please check the output' + exit 1 + fi + exit 0 + fi + for path in "${paths[@]}"; do if ! realpath=$(realpath -e "${path}"); then - error "No such directory: ${path}" - continue + die "No such directory: ${path}" fi pkgbase=$(basename "${realpath}") @@ -168,8 +188,7 @@ pkgctl_repo_configure() { msg "Configuring ${pkgbase}" if [[ ! -d "${path}/.git" ]]; then - error "Not a Git repository: ${path}" - continue + die "Not a Git repository: ${path}" fi pushd "${path}" >/dev/null -- cgit v1.2.3-70-g09d2 From a08bc2acf49c68061284c7991d41dc78c46ae2b4 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Wed, 24 May 2023 02:40:52 +0200 Subject: feature(clone): add protocol option to force cloning over HTTPS This is a rather quick and simple implementation to override the current logic and force clone with HTTPS. Allowing to explicitly clone over HTTPS is currently required to unblock reproducible builds where no ssh keys and GitLab user accounts are set up as of now. Hence this quick solution comes into play to mitigate the regression on reproducible builds builders. Revisit the overall auto detection and protocol logic approach for a later release related to some ideas floating around in pending merge-requests. Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 7 +++++++ contrib/completion/zsh/_devtools.in | 2 ++ doc/man/pkgctl-repo-clone.1.asciidoc | 3 +++ doc/man/pkgctl-repo-configure.1.asciidoc | 3 +++ src/lib/repo/clone.sh | 15 +++++++++++++-- src/lib/repo/configure.sh | 21 +++++++++++++++++++-- 6 files changed, 47 insertions(+), 4 deletions(-) (limited to 'src/lib') diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 17f863f..3faad27 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -265,6 +265,7 @@ _pkgctl_repo_cmds=( _pkgctl_repo_clone_args=( -m --maintainer + --protocol --switch -u --unprivileged --universe @@ -273,6 +274,7 @@ _pkgctl_repo_clone_args=( ) _pkgctl_repo_clone_args__maintainer_opts() { :; } _pkgctl_repo_clone_args_m_opts() { _pkgctl_repo_clone_args__maintainer_opts; } +_pkgctl_repo_clone_args__protocol_opts() { _devtools_completions_protocol; } _pkgctl_repo_clone_args__switch_opts() { :; } _pkgctl_repo_clone_args__jobs_opts() { :; } _pkgctl_repo_clone_args_j_opts() { _pkgctl_repo_clone_args__jobs_opts; } @@ -280,9 +282,11 @@ _pkgctl_repo_clone_opts() { _devtools_completions_all_packages; } _pkgctl_repo_configure_args=( + --protocol -j --jobs -h --help ) +_pkgctl_repo_configure_args__protocol_opts() { _devtools_completions_protocol; } _pkgctl_repo_configure_args__jobs_opts() { :; } _pkgctl_repo_configure_args_j_opts() { _pkgctl_repo_clone_args__jobs_opts; } _pkgctl_repo_configure_opts() { _filedir -d; } @@ -363,6 +367,9 @@ _devtools_completions_build_repo() { _devtools_completions_all_packages() { mapfile -t COMPREPLY < <(compgen -W "$(pacman -Sql)" -- "$cur") } +_devtools_completions_protocol() { + mapfile -t COMPREPLY < <(compgen -W "https" -- "$cur") +} __devtools_complete() { local service=$1 diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 240f781..a473bc2 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -108,6 +108,7 @@ _pkgctl_repo_switch_args=( _pkgctl_repo_clone_args=( '(-m --maintainer=)'{-m,--maintainer=}'[Clone all packages of the named maintainer]:maintainer:' + '--protocol[Clone the repository over https]:proto:(https)' '--switch=[Switch the current working tree to a specified version]' '--universe[Clone all existing packages, useful for cache warming]' '(-j --jobs)'{-j,--jobs}'[Run up to N jobs in parallel (default: number of processing units)]:jobs:' @@ -116,6 +117,7 @@ _pkgctl_repo_clone_args=( ) _pkgctl_repo_configure_args=( + '--protocol[Configure remote url to use https]:proto:(https)' '(-j --jobs)'{-j,--jobs}'[Run up to N jobs in parallel (default: number of processing units)]:jobs:' '(-h --help)'{-h,--help}'[Display usage]' '*:git_dir:_files -/' diff --git a/doc/man/pkgctl-repo-clone.1.asciidoc b/doc/man/pkgctl-repo-clone.1.asciidoc index d6da062..421c71f 100644 --- a/doc/man/pkgctl-repo-clone.1.asciidoc +++ b/doc/man/pkgctl-repo-clone.1.asciidoc @@ -25,6 +25,9 @@ Options *-m, --maintainer* 'NAME':: Clone all packages of the named maintainer +*--protocol* 'https':: + Clone the repository over https + *--universe*:: Clone all existing packages, useful for cache warming diff --git a/doc/man/pkgctl-repo-configure.1.asciidoc b/doc/man/pkgctl-repo-configure.1.asciidoc index 1b07dc7..6bdea93 100644 --- a/doc/man/pkgctl-repo-configure.1.asciidoc +++ b/doc/man/pkgctl-repo-configure.1.asciidoc @@ -25,6 +25,9 @@ read-only HTTPS otherwise. Options ------- +*--protocol* 'https':: + Configure remote url to use https + *-j, --jobs* 'N':: Run up to N jobs in parallel. By default the number of jobs is equal to the number of available processing units. For sequential processing this option diff --git a/src/lib/repo/clone.sh b/src/lib/repo/clone.sh index a02d799..08bded4 100644 --- a/src/lib/repo/clone.sh +++ b/src/lib/repo/clone.sh @@ -26,12 +26,13 @@ pkgctl_repo_clone_usage() { 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 + specs and makepkg.conf settings. The protocol 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 + --protocol https Clone the repository over https --switch VERSION Switch the current working tree to a specified version --universe Clone all existing packages, useful for cache warming -j, --jobs N Run up to N jobs in parallel (default: $(nproc)) @@ -69,11 +70,21 @@ pkgctl_repo_clone() { pkgctl_repo_clone_usage exit 0 ;; - -u|--unprivileged) + --protocol=https) GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS} CONFIGURE_OPTIONS+=("$1") shift ;; + --protocol) + (( $# <= 1 )) && die "missing argument for %s" "$1" + if [[ $2 == https ]]; then + GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS} + else + die "unsupported protocol: %s" "$2" + fi + CONFIGURE_OPTIONS+=("$1" "$2") + shift 2 + ;; -m|--maintainer) (( $# <= 1 )) && die "missing argument for %s" "$1" MAINTAINER="$2" diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh index a5708a0..81b7d19 100644 --- a/src/lib/repo/configure.sh +++ b/src/lib/repo/configure.sh @@ -33,6 +33,7 @@ pkgctl_repo_configure_usage() { read-only HTTPS otherwise. OPTIONS + --protocol https Configure remote url to use https -j, --jobs N Run up to N jobs in parallel (default: $(nproc)) -h, --help Show this help text @@ -94,6 +95,7 @@ pkgctl_repo_configure() { local GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS} local official=0 local proto=https + local proto_force=0 local jobs= jobs=$(nproc) local paths=() @@ -109,6 +111,19 @@ pkgctl_repo_configure() { pkgctl_repo_configure_usage exit 0 ;; + --protocol=https) + proto_force=1 + shift + ;; + --protocol) + (( $# <= 1 )) && die "missing argument for %s" "$1" + if [[ $2 == https ]]; then + proto_force=1 + else + die "unsupported protocol: %s" "$2" + fi + shift 2 + ;; -j|--jobs) (( $# <= 1 )) && die "missing argument for %s" "$1" jobs=$2 @@ -152,8 +167,10 @@ pkgctl_repo_configure() { fi if is_packager_email_official "${packager_email}"; then official=1 - proto=ssh - GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} + if (( ! proto_force )); then + proto=ssh + GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} + fi fi fi -- cgit v1.2.3-70-g09d2 From e4c40a980236f22e3d9e7ae292efd09a3a8c7af4 Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Sun, 21 May 2023 00:46:12 +0800 Subject: fix(completion): incorporate repo layout into offload-build completion Use new repo names for build targets. This follows /usr/bin/*-build links other than x86_64_v3 ones. --- src/lib/valid-repos.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/valid-repos.sh b/src/lib/valid-repos.sh index 1f823f4..14f90ce 100644 --- a/src/lib/valid-repos.sh +++ b/src/lib/valid-repos.sh @@ -14,7 +14,8 @@ _repos=( # shellcheck disable=2034 _build_repos=( - extra staging testing + core-staging core-testing + extra extra-staging extra-testing multilib multilib-staging multilib-testing gnome-unstable kde-unstable -- cgit v1.2.3-70-g09d2 From 9b11b16a7e6cdfdff142ff1c5184a760673988d2 Mon Sep 17 00:00:00 2001 From: "Daniel M. Capella" Date: Fri, 26 May 2023 22:41:37 -0400 Subject: chore(doc): remove duplicate subcommand from example help text --- src/lib/repo/configure.sh | 2 +- src/lib/repo/web.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/lib') diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh index 81b7d19..73300ae 100644 --- a/src/lib/repo/configure.sh +++ b/src/lib/repo/configure.sh @@ -38,7 +38,7 @@ pkgctl_repo_configure_usage() { -h, --help Show this help text EXAMPLES - $ ${COMMAND} configure * + $ ${COMMAND} * _EOF_ } diff --git a/src/lib/repo/web.sh b/src/lib/repo/web.sh index 3fa214d..45ea53b 100644 --- a/src/lib/repo/web.sh +++ b/src/lib/repo/web.sh @@ -26,7 +26,7 @@ pkgctl_repo_web_usage() { -h, --help Show this help text EXAMPLES - $ ${COMMAND} web linux + $ ${COMMAND} linux _EOF_ } -- cgit v1.2.3-70-g09d2 From e47035e74d87e2976e1a65e4b2a86476f8cd05ac Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Tue, 23 May 2023 11:48:54 +0200 Subject: chore(build): improve error wording if no package repo could be detected Not being in any official repo does not necessarily mean this is a new package. One could simply be building an AUR or custom local package. Make the message less confusing in such case. --- src/lib/build/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/lib') diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 191fded..3394395 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -298,7 +298,7 @@ pkgctl_build() { die 'failed to get pacman repo' fi if [[ -z "${pkgrepo}" ]]; then - die 'unknown repo, please specify --repo for new packages' + die 'unknown repo, specify --repo for packages not currently in any official repo' fi fi -- cgit v1.2.3-70-g09d2