From a8be7423efb287edd5ef80002a75a853fc0c9c1d Mon Sep 17 00:00:00 2001
From: Levente Polyak <anthraxx@archlinux.org>
Date: Mon, 12 Sep 2022 01:34:08 +0200
Subject: pkgctl: add a unified command-line frontend for devtools

This is the first step of a simple and highly structured unified
interface to devtools commands in a single wrapper.

The split is based on groups like `repo`, `build` and `diff`

Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
---
 doc/man/pkgctl-repo-clone.1.asciidoc | 42 ++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)
 create mode 100644 doc/man/pkgctl-repo-clone.1.asciidoc

(limited to 'doc/man/pkgctl-repo-clone.1.asciidoc')

diff --git a/doc/man/pkgctl-repo-clone.1.asciidoc b/doc/man/pkgctl-repo-clone.1.asciidoc
new file mode 100644
index 0000000..9770ef8
--- /dev/null
+++ b/doc/man/pkgctl-repo-clone.1.asciidoc
@@ -0,0 +1,42 @@
+pkgctl-repo-clone(1)
+======================
+
+Name
+----
+pkgctl-repo-clone - Clone a package repository
+
+Synopsis
+--------
+pkgctl repo clone [OPTIONS] [PKGNAME...]
+
+Description
+-----------
+
+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 a help text
+
+See Also
+--------
+
+linkman:pkgctl-repo-configure[1]
+
+include::include/footer.asciidoc[]
-- 
cgit v1.2.3-70-g09d2


From f669a71e847da88fefc1296dd2dd9ba82549a8c6 Mon Sep 17 00:00:00 2001
From: Levente Polyak <anthraxx@archlinux.org>
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 <anthraxx@archlinux.org>
---
 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 'doc/man/pkgctl-repo-clone.1.asciidoc')

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 8e3b6bcc5b82b270f8d310865f14f2b0405eddd7 Mon Sep 17 00:00:00 2001
From: Christian Heusel <christian@heusel.eu>
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 <christian@heusel.eu>
Signed-off-by: Levente Polyak <anthraxx@archlinux.org>
---
 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 'doc/man/pkgctl-repo-clone.1.asciidoc')

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 1da97a8b362addc1cf8b936d918bddfa92192aa6 Mon Sep 17 00:00:00 2001
From: Caleb Maclennan <caleb@alerque.com>
Date: Thu, 18 May 2023 09:57:50 +0300
Subject: doc: Fixup formatting issues in asciidoc man pages

---
 doc/man/diffpkg.1.asciidoc            | 2 +-
 doc/man/makerepropkg.1.asciidoc       | 2 +-
 doc/man/mkarchroot.1.asciidoc         | 2 +-
 doc/man/pkgctl-repo-clone.1.asciidoc  | 2 +-
 doc/man/pkgctl-repo-create.1.asciidoc | 2 +-
 doc/man/pkgctl-repo.1.asciidoc        | 2 +-
 6 files changed, 6 insertions(+), 6 deletions(-)

(limited to 'doc/man/pkgctl-repo-clone.1.asciidoc')

diff --git a/doc/man/diffpkg.1.asciidoc b/doc/man/diffpkg.1.asciidoc
index 2f7c115..35b2ded 100644
--- a/doc/man/diffpkg.1.asciidoc
+++ b/doc/man/diffpkg.1.asciidoc
@@ -1,5 +1,5 @@
 diffpkg(1)
-===========
+==========
 
 Name
 ----
diff --git a/doc/man/makerepropkg.1.asciidoc b/doc/man/makerepropkg.1.asciidoc
index 4e694b3..6044d7c 100644
--- a/doc/man/makerepropkg.1.asciidoc
+++ b/doc/man/makerepropkg.1.asciidoc
@@ -1,5 +1,5 @@
 makerepropkg(1)
-================
+===============
 
 Name
 ----
diff --git a/doc/man/mkarchroot.1.asciidoc b/doc/man/mkarchroot.1.asciidoc
index 7930c4c..a435852 100644
--- a/doc/man/mkarchroot.1.asciidoc
+++ b/doc/man/mkarchroot.1.asciidoc
@@ -1,5 +1,5 @@
 mkarchroot(1)
-==============
+=============
 
 Name
 ----
diff --git a/doc/man/pkgctl-repo-clone.1.asciidoc b/doc/man/pkgctl-repo-clone.1.asciidoc
index 8f3aef7..487ec35 100644
--- a/doc/man/pkgctl-repo-clone.1.asciidoc
+++ b/doc/man/pkgctl-repo-clone.1.asciidoc
@@ -1,5 +1,5 @@
 pkgctl-repo-clone(1)
-======================
+====================
 
 Name
 ----
diff --git a/doc/man/pkgctl-repo-create.1.asciidoc b/doc/man/pkgctl-repo-create.1.asciidoc
index b9d980b..7c58776 100644
--- a/doc/man/pkgctl-repo-create.1.asciidoc
+++ b/doc/man/pkgctl-repo-create.1.asciidoc
@@ -1,5 +1,5 @@
 pkgctl-repo-create(1)
-======================
+=====================
 
 Name
 ----
diff --git a/doc/man/pkgctl-repo.1.asciidoc b/doc/man/pkgctl-repo.1.asciidoc
index 713b474..57be170 100644
--- a/doc/man/pkgctl-repo.1.asciidoc
+++ b/doc/man/pkgctl-repo.1.asciidoc
@@ -1,5 +1,5 @@
 pkgctl-repo(1)
-================
+==============
 
 Name
 ----
-- 
cgit v1.2.3-70-g09d2


From 6ce666a1669235749c17d5c44d8a24dea4a135da Mon Sep 17 00:00:00 2001
From: Levente Polyak <anthraxx@archlinux.org>
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 <anthraxx@archlinux.org>
---
 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 'doc/man/pkgctl-repo-clone.1.asciidoc')

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 <anthraxx@archlinux.org>
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 <anthraxx@archlinux.org>
---
 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 'doc/man/pkgctl-repo-clone.1.asciidoc')

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

