summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Heusel <christian@heusel.eu>2023-04-15 19:44:22 +0200
committerLevente Polyak <anthraxx@archlinux.org>2023-05-20 00:08:13 +0200
commited966351410b39bfcec749df59dbc434a5dade1e (patch)
treee32d30d3bc2f14d5bc2b3b19b71491034a228a3a
parentf961e2e94803dd46c4fa5941eb15a7d4612bd0f0 (diff)
downloaddevtools-ed966351410b39bfcec749df59dbc434a5dade1e.tar.xz
pkgctl repo: introduce the switch subcommand
Signed-off-by: Christian Heusel <christian@heusel.eu> Co-Authored-By: Levente Polyak <anthraxx@archlinux.org>
-rw-r--r--contrib/completion/bash/devtools.in19
-rw-r--r--contrib/completion/zsh/_devtools.in8
-rw-r--r--doc/man/pkgctl-repo-switch.1.asciidoc36
-rw-r--r--doc/man/pkgctl-repo.1.asciidoc4
-rw-r--r--src/lib/repo.sh10
-rw-r--r--src/lib/repo/switch.sh119
6 files changed, 196 insertions, 0 deletions
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
+}