200 lines
5.5 KiB
Bash
200 lines
5.5 KiB
Bash
#!/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 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))
|
|
-h, --help Show this help text
|
|
|
|
EXAMPLES
|
|
$ ${COMMAND} libfoo linux libbar
|
|
$ ${COMMAND} --maintainer mynickname
|
|
$ ${COMMAND} --switch 1:1.0-2 libfoo
|
|
_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 VERSION=
|
|
local CONFIGURE_OPTIONS=()
|
|
local jobs=
|
|
jobs=$(nproc)
|
|
|
|
# variables
|
|
local command=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
|
|
local project_path
|
|
|
|
while (( $# )); do
|
|
case $1 in
|
|
-h|--help)
|
|
pkgctl_repo_clone_usage
|
|
exit 0
|
|
;;
|
|
--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"
|
|
shift 2
|
|
;;
|
|
--maintainer=*)
|
|
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
|
|
;;
|
|
-j|--jobs)
|
|
(( $# <= 1 )) && die "missing argument for %s" "$1"
|
|
jobs=$2
|
|
shift 2
|
|
;;
|
|
--)
|
|
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
|
|
|
|
# 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"
|
|
if ! git clone --origin origin "${remote_url}" "${pkgbase}"; then
|
|
die 'failed to clone %s' "${pkgbase}"
|
|
fi
|
|
else
|
|
warning "Skip cloning ${pkgbase}: Directory exists"
|
|
fi
|
|
|
|
pkgctl_repo_configure "${CONFIGURE_OPTIONS[@]}" "${pkgbase}"
|
|
|
|
if [[ -n "${VERSION}" ]]; then
|
|
pkgctl_repo_switch "${VERSION}" "${pkgbase}"
|
|
fi
|
|
done
|
|
}
|