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 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