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.
This commit is contained in:
Levente Polyak 2022-10-10 00:37:51 +02:00
parent a8be7423ef
commit b5d5402e43
No known key found for this signature in database
GPG Key ID: FC1B547C8D8172C8
27 changed files with 618 additions and 406 deletions

View File

@ -1,12 +1,19 @@
SHELL=/bin/bash
V=20230307
BUILDTOOLVER ?= $(V)
PREFIX = /usr/local
MANDIR = $(PREFIX)/share/man
DATADIR = $(PREFIX)/share/devtools
BUILDDIR = build
BINPROGS = $(addprefix $(BUILDDIR)/,$(patsubst src/%,bin/%,$(patsubst %.in,%,$(wildcard src/*.in))))
LIBUTILS = $(wildcard lib/*)
rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))
BINPROGS_SRC = $(wildcard src/*.in)
BINPROGS = $(addprefix $(BUILDDIR)/,$(patsubst src/%,bin/%,$(patsubst %.in,%,$(BINPROGS_SRC))))
LIBRARY_SRC = $(call rwildcard,src/lib,*.sh)
LIBRARY = $(addprefix $(BUILDDIR)/,$(patsubst src/%,%,$(patsubst %.in,%,$(LIBRARY_SRC))))
MAKEPKG_CONFIGS=$(wildcard config/makepkg/*)
PACMAN_CONFIGS=$(wildcard config/pacman/*)
SETARCH_ALIASES = $(wildcard config/setarch-aliases.d/*)
@ -41,8 +48,9 @@ ARCHBUILD_LINKS = \
COMPLETIONS = $(addprefix $(BUILDDIR)/,$(patsubst %.in,%,$(wildcard contrib/completion/*/*)))
all: binprogs completion man
all: binprogs library completion man
binprogs: $(BINPROGS)
library: $(LIBRARY)
completion: $(COMPLETIONS)
man: $(MANS)
@ -61,41 +69,45 @@ ifneq ($(wildcard setarch-aliases.d/*),)
endif
edit = sed -e "s|@pkgdatadir[@]|$(PREFIX)/share/devtools|g"
edit = sed -e "s|@pkgdatadir[@]|$(DATADIR)|g"
GEN_MSG = @echo "GEN $(patsubst $(BUILDDIR)/%,%,$@)"
define buildInScript
$(1)/%: $(2)%.in $(LIBUTILS)
$(1)/%: $(2)%$(3)
$$(GEN_MSG)
@mkdir -p $$(dir $$@)
@$(RM) "$$@"
@{ echo -n 'm4_changequote([[[,]]])'; cat $$<; } | m4 -P --define=m4_devtools_version=$$(BUILDTOOLVER) | $(edit) >$$@
@chmod $(3) "$$@"
@chmod $(4) "$$@"
@bash -O extglob -n "$$@"
endef
$(eval $(call buildInScript,build/bin,src/,555))
$(foreach completion,$(wildcard contrib/completion/*),$(eval $(call buildInScript,build/$(completion),$(completion)/,444)))
$(eval $(call buildInScript,build/bin,src/,.in,755))
$(eval $(call buildInScript,build/lib,src/lib/,,644))
$(foreach completion,$(wildcard contrib/completion/*),$(eval $(call buildInScript,build/$(completion),$(completion)/,.in,444)))
$(BUILDDIR)/doc/man/%: doc/man/%.asciidoc doc/asciidoc.conf doc/man/include/footer.asciidoc
$(GEN_MSG)
@mkdir -p $(BUILDDIR)/doc/man
@a2x --no-xmllint --asciidoc-opts="-f doc/asciidoc.conf" -d manpage -f manpage --destination-dir=$(BUILDDIR)/doc/man -a pkgdatadir=$(PREFIX)/share/devtools $<
@a2x --no-xmllint --asciidoc-opts="-f doc/asciidoc.conf" -d manpage -f manpage --destination-dir=$(BUILDDIR)/doc/man -a pkgdatadir=$(DATADIR) $<
clean:
rm -rf $(BUILDDIR)
install: all
install -dm0755 $(DESTDIR)$(PREFIX)/bin
install -dm0755 $(DESTDIR)$(PREFIX)/share/devtools/setarch-aliases.d
install -dm0755 $(DESTDIR)$(DATADIR)/setarch-aliases.d
install -m0755 ${BINPROGS} $(DESTDIR)$(PREFIX)/bin
for conf in ${MAKEPKG_CONFIGS}; do install -Dm0644 $$conf $(DESTDIR)$(PREFIX)/share/devtools/makepkg-$${conf##*/}; done
for conf in ${PACMAN_CONFIGS}; do install -Dm0644 $$conf $(DESTDIR)$(PREFIX)/share/devtools/pacman-$${conf##*/}; done
for a in ${SETARCH_ALIASES}; do install -m0644 $$a -t $(DESTDIR)$(PREFIX)/share/devtools/setarch-aliases.d; done
install -dm0755 $(DESTDIR)$(DATADIR)/lib
cp -ra $(BUILDDIR)/lib/* $(DESTDIR)$(DATADIR)/lib
for conf in ${MAKEPKG_CONFIGS}; do install -Dm0644 $$conf $(DESTDIR)$(DATADIR)/makepkg-$${conf##*/}; done
for conf in ${PACMAN_CONFIGS}; do install -Dm0644 $$conf $(DESTDIR)$(DATADIR)/pacman-$${conf##*/}; done
for a in ${SETARCH_ALIASES}; do install -m0644 $$a -t $(DESTDIR)$(DATADIR)/setarch-aliases.d; done
for l in ${COMMITPKG_LINKS}; do ln -sf commitpkg $(DESTDIR)$(PREFIX)/bin/$$l; done
for l in ${ARCHBUILD_LINKS}; do ln -sf archbuild $(DESTDIR)$(PREFIX)/bin/$$l; done
ln -sf find-libdeps $(DESTDIR)$(PREFIX)/bin/find-libprovides
install -Dm0644 $(BUILDDIR)/contrib/completion/bash/devtools $(DESTDIR)$(PREFIX)/share/bash-completion/completions/devtools
for f in $(notdir $(BINPROGS)); do ln -sf devtools $(DESTDIR)$(PREFIX)/share/bash-completion/completions/$$f; done
install -Dm0644 $(BUILDDIR)/contrib/completion/zsh/_devtools $(DESTDIR)$(PREFIX)/share/zsh/site-functions/_devtools
for manfile in $(MANS); do \
install -Dm644 $$manfile -t $(DESTDIR)$(MANDIR)/man$${manfile##*.}; \
@ -103,16 +115,21 @@ install: all
uninstall:
for f in $(notdir $(BINPROGS)); do rm -f $(DESTDIR)$(PREFIX)/bin/$$f; done
for conf in ${MAKEPKG_CONFIGS}; do rm -f $(DESTDIR)$(PREFIX)/share/devtools/makepkg-$${conf##*/}; done
for conf in ${PACMAN_CONFIGS}; do rm -f $(DESTDIR)$(PREFIX)/share/devtools/pacman-$${conf##*/}; done
for f in $(notdir $(SETARCH_ALIASES)); do rm -f $(DESTDIR)$(PREFIX)/share/devtools/setarch-aliases.d/$$f; done
for f in $(notdir $(LIBRARY)); do rm -f $(DESTDIR)$(DATADIR)/lib/$$f; done
rm -rf $(DESTDIR)$(DATADIR)/lib
for conf in ${MAKEPKG_CONFIGS}; do rm -f $(DESTDIR)$(DATADIR)/makepkg-$${conf##*/}; done
for conf in ${PACMAN_CONFIGS}; do rm -f $(DESTDIR)$(DATADIR)/pacman-$${conf##*/}; done
for f in $(notdir $(SETARCH_ALIASES)); do rm -f $(DESTDIR)$(DATADIR)/setarch-aliases.d/$$f; done
for l in ${COMMITPKG_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$l; done
for l in ${ARCHBUILD_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$l; done
rm $(DESTDIR)$(PREFIX)/share/bash-completion/completions/devtools
rm $(DESTDIR)$(PREFIX)/share/zsh/site-functions/_devtools
rm -f $(DESTDIR)$(PREFIX)/share/bash-completion/completions/devtools
for f in $(notdir $(BINPROGS)); do rm -f $(DESTDIR)$(PREFIX)/share/bash-completion/completions/$$f; done
rm -f $(DESTDIR)$(PREFIX)/share/zsh/site-functions/_devtools
rm -f $(DESTDIR)$(PREFIX)/bin/find-libprovides
for manfile in $(notdir $(MANS)); do rm -f $(DESTDIR)$(MANDIR)/man$${manfile##*.}/$${manfile}; done;
rmdir --ignore-fail-on-non-empty $(DESTDIR)$(PREFIX)/share/devtools/setarch-aliases.d $(DESTDIR)$(PREFIX)/share/devtools
rmdir --ignore-fail-on-non-empty \
$(DESTDIR)$(DATADIR)/setarch-aliases.d \
$(DESTDIR)$(DATADIR)
TODAY=$(shell date +"%Y%m%d")
tag:
@ -127,8 +144,8 @@ dist:
upload:
scp devtools-$(V).tar.gz devtools-$(V).tar.gz.sig repos.archlinux.org:/srv/ftp/other/devtools/
check: $(BINPROGS) $(BUILDDIR)/contrib/completion/bash/devtools config/makepkg/x86_64.conf contrib/makepkg/PKGBUILD.proto
check: $(BINPROGS_SRC) $(LIBRARY_SRC) contrib/completion/bash/devtools.in config/makepkg/x86_64.conf contrib/makepkg/PKGBUILD.proto
shellcheck $^
.PHONY: all completion man clean install uninstall dist upload check tag
.PHONY: all binprogs library completion man clean install uninstall tag dist upload check
.DELETE_ON_ERROR:

View File

@ -1,9 +1,12 @@
#compdef archbuild pkgrepo arch-nspawn archrelease commitpkg pkgctl diffpkg finddeps makechrootpkg mkarchroot rebuildpkgs extrapkg=commitpkg corepkg=commitpkg testingpkg=commitpkg stagingpkg=commitpkg communitypkg=commitpkg community-testingpkg=commitpkg community-stagingpkg=commitpkg multilibpkg=commitpkg multilib-testingpkg=commitpkg extra-x86_64-build=archbuild testing-x86_64-build=archbuild staging-x86_64-build=archbuild multilib-build=archbuild multilib-testing-build=archbuild multilib-staging-build=archbuild kde-unstable-x86_64-build=archbuild gnome-unstable-x86_64-build=archbuild checkpkg sogrep offload-build makerepropkg
#compdef archbuild arch-nspawn archrelease commitpkg pkgctl diffpkg finddeps makechrootpkg mkarchroot rebuildpkgs extrapkg=commitpkg corepkg=commitpkg testingpkg=commitpkg stagingpkg=commitpkg communitypkg=commitpkg community-testingpkg=commitpkg community-stagingpkg=commitpkg multilibpkg=commitpkg multilib-testingpkg=commitpkg extra-x86_64-build=archbuild testing-x86_64-build=archbuild staging-x86_64-build=archbuild multilib-build=archbuild multilib-testing-build=archbuild multilib-staging-build=archbuild kde-unstable-x86_64-build=archbuild gnome-unstable-x86_64-build=archbuild checkpkg sogrep offload-build makerepropkg
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/valid-tags.sh)
m4_include(lib/valid-repos.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/valid-tags.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh
# shellcheck source=src/lib/valid-repos.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh
_binary_arch=${_arch[*]:0:-1}
_colors=(never always auto)
@ -15,14 +18,14 @@ _archbuild_args=(
'--[Introduce makechrootpkg options]:*::makechrootpkg options:= _dispatch makechrootpkg makechrootpkg'
)
_pkgrepo_cmds=(
"pkgrepo command"
_pkgctl_repo_cmds=(
"pkgctl repo command"
"clone[Clone a package repository]"
"configure[Configure a clone according to distro specs]"
"web[Open the packaging repository's website]"
)
_pkgrepo_clone_args=(
_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]'
@ -30,13 +33,13 @@ _pkgrepo_clone_args=(
'*:packages:_devtools_completions_all_packages'
)
_pkgrepo_configure_args=(
_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 -/'
)
_pkgrepo_web_args=(
_pkgctl_repo_web_args=(
'(-h --help)'{-h,--help}'[Display usage]'
'*:git_dir:_files -/'
)
@ -157,10 +160,6 @@ _pkgctl_cmds=(
_pkgctl_diff_args=("${_diffpkg_args[@]}")
_pkgctl_repo_cmds=("${_pkgrepo_cmds[@]}")
_pkgctl_repo_clone_args=("${_pkgrepo_clone_args[@]}")
_pkgctl_repo_configure_args=("${_pkgrepo_configure_args[@]}")
_handle_subcommands() {
local service_name=${1}
if typeset -p ${service_name}_cmds &> /dev/null; then

View File

@ -2,8 +2,12 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
m4_include(lib/archroot.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
# shellcheck source=src/lib/archroot.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/archroot.sh
# umask might have been changed in /etc/profile
# ensure that sane default is set again

View File

@ -2,8 +2,12 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
m4_include(lib/archroot.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
# shellcheck source=src/lib/archroot.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/archroot.sh
base_packages=(base-devel)
makechrootpkg_args=(-c -n -C)

View File

@ -2,8 +2,12 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
m4_include(lib/valid-tags.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
# shellcheck source=src/lib/valid-tags.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh
# parse command line options
FORCE=

View File

@ -2,7 +2,10 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
usage() {
cat <<- _EOF_

View File

@ -2,7 +2,12 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
_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/util.sh
check_pkgbuild_validity() {
# shellcheck source=contrib/makepkg/PKGBUILD.proto

View File

@ -2,7 +2,10 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
usage() {
local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}

View File

@ -2,7 +2,10 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
usage() {
cat <<- _EOF_
@ -35,7 +38,7 @@ if [[ ! -f PKGBUILD ]]; then
fi
mapfile -t validpgpkeys < <(
# shellcheck source=PKGBUILD.proto
# shellcheck source=contrib/makepkg/PKGBUILD.proto
. ./PKGBUILD
if (( ${#validpgpkeys[@]} )); then
printf "%s\n" "${validpgpkeys[@]}"

View File

@ -2,7 +2,10 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
set -e

View File

@ -4,7 +4,10 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
match=$1

View File

@ -4,7 +4,10 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
ifs=$IFS
IFS="${IFS}:"

View File

@ -4,13 +4,13 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
[[ -z ${_INCLUDE_COMMON_SH:-} ]] || return 0
_INCLUDE_COMMON_SH="$(set +o|grep nounset)"
[[ -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
$_INCLUDE_COMMON_SH
$DEVTOOLS_INCLUDE_COMMON_SH
# Avoid any encoding problems
export LANG=C

90
src/lib/repo.sh Normal file
View File

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

139
src/lib/repo/clone.sh Normal file
View File

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

169
src/lib/repo/configure.sh Normal file
View File

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

84
src/lib/repo/web.sh Normal file
View File

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

View File

@ -2,8 +2,13 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
m4_include(lib/archroot.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
# shellcheck source=src/lib/archroot.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/archroot.sh
source /usr/share/makepkg/util/config.sh

View File

@ -6,8 +6,12 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
m4_include(lib/archroot.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
# shellcheck source=src/lib/archroot.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/archroot.sh
source /usr/share/makepkg/util/config.sh
source /usr/share/makepkg/util/message.sh

View File

@ -2,8 +2,12 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
m4_include(lib/archroot.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
# shellcheck source=src/lib/archroot.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/archroot.sh
# umask might have been changed in /etc/profile
# ensure that sane default is set again

View File

@ -2,7 +2,9 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
set -e
@ -40,7 +42,9 @@ while (( $# )); do
repo)
_DEVTOOLS_COMMAND+=" $1"
shift
pkgrepo "$@"
# shellcheck source=src/lib/repo.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo.sh
pkgctl_repo "$@"
exit 0
;;
diff)

View File

@ -1,345 +0,0 @@
#!/bin/bash
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
source /usr/share/makepkg/util/config.sh
source /usr/share/makepkg/util/message.sh
set -e
COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
usage() {
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 Opens the packaging repository's website
OPTIONS
-h, --help Show this help text
_EOF_
}
usage_clone() {
cat <<- _EOF_
Usage: ${COMMAND} clone [OPTIONS] [PKGNAME...]
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
_EOF_
}
usage_configure() {
cat <<- _EOF_
Usage: ${COMMAND} configure [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
_EOF_
}
usage_web() {
cat <<- _EOF_
Usage: ${COMMAND} web [PKGNAME...]
Opens 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
_EOF_
}
if (( $# < 1 )); then
usage
exit 1
fi
# commands
CLONE=0
CONFIGURE=0
# options
GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH}
UNPRIVILEGED=0
CLONE_ALL=0
MAINTAINER=
PACKAGER_NAME=
PACKAGER_EMAIL=
# command checking
while (( $# )); do
case $1 in
-h|--help)
usage
exit 0
;;
clone)
CLONE=1
CONFIGURE=1
shift
break
;;
configure)
CONFIGURE=1
shift
break
;;
web)
WEB=1
shift
break
;;
*)
die "invalid argument: %s" "$1"
;;
esac
done
if (( CLONE )); then
# option checking
if (( $# < 1 )); then
usage_clone
exit 1
fi
while (( $# )); do
case $1 in
-h|--help)
usage_clone
exit 0
;;
-u|--unprivileged)
GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS}
UNPRIVILEGED=1
shift
;;
-m|--maintainer)
(( $# <= 1 )) && die "missing argument for %s" "$1"
MAINTAINER="$2"
shift 2
;;
--maintainer=*)
MAINTAINER="${1#*=}"
shift
;;
--all)
CLONE_ALL=1
shift
;;
--)
shift
break
;;
-*)
die "invalid argument: %s" "$1"
;;
*)
break
;;
esac
done
elif (( CONFIGURE )); then
# option checking
if (( $# < 1 )); then
usage_configure
exit 1
fi
while (( $# )); do
case $1 in
-h|--help)
usage_configure
exit 0
;;
-u|--unprivileged)
GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS}
UNPRIVILEGED=1
shift
;;
--)
shift
break
;;
-*)
die "invalid argument: %s" "$1"
;;
*)
break
;;
esac
done
elif (( WEB )); then
# option checking
while (( $# )); do
case $1 in
-h|--help)
usage_web
exit 0
;;
--)
shift
break
;;
-*)
die "invalid argument: %s" "$1"
;;
*)
break
;;
esac
done
fi
pkgbases=("$@")
# Load makepkg.conf variables to be available
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
# Query packages of a maintainer
if [[ -n ${MAINTAINER} ]]; then
stat_busy "Query packages for ${MAINTAINER}"
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')
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')
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
# Check web mode requirements and current directory shorthand
if (( WEB )); then
# 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
fi
for pkgbase in "${pkgbases[@]}"; do
if (( CLONE )); then
if [[ ! -d ${pkgbase} ]]; then
msg "Cloning ${pkgbase} ..."
remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git"
git clone --origin origin "${remote_url}"
else
warning "Skip cloning ${pkgbase}: Directory exists"
fi
fi
if (( CONFIGURE )); then
msg "Configuring $(basename "${pkgbase}") ..."
path=${pkgbase}
if [[ ! -d "${path}/.git" ]]; then
error "Not a Git repository: ${path}"
continue
fi
giturl=$(git -C "${path}" remote get-url origin)
if [[ ${giturl} != *${GIT_PACKAGING_NAMESPACE}* ]]; then
error "Not a packaging repository: ${path}"
continue
fi
pkgbase=$(basename "${giturl}")
pkgbase=${pkgbase%.git}
remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git"
git -C "${path}" remote set-url origin "${remote_url}"
git -C "${path}" config devtools.version "${GIT_REPO_SPEC_VERSION}"
git -C "${path}" config commit.gpgsign true
git -C "${path}" config pull.rebase true
git -C "${path}" config branch.main.rebase true
if (( ! UNPRIVILEGED )); then
git -C "${path}" config user.name "${PACKAGER_NAME}"
git -C "${path}" config user.email "${PACKAGER_EMAIL}"
if [[ -n $GPGKEY ]]; then
git -C "${path}" config user.signingKey "${GPGKEY}"
fi
fi
fi
if (( WEB )); then
xdg-open "${GIT_PACKAGING_URL_HTTPS}/${pkgbase}"
fi
done

View File

@ -12,7 +12,10 @@
# Currently uses $(pwd)/rebuilds as the directory for rebuilding...
# TODO make this work for community too
m4_include(lib/common.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
if (( $# < 1 )); then
printf 'Usage: %s <chrootdir> <packages to rebuild>\n' "$(basename "${BASH_SOURCE[0]}")"

View File

@ -6,13 +6,17 @@
#
# SPDX-License-Identifier: GPL-3.0-or-later
m4_include(lib/common.sh)
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
# shellcheck source=src/lib/common.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
# shellcheck source=src/lib/valid-repos.sh
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh
# globals
fallback_mirror='https://geo.mirror.pkgbuild.com'
: ${SOCACHE_DIR:="${XDG_CACHE_HOME:-${HOME}/.cache}/sogrep"}
m4_include(lib/valid-repos.sh)
arches=('x86_64')
# options