From ea782a8ab7f2e227415d48b933bae87ad9a471ea Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Tue, 3 Jan 2023 23:16:28 +0100 Subject: makepkg.conf: enable rust debuginfo This enables DEBUG_RUSTFLAGS with the appropriate debuginfo settings. The empty RUSTFLAGS variable is required workaround to avoid double compilation during package function call. The issue is that the behavior of the current implementation of buildenv_debugflags is not idempotent, so consecutive calls will append the same flags again leading to cargo consider the build inputs to have changed. Signed-off-by: Levente Polyak --- config/makepkg/x86_64.conf | 4 ++-- config/makepkg/x86_64_v3.conf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/makepkg/x86_64.conf b/config/makepkg/x86_64.conf index 43215af..41fd6b0 100644 --- a/config/makepkg/x86_64.conf +++ b/config/makepkg/x86_64.conf @@ -46,13 +46,13 @@ CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions \ CXXFLAGS="$CFLAGS -Wp,-D_GLIBCXX_ASSERTIONS" LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now" LTOFLAGS="-flto=auto" -#RUSTFLAGS="-C opt-level=2" +RUSTFLAGS="" #-- Make Flags: change this for DistCC/SMP systems #MAKEFLAGS="-j2" #-- Debugging flags DEBUG_CFLAGS="-g" DEBUG_CXXFLAGS="$DEBUG_CFLAGS" -#DEBUG_RUSTFLAGS="-C debuginfo=2" +DEBUG_RUSTFLAGS="-C debuginfo=2" ######################################################################### # BUILD ENVIRONMENT diff --git a/config/makepkg/x86_64_v3.conf b/config/makepkg/x86_64_v3.conf index d9405d8..3c9d20d 100644 --- a/config/makepkg/x86_64_v3.conf +++ b/config/makepkg/x86_64_v3.conf @@ -46,13 +46,13 @@ CFLAGS="-march=x86-64-v3 -mtune=generic -O2 -pipe -fno-plt -fexceptions \ CXXFLAGS="$CFLAGS -Wp,-D_GLIBCXX_ASSERTIONS" LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now" LTOFLAGS="-flto=auto" -#RUSTFLAGS="-C opt-level=2" +RUSTFLAGS="" #-- Make Flags: change this for DistCC/SMP systems #MAKEFLAGS="-j2" #-- Debugging flags DEBUG_CFLAGS="-g" DEBUG_CXXFLAGS="$DEBUG_CFLAGS" -#DEBUG_RUSTFLAGS="-C debuginfo=2" +DEBUG_RUSTFLAGS="-C debuginfo=2" ######################################################################### # BUILD ENVIRONMENT -- cgit v1.2.3-70-g09d2 From f870ab6864bedcf9e5af137214aa9bc726b8299c Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 5 Jan 2023 16:20:42 +0100 Subject: Version 20230105 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9b4e6ba..14ced32 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -V=20221012 +V=20230105 BUILDTOOLVER ?= $(V) PREFIX = /usr/local -- cgit v1.2.3-70-g09d2 From 112026580d21c35b505de2378f21580d274e898f Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Wed, 2 Nov 2022 00:44:50 +0000 Subject: makechrootpkg: make /tmp inside nspawn larger systemd by default limits the /tmp folder to be 10% of the host memory: https://github.com/systemd/systemd/blob/6f2cea06bfce6ad99f0ac37ab12af61ef7549fe3/src/shared/mount-util.h#L33 This is problematic to our builds because many toolchains opt to put build artifacts in /tmp, and expecting the host memory to be 10 times larger is not optimal or even realistic sometimes. This MR attempts to enlarge it to 50% memory as the host machine's default value of /tmp. This should be a fair compromise between being overly conservative and taking up too much memory to crash the system. --- src/makechrootpkg.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/makechrootpkg.in b/src/makechrootpkg.in index 895c1de..5d3eaae 100644 --- a/src/makechrootpkg.in +++ b/src/makechrootpkg.in @@ -24,6 +24,7 @@ clean_first=0 run_namcap=0 run_checkpkg=0 temp_chroot=0 +tmp_opts="nosuid,nodev,size=50%,nr_inodes=2m" bindmounts_ro=() bindmounts_rw=() @@ -365,6 +366,7 @@ prepare_chroot if arch-nspawn "$copydir" \ --bind="${PWD//:/\\:}:/startdir" \ --bind="${SRCDEST//:/\\:}:/srcdest" \ + --tmpfs="/tmp:${tmp_opts}" \ "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \ /chrootbuild "${makepkg_args[@]}" then -- cgit v1.2.3-70-g09d2 From 009c58f7c94b5f63aa41a0a82cd23ee7712f05a9 Mon Sep 17 00:00:00 2001 From: Celeste Liu Date: Thu, 13 Oct 2022 18:07:18 +0800 Subject: archbuild: add architecture-specific mount config config path: @pkgdatadir@/mount.d/${arch} config format: Each line will start with 'ro' and 'rw' will be used, other lines will be ignore, rest of line is out/path:in/path. e.g. ``` ro /some/path:/proc/cpuinfo rw /some/some/path:/var/cache/pacman/pkg ``` For example, in the RISC-V port, if we use qemu-user to build, we need to pass a parameter to makechrootpkg to map a correct /proc/cpuinfo, so that software that relies on /proc/cpuinfo to obtain information can be built normally. Signed-off-by: Celeste Liu --- src/archbuild.in | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/archbuild.in b/src/archbuild.in index e6cf19a..ba3ba94 100644 --- a/src/archbuild.in +++ b/src/archbuild.in @@ -23,6 +23,22 @@ if [[ -f "@pkgdatadir@/setarch-aliases.d/${arch}" ]]; then else set_arch="${arch}" fi + +# Architecture-specific Mount +arch_mounts=() +if [[ -f "@pkgdatadir@/mount.d/${arch}" ]]; then + mapfile -t arch_mounts < "@pkgdatadir@/mount.d/${arch}" +fi +for arch_mount in "${arch_mounts[@]}"; do + if [[ $arch_mount = rw* ]]; then + arch_mount=${arch_mount#rw } + in_array "$arch_mount" "${makechrootpkg_args[@]}" || makechrootpkg_args+=("-d" "$arch_mount") + elif [[ $arch_mount = ro* ]]; then + arch_mount=${arch_mount#ro } + in_array "$arch_mount" "${makechrootpkg_args[@]}" || makechrootpkg_args+=("-D" "$arch_mount") + fi +done + chroots='/var/lib/archbuild' clean_first=false -- cgit v1.2.3-70-g09d2 From d45e77738bda2d17b10f87d05167a12fa5be8d63 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 12 Jan 2023 21:33:00 +0100 Subject: commitpkg: properly cleanup commit msg file on abort Use the workdir location which gets cleaned up automatically. Previously this was leaking tmpfiles if the commitpkg command got aborted after file creation. Signed-off-by: Levente Polyak --- src/commitpkg.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/commitpkg.in b/src/commitpkg.in index 235d12b..2f0ea1f 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -132,7 +132,8 @@ if [[ -n $(svn status -q) ]]; then svn commit -q -m "${msgtemplate}: ${1}" || die stat_done else - msgfile="$(mktemp)" + [[ -z ${WORKDIR:-} ]] && setup_workdir + msgfile=$(mktemp --tmpdir="${WORKDIR}" commitpkg.XXXXXXXXXX) echo "$msgtemplate" > "$msgfile" if [[ -n $SVN_EDITOR ]]; then $SVN_EDITOR "$msgfile" -- cgit v1.2.3-70-g09d2 From 7b209b63a785c7375c360209ca5efe0c46a75c7a Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 12 Jan 2023 22:19:08 +0100 Subject: commitpkg: abort execution if msg file editor exits none-successfully Previously the script execution did not abort if the msg file editor exited none-successfully leading to undesired commits with a potentially unfinished message. Instead abort the commit if the msg file editor is deliberately terminated with a failure code. Signed-off-by: Levente Polyak --- src/commitpkg.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commitpkg.in b/src/commitpkg.in index 2f0ea1f..ef30544 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -136,13 +136,13 @@ if [[ -n $(svn status -q) ]]; then msgfile=$(mktemp --tmpdir="${WORKDIR}" commitpkg.XXXXXXXXXX) echo "$msgtemplate" > "$msgfile" if [[ -n $SVN_EDITOR ]]; then - $SVN_EDITOR "$msgfile" + $SVN_EDITOR "$msgfile" || die elif [[ -n $VISUAL ]]; then - $VISUAL "$msgfile" + $VISUAL "$msgfile" || die elif [[ -n $EDITOR ]]; then - $EDITOR "$msgfile" + $EDITOR "$msgfile" || die else - vi "$msgfile" + vi "$msgfile" || die fi [[ -s $msgfile ]] || die stat_busy 'Committing changes to trunk' -- cgit v1.2.3-70-g09d2 From 320c1fd0ace54dfcf94a34f1009bf597963c3ea5 Mon Sep 17 00:00:00 2001 From: Evangelos Foutras Date: Wed, 15 Feb 2023 22:48:43 +0200 Subject: mkarchroot: stop adding C.UTF-8 to locale.gen Adding such an entry is problematic as it results in locale -a showing: C C.UTF-8 C.utf8 POSIX (other locales) In the above, C.UTF-8 is built-in whereas C.utf8 comes from locale.gen. The duplicate locale has the potential to expose undesired behavior in upstream software: https://github.com/sudo-project/sudo/issues/241 --- src/mkarchroot.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mkarchroot.in b/src/mkarchroot.in index 45ad19c..ff3426e 100644 --- a/src/mkarchroot.in +++ b/src/mkarchroot.in @@ -84,7 +84,7 @@ done unshare --mount pacstrap -${umode}Mc ${pac_conf:+-C "$pac_conf"} "$working_dir" \ "${cache_dirs[@]/#/--cachedir=}" "$@" || die 'Failed to install all packages' -printf '%s.UTF-8 UTF-8\n' C en_US de_DE > "$working_dir/etc/locale.gen" +printf '%s.UTF-8 UTF-8\n' en_US de_DE > "$working_dir/etc/locale.gen" echo 'LANG=C.UTF-8' > "$working_dir/etc/locale.conf" echo "$CHROOT_VERSION" > "$working_dir/.arch-chroot" -- cgit v1.2.3-70-g09d2 From 4ff7aa0d8a8c88a6d1d02fa8462fa59c24a97422 Mon Sep 17 00:00:00 2001 From: Celeste Liu Date: Wed, 11 Jan 2023 16:27:11 +0800 Subject: archbuild: add doc for bind mount config Signed-off-by: Celeste Liu --- doc/man/archbuild.1.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/man/archbuild.1.asciidoc b/doc/man/archbuild.1.asciidoc index 6b00572..777e3f2 100644 --- a/doc/man/archbuild.1.asciidoc +++ b/doc/man/archbuild.1.asciidoc @@ -25,6 +25,7 @@ Description The symlink used to run it will be inspected by archbuild, to determine which target you want it to use. It will load the available pacman configuration from 'pacman-reponame-arch.conf' with a fallback to 'pacman-reponame.conf' from {pkgdatadir}. The makepkg configuration is loaded from 'makepkg-repo-arch.conf' with a fallback to 'makepkg-reponame.conf' from {pkgdatadir}. +It will also load the bind mount configuration from 'mount.d/arch' in {pkgdatadir}. The file format is that each line starting with ro and rw will be used, other lines will be ignored, and the rest of the used line is out/path:in/path preceded by a space as a separator. ro means it is a read-only mount, rw means a read-write mount. Options ------- -- cgit v1.2.3-70-g09d2 From 0365edb264c08b6520c8b57fadbff55967e1e948 Mon Sep 17 00:00:00 2001 From: Tobias Powalowski Date: Tue, 31 Jan 2023 09:43:15 +0100 Subject: fix: enable extglob before func definition for bash-5.2 compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `extglob` option changes the behavior of the shell parser, since extended glob patterns would otherwise be syntax errors. bash-5.2 changed the way a function definition is processed by calling the parser instead of relying on the ad-hoc code in bash-5.1 and earlier versions. This means, in bash-5.2 the shell function was parsed without `extglob` being enabled because the `shopt` command to enable it was part of the function body. Add `shopt` options for `extglob` around function definitions to address this issue and allow bash-5.2 to correctly parse the function. Co-authored-by: Frédéric Pierret (fepitre) Co-authored-by: Levente Polyak Signed-off-by: Levente Polyak --- Makefile | 2 +- lib/common.sh | 3 ++- src/diffpkg.in | 2 ++ src/find-libdeps.in | 2 ++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 14ced32..8859946 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ $(1)/%: $(2)%.in $(LIBUTILS) @$(RM) "$$@" @{ echo -n 'm4_changequote([[[,]]])'; cat $$<; } | m4 -P --define=m4_devtools_version=$$(BUILDTOOLVER) | $(edit) >$$@ @chmod $(3) "$$@" - @bash -n "$$@" + @bash -O extglob -n "$$@" endef $(eval $(call buildInScript,build/bin,src/,555)) diff --git a/lib/common.sh b/lib/common.sh index a5e4616..d345307 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -137,6 +137,7 @@ pkgver_equal() { # $pkgver can be supplied with or without a pkgrel appended. # If not supplied, any pkgrel will be matched. ## +shopt -s extglob find_cached_package() { local searchdirs=("$PWD" "$PKGDEST") results=() local targetname=$1 targetver=$2 targetarch=$3 @@ -191,7 +192,7 @@ find_cached_package() { return 1 esac } - +shopt -u extglob check_package_validity(){ local pkgfile=$1 diff --git a/src/diffpkg.in b/src/diffpkg.in index 10b0904..6d07419 100644 --- a/src/diffpkg.in +++ b/src/diffpkg.in @@ -248,6 +248,7 @@ diff_pkgs() { fi } +shopt -s extglob fetch_pkg() { local pkg pkgdest pkgurl case $1 in @@ -295,6 +296,7 @@ fetch_pkg() { echo "$pkgdest" } +shopt -u extglob if (( $# < 2 )); then if [[ ! -f PKGBUILD ]]; then diff --git a/src/find-libdeps.in b/src/find-libdeps.in index 5a11580..2517879 100644 --- a/src/find-libdeps.in +++ b/src/find-libdeps.in @@ -40,6 +40,7 @@ else pushd "$WORKDIR" >/dev/null fi +shopt -s extglob process_sofile() { # extract the library name: libfoo.so shopt -s extglob nullglob @@ -56,6 +57,7 @@ process_sofile() { soobjects+=("${soname}=${soversion}-${soarch}") fi } +shopt -u extglob case $script_mode in deps) find_args=(-perm -u+x);; -- cgit v1.2.3-70-g09d2 From 6dd7be3fd4d3104101f5a8bbf0f12fcfe8124fd7 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Tue, 7 Mar 2023 01:51:40 +0100 Subject: Version 20230307 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8859946..eb121e1 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -V=20230105 +V=20230307 BUILDTOOLVER ?= $(V) PREFIX = /usr/local -- cgit v1.2.3-70-g09d2 From b34814419dff4c266201c7ee2402bdf9648c6078 Mon Sep 17 00:00:00 2001 From: nl6720 Date: Sat, 10 Sep 2022 12:44:49 +0300 Subject: sogrep: do not hardcode the mirror Use the first mirror that is configured for each repo in pacman.conf. With the default configuration, this means to use the first mirror from /etc/pacman.d/mirrorlist. If a repo is not configured in pacman.conf, fall back to https://geo.mirror.pkgbuild.com. --- src/sogrep.in | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/sogrep.in b/src/sogrep.in index d1ca1a1..031d28e 100644 --- a/src/sogrep.in +++ b/src/sogrep.in @@ -9,7 +9,7 @@ m4_include(lib/common.sh) # globals -: ${SOLINKS_MIRROR:="https://mirror.pkgbuild.com"} +fallback_mirror='https://geo.mirror.pkgbuild.com' : ${SOCACHE_DIR:="${XDG_CACHE_HOME:-${HOME}/.cache}/sogrep"} m4_include(lib/valid-repos.sh) @@ -23,11 +23,16 @@ source /usr/share/makepkg/util/parseopts.sh source /usr/share/makepkg/util/util.sh recache() { - local repo arch verbosity=-s + local repo arch fallback_linksdburl linksdburl mirror verbosity=-s (( VERBOSE )) && verbosity=--progress-bar for repo in "${_repos[@]}"; do + if [[ -n "$SOLINKS_MIRROR" ]]; then + mirror="$SOLINKS_MIRROR" + elif ! mirror="$(set -o pipefail; pacman-conf --repo "$repo" Server 2>/dev/null | head -n1)"; then + mirror="$fallback_mirror" + fi for arch in "${arches[@]}"; do # delete extracted tarballs from previous sogrep versions rm -rf "${SOCACHE_DIR}/${arch}/${repo}" @@ -36,8 +41,20 @@ recache() { local dbpath=${SOCACHE_DIR}/${arch}/${repo}.links.tar.gz mkdir -p "${dbpath%/*}" (( VERBOSE )) && echo "Fetching ${repo}.links.tar.gz..." - if ! curl -fLR "${verbosity}" -o "${dbpath}" -z "${dbpath}" \ - "${SOLINKS_MIRROR}/${repo}/os/${arch}/${repo}.links.tar.gz"; then + + if [[ "$mirror" == *"/${repo}/os/${arch}" ]]; then + linksdburl="${mirror}/${repo}.links.tar.gz" + else + linksdburl="${mirror}/${repo}/os/${arch}/${repo}.links.tar.gz" + fi + fallback_linksdburl="${fallback_mirror}/${repo}/os/${arch}/${repo}.links.tar.gz" + + if curl -fLR "${verbosity}" -o "${dbpath}" -z "${dbpath}" "$linksdburl"; then + : + elif [[ "$linksdburl" != "$fallback_linksdburl" ]] \ + && curl -fLR "${verbosity}" -o "${dbpath}" -z "${dbpath}" "$fallback_linksdburl"; then + : + else echo "error: failed to download links database for repo ${repo}" exit 1 fi -- cgit v1.2.3-70-g09d2 From 9297eb344e997b716ee3de9f17c7ebb33cd1791d Mon Sep 17 00:00:00 2001 From: Jelle van der Waa Date: Mon, 2 Jan 2023 15:16:29 +0100 Subject: commitpkg: disallow weak hashing algorithms Do not allow uploads of source=() with only weak cryptographic hashing algorithms but require at least one strong algorithm. This doesn't 100% enforce it ofcourse, but it allows for an early failure instead of failing in `db-update`. Signed-off-by: Levente Polyak --- src/commitpkg.in | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/commitpkg.in b/src/commitpkg.in index ef30544..6b9d727 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -4,6 +4,33 @@ m4_include(lib/common.sh) +check_pkgbuild_validity() { + # shellcheck source=contrib/makepkg/PKGBUILD.proto + . ./PKGBUILD + + # skip when there are no sources available + if (( ! ${#source[@]} )); then + return + fi + + # validate sources hash algo is at least > sha1 + local bad_algos=("cksums" "md5sums" "sha1sums") + local good_hash_algo=false + + # from makepkg libmakepkg/util/schema.sh + for integ in "${known_hash_algos[@]}"; do + local sumname="${integ}sums" + if [[ -n ${!sumname} ]] && ! in_array "${sumname}" "${bad_algos[@]}"; then + good_hash_algo=true + break + fi + done + + if ! $good_hash_algo; then + die "PKGBUILD lacks a secure cryptographic checksum, insecure algorithms: ${bad_algos[*]}" + fi +} + # Source makepkg.conf; fail if it is not found if [[ -r '/etc/makepkg.conf' ]]; then # shellcheck source=config/makepkg/x86_64.conf @@ -121,6 +148,9 @@ for _arch in "${arch[@]}"; do fi done +# check for PKGBUILD standards +check_pkgbuild_validity + if [[ -z $server ]]; then server='repos.archlinux.org' fi -- cgit v1.2.3-70-g09d2 From 90aba4f84b001bc2063b104d93a1e43810c22cbb Mon Sep 17 00:00:00 2001 From: Morten Linderud Date: Wed, 27 May 2020 17:48:53 +0200 Subject: git: first iteration of git support Signed-off-by: Morten Linderud Adjusted-by: Levente Polyak --- src/archrelease.in | 52 +++++++--------------------------------------------- src/commitpkg.in | 46 +++++++++++++--------------------------------- src/rebuildpkgs.in | 2 +- 3 files changed, 21 insertions(+), 79 deletions(-) diff --git a/src/archrelease.in b/src/archrelease.in index 3490ee2..e80271b 100644 --- a/src/archrelease.in +++ b/src/archrelease.in @@ -34,54 +34,16 @@ if [[ ! -f PKGBUILD ]]; then die 'archrelease: PKGBUILD not found' fi -trunk=${PWD##*/} +. ./PKGBUILD +pkgbase=${pkgbase:-$pkgname} +pkgver=$(get_full_version "$pkgbase") -# Normally this should be trunk, but it may be something -# such as 'gnome-unstable' -IFS='/' read -r -d '' -a parts <<< "$PWD" -if [[ "${parts[*]:(-2):1}" == "repos" ]]; then - die 'archrelease: Should not be in repos dir (try from trunk/)' +if git rev-parse "$pkgver" >/dev/null 2>&1; then + die "archrelease: the tag $pkgver already exists in the repository!" fi -unset parts - -if [[ $(svn status -q) ]]; then - die 'archrelease: You have not committed your changes yet!' -fi - -pushd .. >/dev/null -mapfile -t known_files < <(svn ls -r HEAD "$trunk") -wait $! || die "failed to discover committed files" - -# gracefully handle files containing an "@" character -known_files=("${known_files[@]/%/@}") - -# update repo directory first to avoid a commit failure -svn up repos - -for tag in "$@"; do - stat_busy "Copying %s to %s" "${trunk}" "${tag}" - - if [[ -d repos/$tag ]]; then - mapfile -t trash < <(svn ls --recursive "repos/$tag") - wait $! || die "failed to discover existing files" - if (( ${#trash[@]} )); then - trash=("${trash[@]/#/repos/$tag/}") - svn rm -q "${trash[@]/%/@}" - fi - else - mkdir -p "repos/$tag" - svn add --parents -q "repos/$tag" - fi - - # copy all files at once from trunk to the subdirectory in repos/ - svn copy -q -r HEAD "${known_files[@]/#/$trunk/}" "repos/$tag/" - - stat_done -done stat_busy "Releasing package" printf -v tag_list ", %s" "$@"; tag_list="${tag_list#, }" -svn commit -q -m "archrelease: copy ${trunk} to $tag_list" || abort +git tag -s -m "archrelease: released $pkgbase-$pkgver to $tag_list" "$pkgver" || abort +git push --tags || abort stat_done - -popd >/dev/null diff --git a/src/commitpkg.in b/src/commitpkg.in index 6b9d727..d57b30c 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -106,13 +106,13 @@ for key in "${validpgpkeys[@]}"; do needsversioning+=("keys/pgp/$key.asc") done -# assert that they really are controlled by SVN +# assert that they really are controlled by git if (( ${#needsversioning[*]} )); then - # svn status's output is only two columns when the status is unknown - while read -r status filename; do - [[ $status = '?' ]] && unversioned+=("$filename") - done < <(svn status -v "${needsversioning[@]}") - (( ${#unversioned[*]} )) && die "%s is not under version control" "${unversioned[@]}" + for file in "${needsversioning[@]}"; do + if ! git ls-files --error-unmatch "$file"; then + die "%s is not under version control" "$file" + fi + done fi rsyncopts=(-e ssh -p '--chmod=ug=rw,o=r' -c -h -L --progress --partial -y) @@ -155,18 +155,18 @@ if [[ -z $server ]]; then server='repos.archlinux.org' fi -if [[ -n $(svn status -q) ]]; then +if [[ -n $(git status --short --untracked-files=no) ]]; then msgtemplate="upgpkg: $pkgbase $(get_full_version)" if [[ -n $1 ]]; then - stat_busy 'Committing changes to trunk' - svn commit -q -m "${msgtemplate}: ${1}" || die + stat_busy 'Committing changes' + git commit -q -m "${msgtemplate}: ${1}" || die stat_done else [[ -z ${WORKDIR:-} ]] && setup_workdir msgfile=$(mktemp --tmpdir="${WORKDIR}" commitpkg.XXXXXXXXXX) echo "$msgtemplate" > "$msgfile" - if [[ -n $SVN_EDITOR ]]; then - $SVN_EDITOR "$msgfile" || die + if [[ -n $GIT_EDITOR ]]; then + $GIT_EDITOR "$msgfile" || die elif [[ -n $VISUAL ]]; then $VISUAL "$msgfile" || die elif [[ -n $EDITOR ]]; then @@ -175,8 +175,8 @@ if [[ -n $(svn status -q) ]]; then vi "$msgfile" || die fi [[ -s $msgfile ]] || die - stat_busy 'Committing changes to trunk' - svn commit -q -F "$msgfile" || die + stat_busy 'Committing changes' + git commit -v -q -F "$msgfile" || die unlink "$msgfile" stat_done fi @@ -250,23 +250,3 @@ if [[ ${#uploads[*]} -gt 0 ]]; then msg 'Uploading all package and signature files' rsync "${rsyncopts[@]}" "${uploads[@]}" "$server:staging/$repo/" || die fi - -if [[ "${arch[*]}" == 'any' ]]; then - if [[ -d ../repos/$repo-x86_64 ]]; then - pushd ../repos/ >/dev/null - stat_busy "Removing %s" "$repo-x86_64" - svn rm -q "$repo-x86_64" - svn commit -q -m "Removed $repo-x86_64 for $pkgname" - stat_done - popd >/dev/null - fi -else - if [[ -d ../repos/$repo-any ]]; then - pushd ../repos/ >/dev/null - stat_busy "Removing %s" "$repo-any" - svn rm -q "$repo-any" - svn commit -q -m "Removed $repo-any for $pkgname" - stat_done - popd >/dev/null - fi -fi diff --git a/src/rebuildpkgs.in b/src/rebuildpkgs.in index eddc17f..f58cfab 100644 --- a/src/rebuildpkgs.in +++ b/src/rebuildpkgs.in @@ -38,7 +38,7 @@ elif [[ -r "$HOME/.makepkg.conf" ]]; then fi bump_pkgrel() { - # Get the current pkgrel from SVN and update the working copy with it + # Get the current pkgrel from git and update the working copy with it # This prevents us from incrementing out of control :) pbuild='.svn/text-base/PKGBUILD.svn-base' oldrel=$(grep 'pkgrel=' $pbuild | cut -d= -f2) -- cgit v1.2.3-70-g09d2 From f4213f9c360c3eb8d93a9365e844e254c47c827a Mon Sep 17 00:00:00 2001 From: Morten Linderud Date: Fri, 29 May 2020 23:09:01 +0200 Subject: commitpkg: ensure we always use the main branch Signed-off-by: Morten Linderud Signed-off-by: Levente Polyak --- src/commitpkg.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/commitpkg.in b/src/commitpkg.in index d57b30c..9186378 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -54,6 +54,10 @@ if [[ ! -f PKGBUILD ]]; then die 'No PKGBUILD file' fi +if [[ "$(git symbolic-ref --short HEAD)" != main ]]; then + die 'must be run from the main branch' +fi + source=() # shellcheck source=contrib/makepkg/PKGBUILD.proto . ./PKGBUILD -- cgit v1.2.3-70-g09d2 From b6f5220bed76c9ea9f83f4c6c81ced9977b26d77 Mon Sep 17 00:00:00 2001 From: Morten Linderud Date: Fri, 29 May 2020 23:10:18 +0200 Subject: commitpkg: ensure we always stage and rm files Signed-off-by: Morten Linderud --- src/commitpkg.in | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/commitpkg.in b/src/commitpkg.in index 9186378..59471bf 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -160,6 +160,15 @@ if [[ -z $server ]]; then fi if [[ -n $(git status --short --untracked-files=no) ]]; then + stat_busy 'Staging files' + for f in $(git ls-files --modified); do + git add "$f" + done + for f in $(git ls-files --deleted); do + git rm "$f" + done + stat_done + msgtemplate="upgpkg: $pkgbase $(get_full_version)" if [[ -n $1 ]]; then stat_busy 'Committing changes' -- cgit v1.2.3-70-g09d2 From f7d122044b42b6f296e38dcd37d458d58f33612d Mon Sep 17 00:00:00 2001 From: Morten Linderud Date: Sat, 30 May 2020 01:59:58 +0200 Subject: archrelease: ensure we check the checksum of the package Signed-off-by: Morten Linderud --- src/archrelease.in | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/archrelease.in b/src/archrelease.in index e80271b..55d3726 100644 --- a/src/archrelease.in +++ b/src/archrelease.in @@ -42,6 +42,17 @@ if git rev-parse "$pkgver" >/dev/null 2>&1; then die "archrelease: the tag $pkgver already exists in the repository!" fi +# If the tag exists we check if it's properly signed and that it +# matches the working directory PKGBUILD. +if git tag --verify "$pkgver" &> /dev/null; then + cwd_checksum=$(sha256sum PKGBUILD|cut -d' ' -f1) + tag_checksum=$(git show $pkgver:PKGBUILD | sha256sum |cut -d' ' -f1) + if [[ "$cwd_checksum" != "$tag_checksum" ]]; then + die "tagged PKGBUILD is not the same as the working dir PKGBUILD" + fi + exit 0 +fi + stat_busy "Releasing package" printf -v tag_list ", %s" "$@"; tag_list="${tag_list#, }" git tag -s -m "archrelease: released $pkgbase-$pkgver to $tag_list" "$pkgver" || abort -- cgit v1.2.3-70-g09d2 From f0946c65f52eab3a82c55c04d76ac3bb7e81bbb1 Mon Sep 17 00:00:00 2001 From: Morten Linderud Date: Wed, 16 Sep 2020 00:17:55 +0200 Subject: archrelease: Added pkgver to git tag conversion Signed-off-by: Morten Linderud --- src/archrelease.in | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/archrelease.in b/src/archrelease.in index 55d3726..0d37eb2 100644 --- a/src/archrelease.in +++ b/src/archrelease.in @@ -37,16 +37,17 @@ fi . ./PKGBUILD pkgbase=${pkgbase:-$pkgname} pkgver=$(get_full_version "$pkgbase") +tag_pkgver=release-${pkgver/:/-} -if git rev-parse "$pkgver" >/dev/null 2>&1; then +if git rev-parse "$tag_pkgver" >/dev/null 2>&1; then die "archrelease: the tag $pkgver already exists in the repository!" fi # If the tag exists we check if it's properly signed and that it # matches the working directory PKGBUILD. -if git tag --verify "$pkgver" &> /dev/null; then +if git tag --verify "$tag_pkgver" &> /dev/null; then cwd_checksum=$(sha256sum PKGBUILD|cut -d' ' -f1) - tag_checksum=$(git show $pkgver:PKGBUILD | sha256sum |cut -d' ' -f1) + tag_checksum=$(git show $tag_pkgver:PKGBUILD | sha256sum |cut -d' ' -f1) if [[ "$cwd_checksum" != "$tag_checksum" ]]; then die "tagged PKGBUILD is not the same as the working dir PKGBUILD" fi @@ -55,6 +56,6 @@ fi stat_busy "Releasing package" printf -v tag_list ", %s" "$@"; tag_list="${tag_list#, }" -git tag -s -m "archrelease: released $pkgbase-$pkgver to $tag_list" "$pkgver" || abort +git tag -s -m "archrelease: released $pkgbase-$pkgver to $tag_list" "$tag_pkgver" || abort git push --tags || abort stat_done -- cgit v1.2.3-70-g09d2 From 184441895606f59dc85c695c627660758ca2b882 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Wed, 7 Sep 2022 23:10:51 +0200 Subject: archrelease: explicitly push the main refspec --- src/archrelease.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/archrelease.in b/src/archrelease.in index 0d37eb2..3607d19 100644 --- a/src/archrelease.in +++ b/src/archrelease.in @@ -57,5 +57,5 @@ fi stat_busy "Releasing package" printf -v tag_list ", %s" "$@"; tag_list="${tag_list#, }" git tag -s -m "archrelease: released $pkgbase-$pkgver to $tag_list" "$tag_pkgver" || abort -git push --tags || abort +git push --tags main || abort stat_done -- cgit v1.2.3-70-g09d2 From b9d20c10a988775bc444ceaf872766fec32b54b5 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 11 Sep 2022 12:31:39 +0200 Subject: archrelease: fix git tag conversion and use library function for it This allows us to reuse the code and have the conversion in a single place instead of cluttering rules across different execution units. It also fixes the implementations according to the specs of git-check-ref-format. Signed-off-by: Levente Polyak --- lib/common.sh | 10 ++++++++++ src/archrelease.in | 13 ++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/common.sh b/lib/common.sh index d345307..577bb6e 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -255,6 +255,16 @@ getpkgdesc() { } +get_tag_from_pkgver() { + local pkgver=$1 + local tag=${pkgver} + + tag=${tag/:/-} + tag=${tag//~/.} + echo "${tag}" +} + + is_debug_package() { local pkgfile=${1} pkgbase pkgname pkgdesc pkgbase="$(getpkgbase "${pkgfile}")" diff --git a/src/archrelease.in b/src/archrelease.in index 3607d19..3dd969b 100644 --- a/src/archrelease.in +++ b/src/archrelease.in @@ -37,17 +37,17 @@ fi . ./PKGBUILD pkgbase=${pkgbase:-$pkgname} pkgver=$(get_full_version "$pkgbase") -tag_pkgver=release-${pkgver/:/-} +gittag=$(get_tag_from_pkgver "$pkgver") -if git rev-parse "$tag_pkgver" >/dev/null 2>&1; then - die "archrelease: the tag $pkgver already exists in the repository!" +if git rev-parse "$gittag" >/dev/null 2>&1; then + die "archrelease: the tag $gittag for version $pkgver already exists in the repository!" fi # If the tag exists we check if it's properly signed and that it # matches the working directory PKGBUILD. -if git tag --verify "$tag_pkgver" &> /dev/null; then +if git tag --verify "$gittag" &> /dev/null; then cwd_checksum=$(sha256sum PKGBUILD|cut -d' ' -f1) - tag_checksum=$(git show $tag_pkgver:PKGBUILD | sha256sum |cut -d' ' -f1) + tag_checksum=$(git show "${gittag}:PKGBUILD" | sha256sum |cut -d' ' -f1) if [[ "$cwd_checksum" != "$tag_checksum" ]]; then die "tagged PKGBUILD is not the same as the working dir PKGBUILD" fi @@ -55,7 +55,6 @@ if git tag --verify "$tag_pkgver" &> /dev/null; then fi stat_busy "Releasing package" -printf -v tag_list ", %s" "$@"; tag_list="${tag_list#, }" -git tag -s -m "archrelease: released $pkgbase-$pkgver to $tag_list" "$tag_pkgver" || abort +git tag --sign --message="Package release ${pkgver}" "$gittag" || abort git push --tags main || abort stat_done -- cgit v1.2.3-70-g09d2 From 1f4ca51ca14d0a5fe5dcd4014f3756de2fbc835f Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Wed, 7 Sep 2022 23:28:10 +0200 Subject: commitpkg: omit pkgbase in commit msg as git repos are per pkgbase --- src/commitpkg.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commitpkg.in b/src/commitpkg.in index 59471bf..0c65658 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -169,7 +169,7 @@ if [[ -n $(git status --short --untracked-files=no) ]]; then done stat_done - msgtemplate="upgpkg: $pkgbase $(get_full_version)" + msgtemplate="upgpkg: $(get_full_version)" if [[ -n $1 ]]; then stat_busy 'Committing changes' git commit -q -m "${msgtemplate}: ${1}" || die -- cgit v1.2.3-70-g09d2 From bb72473529e300724eb7d78890da85a9ca7f6157 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 9 Sep 2022 20:14:34 +0200 Subject: crossrepomove: drop support as this is not needed anymore We unified the source repositories to a single location. Having to cross repo move them between physical locations is not required anymore. --- Makefile | 13 ------ contrib/completion/bash/devtools.in | 2 +- contrib/completion/zsh/_devtools.in | 2 +- doc/man/devtools.7.asciidoc | 2 +- src/crossrepomove.in | 91 ------------------------------------- 5 files changed, 3 insertions(+), 107 deletions(-) delete mode 100644 src/crossrepomove.in diff --git a/Makefile b/Makefile index eb121e1..70e977c 100644 --- a/Makefile +++ b/Makefile @@ -38,14 +38,7 @@ ARCHBUILD_LINKS = \ kde-unstable-x86_64-build \ gnome-unstable-x86_64-build -CROSSREPOMOVE_LINKS = \ - extra2community \ - community2extra - COMPLETIONS = $(addprefix $(BUILDDIR)/,$(patsubst %.in,%,$(wildcard contrib/completion/*/*))) -BASHCOMPLETION_LINKS = \ - archco \ - communityco all: binprogs completion man @@ -101,12 +94,9 @@ install: all for a in ${SETARCH_ALIASES}; do install -m0644 $$a -t $(DESTDIR)$(PREFIX)/share/devtools/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 - for l in ${CROSSREPOMOVE_LINKS}; do ln -sf crossrepomove $(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 l in ${BASHCOMPLETION_LINKS}; do ln -sf devtools $(DESTDIR)$(PREFIX)/share/bash-completion/completions/$$l; done install -Dm0644 $(BUILDDIR)/contrib/completion/zsh/_devtools $(DESTDIR)$(PREFIX)/share/zsh/site-functions/_devtools - ln -sf archco $(DESTDIR)$(PREFIX)/bin/communityco for manfile in $(MANS); do \ install -Dm644 $$manfile -t $(DESTDIR)$(MANDIR)/man$${manfile##*.}; \ done; @@ -118,11 +108,8 @@ uninstall: for f in $(notdir $(SETARCH_ALIASES)); do rm -f $(DESTDIR)$(PREFIX)/share/devtools/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 - for l in ${CROSSREPOMOVE_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$l; done - for l in ${BASHCOMPLETION_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/share/bash-completion/completions/$$l; done rm $(DESTDIR)$(PREFIX)/share/bash-completion/completions/devtools rm $(DESTDIR)$(PREFIX)/share/zsh/site-functions/_devtools - rm -f $(DESTDIR)$(PREFIX)/bin/communityco 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 diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index e7925b3..8183395 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -29,7 +29,7 @@ _archco() { _archco_pkg Slq true } && -complete -F _archco archco communityco +complete -F _archco archco _makechrootpkg() { local cur diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 48d3dfd..707e3fa 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -1,4 +1,4 @@ -#compdef archbuild archco arch-nspawn archrelease commitpkg 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 communityco=archco checkpkg sogrep offload-build makerepropkg +#compdef archbuild archco arch-nspawn archrelease commitpkg 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 diff --git a/doc/man/devtools.7.asciidoc b/doc/man/devtools.7.asciidoc index 9062278..1bd118f 100644 --- a/doc/man/devtools.7.asciidoc +++ b/doc/man/devtools.7.asciidoc @@ -11,7 +11,7 @@ Description Devtools contains tools for package maintenance in Arch Linux. The toolset varies from tools for building packages in a clean chroot ('mkarchroot',...), packaging related tools for sonames ('sogrep', 'lddd') and tools for -repository management such as ('archco', 'extra2community') +repository management such as ('archco') Programs -------- diff --git a/src/crossrepomove.in b/src/crossrepomove.in deleted file mode 100644 index 08a3067..0000000 --- a/src/crossrepomove.in +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-3.0-or-later - -m4_include(lib/common.sh) - -scriptname=${0##*/} - -if [[ -z $1 ]]; then - printf 'Usage: %s [pkgbase]\n' "$scriptname" - exit 1 -fi - -pkgbase="${1}" - -case $scriptname in - extra2community) - source_name='packages' - target_name='community' - source_repo='extra' - target_repo='community' - ;; - community2extra) - source_name='community' - target_name='packages' - source_repo='community' - target_repo='extra' - ;; - *) - die "Couldn't find configuration for %s" "$scriptname" - ;; -esac - -server='repos.archlinux.org' -source_svn="svn+ssh://svn-${source_name}@${server}/srv/repos/svn-${source_name}/svn" -target_svn="svn+ssh://svn-${target_name}@${server}/srv/repos/svn-${target_name}/svn" -source_dbscripts="/srv/repos/svn-${source_name}/dbscripts" -target_dbscripts="/srv/repos/svn-${target_name}/dbscripts" - -setup_workdir - -pushd "$WORKDIR" >/dev/null - -msg "Downloading sources for %s" "${pkgbase}" -svn -q checkout -N "${target_svn}" target_checkout -mkdir -p "target_checkout/${pkgbase}/repos" -svn -q export "${source_svn}/${pkgbase}/trunk" "target_checkout/${pkgbase}/trunk" || die -# shellcheck source=contrib/makepkg/PKGBUILD.proto -. "target_checkout/${pkgbase}/trunk/PKGBUILD" - -msg "Downloading packages for %s" "${pkgbase}" -for _arch in "${arch[@]}"; do - if [[ "${_arch[*]}" == 'any' ]]; then - repo_arch='x86_64' - else - repo_arch=${_arch} - fi - for _pkgname in "${pkgname[@]}"; do - fullver=$(get_full_version "$_pkgname") - pkgpath="/srv/ftp/${source_repo}/os/${repo_arch}/${_pkgname}-${fullver}-${_arch}.pkg.tar.*" - debugpath="/srv/ftp/${source_repo}-debug/os/${repo_arch}/${_pkgname}-debug-${fullver}-${_arch}.pkg.tar.*" - # Fail if $pkgpath doesn't match but keep $debugpath optional - # shellcheck disable=2029 - ssh "${server}" "bash -c ' - install ${pkgpath} -Dt staging/${target_repo} && - (install ${debugpath} -Dt staging/${target_repo} 2>/dev/null || true) - '" || die - done -done - -msg "Adding %s to %s" "${pkgbase}" "${target_repo}" -svn -q add "target_checkout/${pkgbase}" -svn -q commit -m"${scriptname}: Moving ${pkgbase} from ${source_repo} to ${target_repo}" target_checkout -pushd "target_checkout/${pkgbase}/trunk" >/dev/null -archrelease "${arch[@]/#/$target_repo-}" || die -popd >/dev/null - -# shellcheck disable=2029 -ssh "${server}" "${target_dbscripts}/db-update" || die - -msg "Removing %s from %s" "${pkgbase}" "${source_repo}" -for _arch in "${arch[@]}"; do - # shellcheck disable=2029 - ssh "${server}" "${source_dbscripts}/db-remove ${source_repo} ${_arch} ${pkgbase}" -done -svn -q checkout -N "${source_svn}" source_checkout -svn -q up "source_checkout/${pkgbase}" -svn -q rm "source_checkout/${pkgbase}" -svn -q commit -m"${scriptname}: Moving ${pkgbase} from ${source_repo} to ${target_repo}" source_checkout - -popd >/dev/null -- cgit v1.2.3-70-g09d2 From 66758941594831e5da81a7c00280e73ccc842688 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 9 Sep 2022 20:35:11 +0200 Subject: archco: convert tool to git clone --- src/archco.in | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/archco.in b/src/archco.in index a93d819..c569e52 100644 --- a/src/archco.in +++ b/src/archco.in @@ -13,14 +13,12 @@ fi case $scriptname in archco) - SVNURL="svn+ssh://svn-packages@repos.archlinux.org/srv/repos/svn-packages/svn";; - communityco) - SVNURL="svn+ssh://svn-community@repos.archlinux.org/srv/repos/svn-community/svn";; + GITURL="ssh://git@gitlab.archlinux.org:222/bot-test/packages";; *) - die "Couldn't find svn url for %s" "$scriptname" + die "Couldn't find Git url for %s" "$scriptname" ;; esac -for i in "$@"; do - svn co "$SVNURL/$i" +for pkgbase in "$@"; do + git clone --origin origin --config commit.gpgsign=true "${GITURL}/${pkgbase}.git" done -- cgit v1.2.3-70-g09d2 From 5eb09a9cc931ca506875276dcd7b794395ba77d0 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 11 Sep 2022 20:42:30 +0200 Subject: archco: implement clone and configure subcommands Manages 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. Signed-off-by: Levente Polyak --- contrib/completion/zsh/_devtools.in | 40 +++++- lib/common.sh | 9 ++ src/archco.in | 238 ++++++++++++++++++++++++++++++++++-- 3 files changed, 273 insertions(+), 14 deletions(-) diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 707e3fa..1dc112f 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -15,10 +15,24 @@ _archbuild_args=( '--[Introduce makechrootpkg options]:*::makechrootpkg options:= _dispatch makechrootpkg makechrootpkg' ) -_archco_args=( +_archco_cmds=( + "archco command" + "clone[Clone a package repository]" + "configure[Configure a clone according to distro specs]" +) + +_archco_clone_args=( + '(-u --unprivileged)'{-u,--unprivileged}'[Read-only access without packager info as Git author]' + '(-h --help)'{-h,--help}'[Display usage]' '*:packages:_devtools_completions_all_packages' ) +_archco_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 -/' +) + _arch_nspawn_args=( '-C[Location of a pacman config file]:pacman_config:_files -g "*.conf(.)"' '-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"' @@ -128,8 +142,30 @@ _devtools_completions_all_packages() { } _devtools() { - local argname="_${service//-/_}_args[@]" + local service_func=_${service//-/_} + local service_cmds=${service_func}_cmds + if typeset -p ${service_cmds} &> /dev/null; then + _arguments -C \ + "1: :->cmds" \ + '*::arg:->args' + case $state in + cmds) + local service_cmds_array=${service_cmds}[@] + _values "${(P)service_cmds_array}" + ;; + args) + local cmd_args_array=${service_func}_$line[1]_args + if typeset -p ${cmd_args_array} &> /dev/null; then + local cmd_args=${cmd_args_array}[@] + _arguments -s "${(P)cmd_args}" + fi + ;; + esac + return 0 + fi + local argname="${service_func}_args[@]" _arguments -s "${(P)argname}" + } _devtools diff --git a/lib/common.sh b/lib/common.sh index 577bb6e..5f134ae 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -19,6 +19,15 @@ export LANG=C export BUILDTOOL=devtools export BUILDTOOLVER=m4_devtools_version +# Set common properties +export PACMAN_KEYRING_DIR=/etc/pacman.d/gnupg +export GITLAB_HOST=gitlab.archlinux.org +export GIT_REPO_SPEC_VERSION=1 +export GIT_PACKAGING_NAMESPACE=archlinux/packaging/packages +export GIT_PACKAGING_NAMESPACE_ID=11323 +export GIT_PACKAGING_URL_SSH="ssh://git@${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}" +export GIT_PACKAGING_URL_HTTPS="https://${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}" + # check if messages are to be printed using color if [[ -t 2 && "$TERM" != dumb ]]; then colorize diff --git a/src/archco.in b/src/archco.in index c569e52..b401c23 100644 --- a/src/archco.in +++ b/src/archco.in @@ -4,21 +4,235 @@ m4_include(lib/common.sh) -scriptname=${0##*/} +source /usr/share/makepkg/util/config.sh +source /usr/share/makepkg/util/message.sh -if [[ -z $1 ]]; then - printf 'Usage: %s ...\n' "$scriptname" +set -e + + +usage() { + cat <<- _EOF_ + Usage: ${BASH_SOURCE[0]##*/} [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 + + OPTIONS + -h, --help Show this help text +_EOF_ +} + +usage_clone() { + cat <<- _EOF_ + Usage: ${BASH_SOURCE[0]##*/} 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 + -u, --unprivileged Clone package with read-only access and without + packager info as Git author. + -h, --help Show this help text +_EOF_ +} + +usage_configure() { + cat <<- _EOF_ + Usage: ${BASH_SOURCE[0]##*/} 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_ +} + +if (( $# < 1 )); then + usage exit 1 fi -case $scriptname in - archco) - GITURL="ssh://git@gitlab.archlinux.org:222/bot-test/packages";; - *) - die "Couldn't find Git url for %s" "$scriptname" - ;; -esac +# commands +CLONE=0 +CONFIGURE=0 + +# options +GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} +UNPRIVILEGED=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 + ;; + *) + 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 + ;; + --) + 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 +fi + +# 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 + +pkgbases=("$@") +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 -for pkgbase in "$@"; do - git clone --origin origin --config commit.gpgsign=true "${GITURL}/${pkgbase}.git" + 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 done -- cgit v1.2.3-70-g09d2 From 30616c4fdea37dda26c33d4f94052b99dba2401d Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 11 Sep 2022 22:08:47 +0200 Subject: archco: add option to clone all packages of a maintainer Query Archweb to retrieve a list of all packages of a maintainer by their pkgbase. AFterwards loop through all packages and clone them. Signed-off-by: Levente Polyak --- contrib/completion/zsh/_devtools.in | 1 + lib/common.sh | 5 +++++ src/archco.in | 24 +++++++++++++++++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 1dc112f..d2fcfed 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -22,6 +22,7 @@ _archco_cmds=( ) _archco_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]' '(-h --help)'{-h,--help}'[Display usage]' '*:packages:_devtools_completions_all_packages' diff --git a/lib/common.sh b/lib/common.sh index 5f134ae..fe6450a 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -42,6 +42,11 @@ stat_busy() { printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}...${ALL_OFF}" "$@" >&2 } +stat_progress() { + # shellcheck disable=2059 + printf "${BOLD}.${ALL_OFF}" >&2 +} + stat_done() { # shellcheck disable=2059 printf "${BOLD}done${ALL_OFF}\n" >&2 diff --git a/src/archco.in b/src/archco.in index b401c23..2804cba 100644 --- a/src/archco.in +++ b/src/archco.in @@ -46,6 +46,7 @@ usage_clone() { 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. -h, --help Show this help text @@ -127,6 +128,15 @@ if (( CLONE )); then UNPRIVILEGED=1 shift ;; + -m|--maintainer) + (( $# <= 1 )) && die "missing argument for %s" "$1" + MAINTAINER="$2" + shift 2 + ;; + --maintainer=*) + MAINTAINER="${1#*=}" + shift + ;; --) shift break @@ -170,6 +180,8 @@ elif (( CONFIGURE )); then done fi +pkgbases=("$@") + # Load makepkg.conf variables to be available load_makepkg_config @@ -191,7 +203,17 @@ if (( ! UNPRIVILEGED )); then fi fi -pkgbases=("$@") +# 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 + for pkgbase in "${pkgbases[@]}"; do if (( CLONE )); then if [[ ! -d ${pkgbase} ]]; then -- cgit v1.2.3-70-g09d2 From 6aa42e1f6e913fd8706bd809f784f6c492762a20 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Mon, 12 Sep 2022 19:55:03 +0200 Subject: commitpkg: use library location for common server and remote properties It makes a lot of sense to have them in a central place that can be swapped and also re-used across different execution units. Hence lets move the repos.archlinux.org host to lib/common.sh Signed-off-by: Levente Polyak --- lib/common.sh | 1 + src/commitpkg.in | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/common.sh b/lib/common.sh index fe6450a..d2351af 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -27,6 +27,7 @@ export GIT_PACKAGING_NAMESPACE=archlinux/packaging/packages export GIT_PACKAGING_NAMESPACE_ID=11323 export GIT_PACKAGING_URL_SSH="ssh://git@${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}" 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 diff --git a/src/commitpkg.in b/src/commitpkg.in index 0c65658..7b6e904 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -119,6 +119,8 @@ if (( ${#needsversioning[*]} )); then done fi + +server=${PACKAGING_REPO_RELEASE_HOST} rsyncopts=(-e ssh -p '--chmod=ug=rw,o=r' -c -h -L --progress --partial -y) archreleaseopts=() while getopts ':l:a:s:f' flag; do @@ -155,10 +157,6 @@ done # check for PKGBUILD standards check_pkgbuild_validity -if [[ -z $server ]]; then - server='repos.archlinux.org' -fi - if [[ -n $(git status --short --untracked-files=no) ]]; then stat_busy 'Staging files' for f in $(git ls-files --modified); do -- cgit v1.2.3-70-g09d2 From 3d3176beb6eb0319809be386cd903fa03bdabc73 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 11 Sep 2022 22:17:09 +0200 Subject: pkgrepo: rename archco as a general purpose tool for packaging repos Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 10 +- contrib/completion/zsh/_devtools.in | 10 +- doc/man/devtools.7.asciidoc | 2 +- src/archco.in | 260 ------------------------------------ src/pkgrepo.in | 260 ++++++++++++++++++++++++++++++++++++ 5 files changed, 271 insertions(+), 271 deletions(-) delete mode 100644 src/archco.in create mode 100644 src/pkgrepo.in diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 8183395..a353b99 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -14,22 +14,22 @@ _devtools_compgen() { done } -_archco_pkg() { +_pkgrepo_pkg() { _devtools_compgen "$( command pacman "-$1" )" } -_archco() { - local cur prev +_pkgrepo() { + local cur prev COMPREPLY=() cur=$(_get_cword) prev=${COMP_WORDS[COMP_CWORD-1]} - _archco_pkg Slq + _pkgrepo_pkg Slq true } && -complete -F _archco archco +complete -F _pkgrepo pkgrepo _makechrootpkg() { local cur diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index d2fcfed..f6417df 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -1,4 +1,4 @@ -#compdef archbuild archco arch-nspawn archrelease commitpkg 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 pkgrepo arch-nspawn archrelease commitpkg 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 @@ -15,20 +15,20 @@ _archbuild_args=( '--[Introduce makechrootpkg options]:*::makechrootpkg options:= _dispatch makechrootpkg makechrootpkg' ) -_archco_cmds=( - "archco command" +_pkgrepo_cmds=( + "pkgrepo command" "clone[Clone a package repository]" "configure[Configure a clone according to distro specs]" ) -_archco_clone_args=( +_pkgrepo_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]' '(-h --help)'{-h,--help}'[Display usage]' '*:packages:_devtools_completions_all_packages' ) -_archco_configure_args=( +_pkgrepo_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/devtools.7.asciidoc b/doc/man/devtools.7.asciidoc index 1bd118f..6b2d0c1 100644 --- a/doc/man/devtools.7.asciidoc +++ b/doc/man/devtools.7.asciidoc @@ -11,7 +11,7 @@ Description Devtools contains tools for package maintenance in Arch Linux. The toolset varies from tools for building packages in a clean chroot ('mkarchroot',...), packaging related tools for sonames ('sogrep', 'lddd') and tools for -repository management such as ('archco') +repository management such as ('pkgrepo') Programs -------- diff --git a/src/archco.in b/src/archco.in deleted file mode 100644 index 2804cba..0000000 --- a/src/archco.in +++ /dev/null @@ -1,260 +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 - - -usage() { - cat <<- _EOF_ - Usage: ${BASH_SOURCE[0]##*/} [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 - - OPTIONS - -h, --help Show this help text -_EOF_ -} - -usage_clone() { - cat <<- _EOF_ - Usage: ${BASH_SOURCE[0]##*/} 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. - -h, --help Show this help text -_EOF_ -} - -usage_configure() { - cat <<- _EOF_ - Usage: ${BASH_SOURCE[0]##*/} 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_ -} - -if (( $# < 1 )); then - usage - exit 1 -fi - -# commands -CLONE=0 -CONFIGURE=0 - -# options -GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} -UNPRIVILEGED=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 - ;; - *) - 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 - ;; - --) - 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 -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 - -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 -done diff --git a/src/pkgrepo.in b/src/pkgrepo.in new file mode 100644 index 0000000..2804cba --- /dev/null +++ b/src/pkgrepo.in @@ -0,0 +1,260 @@ +#!/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 + + +usage() { + cat <<- _EOF_ + Usage: ${BASH_SOURCE[0]##*/} [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 + + OPTIONS + -h, --help Show this help text +_EOF_ +} + +usage_clone() { + cat <<- _EOF_ + Usage: ${BASH_SOURCE[0]##*/} 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. + -h, --help Show this help text +_EOF_ +} + +usage_configure() { + cat <<- _EOF_ + Usage: ${BASH_SOURCE[0]##*/} 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_ +} + +if (( $# < 1 )); then + usage + exit 1 +fi + +# commands +CLONE=0 +CONFIGURE=0 + +# options +GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} +UNPRIVILEGED=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 + ;; + *) + 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 + ;; + --) + 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 +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 + +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 +done -- cgit v1.2.3-70-g09d2 From 95424a88eb11e06b7290fcabd6e3a6cf2b9cc9b3 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Mon, 12 Sep 2022 02:24:25 +0200 Subject: pkgrepo: add option to clone all existing packages This can be very handy for cache warming on the repo server or to perform mass operations on all PKGBUILDs. Signed-off-by: Levente Polyak --- contrib/completion/zsh/_devtools.in | 1 + src/pkgrepo.in | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index f6417df..06e05e1 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -24,6 +24,7 @@ _pkgrepo_cmds=( _pkgrepo_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' ) diff --git a/src/pkgrepo.in b/src/pkgrepo.in index 2804cba..13f8847 100644 --- a/src/pkgrepo.in +++ b/src/pkgrepo.in @@ -49,6 +49,7 @@ usage_clone() { -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_ } @@ -83,6 +84,7 @@ CONFIGURE=0 # options GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} UNPRIVILEGED=0 +CLONE_ALL=0 MAINTAINER= PACKAGER_NAME= PACKAGER_EMAIL= @@ -137,6 +139,10 @@ if (( CLONE )); then MAINTAINER="${1#*=}" shift ;; + --all) + CLONE_ALL=1 + shift + ;; --) shift break @@ -214,6 +220,17 @@ if [[ -n ${MAINTAINER} ]]; then 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 + for pkgbase in "${pkgbases[@]}"; do if (( CLONE )); then if [[ ! -d ${pkgbase} ]]; then -- cgit v1.2.3-70-g09d2 From d15bd29a9d411dedc0a0682ec54b55e079d4f00f Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Tue, 13 Sep 2022 00:24:31 +0200 Subject: pkgrepo: add subcommand to open the packaging repository's website This can be quite handy if a packager quickly wants to check the GitLab page for merge requests or but reports. Quickly calling a cli command inside the current packaging clone or with the pkgname provided will open the remote location inside the browser. Signed-off-by: Levente Polyak --- contrib/completion/zsh/_devtools.in | 6 ++++ src/pkgrepo.in | 67 +++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 06e05e1..d30648a 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -19,6 +19,7 @@ _pkgrepo_cmds=( "pkgrepo command" "clone[Clone a package repository]" "configure[Configure a clone according to distro specs]" + "web[Open the packaging repository's website]" ) _pkgrepo_clone_args=( @@ -35,6 +36,11 @@ _pkgrepo_configure_args=( '*:git_dir:_files -/' ) +_pkgrepo_web_args=( + '(-h --help)'{-h,--help}'[Display usage]' + '*:git_dir:_files -/' +) + _arch_nspawn_args=( '-C[Location of a pacman config file]:pacman_config:_files -g "*.conf(.)"' '-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"' diff --git a/src/pkgrepo.in b/src/pkgrepo.in index 13f8847..c6f5951 100644 --- a/src/pkgrepo.in +++ b/src/pkgrepo.in @@ -28,6 +28,7 @@ usage() { 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 @@ -72,6 +73,18 @@ usage_configure() { _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 @@ -107,6 +120,11 @@ while (( $# )); do shift break ;; + web) + WEB=1 + shift + break + ;; *) die "invalid argument: %s" "$1" ;; @@ -184,6 +202,26 @@ elif (( CONFIGURE )); then ;; 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=("$@") @@ -231,6 +269,31 @@ if (( CLONE_ALL )); then 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 @@ -274,4 +337,8 @@ for pkgbase in "${pkgbases[@]}"; do fi fi fi + + if (( WEB )); then + xdg-open "${GIT_PACKAGING_URL_HTTPS}/${pkgbase}" + fi done -- cgit v1.2.3-70-g09d2 From a8be7423efb287edd5ef80002a75a853fc0c9c1d Mon Sep 17 00:00:00 2001 From: Levente Polyak 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 --- contrib/completion/zsh/_devtools.in | 42 ++++++++++++------ doc/man/devtools.7.asciidoc | 20 +++++++-- doc/man/diffpkg.1.asciidoc | 4 -- doc/man/pkgctl-diff.1.asciidoc | 73 ++++++++++++++++++++++++++++++++ doc/man/pkgctl-repo-clone.1.asciidoc | 42 ++++++++++++++++++ doc/man/pkgctl-repo-configure.1.asciidoc | 32 ++++++++++++++ doc/man/pkgctl-repo-web.1.asciidoc | 24 +++++++++++ doc/man/pkgctl-repo.1.asciidoc | 51 ++++++++++++++++++++++ doc/man/pkgctl.1.asciidoc | 32 ++++++++++++++ src/diffpkg.in | 11 ++--- src/pkgctl.in | 56 ++++++++++++++++++++++++ src/pkgrepo.in | 7 +-- 12 files changed, 365 insertions(+), 29 deletions(-) create mode 100644 doc/man/pkgctl-diff.1.asciidoc create mode 100644 doc/man/pkgctl-repo-clone.1.asciidoc create mode 100644 doc/man/pkgctl-repo-configure.1.asciidoc create mode 100644 doc/man/pkgctl-repo-web.1.asciidoc create mode 100644 doc/man/pkgctl-repo.1.asciidoc create mode 100644 doc/man/pkgctl.1.asciidoc create mode 100644 src/pkgctl.in diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index d30648a..959497e 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -1,4 +1,4 @@ -#compdef archbuild pkgrepo arch-nspawn archrelease commitpkg 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 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 # # SPDX-License-Identifier: GPL-3.0-or-later @@ -149,31 +149,47 @@ _devtools_completions_all_packages() { compadd - "${(@)packages}" } -_devtools() { - local service_func=_${service//-/_} - local service_cmds=${service_func}_cmds - if typeset -p ${service_cmds} &> /dev/null; then +_pkgctl_cmds=( + "pkgctl command" + "diff[Compare package files using different modes]" + "repo[Manage Git packaging repositories and their configuration]" +) + +_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 _arguments -C \ "1: :->cmds" \ '*::arg:->args' case $state in cmds) - local service_cmds_array=${service_cmds}[@] - _values "${(P)service_cmds_array}" + local service_cmds=${service_name}_cmds[@] + _values "${(P)service_cmds}" ;; args) - local cmd_args_array=${service_func}_$line[1]_args - if typeset -p ${cmd_args_array} &> /dev/null; then - local cmd_args=${cmd_args_array}[@] + local service_sub=${service_name}_$line[1] + if typeset -p ${service_sub}_args &> /dev/null; then + local cmd_args=${service_sub}_args[@] _arguments -s "${(P)cmd_args}" + elif typeset -p ${service_sub}_cmds &> /dev/null; then + _handle_subcommands "${service_sub}" fi ;; esac - return 0 + elif typeset -p ${service_name}_args &> /dev/null; then + local argname="${service_name}_args[@]" + _arguments -s "${(P)argname}" fi - local argname="${service_func}_args[@]" - _arguments -s "${(P)argname}" +} +_devtools() { + _handle_subcommands _${service//-/_} } _devtools diff --git a/doc/man/devtools.7.asciidoc b/doc/man/devtools.7.asciidoc index 6b2d0c1..4ed11cf 100644 --- a/doc/man/devtools.7.asciidoc +++ b/doc/man/devtools.7.asciidoc @@ -8,16 +8,22 @@ devtools - Developer tools for the Arch Linux distribution Description ----------- -Devtools contains tools for package maintenance in Arch Linux. The toolset -varies from tools for building packages in a clean chroot ('mkarchroot',...), -packaging related tools for sonames ('sogrep', 'lddd') and tools for -repository management such as ('pkgrepo') +Devtools contains tools for package maintenance in Arch Linux. It comes with a +unified command-line frontend called 'pkgctl' that aids to conveniently +interact with all the different tools this collection provides. + +The toolset varies from tools for building packages in a clean chroot +('mkarchroot', 'archbuild', ...), packaging related tools ('sogrep', 'diffpkg', +'lddd') and tools for repository management such as ('pkgrepo'). Programs -------- The list below gives a short overview; see the respective documentation for details. +linkman:pkgctl[1] + Unified command-line frontend for devtools + linkman:archbuild[1] Build an Arch Linux package inside a clean chroot @@ -27,6 +33,12 @@ linkman:arch-nspawn[1] linkman:checkpkg[1] Compare the current build package with the repository version +linkman:diffpkg[1] + Compare package files using different modes + +linkman:export-pkgbuild-keys[1] + Export valid source signing keys from a PKGBUILD + linkman:find-libdeps[1] Find soname dependencies for a package diff --git a/doc/man/diffpkg.1.asciidoc b/doc/man/diffpkg.1.asciidoc index bfb2094..2f7c115 100644 --- a/doc/man/diffpkg.1.asciidoc +++ b/doc/man/diffpkg.1.asciidoc @@ -30,7 +30,6 @@ Options *-M, --makepkg-config*:: Set an alternate makepkg configuration file - *-P, --pool*='DIR':: Search diff target in pool dir (default `'/srv/ftp/pool'`) @@ -71,7 +70,4 @@ Modes *-b, --buildinfo*:: Activate .BUILDINFO diff mode -See Also --------- - include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-diff.1.asciidoc b/doc/man/pkgctl-diff.1.asciidoc new file mode 100644 index 0000000..7eb9e68 --- /dev/null +++ b/doc/man/pkgctl-diff.1.asciidoc @@ -0,0 +1,73 @@ +pkgctl-diff(1) +============== + +Name +---- +pkgctl-diff - Compare package files using different modes. + +Synopsis +-------- +pkgctl diff [OPTIONS] [MODES] [FILE|PKGNAME...] + +Description +----------- + +Searches for a locally built package corresponding to the PKGBUILD, and +downloads the last version of that package from the Pacman repositories. +It then compares the package archives using different modes while using +simple tar content list by default. + +When given one package, use it to diff against the locally built one. +When given two packages, diff both packages against each other. + +In either case, a package name will be converted to a filename from the cache +or pool, and 'pkgctl diff' will proceed as though this filename was initially +specified. + +Options +------- + +*-M, --makepkg-config*:: + Set an alternate makepkg configuration file + +*-P, --pool*='DIR':: + Search diff target in pool dir (default `'/srv/ftp/pool'`) + +*-v, --verbose*:: + Provide more detailed/unfiltered output + +*-h, --help*:: + Show a help text + +Output Options +-------------- + +*--color*[='WHEN']:: + Color output; 'WHEN' is `'never'`, `'always'`, or `'auto'`; Plain *--color* means *--color='auto'* + +*-u, -U, --unified*:: + Output 3 lines of unified context + +*-y, --side-by-side*:: + Output in two columns + +*-W, --width*[='NUM']:: + Output at most 'NUM' (default `'auto'`) print columns; 'NUM' can be `'auto'`, `'columns'` or a number. + `'auto'` will be resolved to the maximum line length of both files, guaranteeing the diff to be uncut. + +Modes +----- + +*-l, --list*:: + Activate tar content list diff mode (default) + +*-d, --diffoscope*:: + Activate diffoscope diff mode + +*-p, --pkginfo*:: + Activate .PKGINFO diff mode + +*-b, --buildinfo*:: + Activate .BUILDINFO diff mode + +include::include/footer.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[] diff --git a/doc/man/pkgctl-repo-configure.1.asciidoc b/doc/man/pkgctl-repo-configure.1.asciidoc new file mode 100644 index 0000000..c3a14de --- /dev/null +++ b/doc/man/pkgctl-repo-configure.1.asciidoc @@ -0,0 +1,32 @@ +pkgctl-repo-configure(1) +======================== + +Name +---- +pkgctl-repo-configure - Configure a clone according to distro specs + +Synopsis +-------- +pkgctl repo configure [OPTIONS] [PATH...] + +Description +----------- + +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 a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-repo-web.1.asciidoc b/doc/man/pkgctl-repo-web.1.asciidoc new file mode 100644 index 0000000..8769be7 --- /dev/null +++ b/doc/man/pkgctl-repo-web.1.asciidoc @@ -0,0 +1,24 @@ +pkgctl-repo-web(1) +================== + +Name +---- +pkgctl-repo-web - Open the packaging repository's website + +Synopsis +-------- +pkgctl repo web [OPTIONS] [PKGBASE...] + +Description +----------- + +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 a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-repo.1.asciidoc b/doc/man/pkgctl-repo.1.asciidoc new file mode 100644 index 0000000..564679a --- /dev/null +++ b/doc/man/pkgctl-repo.1.asciidoc @@ -0,0 +1,51 @@ +pkgctl-repo(1) +================ + +Name +---- +pkgctl-repo - Manage Git packaging repositories and their configuration + +Synopsis +-------- +pkgctl repo [OPTIONS] [SUBCOMMAND] + +Description +----------- + +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. + +Options +------- + +*-h, --help*:: + Show a help text + +Subcommands +----------- + +pkgctl repo clone:: + Clone a package repository + +pkgctl repo configure:: + Configure a clone according to distro specs + +pkgctl repo web:: + Open the packaging repository's website + +See Also +-------- + +linkman:pkgctl-repo-clone[1] +linkman:pkgctl-repo-configure[1] +linkman:pkgctl-repo-web[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc new file mode 100644 index 0000000..0455074 --- /dev/null +++ b/doc/man/pkgctl.1.asciidoc @@ -0,0 +1,32 @@ +pkgctl(1) +========= + +Name +---- +pkgctl - Unified command-line frontend for devtools + +Synopsis +-------- +pkgctl [SUBCOMMAND] [OPTIONS] + +Description +----------- + +TODO + +Subcommands +----------- + +pkgctl diff:: + Compare package files using different modes + +pkgctl repo:: + Manage Git packaging repositories and their configuration + +See Also +-------- + +linkman:pkgctl-diff[1] +linkman:pkgctl-repo[1] + +include::include/footer.asciidoc[] diff --git a/src/diffpkg.in b/src/diffpkg.in index 6d07419..4856e44 100644 --- a/src/diffpkg.in +++ b/src/diffpkg.in @@ -5,8 +5,9 @@ m4_include(lib/common.sh) usage() { - cat <<- _EOF_ - Usage: ${BASH_SOURCE[0]##*/} [OPTIONS] [MODES] [FILE|PKGNAME...] + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [MODES] [FILE|PKGNAME...] Searches for a locally built package corresponding to the PKGBUILD, and downloads the last version of that package from the Pacman repositories. @@ -17,8 +18,8 @@ usage() { When given two packages, diff both packages against each other. In either case, a package name will be converted to a filename from the - cache, and diffpkg will proceed as though this filename was initially - specified. + cache, and '${COMMAND}' will proceed as though this filename was + initially specified. OPTIONS -M, --makepkg-config Set an alternate makepkg configuration file @@ -300,7 +301,7 @@ shopt -u extglob if (( $# < 2 )); then if [[ ! -f PKGBUILD ]]; then - die "This must be run in the directory of a built package.\nTry '$(basename "$0") --help' for more information." + die "This must be run in the directory of a built package.\nTry '${COMMAND} --help' for more information." fi # shellcheck source=contrib/makepkg/PKGBUILD.proto diff --git a/src/pkgctl.in b/src/pkgctl.in new file mode 100644 index 0000000..9b7d89c --- /dev/null +++ b/src/pkgctl.in @@ -0,0 +1,56 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +m4_include(lib/common.sh) + +set -e + + +usage() { + local -r COMMAND=${BASH_SOURCE[0]##*/} + cat <<- _EOF_ + Usage: ${COMMAND} [COMMAND] [OPTIONS] + + Unified command-line frontend for devtools. + + COMMANDS + diff Compare package files using different modes + repo Manage Git packaging repositories and their configuration + + OPTIONS + -h, --help Show this help text +_EOF_ +} + +if (( $# < 1 )); then + usage + exit 1 +fi + +export _DEVTOOLS_COMMAND='pkgctl' + +# command checking +while (( $# )); do + case $1 in + -h|--help) + usage + exit 0 + ;; + repo) + _DEVTOOLS_COMMAND+=" $1" + shift + pkgrepo "$@" + exit 0 + ;; + diff) + _DEVTOOLS_COMMAND+=" $1" + shift + diffpkg "$@" + exit 0 + ;; + *) + die "invalid command: %s" "$1" + ;; + esac +done diff --git a/src/pkgrepo.in b/src/pkgrepo.in index c6f5951..00f46e1 100644 --- a/src/pkgrepo.in +++ b/src/pkgrepo.in @@ -9,10 +9,11 @@ source /usr/share/makepkg/util/message.sh set -e +COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} usage() { cat <<- _EOF_ - Usage: ${BASH_SOURCE[0]##*/} [COMMAND] [OPTIONS] + Usage: ${COMMAND} [COMMAND] [OPTIONS] Manage Git packaging repositories and helps with their configuration according to distro specs. @@ -37,7 +38,7 @@ _EOF_ usage_clone() { cat <<- _EOF_ - Usage: ${BASH_SOURCE[0]##*/} clone [OPTIONS] [PKGNAME...] + Usage: ${COMMAND} clone [OPTIONS] [PKGNAME...] Clone Git packaging repositories from the canonical namespace. @@ -57,7 +58,7 @@ _EOF_ usage_configure() { cat <<- _EOF_ - Usage: ${BASH_SOURCE[0]##*/} configure [OPTIONS] [PATH...] + Usage: ${COMMAND} configure [OPTIONS] [PATH...] Configure Git packaging repositories according to distro specs and makepkg.conf settings. -- cgit v1.2.3-70-g09d2 From b5d5402e439f5edfd642fb4f680d596f5992e874 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Mon, 10 Oct 2022 00:37:51 +0200 Subject: 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. --- Makefile | 59 +++--- contrib/completion/zsh/_devtools.in | 23 ++- lib/archroot.sh | 62 ------- lib/common.sh | 289 ------------------------------ lib/valid-repos.sh | 32 ---- lib/valid-tags.sh | 26 --- src/arch-nspawn.in | 8 +- src/archbuild.in | 8 +- src/archrelease.in | 8 +- src/checkpkg.in | 5 +- src/commitpkg.in | 7 +- src/diffpkg.in | 5 +- src/export-pkgbuild-keys.in | 7 +- src/find-libdeps.in | 5 +- src/finddeps.in | 5 +- src/lddd.in | 5 +- src/lib/archroot.sh | 62 +++++++ src/lib/common.sh | 289 ++++++++++++++++++++++++++++++ src/lib/repo.sh | 90 ++++++++++ src/lib/repo/clone.sh | 139 +++++++++++++++ src/lib/repo/configure.sh | 169 ++++++++++++++++++ src/lib/repo/web.sh | 84 +++++++++ src/lib/valid-repos.sh | 32 ++++ src/lib/valid-tags.sh | 26 +++ src/makechrootpkg.in | 9 +- src/makerepropkg.in | 8 +- src/mkarchroot.in | 8 +- src/pkgctl.in | 8 +- src/pkgrepo.in | 345 ------------------------------------ src/rebuildpkgs.in | 5 +- src/sogrep.in | 8 +- 31 files changed, 1024 insertions(+), 812 deletions(-) delete mode 100644 lib/archroot.sh delete mode 100644 lib/common.sh delete mode 100644 lib/valid-repos.sh delete mode 100644 lib/valid-tags.sh create mode 100644 src/lib/archroot.sh create mode 100644 src/lib/common.sh create mode 100644 src/lib/repo.sh create mode 100644 src/lib/repo/clone.sh create mode 100644 src/lib/repo/configure.sh create mode 100644 src/lib/repo/web.sh create mode 100644 src/lib/valid-repos.sh create mode 100644 src/lib/valid-tags.sh delete mode 100644 src/pkgrepo.in diff --git a/Makefile b/Makefile index 70e977c..f59ca26 100644 --- a/Makefile +++ b/Makefile @@ -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: diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 959497e..b210378 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -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 diff --git a/lib/archroot.sh b/lib/archroot.sh deleted file mode 100644 index d7917da..0000000 --- a/lib/archroot.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/hint/bash -# -# SPDX-License-Identifier: GPL-3.0-or-later -: - -# shellcheck disable=2034 -CHROOT_VERSION='v4' - -## -# usage : check_root $keepenv -## -orig_argv=("${BASH_SOURCE[0]}" "$@") -check_root() { - local keepenv=$1 - - (( EUID == 0 )) && return - if type -P sudo >/dev/null; then - exec sudo --preserve-env=$keepenv -- "${orig_argv[@]}" - else - exec su root -c "$(printf ' %q' "${orig_argv[@]}")" - fi -} - -## -# usage : is_btrfs( $path ) -# return : whether $path is on a btrfs -## -is_btrfs() { - [[ -e "$1" && "$(stat -f -c %T "$1")" == btrfs ]] -} - -## -# usage : is_subvolume( $path ) -# return : whether $path is a the root of a btrfs subvolume (including -# the top-level subvolume). -## -is_subvolume() { - [[ -e "$1" && "$(stat -f -c %T "$1")" == btrfs && "$(stat -c %i "$1")" == 256 ]] -} - -## -# usage : subvolume_delete_recursive( $path ) -# -# Find all btrfs subvolumes under and including $path and delete them. -## -subvolume_delete_recursive() { - local subvol - - is_subvolume "$1" || return 0 - - while IFS= read -d $'\0' -r subvol; do - if ! subvolume_delete_recursive "$subvol"; then - return 1 - fi - done < <(find "$1" -mindepth 1 -xdev -depth -inum 256 -print0) - if ! btrfs subvolume delete "$1" &>/dev/null; then - error "Unable to delete subvolume %s" "$subvol" - return 1 - fi - - return 0 -} diff --git a/lib/common.sh b/lib/common.sh deleted file mode 100644 index d2351af..0000000 --- a/lib/common.sh +++ /dev/null @@ -1,289 +0,0 @@ -#!/hint/bash -# -# This may be included with or without `set -euE` -# -# SPDX-License-Identifier: GPL-3.0-or-later - -[[ -z ${_INCLUDE_COMMON_SH:-} ]] || return 0 -_INCLUDE_COMMON_SH="$(set +o|grep nounset)" - -set +u +o posix -# shellcheck disable=1091 -. /usr/share/makepkg/util.sh -$_INCLUDE_COMMON_SH - -# Avoid any encoding problems -export LANG=C - -# Set buildtool properties -export BUILDTOOL=devtools -export BUILDTOOLVER=m4_devtools_version - -# Set common properties -export PACMAN_KEYRING_DIR=/etc/pacman.d/gnupg -export GITLAB_HOST=gitlab.archlinux.org -export GIT_REPO_SPEC_VERSION=1 -export GIT_PACKAGING_NAMESPACE=archlinux/packaging/packages -export GIT_PACKAGING_NAMESPACE_ID=11323 -export GIT_PACKAGING_URL_SSH="ssh://git@${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}" -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 - colorize -else - # shellcheck disable=2034 - declare -gr ALL_OFF='' BOLD='' BLUE='' GREEN='' RED='' YELLOW='' -fi - -stat_busy() { - local mesg=$1; shift - # shellcheck disable=2059 - printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}...${ALL_OFF}" "$@" >&2 -} - -stat_progress() { - # shellcheck disable=2059 - printf "${BOLD}.${ALL_OFF}" >&2 -} - -stat_done() { - # shellcheck disable=2059 - printf "${BOLD}done${ALL_OFF}\n" >&2 -} - -_setup_workdir=false -setup_workdir() { - [[ -z ${WORKDIR:-} ]] && WORKDIR=$(mktemp -d --tmpdir "${0##*/}.XXXXXXXXXX") - _setup_workdir=true - trap 'trap_abort' INT QUIT TERM HUP - trap 'trap_exit' EXIT -} - -cleanup() { - if [[ -n ${WORKDIR:-} ]] && $_setup_workdir; then - rm -rf "$WORKDIR" - fi - exit "${1:-0}" -} - -abort() { - error 'Aborting...' - cleanup 255 -} - -trap_abort() { - trap - EXIT INT QUIT TERM HUP - abort -} - -trap_exit() { - local r=$? - trap - EXIT INT QUIT TERM HUP - cleanup $r -} - -die() { - (( $# )) && error "$@" - cleanup 255 -} - -## -# usage : lock( $fd, $file, $message, [ $message_arguments... ] ) -## -lock() { - # Only reopen the FD if it wasn't handed to us - if ! [[ "/dev/fd/$1" -ef "$2" ]]; then - mkdir -p -- "$(dirname -- "$2")" - eval "exec $1>"'"$2"' - fi - - if ! flock -n "$1"; then - stat_busy "${@:3}" - flock "$1" - stat_done - fi -} - -## -# usage : slock( $fd, $file, $message, [ $message_arguments... ] ) -## -slock() { - # Only reopen the FD if it wasn't handed to us - if ! [[ "/dev/fd/$1" -ef "$2" ]]; then - mkdir -p -- "$(dirname -- "$2")" - eval "exec $1>"'"$2"' - fi - - if ! flock -sn "$1"; then - stat_busy "${@:3}" - flock -s "$1" - stat_done - fi -} - -## -# usage : lock_close( $fd ) -## -lock_close() { - local fd=$1 - # https://github.com/koalaman/shellcheck/issues/862 - # shellcheck disable=2034 - exec {fd}>&- -} - -## -# usage: pkgver_equal( $pkgver1, $pkgver2 ) -## -pkgver_equal() { - if [[ $1 = *-* && $2 = *-* ]]; then - # if both versions have a pkgrel, then they must be an exact match - [[ $1 = "$2" ]] - else - # otherwise, trim any pkgrel and compare the bare version. - [[ ${1%%-*} = "${2%%-*}" ]] - fi -} - -## -# usage: find_cached_package( $pkgname, $pkgver, $arch ) -# -# $pkgver can be supplied with or without a pkgrel appended. -# If not supplied, any pkgrel will be matched. -## -shopt -s extglob -find_cached_package() { - local searchdirs=("$PWD" "$PKGDEST") results=() - local targetname=$1 targetver=$2 targetarch=$3 - local dir pkg packages pkgbasename name ver rel arch r results - - for dir in "${searchdirs[@]}"; do - [[ -d $dir ]] || continue - - shopt -s extglob nullglob - mapfile -t packages < <(printf "%s\n" "$dir"/"${targetname}"-"${targetver}"-*"${targetarch}".pkg.tar?(.!(sig|*.*))) - shopt -u extglob nullglob - - for pkg in "${packages[@]}"; do - [[ -f $pkg ]] || continue - - # avoid adding duplicates of the same inode - for r in "${results[@]}"; do - [[ $r -ef $pkg ]] && continue 2 - done - - # split apart package filename into parts - pkgbasename=${pkg##*/} - pkgbasename=${pkgbasename%.pkg.tar*} - - arch=${pkgbasename##*-} - pkgbasename=${pkgbasename%-"$arch"} - - rel=${pkgbasename##*-} - pkgbasename=${pkgbasename%-"$rel"} - - ver=${pkgbasename##*-} - name=${pkgbasename%-"$ver"} - - if [[ $targetname = "$name" && $targetarch = "$arch" ]] && - pkgver_equal "$targetver" "$ver-$rel"; then - results+=("$pkg") - fi - done - done - - case ${#results[*]} in - 0) - return 1 - ;; - 1) - printf '%s\n' "${results[0]}" - return 0 - ;; - *) - error 'Multiple packages found:' - printf '\t%s\n' "${results[@]}" >&2 - return 1 - esac -} -shopt -u extglob - -check_package_validity(){ - local pkgfile=$1 - if grep -q "packager = Unknown Packager" <(bsdtar -xOqf "$pkgfile" .PKGINFO); then - die "PACKAGER was not set when building package" - fi - hashsum=sha256sum - pkgbuild_hash=$(awk -v"hashsum=$hashsum" -F' = ' '$1 == "pkgbuild_"hashsum {print $2}' <(bsdtar -xOqf "$pkgfile" .BUILDINFO)) - if [[ "$pkgbuild_hash" != "$($hashsum PKGBUILD|cut -d' ' -f1)" ]]; then - die "PKGBUILD $hashsum mismatch: expected $pkgbuild_hash" - fi -} - - -# usage: grep_pkginfo pkgfile pattern -grep_pkginfo() { - local _ret=() - mapfile -t _ret < <(bsdtar -xOqf "$1" ".PKGINFO" | grep "^${2} = ") - printf '%s\n' "${_ret[@]#${2} = }" -} - - -# Get the package name -getpkgname() { - local _name - - _name="$(grep_pkginfo "$1" "pkgname")" - if [[ -z $_name ]]; then - error "Package '%s' has no pkgname in the PKGINFO. Fail!" "$1" - exit 1 - fi - - echo "$_name" -} - - -# Get the package base or name as fallback -getpkgbase() { - local _base - - _base="$(grep_pkginfo "$1" "pkgbase")" - if [[ -z $_base ]]; then - getpkgname "$1" - else - echo "$_base" - fi -} - - -getpkgdesc() { - local _desc - - _desc="$(grep_pkginfo "$1" "pkgdesc")" - if [[ -z $_desc ]]; then - error "Package '%s' has no pkgdesc in the PKGINFO. Fail!" "$1" - exit 1 - fi - - echo "$_desc" -} - - -get_tag_from_pkgver() { - local pkgver=$1 - local tag=${pkgver} - - tag=${tag/:/-} - tag=${tag//~/.} - echo "${tag}" -} - - -is_debug_package() { - local pkgfile=${1} pkgbase pkgname pkgdesc - pkgbase="$(getpkgbase "${pkgfile}")" - pkgname="$(getpkgname "${pkgfile}")" - pkgdesc="$(getpkgdesc "${pkgfile}")" - [[ ${pkgdesc} == "Detached debugging symbols for "* && ${pkgbase}-debug = "${pkgname}" ]] -} diff --git a/lib/valid-repos.sh b/lib/valid-repos.sh deleted file mode 100644 index 9ac9639..0000000 --- a/lib/valid-repos.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/hint/bash -# -# SPDX-License-Identifier: GPL-3.0-or-later -: - -# shellcheck disable=2034 -_repos=( - staging - testing - core - extra - community-staging - community-testing - community - multilib-staging - multilib-testing - multilib - gnome-unstable - kde-unstable -) - -# shellcheck disable=2034 -_build_repos=( - staging - testing - extra - multilib-staging - multilib-testing - multilib - gnome-unstable - kde-unstable -) diff --git a/lib/valid-tags.sh b/lib/valid-tags.sh deleted file mode 100644 index d628fd1..0000000 --- a/lib/valid-tags.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/hint/bash -# -# SPDX-License-Identifier: GPL-3.0-or-later -: - -# shellcheck disable=2034 -_arch=( - x86_64 - any -) - -# shellcheck disable=2034 -_tags=( - core-x86_64 core-any - extra-x86_64 extra-any - multilib-x86_64 - staging-x86_64 staging-any - testing-x86_64 testing-any - multilib-testing-x86_64 - multilib-staging-x86_64 - community-x86_64 community-any - community-staging-x86_64 community-staging-any - community-testing-x86_64 community-testing-any - kde-unstable-x86_64 kde-unstable-any - gnome-unstable-x86_64 gnome-unstable-any -) diff --git a/src/arch-nspawn.in b/src/arch-nspawn.in index 275cff7..77a27ad 100644 --- a/src/arch-nspawn.in +++ b/src/arch-nspawn.in @@ -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 diff --git a/src/archbuild.in b/src/archbuild.in index ba3ba94..3367011 100644 --- a/src/archbuild.in +++ b/src/archbuild.in @@ -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) diff --git a/src/archrelease.in b/src/archrelease.in index 3dd969b..b89dad2 100644 --- a/src/archrelease.in +++ b/src/archrelease.in @@ -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= diff --git a/src/checkpkg.in b/src/checkpkg.in index fe5b71a..ccb7259 100644 --- a/src/checkpkg.in +++ b/src/checkpkg.in @@ -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_ diff --git a/src/commitpkg.in b/src/commitpkg.in index 7b6e904..9158763 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -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 diff --git a/src/diffpkg.in b/src/diffpkg.in index 4856e44..ab1a5af 100644 --- a/src/diffpkg.in +++ b/src/diffpkg.in @@ -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]##*/}} diff --git a/src/export-pkgbuild-keys.in b/src/export-pkgbuild-keys.in index 8697b3d..c19fc8b 100644 --- a/src/export-pkgbuild-keys.in +++ b/src/export-pkgbuild-keys.in @@ -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[@]}" diff --git a/src/find-libdeps.in b/src/find-libdeps.in index 2517879..afdf0f5 100644 --- a/src/find-libdeps.in +++ b/src/find-libdeps.in @@ -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 diff --git a/src/finddeps.in b/src/finddeps.in index da7cb85..20d7095 100644 --- a/src/finddeps.in +++ b/src/finddeps.in @@ -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 diff --git a/src/lddd.in b/src/lddd.in index 12f8d67..80c22c4 100644 --- a/src/lddd.in +++ b/src/lddd.in @@ -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}:" diff --git a/src/lib/archroot.sh b/src/lib/archroot.sh new file mode 100644 index 0000000..d7917da --- /dev/null +++ b/src/lib/archroot.sh @@ -0,0 +1,62 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +: + +# shellcheck disable=2034 +CHROOT_VERSION='v4' + +## +# usage : check_root $keepenv +## +orig_argv=("${BASH_SOURCE[0]}" "$@") +check_root() { + local keepenv=$1 + + (( EUID == 0 )) && return + if type -P sudo >/dev/null; then + exec sudo --preserve-env=$keepenv -- "${orig_argv[@]}" + else + exec su root -c "$(printf ' %q' "${orig_argv[@]}")" + fi +} + +## +# usage : is_btrfs( $path ) +# return : whether $path is on a btrfs +## +is_btrfs() { + [[ -e "$1" && "$(stat -f -c %T "$1")" == btrfs ]] +} + +## +# usage : is_subvolume( $path ) +# return : whether $path is a the root of a btrfs subvolume (including +# the top-level subvolume). +## +is_subvolume() { + [[ -e "$1" && "$(stat -f -c %T "$1")" == btrfs && "$(stat -c %i "$1")" == 256 ]] +} + +## +# usage : subvolume_delete_recursive( $path ) +# +# Find all btrfs subvolumes under and including $path and delete them. +## +subvolume_delete_recursive() { + local subvol + + is_subvolume "$1" || return 0 + + while IFS= read -d $'\0' -r subvol; do + if ! subvolume_delete_recursive "$subvol"; then + return 1 + fi + done < <(find "$1" -mindepth 1 -xdev -depth -inum 256 -print0) + if ! btrfs subvolume delete "$1" &>/dev/null; then + error "Unable to delete subvolume %s" "$subvol" + return 1 + fi + + return 0 +} diff --git a/src/lib/common.sh b/src/lib/common.sh new file mode 100644 index 0000000..f977726 --- /dev/null +++ b/src/lib/common.sh @@ -0,0 +1,289 @@ +#!/hint/bash +# +# This may be included with or without `set -euE` +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -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 +$DEVTOOLS_INCLUDE_COMMON_SH + +# Avoid any encoding problems +export LANG=C + +# Set buildtool properties +export BUILDTOOL=devtools +export BUILDTOOLVER=m4_devtools_version + +# Set common properties +export PACMAN_KEYRING_DIR=/etc/pacman.d/gnupg +export GITLAB_HOST=gitlab.archlinux.org +export GIT_REPO_SPEC_VERSION=1 +export GIT_PACKAGING_NAMESPACE=archlinux/packaging/packages +export GIT_PACKAGING_NAMESPACE_ID=11323 +export GIT_PACKAGING_URL_SSH="ssh://git@${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}" +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 + colorize +else + # shellcheck disable=2034 + declare -gr ALL_OFF='' BOLD='' BLUE='' GREEN='' RED='' YELLOW='' +fi + +stat_busy() { + local mesg=$1; shift + # shellcheck disable=2059 + printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}...${ALL_OFF}" "$@" >&2 +} + +stat_progress() { + # shellcheck disable=2059 + printf "${BOLD}.${ALL_OFF}" >&2 +} + +stat_done() { + # shellcheck disable=2059 + printf "${BOLD}done${ALL_OFF}\n" >&2 +} + +_setup_workdir=false +setup_workdir() { + [[ -z ${WORKDIR:-} ]] && WORKDIR=$(mktemp -d --tmpdir "${0##*/}.XXXXXXXXXX") + _setup_workdir=true + trap 'trap_abort' INT QUIT TERM HUP + trap 'trap_exit' EXIT +} + +cleanup() { + if [[ -n ${WORKDIR:-} ]] && $_setup_workdir; then + rm -rf "$WORKDIR" + fi + exit "${1:-0}" +} + +abort() { + error 'Aborting...' + cleanup 255 +} + +trap_abort() { + trap - EXIT INT QUIT TERM HUP + abort +} + +trap_exit() { + local r=$? + trap - EXIT INT QUIT TERM HUP + cleanup $r +} + +die() { + (( $# )) && error "$@" + cleanup 255 +} + +## +# usage : lock( $fd, $file, $message, [ $message_arguments... ] ) +## +lock() { + # Only reopen the FD if it wasn't handed to us + if ! [[ "/dev/fd/$1" -ef "$2" ]]; then + mkdir -p -- "$(dirname -- "$2")" + eval "exec $1>"'"$2"' + fi + + if ! flock -n "$1"; then + stat_busy "${@:3}" + flock "$1" + stat_done + fi +} + +## +# usage : slock( $fd, $file, $message, [ $message_arguments... ] ) +## +slock() { + # Only reopen the FD if it wasn't handed to us + if ! [[ "/dev/fd/$1" -ef "$2" ]]; then + mkdir -p -- "$(dirname -- "$2")" + eval "exec $1>"'"$2"' + fi + + if ! flock -sn "$1"; then + stat_busy "${@:3}" + flock -s "$1" + stat_done + fi +} + +## +# usage : lock_close( $fd ) +## +lock_close() { + local fd=$1 + # https://github.com/koalaman/shellcheck/issues/862 + # shellcheck disable=2034 + exec {fd}>&- +} + +## +# usage: pkgver_equal( $pkgver1, $pkgver2 ) +## +pkgver_equal() { + if [[ $1 = *-* && $2 = *-* ]]; then + # if both versions have a pkgrel, then they must be an exact match + [[ $1 = "$2" ]] + else + # otherwise, trim any pkgrel and compare the bare version. + [[ ${1%%-*} = "${2%%-*}" ]] + fi +} + +## +# usage: find_cached_package( $pkgname, $pkgver, $arch ) +# +# $pkgver can be supplied with or without a pkgrel appended. +# If not supplied, any pkgrel will be matched. +## +shopt -s extglob +find_cached_package() { + local searchdirs=("$PWD" "$PKGDEST") results=() + local targetname=$1 targetver=$2 targetarch=$3 + local dir pkg packages pkgbasename name ver rel arch r results + + for dir in "${searchdirs[@]}"; do + [[ -d $dir ]] || continue + + shopt -s extglob nullglob + mapfile -t packages < <(printf "%s\n" "$dir"/"${targetname}"-"${targetver}"-*"${targetarch}".pkg.tar?(.!(sig|*.*))) + shopt -u extglob nullglob + + for pkg in "${packages[@]}"; do + [[ -f $pkg ]] || continue + + # avoid adding duplicates of the same inode + for r in "${results[@]}"; do + [[ $r -ef $pkg ]] && continue 2 + done + + # split apart package filename into parts + pkgbasename=${pkg##*/} + pkgbasename=${pkgbasename%.pkg.tar*} + + arch=${pkgbasename##*-} + pkgbasename=${pkgbasename%-"$arch"} + + rel=${pkgbasename##*-} + pkgbasename=${pkgbasename%-"$rel"} + + ver=${pkgbasename##*-} + name=${pkgbasename%-"$ver"} + + if [[ $targetname = "$name" && $targetarch = "$arch" ]] && + pkgver_equal "$targetver" "$ver-$rel"; then + results+=("$pkg") + fi + done + done + + case ${#results[*]} in + 0) + return 1 + ;; + 1) + printf '%s\n' "${results[0]}" + return 0 + ;; + *) + error 'Multiple packages found:' + printf '\t%s\n' "${results[@]}" >&2 + return 1 + esac +} +shopt -u extglob + +check_package_validity(){ + local pkgfile=$1 + if grep -q "packager = Unknown Packager" <(bsdtar -xOqf "$pkgfile" .PKGINFO); then + die "PACKAGER was not set when building package" + fi + hashsum=sha256sum + pkgbuild_hash=$(awk -v"hashsum=$hashsum" -F' = ' '$1 == "pkgbuild_"hashsum {print $2}' <(bsdtar -xOqf "$pkgfile" .BUILDINFO)) + if [[ "$pkgbuild_hash" != "$($hashsum PKGBUILD|cut -d' ' -f1)" ]]; then + die "PKGBUILD $hashsum mismatch: expected $pkgbuild_hash" + fi +} + + +# usage: grep_pkginfo pkgfile pattern +grep_pkginfo() { + local _ret=() + mapfile -t _ret < <(bsdtar -xOqf "$1" ".PKGINFO" | grep "^${2} = ") + printf '%s\n' "${_ret[@]#${2} = }" +} + + +# Get the package name +getpkgname() { + local _name + + _name="$(grep_pkginfo "$1" "pkgname")" + if [[ -z $_name ]]; then + error "Package '%s' has no pkgname in the PKGINFO. Fail!" "$1" + exit 1 + fi + + echo "$_name" +} + + +# Get the package base or name as fallback +getpkgbase() { + local _base + + _base="$(grep_pkginfo "$1" "pkgbase")" + if [[ -z $_base ]]; then + getpkgname "$1" + else + echo "$_base" + fi +} + + +getpkgdesc() { + local _desc + + _desc="$(grep_pkginfo "$1" "pkgdesc")" + if [[ -z $_desc ]]; then + error "Package '%s' has no pkgdesc in the PKGINFO. Fail!" "$1" + exit 1 + fi + + echo "$_desc" +} + + +get_tag_from_pkgver() { + local pkgver=$1 + local tag=${pkgver} + + tag=${tag/:/-} + tag=${tag//~/.} + echo "${tag}" +} + + +is_debug_package() { + local pkgfile=${1} pkgbase pkgname pkgdesc + pkgbase="$(getpkgbase "${pkgfile}")" + pkgname="$(getpkgname "${pkgfile}")" + pkgdesc="$(getpkgdesc "${pkgfile}")" + [[ ${pkgdesc} == "Detached debugging symbols for "* && ${pkgbase}-debug = "${pkgname}" ]] +} diff --git a/src/lib/repo.sh b/src/lib/repo.sh new file mode 100644 index 0000000..8b8df11 --- /dev/null +++ b/src/lib/repo.sh @@ -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 +} diff --git a/src/lib/repo/clone.sh b/src/lib/repo/clone.sh new file mode 100644 index 0000000..42dc383 --- /dev/null +++ b/src/lib/repo/clone.sh @@ -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 +} diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh new file mode 100644 index 0000000..5c99562 --- /dev/null +++ b/src/lib/repo/configure.sh @@ -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 +} diff --git a/src/lib/repo/web.sh b/src/lib/repo/web.sh new file mode 100644 index 0000000..3fa214d --- /dev/null +++ b/src/lib/repo/web.sh @@ -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 +} diff --git a/src/lib/valid-repos.sh b/src/lib/valid-repos.sh new file mode 100644 index 0000000..9ac9639 --- /dev/null +++ b/src/lib/valid-repos.sh @@ -0,0 +1,32 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +: + +# shellcheck disable=2034 +_repos=( + staging + testing + core + extra + community-staging + community-testing + community + multilib-staging + multilib-testing + multilib + gnome-unstable + kde-unstable +) + +# shellcheck disable=2034 +_build_repos=( + staging + testing + extra + multilib-staging + multilib-testing + multilib + gnome-unstable + kde-unstable +) diff --git a/src/lib/valid-tags.sh b/src/lib/valid-tags.sh new file mode 100644 index 0000000..d628fd1 --- /dev/null +++ b/src/lib/valid-tags.sh @@ -0,0 +1,26 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +: + +# shellcheck disable=2034 +_arch=( + x86_64 + any +) + +# shellcheck disable=2034 +_tags=( + core-x86_64 core-any + extra-x86_64 extra-any + multilib-x86_64 + staging-x86_64 staging-any + testing-x86_64 testing-any + multilib-testing-x86_64 + multilib-staging-x86_64 + community-x86_64 community-any + community-staging-x86_64 community-staging-any + community-testing-x86_64 community-testing-any + kde-unstable-x86_64 kde-unstable-any + gnome-unstable-x86_64 gnome-unstable-any +) diff --git a/src/makechrootpkg.in b/src/makechrootpkg.in index 5d3eaae..8d3d093 100644 --- a/src/makechrootpkg.in +++ b/src/makechrootpkg.in @@ -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 diff --git a/src/makerepropkg.in b/src/makerepropkg.in index c58a923..e0a5b85 100644 --- a/src/makerepropkg.in +++ b/src/makerepropkg.in @@ -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 diff --git a/src/mkarchroot.in b/src/mkarchroot.in index ff3426e..6c8d8a2 100644 --- a/src/mkarchroot.in +++ b/src/mkarchroot.in @@ -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 diff --git a/src/pkgctl.in b/src/pkgctl.in index 9b7d89c..64d9bcd 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -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) diff --git a/src/pkgrepo.in b/src/pkgrepo.in deleted file mode 100644 index 00f46e1..0000000 --- a/src/pkgrepo.in +++ /dev/null @@ -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 diff --git a/src/rebuildpkgs.in b/src/rebuildpkgs.in index f58cfab..7bf8b12 100644 --- a/src/rebuildpkgs.in +++ b/src/rebuildpkgs.in @@ -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 \n' "$(basename "${BASH_SOURCE[0]}")" diff --git a/src/sogrep.in b/src/sogrep.in index 031d28e..0ee05cc 100644 --- a/src/sogrep.in +++ b/src/sogrep.in @@ -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 -- cgit v1.2.3-70-g09d2 From f63d343e40f7f07c7a900cbb7445bbefa0997259 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 22 Oct 2022 15:49:57 +0200 Subject: config: implemented simple config module to store token and settings --- src/lib/config.sh | 27 +++++++++++++++++++++++++++ src/pkgctl.in | 4 ++++ 2 files changed, 31 insertions(+) create mode 100644 src/lib/config.sh diff --git a/src/lib/config.sh b/src/lib/config.sh new file mode 100644 index 0000000..5034c6e --- /dev/null +++ b/src/lib/config.sh @@ -0,0 +1,27 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_CONFIG_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_CONFIG_SH=1 + +set -e + +readonly XDG_DEVTOOLS_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/devtools" +readonly XDG_DEVTOOLS_GITLAB_CONFIG="${XDG_DEVTOOLS_DIR}/gitlab.conf" + +# default config variables +export GITLAB_TOKEN="" + +load_devtools_config() { + if [[ ! -f "${XDG_DEVTOOLS_GITLAB_CONFIG}" ]]; then + GITLAB_TOKEN="" + return + fi + GITLAB_TOKEN=$(grep GITLAB_TOKEN "${XDG_DEVTOOLS_GITLAB_CONFIG}"|cut -d= -f2|cut -d\" -f2) +} + +save_devtools_config() { + mkdir -p "${XDG_DEVTOOLS_DIR}" + printf 'GITLAB_TOKEN="%s"\n' "${GITLAB_TOKEN}" > "${XDG_DEVTOOLS_GITLAB_CONFIG}" +} diff --git a/src/pkgctl.in b/src/pkgctl.in index 64d9bcd..35305c1 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -5,6 +5,8 @@ _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} # shellcheck source=src/lib/common.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/config.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/config.sh set -e @@ -32,6 +34,8 @@ fi export _DEVTOOLS_COMMAND='pkgctl' +load_devtools_config + # command checking while (( $# )); do case $1 in -- cgit v1.2.3-70-g09d2 From d2245b1943fd30ab0252e47d47871ac94e143339 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 22 Oct 2022 15:40:40 +0200 Subject: gitlab: implemented module for required API calls We need to use API calls as we can't create repositories in protected namespaces by simply pushing a none existing repository. For privacy reasons this is limited to private personal repositories in GitLab. --- src/lib/api/gitlab.sh | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/common.sh | 24 +++++++++++ 2 files changed, 132 insertions(+) create mode 100644 src/lib/api/gitlab.sh diff --git a/src/lib/api/gitlab.sh b/src/lib/api/gitlab.sh new file mode 100644 index 0000000..649e205 --- /dev/null +++ b/src/lib/api/gitlab.sh @@ -0,0 +1,108 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_API_GITLAB_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_API_GITLAB_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/config.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/config.sh + +set -e + + +gitlab_api_call() { + local outfile=$1 + local request=$2 + local endpoint=$3 + local data=${4:-} + local error + + # empty token + if [[ -z "${GITLAB_TOKEN}" ]]; then + msg_error " api call failed: No token provided" + return 1 + fi + + if ! curl --request "${request}" \ + --url "https://${GITLAB_HOST}/api/v4/${endpoint}" \ + --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \ + --header "Content-Type: application/json" \ + --data "${data}" \ + --output "${outfile}" \ + --silent; then + msg_error " api call failed: $(cat "${outfile}")" + return 1 + fi + + # check for general purpose api error + if error=$(jq --raw-output --exit-status '.error' < "${outfile}"); then + msg_error " api call failed: ${error}" + return 1 + fi + + # check for api specific error messages + if ! jq --raw-output --exit-status '.id' < "${outfile}" >/dev/null; then + if jq --raw-output --exit-status '.message | keys[]' < "${outfile}" &>/dev/null; then + while read -r error; do + msg_error " api call failed: ${error}" + done < <(jq --raw-output --exit-status '.message|to_entries|map("\(.key) \(.value[])")[]' < "${outfile}") + elif error=$(jq --raw-output --exit-status '.message' < "${outfile}"); then + msg_error " api call failed: ${error}" + fi + return 1 + fi + + return 0 +} + +gitlab_api_get_user() { + local outfile username + + [[ -z ${WORKDIR:-} ]] && setup_workdir + outfile=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api.XXXXXXXXXX) + + # query user details + if ! gitlab_api_call "${outfile}" GET "user/"; then + msg_warn " Invalid token provided?" + exit 1 + fi + + # extract username from details + if ! username=$(jq --raw-output --exit-status '.username' < "${outfile}"); then + msg_error " failed to query username: $(cat "${outfile}")" + return 1 + fi + + printf "%s" "${username}" + return 0 +} + +gitlab_api_create_project() { + local pkgbase=$1 + local outfile data path + + [[ -z ${WORKDIR:-} ]] && setup_workdir + outfile=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api.XXXXXXXXXX) + + # create GitLab project + data='{ + "name": "'"${pkgbase}"'", + "namespace_id": "'"${GIT_PACKAGING_NAMESPACE_ID}"'", + "request_access_enabled": "false" + }' + if ! gitlab_api_call "${outfile}" POST "projects/" "${data}"; then + return 1 + fi + + if ! path=$(jq --raw-output --exit-status '.path' < "${outfile}"); then + msg_error " failed to query path: $(cat "${outfile}")" + return 1 + fi + + printf "%s" "${path}" + return 0 +} diff --git a/src/lib/common.sh b/src/lib/common.sh index f977726..1fe396c 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -53,6 +53,30 @@ stat_done() { printf "${BOLD}done${ALL_OFF}\n" >&2 } +msg_success() { + local msg=$1 + local padding + padding=$(echo "${msg}"|sed -E 's/( *).*/\1/') + msg=$(echo "${msg}"|sed -E 's/ *(.*)/\1/') + printf "%s %s\n" "${padding}${GREEN}✓${ALL_OFF}" "${msg}" >&2 +} + +msg_error() { + local msg=$1 + local padding + padding=$(echo "${msg}"|sed -E 's/( *).*/\1/') + msg=$(echo "${msg}"|sed -E 's/ *(.*)/\1/') + printf "%s %s\n" "${padding}${RED}x${ALL_OFF}" "${msg}" >&2 +} + +msg_warn() { + local msg=$1 + local padding + padding=$(echo "${msg}"|sed -E 's/( *).*/\1/') + msg=$(echo "${msg}"|sed -E 's/ *(.*)/\1/') + printf "%s %s\n" "${padding}${YELLOW}!${ALL_OFF}" "${msg}" >&2 +} + _setup_workdir=false setup_workdir() { [[ -z ${WORKDIR:-} ]] && WORKDIR=$(mktemp -d --tmpdir "${0##*/}.XXXXXXXXXX") -- cgit v1.2.3-70-g09d2 From 77d800eab2419b334cafd94b2e986351919def77 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 23 Oct 2022 20:42:34 +0200 Subject: auth: implemented module to authenticate against our GitLab This helps to have a convenient way to manage and test our personal GitLab tokens. Those are used for certain API calls like creating new repositories. prefill the access token web view as per https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#prefill-personal-access-token-name-and-scopes Signed-off-by: Levente Polyak --- contrib/completion/zsh/_devtools.in | 17 +++++++ doc/man/pkgctl-auth-login.1.asciidoc | 33 +++++++++++++ doc/man/pkgctl-auth-status.1.asciidoc | 32 ++++++++++++ doc/man/pkgctl-auth.1.asciidoc | 38 ++++++++++++++ doc/man/pkgctl.1.asciidoc | 4 ++ src/lib/auth.sh | 72 +++++++++++++++++++++++++++ src/lib/auth/login.sh | 93 +++++++++++++++++++++++++++++++++++ src/lib/auth/status.sh | 69 ++++++++++++++++++++++++++ src/pkgctl.in | 9 ++++ 9 files changed, 367 insertions(+) create mode 100644 doc/man/pkgctl-auth-login.1.asciidoc create mode 100644 doc/man/pkgctl-auth-status.1.asciidoc create mode 100644 doc/man/pkgctl-auth.1.asciidoc create mode 100644 src/lib/auth.sh create mode 100644 src/lib/auth/login.sh create mode 100644 src/lib/auth/status.sh diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index b210378..6ff6cad 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -18,6 +18,22 @@ _archbuild_args=( '--[Introduce makechrootpkg options]:*::makechrootpkg options:= _dispatch makechrootpkg makechrootpkg' ) +_pkgctl_auth_cmds=( + "pkgctl auth command" + "login[Authenticate with the GitLab instance]" + "status[View authentication status]" +) + +_pkgctl_auth_login_args=( + '(-g --gen-access-token)'{-g,--gen-access-token}'[Open the URL to generate a new personal access token]' + '(-h --help)'{-h,--help}'[Display usage]' +) + +_pkgctl_auth_status_args=( + '(-t --show-token)'{-t,--show-token}'[Display the auth token]' + '(-h --help)'{-h,--help}'[Display usage]' +) + _pkgctl_repo_cmds=( "pkgctl repo command" "clone[Clone a package repository]" @@ -154,6 +170,7 @@ _devtools_completions_all_packages() { _pkgctl_cmds=( "pkgctl command" + "auth[Authenticate with services like GitLab]" "diff[Compare package files using different modes]" "repo[Manage Git packaging repositories and their configuration]" ) diff --git a/doc/man/pkgctl-auth-login.1.asciidoc b/doc/man/pkgctl-auth-login.1.asciidoc new file mode 100644 index 0000000..9c32ab2 --- /dev/null +++ b/doc/man/pkgctl-auth-login.1.asciidoc @@ -0,0 +1,33 @@ +pkgctl-auth-login(1) +==================== + +Name +---- +pkgctl-auth-login - Authenticate with the GitLab instance + +Synopsis +-------- +pkgctl auth login [OPTIONS] + +Description +----------- + +Interactively authenticate with the GitLab instance. + +The minimum required scopes for the token are: 'api', 'write_repository'. + +Options +------- + +*-g, --gen-access-token*:: + Open the URL to generate a new personal access token + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-auth-status[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-auth-status.1.asciidoc b/doc/man/pkgctl-auth-status.1.asciidoc new file mode 100644 index 0000000..e23ee2e --- /dev/null +++ b/doc/man/pkgctl-auth-status.1.asciidoc @@ -0,0 +1,32 @@ +pkgctl-auth-status(1) +===================== + +Name +---- +pkgctl-auth-status - View authentication status + +Synopsis +-------- +pkgctl auth status [OPTIONS] + +Description +----------- + +Verifies and displays information about your authentication state of +services like the GitLab instance and reports issues if any. + +Options +------- + +*-t, --show-token*:: + Display the auth token + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-auth-login[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-auth.1.asciidoc b/doc/man/pkgctl-auth.1.asciidoc new file mode 100644 index 0000000..4912b02 --- /dev/null +++ b/doc/man/pkgctl-auth.1.asciidoc @@ -0,0 +1,38 @@ +pkgctl-auth(1) +============== + +Name +---- +pkgctl-auth - Authenticate with serivces like GitLab. + +Synopsis +-------- +pkgctl auth [OPTIONS] [SUBCOMMAND] + +Description +----------- + +Manage the authorization for the GitLab instance and show its current status. + +Options +------- + +*-h, --help*:: + Show a help text + +Subcommands +----------- + +pkgctl auth login:: + Authenticate with the GitLab instance + +pkgctl auth status:: + View authentication status + +See Also +-------- + +linkman:pkgctl-auth-login[1] +linkman:pkgctl-auth-status[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 0455074..45d5187 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -17,6 +17,9 @@ TODO Subcommands ----------- +pkgctl auth:: + Authenticate with services like GitLab + pkgctl diff:: Compare package files using different modes @@ -26,6 +29,7 @@ pkgctl repo:: See Also -------- +linkman:pkgctl-auth[1] linkman:pkgctl-diff[1] linkman:pkgctl-repo[1] diff --git a/src/lib/auth.sh b/src/lib/auth.sh new file mode 100644 index 0000000..77d6a90 --- /dev/null +++ b/src/lib/auth.sh @@ -0,0 +1,72 @@ +#!/hint/bash +# +# This may be included with or without `set -euE` +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_AUTH_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_AUTH_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + +set -e + + +pkgctl_auth_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [COMMAND] [OPTIONS] + + Authenticate with services like GitLab. + + COMMANDS + login Authenticate with the GitLab instance + status View authentication status + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} login --gen-access-token + $ ${COMMAND} status +_EOF_ +} + +pkgctl_auth() { + if (( $# < 1 )); then + pkgctl_auth_usage + exit 0 + fi + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_auth_usage + exit 0 + ;; + login) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/auth/login.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/auth/login.sh + pkgctl_auth_login "$@" + exit 0 + ;; + status) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/auth/status.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/auth/status.sh + pkgctl_auth_status "$@" + exit 0 + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + die "invalid command: %s" "$1" + ;; + esac + done +} diff --git a/src/lib/auth/login.sh b/src/lib/auth/login.sh new file mode 100644 index 0000000..083e80a --- /dev/null +++ b/src/lib/auth/login.sh @@ -0,0 +1,93 @@ +#!/hint/bash +# +# This may be included with or without `set -euE` +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_AUTH_LOGIN_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_AUTH_LOGIN_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/config.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/config.sh +# shellcheck source=src/lib/api/gitlab.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh + +set -e + + +pkgctl_auth_login_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] + + Interactively authenticate with the GitLab instance. + + The minimum required scopes for the token are: 'api', 'write_repository'. + + OPTIONS + -g, --gen-access-token Open the URL to generate a new personal access token + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} + $ ${COMMAND} --gen-access-token +_EOF_ +} + + +pkgctl_auth_login() { + local token personal_access_token_url + local GEN_ACESS_TOKEN=0 + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_auth_login_usage + exit 0 + ;; + -g|--gen-access-token) + GEN_ACESS_TOKEN=1 + shift + ;; + *) + die "invalid argument: %s" "$1" + ;; + esac + done + + personal_access_token_url="https://${GITLAB_HOST}/-/profile/personal_access_tokens?name=pkgctl+token&scopes=api,write_repository" + + cat <<- _EOF_ + Logging into ${BOLD}${GITLAB_HOST}${ALL_OFF} + + Tip: you can generate a Personal Access Token here ${personal_access_token_url} + The minimum required scopes are 'api' and 'write_repository'. +_EOF_ + + if (( GEN_ACESS_TOKEN )); then + xdg-open "${personal_access_token_url}" 2>/dev/null + fi + + # read token from stdin + read -s -r -p "${GREEN}?${ALL_OFF} ${BOLD}Paste your authentication token:${ALL_OFF} " token + echo + + if [[ -z ${token} ]]; then + msg_error " No token provided" + exit 1 + fi + + # check if the passed token works + GITLAB_TOKEN="${token}" + if ! result=$(gitlab_api_get_user); then + printf "%s\n" "$result" + exit 1 + fi + + msg_success " Logged in as ${BOLD}${result}${ALL_OFF}" + save_devtools_config +} diff --git a/src/lib/auth/status.sh b/src/lib/auth/status.sh new file mode 100644 index 0000000..6cbaab1 --- /dev/null +++ b/src/lib/auth/status.sh @@ -0,0 +1,69 @@ +#!/hint/bash +# +# This may be included with or without `set -euE` +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_AUTH_STATUS_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_AUTH_STATUS_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_auth_status_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] + + Verifies and displays information about your authentication state of + services like the GitLab instance and reports issues if any. + + OPTIONS + -t, --show-token Display the auth token + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} + $ ${COMMAND} --show-token +_EOF_ +} + +pkgctl_auth_status() { + local SHOW_TOKEN=0 + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_auth_status_usage + exit 0 + ;; + -t|--show-token) + SHOW_TOKEN=1 + shift + ;; + *) + die "invalid argument: %s" "$1" + ;; + esac + done + + printf "%s\n" "${BOLD}${GITLAB_HOST}${ALL_OFF}" + # shellcheck disable=2119 + if ! username=$(gitlab_api_get_user); then + printf "%s\n" "${username}" + exit 1 + fi + + msg_success " Logged in as ${BOLD}${username}${ALL_OFF}" + if (( SHOW_TOKEN )); then + msg_success " Token: ${GITLAB_TOKEN}" + else + msg_success " Token: **************************" + fi +} diff --git a/src/pkgctl.in b/src/pkgctl.in index 35305c1..e024d1f 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -19,6 +19,7 @@ usage() { Unified command-line frontend for devtools. COMMANDS + auth Authenticate with services like GitLab diff Compare package files using different modes repo Manage Git packaging repositories and their configuration @@ -51,6 +52,14 @@ while (( $# )); do pkgctl_repo "$@" exit 0 ;; + auth) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/auth.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/auth.sh + pkgctl_auth "$@" + exit 0 + ;; diff) _DEVTOOLS_COMMAND+=" $1" shift -- cgit v1.2.3-70-g09d2 From 2a59c32bf4ff117bd02d58a4e3f322b709259f1e Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 30 Oct 2022 14:44:06 +0100 Subject: repo: added command to create a new packaging repository --- contrib/completion/zsh/_devtools.in | 7 +++ doc/man/pkgctl-repo-create.1.asciidoc | 40 ++++++++++++ doc/man/pkgctl-repo.1.asciidoc | 4 ++ src/lib/repo.sh | 10 +++ src/lib/repo/create.sh | 113 ++++++++++++++++++++++++++++++++++ 5 files changed, 174 insertions(+) create mode 100644 doc/man/pkgctl-repo-create.1.asciidoc create mode 100644 src/lib/repo/create.sh diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 6ff6cad..3395338 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -38,6 +38,7 @@ _pkgctl_repo_cmds=( "pkgctl repo command" "clone[Clone a package repository]" "configure[Configure a clone according to distro specs]" + "create[Create a new GitLab package repository]" "web[Open the packaging repository's website]" ) @@ -55,6 +56,12 @@ _pkgctl_repo_configure_args=( '*:git_dir:_files -/' ) +_pkgctl_repo_create_args=( + '(-c --clone)'{-c,--clone}'[Clone the Git repository after creation]' + '(-h --help)'{-h,--help}'[Display usage]' + '1:pkgbase' +) + _pkgctl_repo_web_args=( '(-h --help)'{-h,--help}'[Display usage]' '*:git_dir:_files -/' diff --git a/doc/man/pkgctl-repo-create.1.asciidoc b/doc/man/pkgctl-repo-create.1.asciidoc new file mode 100644 index 0000000..b9d980b --- /dev/null +++ b/doc/man/pkgctl-repo-create.1.asciidoc @@ -0,0 +1,40 @@ +pkgctl-repo-create(1) +====================== + +Name +---- +pkgctl-repo-create - Create a new GitLab package repository + +Synopsis +-------- +pkgctl repo create [OPTIONS] [PKGBASE...] + +Description +----------- + +Create a new Git packaging repository in the canonical GitLab namespace. + +This command requires a valid GitLab API authentication. To setup a new +GitLab token or check the currently configured one please consult the +'auth' subcommand for further instructions. + +If invoked without a parameter, try to create a packaging repository +based on the 'PKGBUILD' from the current working directory. + +Options +------- + +*-c, --clone*:: + Clone the Git repository after creation + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-auth[1] +linkman:pkgctl-repo-clone[1] +linkman:pkgctl-repo-configure[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-repo.1.asciidoc b/doc/man/pkgctl-repo.1.asciidoc index 564679a..630afd8 100644 --- a/doc/man/pkgctl-repo.1.asciidoc +++ b/doc/man/pkgctl-repo.1.asciidoc @@ -38,6 +38,9 @@ pkgctl repo clone:: pkgctl repo configure:: Configure a clone according to distro specs +pkgctl repo create:: + Create a new GitLab package repository + pkgctl repo web:: Open the packaging repository's website @@ -46,6 +49,7 @@ See Also linkman:pkgctl-repo-clone[1] linkman:pkgctl-repo-configure[1] +linkman:pkgctl-repo-create[1] linkman:pkgctl-repo-web[1] include::include/footer.asciidoc[] diff --git a/src/lib/repo.sh b/src/lib/repo.sh index 8b8df11..6b3817a 100644 --- a/src/lib/repo.sh +++ b/src/lib/repo.sh @@ -29,6 +29,7 @@ pkgctl_repo_usage() { COMMANDS clone Clone a package repository configure Configure a clone according to distro specs + create Create a new GitLab package repository web Open the packaging repository's website OPTIONS @@ -38,6 +39,7 @@ pkgctl_repo_usage() { $ ${COMMAND} clone libfoo linux libbar $ ${COMMAND} clone --maintainer mynickname $ ${COMMAND} configure * + $ ${COMMAND} create libfoo $ ${COMMAND} web linux _EOF_ } @@ -71,6 +73,14 @@ pkgctl_repo() { pkgctl_repo_configure "$@" exit 0 ;; + create) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/repo/create.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/create.sh + pkgctl_repo_create "$@" + exit 0 + ;; web) _DEVTOOLS_COMMAND+=" $1" shift diff --git a/src/lib/repo/create.sh b/src/lib/repo/create.sh new file mode 100644 index 0000000..31b46e1 --- /dev/null +++ b/src/lib/repo/create.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_REPO_CREATE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_REPO_CREATE_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/clone.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/clone.sh +# shellcheck source=src/lib/repo/configure.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/configure.sh + +set -e + + +pkgctl_repo_create_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PKGBASE]... + + Create a new Git packaging repository in the canonical GitLab namespace. + + This command requires a valid GitLab API authentication. To setup a new + GitLab token or check the currently configured one please consult the + 'auth' subcommand for further instructions. + + If invoked without a parameter, try to create a packaging repository + based on the PKGBUILD from the current working directory and configure + the local repository afterwards. + + OPTIONS + -c, --clone Clone the Git repository after creation + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} libfoo +_EOF_ +} + +pkgctl_repo_create() { + # options + local pkgbases=() + local pkgbase + local clone=0 + local configure=0 + + # variables + local path + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_repo_create_usage + exit 0 + ;; + -c|--clone) + clone=1 + shift + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + pkgbases=("$@") + break + ;; + esac + done + + # check if invoked without any path from within a packaging repo + if (( ${#pkgbases[@]} == 0 )); then + if [[ -f PKGBUILD ]]; then + if ! path=$(realpath -e .); then + die "failed to read path from current directory" + fi + pkgbases=("$(basename "${path}")") + clone=0 + configure=1 + else + pkgctl_repo_create_usage + exit 1 + fi + fi + + # create projects + for pkgbase in "${pkgbases[@]}"; do + if ! gitlab_api_create_project "${pkgbase}" >/dev/null; then + die "failed to create project: ${pkgbase}" + fi + msg_success "Successfully created ${pkgbase}" + if (( clone )); then + pkgctl_repo_clone "${pkgbase}" + elif (( configure )); then + pkgctl_repo_configure + fi + done + + # some convenience hints if not in auto clone/configure mode + if (( ! clone )) && (( ! configure )); then + cat <<- _EOF_ + + For new clones: + $(msg2 "pkgctl repo clone ${pkgbases[*]}") + For existing clones: + $(msg2 "pkgctl repo configure ${pkgbases[*]}") + _EOF_ + fi +} -- cgit v1.2.3-70-g09d2 From 8b5bcd01b47845e6459a0ceef2f0eaf898482382 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 4 Nov 2022 02:44:22 +0100 Subject: commitpkg: add exported pgp keys with git --- src/commitpkg.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commitpkg.in b/src/commitpkg.in index 9158763..f80a6cd 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -96,7 +96,7 @@ if (( ${#validpgpkeys[@]} != 0 )); then export-pkgbuild-keys || die 'Failed to export valid PGP keys for source files' fi - svn add --parents --force keys/pgp/* + git add --force -- keys/pgp/* fi # find files which should be under source control -- cgit v1.2.3-70-g09d2 From f834fc4700053cb9a83956c98835b0a158cc054c Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 11 Dec 2022 16:16:16 +0100 Subject: db: command for Pacman database modification like update, move etc --- contrib/completion/zsh/_devtools.in | 26 ++++++++++++ doc/man/pkgctl-db-move.1.asciidoc | 24 +++++++++++ doc/man/pkgctl-db-remove.1.asciidoc | 26 ++++++++++++ doc/man/pkgctl-db-update.1.asciidoc | 23 +++++++++++ doc/man/pkgctl.1.asciidoc | 4 ++ src/lib/db.sh | 80 +++++++++++++++++++++++++++++++++++++ src/lib/db/move.sh | 64 +++++++++++++++++++++++++++++ src/lib/db/remove.sh | 69 ++++++++++++++++++++++++++++++++ src/lib/db/update.sh | 46 +++++++++++++++++++++ src/pkgctl.in | 9 +++++ 10 files changed, 371 insertions(+) create mode 100644 doc/man/pkgctl-db-move.1.asciidoc create mode 100644 doc/man/pkgctl-db-remove.1.asciidoc create mode 100644 doc/man/pkgctl-db-update.1.asciidoc create mode 100644 src/lib/db.sh create mode 100644 src/lib/db/move.sh create mode 100644 src/lib/db/remove.sh create mode 100644 src/lib/db/update.sh diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 3395338..62d9fea 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -34,6 +34,31 @@ _pkgctl_auth_status_args=( '(-h --help)'{-h,--help}'[Display usage]' ) +_pkgctl_db_cmds=( + "pkgctl db command" + "move[Move packages between pacman repositories]" + "remove[Remove packages from pacman repositories]" + "update[Update the pacman database as final release step]" +) + +_pkgctl_db_move_args=( + '(-h --help)'{-h,--help}'[Display usage]' + "1:src-repo:($_repos[*])" + "2:target-repo:($_repos[*])" + '*:pkgbase:_devtools_completions_all_packages' +) + +_pkgctl_db_remove_args=( + '(-a --arch=)'{-a,--arch=}"[Override the architecture (disables auto-detection)]:arch:($_arch[*])" + '(-h --help)'{-h,--help}'[Display usage]' + "1:repo:($_repos[*])" + '*:pkgbase:_devtools_completions_all_packages' +) + +_pkgctl_db_update_args=( + '(-h --help)'{-h,--help}'[Display usage]' +) + _pkgctl_repo_cmds=( "pkgctl repo command" "clone[Clone a package repository]" @@ -178,6 +203,7 @@ _devtools_completions_all_packages() { _pkgctl_cmds=( "pkgctl command" "auth[Authenticate with services like GitLab]" + "db[Pacman database modification for packge update, move etc]" "diff[Compare package files using different modes]" "repo[Manage Git packaging repositories and their configuration]" ) diff --git a/doc/man/pkgctl-db-move.1.asciidoc b/doc/man/pkgctl-db-move.1.asciidoc new file mode 100644 index 0000000..1ee02f8 --- /dev/null +++ b/doc/man/pkgctl-db-move.1.asciidoc @@ -0,0 +1,24 @@ +pkgctl-db-move(1) +================= + +Name +---- +pkgctl-db-update - Update the binary repository as final release step + +Synopsis +-------- +pkgctl db update [OPTIONS] + +Description +----------- + +Update the pacman database as final release step for packages that +have been transfered and staged on 'repos.archlinux.org'. + +Options +------- + +*-h, --help*:: + Show a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-db-remove.1.asciidoc b/doc/man/pkgctl-db-remove.1.asciidoc new file mode 100644 index 0000000..a95766d --- /dev/null +++ b/doc/man/pkgctl-db-remove.1.asciidoc @@ -0,0 +1,26 @@ +pkgctl-db-remove(1) +=================== + +Name +---- +pkgctl-db-remove - Remove packages from binary repositories + +Synopsis +-------- +pkgctl db remove [OPTIONS] [REPO] [PKGBASE]... + +Description +----------- + +Remove packages from pacman repositories. + +Options +------- + +*-a, --arch* 'ARCH':: + Override the architecture (disables auto-detection) + +*-h, --help*:: + Show a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-db-update.1.asciidoc b/doc/man/pkgctl-db-update.1.asciidoc new file mode 100644 index 0000000..fa7205e --- /dev/null +++ b/doc/man/pkgctl-db-update.1.asciidoc @@ -0,0 +1,23 @@ +pkgctl-db-move(1) +================= + +Name +---- +pkgctl-db-move - Move packages between binary repositories + +Synopsis +-------- +pkgctl db move [OPTIONS] [SOURCE_REPO] [TARGET_REPO] [PKGBASE]... + +Description +----------- + +Move packages between pacman repositories. + +Options +------- + +*-h, --help*:: + Show a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 45d5187..93fed5b 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -20,6 +20,9 @@ Subcommands pkgctl auth:: Authenticate with services like GitLab +pkgctl db:: + Pacman database modification for packge update, move etc + pkgctl diff:: Compare package files using different modes @@ -30,6 +33,7 @@ See Also -------- linkman:pkgctl-auth[1] +linkman:pkgctl-db[1] linkman:pkgctl-diff[1] linkman:pkgctl-repo[1] diff --git a/src/lib/db.sh b/src/lib/db.sh new file mode 100644 index 0000000..397ff0d --- /dev/null +++ b/src/lib/db.sh @@ -0,0 +1,80 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_DB_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_DB_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + +set -e + + +pkgctl_db_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [COMMAND] [OPTIONS] + + Pacman database modification for packge update, move etc + + COMMANDS + move Move packages between pacman repositories + remove Remove packages from pacman repositories + update Update the pacman database as final release step + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} move extra-staging extra-testing libfoo libbar + $ ${COMMAND} remove core-testing libfoo libbar + $ ${COMMAND} update +_EOF_ +} + +pkgctl_db() { + if (( $# < 1 )); then + pkgctl_db_usage + exit 0 + fi + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_db_usage + exit 0 + ;; + move) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/db/move.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/move.sh + pkgctl_db_move "$@" + exit 0 + ;; + remove) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/db/remove.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/remove.sh + pkgctl_db_remove "$@" + exit 0 + ;; + update) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/db/update.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/update.sh + pkgctl_db_update "$@" + exit 0 + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + die "invalid command: %s" "$1" + ;; + esac + done +} diff --git a/src/lib/db/move.sh b/src/lib/db/move.sh new file mode 100644 index 0000000..825b350 --- /dev/null +++ b/src/lib/db/move.sh @@ -0,0 +1,64 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_DB_MOVE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_DB_MOVE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +set -e + + +pkgctl_db_move_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [SOURCE_REPO] [TARGET_REPO] [PKGBASE]... + + Move packages between binary repositories. + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} extra-staging extra-testing libfoo libbar + $ ${COMMAND} extra core libfoo libbar +_EOF_ +} + +pkgctl_db_move() { + local SOURCE_REPO="" + local TARGET_REPO="" + local PKGBASES=() + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_db_move_usage + exit 0 + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + break + ;; + esac + done + + if (( $# < 3 )); then + pkgctl_db_move_usage + exit 1 + fi + + SOURCE_REPO=$1 + TARGET_REPO=$2 + shift 2 + PKGBASES+=("$@") + + # shellcheck disable=SC2029 + ssh "${PACKAGING_REPO_RELEASE_HOST}" db-move "${SOURCE_REPO}" "${TARGET_REPO}" "${PKGBASES[@]}" +} diff --git a/src/lib/db/remove.sh b/src/lib/db/remove.sh new file mode 100644 index 0000000..ba21c83 --- /dev/null +++ b/src/lib/db/remove.sh @@ -0,0 +1,69 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_DB_REMOVE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_DB_REMOVE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +set -e + + +pkgctl_db_remove_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [REPO] [PKGBASE]... + + Remove packages from binary repositories. + + OPTIONS + -a, --arch Override the architecture (disables auto-detection) + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} core-testing libfoo libbar + $ ${COMMAND} --arch x86_64 core libyay +_EOF_ +} + +pkgctl_db_remove() { + local REPO="" + local ARCH=any + local PKGBASES=() + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_db_remove_usage + exit 0 + ;; + -a|--arch) + (( $# <= 1 )) && die "missing argument for %s" "$1" + ARCH=$2 + shift 2 + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + break + ;; + esac + done + + if (( $# < 2 )); then + pkgctl_db_remove_usage + exit 1 + fi + + REPO=$1 + shift + PKGBASES+=("$@") + + # shellcheck disable=SC2029 + ssh "${PACKAGING_REPO_RELEASE_HOST}" db-remove "${REPO}" "${ARCH}" "${PKGBASES[@]}" +} diff --git a/src/lib/db/update.sh b/src/lib/db/update.sh new file mode 100644 index 0000000..269720d --- /dev/null +++ b/src/lib/db/update.sh @@ -0,0 +1,46 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_DB_UPDATE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_DB_UPDATE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +set -e + + +pkgctl_db_update_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] + + Update the binary repository as final release step for packages that + have been transfered and staged on ${PACKAGING_REPO_RELEASE_HOST}. + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} +_EOF_ +} + +pkgctl_db_update() { + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_db_update_usage + exit 0 + ;; + *) + die "invalid argument: %s" "$1" + ;; + esac + done + + ssh "${PACKAGING_REPO_RELEASE_HOST}" db-update +} diff --git a/src/pkgctl.in b/src/pkgctl.in index e024d1f..d9e1b4c 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -20,6 +20,7 @@ usage() { COMMANDS auth Authenticate with services like GitLab + db Pacman database modification for packge update, move etc diff Compare package files using different modes repo Manage Git packaging repositories and their configuration @@ -60,6 +61,14 @@ while (( $# )); do pkgctl_auth "$@" exit 0 ;; + db) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/auth.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db.sh + pkgctl_db "$@" + exit 0 + ;; diff) _DEVTOOLS_COMMAND+=" $1" shift -- cgit v1.2.3-70-g09d2 From b9db6160a2547a57d19308776a25223eb2130b6b Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Tue, 13 Dec 2022 20:41:37 +0100 Subject: git: convert repos and tags config to new repo layout --- Makefile | 9 ++++----- src/lib/valid-repos.sh | 21 +++++---------------- src/lib/valid-tags.sh | 9 ++++----- 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index f59ca26..89251f4 100644 --- a/Makefile +++ b/Makefile @@ -20,12 +20,11 @@ SETARCH_ALIASES = $(wildcard config/setarch-aliases.d/*) MANS = $(addprefix $(BUILDDIR)/,$(patsubst %.asciidoc,%,$(wildcard doc/man/*.asciidoc))) COMMITPKG_LINKS = \ + core-testingpkg \ + core-stagingpkg \ extrapkg \ - testingpkg \ - stagingpkg \ - communitypkg \ - community-testingpkg \ - community-stagingpkg \ + extra-testingpkg \ + extra-stagingpkg \ multilibpkg \ multilib-testingpkg \ multilib-stagingpkg \ diff --git a/src/lib/valid-repos.sh b/src/lib/valid-repos.sh index 9ac9639..1f823f4 100644 --- a/src/lib/valid-repos.sh +++ b/src/lib/valid-repos.sh @@ -5,28 +5,17 @@ # shellcheck disable=2034 _repos=( - staging - testing - core - extra - community-staging - community-testing - community - multilib-staging - multilib-testing - multilib + core core-staging core-testing + extra extra-staging extra-testing + multilib multilib-staging multilib-testing gnome-unstable kde-unstable ) # shellcheck disable=2034 _build_repos=( - staging - testing - extra - multilib-staging - multilib-testing - multilib + extra staging testing + multilib multilib-staging multilib-testing gnome-unstable kde-unstable ) diff --git a/src/lib/valid-tags.sh b/src/lib/valid-tags.sh index d628fd1..ca8d7d7 100644 --- a/src/lib/valid-tags.sh +++ b/src/lib/valid-tags.sh @@ -12,15 +12,14 @@ _arch=( # shellcheck disable=2034 _tags=( core-x86_64 core-any + core-staging-x86_64 core-staging-any + core-testing-x86_64 core-testing-any extra-x86_64 extra-any + extra-staging-x86_64 extra-staging-any + extra-testing-x86_64 extra-testing-any multilib-x86_64 - staging-x86_64 staging-any - testing-x86_64 testing-any multilib-testing-x86_64 multilib-staging-x86_64 - community-x86_64 community-any - community-staging-x86_64 community-staging-any - community-testing-x86_64 community-testing-any kde-unstable-x86_64 kde-unstable-any gnome-unstable-x86_64 gnome-unstable-any ) -- cgit v1.2.3-70-g09d2 From 5752488ef114513c8f75d753cf91d5b61dfa0660 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 17 Dec 2022 01:51:15 +0100 Subject: release: command to commit, tag and upload build artifacts This is a smart and more convenient invocation of the classical commitpkg and archrelease with auto-discovery for target repositories and a shorthand option to directly call db-update. --- contrib/completion/zsh/_devtools.in | 11 +++ doc/man/pkgctl-release.1.asciidoc | 49 +++++++++++ doc/man/pkgctl.1.asciidoc | 4 + src/lib/release.sh | 167 ++++++++++++++++++++++++++++++++++++ src/lib/util/pacman.sh | 52 +++++++++++ src/pkgctl.in | 9 ++ 6 files changed, 292 insertions(+) create mode 100644 doc/man/pkgctl-release.1.asciidoc create mode 100644 src/lib/release.sh create mode 100644 src/lib/util/pacman.sh diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 62d9fea..2961f6f 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -59,6 +59,16 @@ _pkgctl_db_update_args=( '(-h --help)'{-h,--help}'[Display usage]' ) +_pkgctl_release_args=( + '(-m --message=)'{-m,--message=}"[Use the given as the commit message]:message:" + '(-r --repo=)'{-r,--repo=}"[Specify a target repository (disables auto-detection)]:repo:($_repos[*])" + '(-s --staging)'{-s,--staging}'[Release to the staging counterpart of the auto-detected repo]' + '(-t --testing)'{-t,--testing}'[Release to the testing counterpart of the auto-detected repo]' + '(-u --db-update)'{-u,--db-update}'[Automatically update the pacman database after uploading]' + '(-h --help)'{-h,--help}'[Display usage]' + '*:git_dir:_files -/' +) + _pkgctl_repo_cmds=( "pkgctl repo command" "clone[Clone a package repository]" @@ -205,6 +215,7 @@ _pkgctl_cmds=( "auth[Authenticate with services like GitLab]" "db[Pacman database modification for packge update, move etc]" "diff[Compare package files using different modes]" + "release[Release step to commit, tag and upload build artifacts]" "repo[Manage Git packaging repositories and their configuration]" ) diff --git a/doc/man/pkgctl-release.1.asciidoc b/doc/man/pkgctl-release.1.asciidoc new file mode 100644 index 0000000..c991db4 --- /dev/null +++ b/doc/man/pkgctl-release.1.asciidoc @@ -0,0 +1,49 @@ +pkgctl-release(1) +================= + +Name +---- +pkgctl-release - Release step to commit, tag and upload build artifacts + +Synopsis +-------- +pkgctl release [OPTIONS] [PATH...] + +Description +----------- + +Modified version controlled files will first be staged for commit, +afterwards a Git tag matching the pkgver will be created and finally +all build artifacts will be uploaded. + +By default the target pacman repository will be auto-detected by querying +the repo it is currently released in. When initially adding a new package +to the repositories, the target repo must be specified manually. + +Options +------- + +*-m, --message* 'MSG':: + Use the given as the commit message + +*-r, --repo* 'REPO':: + Specify a target repository (disables auto-detection) + +*-s, --staging*:: + Build against the staging counterpart of the auto-detected repo + +*-t, --testing*:: + Build against the testing counterpart of the auto-detected repo + +*-u, --db-update*:: + Automatically update the pacman database after uploading + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-db-update[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 93fed5b..8da5d19 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -26,6 +26,9 @@ pkgctl db:: pkgctl diff:: Compare package files using different modes +pkgctl release:: + Release step to commit, tag and upload build artifacts + pkgctl repo:: Manage Git packaging repositories and their configuration @@ -35,6 +38,7 @@ See Also linkman:pkgctl-auth[1] linkman:pkgctl-db[1] linkman:pkgctl-diff[1] +linkman:pkgctl-release[1] linkman:pkgctl-repo[1] include::include/footer.asciidoc[] diff --git a/src/lib/release.sh b/src/lib/release.sh new file mode 100644 index 0000000..aabbd35 --- /dev/null +++ b/src/lib/release.sh @@ -0,0 +1,167 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_RELEASE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_RELEASE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/db/update.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/update.sh +# shellcheck source=src/lib/util/pacman.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh +# shellcheck source=src/lib/valid-repos.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh + +source /usr/share/makepkg/util/util.sh + +set -e + + +pkgctl_release_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PATH]... + + Release step to commit, tag and upload build artifacts + + Modified version controlled files will first be staged for commit, + afterwards a Git tag matching the pkgver will be created and finally + all build artifacts will be uploaded. + + By default the target pacman repository will be auto-detected by querying + the repo it is currently released in. When initially adding a new package + to the repositories, the target repo must be specified manually. + + OPTIONS + -m, --message MSG Use the given as the commit message + -r, --repo REPO Specify a target repository (disables auto-detection) + -s, --staging Release to the staging counterpart of the auto-detected repo + -t, --testing Release to the testing counterpart of the auto-detected repo + -u, --db-update Automatically update the pacman database after uploading + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} + $ ${COMMAND} --repo core-testing --message 'libyay 0.42 rebuild' libfoo libbar + $ ${COMMAND} --staging --db-update libfoo +_EOF_ +} + +pkgctl_release_check_option_group() { + local option=$1 + local repo=$2 + local testing=$3 + local staging=$4 + if [[ -n "${repo}" ]] || (( testing )) || (( staging )); then + die "The argument '%s' cannot be used with one or more of the other specified arguments" "${option}" + exit 1 + fi + return 0 +} + +pkgctl_release() { + if (( $# < 1 )) && [[ ! -f PKGBUILD ]]; then + pkgctl_release_usage + exit 1 + fi + + local MESSAGE="" + local PKGBASES=() + local REPO="" + local TESTING=0 + local STAGING=0 + local DB_UPDATE=0 + + local path pkgbase pkgnames repo repos + + # option checking + while (( $# )); do + case $1 in + -h|--help) + pkgctl_release_usage + exit 0 + ;; + -m|--message) + (( $# <= 1 )) && die "missing argument for %s" "$1" + MESSAGE=$2 + shift 2 + ;; + -r|--repo) + (( $# <= 1 )) && die "missing argument for %s" "$1" + pkgctl_release_check_option_group '--repo' "${REPO}" "${TESTING}" "${STAGING}" + REPO=$2 + shift 2 + ;; + -s|--staging) + pkgctl_release_check_option_group '--staging' "${REPO}" "${TESTING}" "${STAGING}" + STAGING=1 + shift + ;; + -t|--testing) + pkgctl_release_check_option_group '--testing' "${REPO}" "${TESTING}" "${STAGING}" + TESTING=1 + shift + ;; + -u|--db-update) + DB_UPDATE=1 + shift + ;; + -*) + die "invalid option: %s" "$1" + ;; + *) + PKGBASES+=("$@") + break + ;; + esac + done + + # Resolve package from current working directory + if (( 0 == ${#PKGBASES[@]} )); then + PKGBASES=("$PWD") + fi + + # Update pacman cache for auto-detection + if [[ -z ${REPO} ]]; then + update_pacman_repo_cache + # Check valid repos if not resolved dynamically + elif ! in_array "${REPO}" "${_repos[@]}"; then + die "Invalid repository target: %s" "${REPO}" + fi + + for path in "${PKGBASES[@]}"; do + pushd "${path}" >/dev/null + pkgbase=$(basename "${path}") + + if [[ -n ${REPO} ]]; then + repo=${REPO} + else + if ! repo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then + die 'Failed to get pacman repo' + fi + if [[ -z "${repo}" ]]; then + die 'Unknown repo, please specify --repo for new packages' + fi + fi + + if (( TESTING )); then + repo="${repo}-testing" + elif (( STAGING )); then + repo="${repo}-staging" + elif [[ $repo == core ]]; then + repo="${repo}-testing" + fi + + msg "Releasing ${pkgbase} to ${repo}" + commitpkg "${repo}" "${MESSAGE}" + + unset repo + popd >/dev/null + done + + if (( DB_UPDATE )); then + # shellcheck disable=2119 + pkgctl_db_update + fi +} diff --git a/src/lib/util/pacman.sh b/src/lib/util/pacman.sh new file mode 100644 index 0000000..f6c2d5f --- /dev/null +++ b/src/lib/util/pacman.sh @@ -0,0 +1,52 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_UTIL_PACMAN_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_UTIL_PACMAN_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh + +set -e + + +readonly _DEVTOOLS_PACMAN_CACHE_DIR=${XDG_CACHE_DIR:-$HOME/.cache}/devtools/pacman/db +readonly _DEVTOOLS_PACMAN_CONF_DIR=${_DEVTOOLS_LIBRARY_DIR}/pacman.conf.d +readonly _DEVTOOLS_MAKEPKG_CONF_DIR=${_DEVTOOLS_LIBRARY_DIR}/makepkg.conf.d + + +update_pacman_repo_cache() { + mkdir -p "${_DEVTOOLS_PACMAN_CACHE_DIR}" + msg "Updating pacman database cache" + lock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache" + fakeroot -- pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/multilib.conf" \ + --dbpath "${_DEVTOOLS_PACMAN_CACHE_DIR}" \ + -Sy + lock_close 10 +} + +get_pacman_repo_from_pkgbuild() { + local path=${1:-PKGBUILD} + + # shellcheck source=contrib/makepkg/PKGBUILD.proto + mapfile -t pkgnames < <(source "${path}"; printf "%s\n" "${pkgname[@]}") + + if (( ${#pkgnames[@]} == 0 )); then + die 'Failed to get pkgname from %s' "${path}" + return + fi + + slock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache" + mapfile -t repos < <(pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/multilib.conf" \ + --dbpath "${_DEVTOOLS_PACMAN_CACHE_DIR}" \ + -S \ + --print \ + --print-format '%n %r' \ + "${pkgnames[0]}" | grep -E "^${pkgnames[0]} " | awk '{print $2}' + ) + lock_close 10 + + printf "%s" "${repos[0]}" +} diff --git a/src/pkgctl.in b/src/pkgctl.in index d9e1b4c..47409de 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -22,6 +22,7 @@ usage() { auth Authenticate with services like GitLab db Pacman database modification for packge update, move etc diff Compare package files using different modes + release Release step to commit, tag and upload build artifacts repo Manage Git packaging repositories and their configuration OPTIONS @@ -75,6 +76,14 @@ while (( $# )); do diffpkg "$@" exit 0 ;; + release) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/release.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh + pkgctl_release "$@" + exit 0 + ;; *) die "invalid command: %s" "$1" ;; -- cgit v1.2.3-70-g09d2 From e0307c7925168f58c3ec5077ea9915db81d4f62a Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 30 Dec 2022 16:49:58 +0100 Subject: conf: move makepkg and pacman config into separate conf.d dirs We have used the datadir like a kitchen sink, lets clean up a bit by having a better and well structured layout. Put makepkg and pacman configs in separate directories: makepkg.conf.d and pacman.conf.d. --- Makefile | 21 +++++++++++++++------ doc/man/archbuild.1.asciidoc | 2 +- src/archbuild.in | 12 ++++++------ src/makerepropkg.in | 6 ++++-- src/offload-build.in | 6 +++--- 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index 89251f4..96a76f5 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ ARCHBUILD_LINKS = \ COMPLETIONS = $(addprefix $(BUILDDIR)/,$(patsubst %.in,%,$(wildcard contrib/completion/*/*))) -all: binprogs library completion man +all: binprogs library conf completion man binprogs: $(BINPROGS) library: $(LIBRARY) completion: $(COMPLETIONS) @@ -90,17 +90,24 @@ $(BUILDDIR)/doc/man/%: doc/man/%.asciidoc doc/asciidoc.conf doc/man/include/foot @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=$(DATADIR) $< +conf: + @install -d $(BUILDDIR)/makepkg.conf.d $(BUILDDIR)/pacman.conf.d + @cp -a $(MAKEPKG_CONFIGS) $(BUILDDIR)/makepkg.conf.d + @cp -a $(PACMAN_CONFIGS) $(BUILDDIR)/pacman.conf.d + clean: rm -rf $(BUILDDIR) install: all install -dm0755 $(DESTDIR)$(PREFIX)/bin install -dm0755 $(DESTDIR)$(DATADIR)/setarch-aliases.d + install -dm0755 $(DESTDIR)$(DATADIR)/makepkg.conf.d + install -dm0755 $(DESTDIR)$(DATADIR)/pacman.conf.d install -m0755 ${BINPROGS} $(DESTDIR)$(PREFIX)/bin 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 conf in $(notdir $(MAKEPKG_CONFIGS)); do install -Dm0644 $(BUILDDIR)/makepkg.conf.d/$$conf $(DESTDIR)$(DATADIR)/makepkg.conf.d/$${conf##*/}; done + for conf in $(notdir $(PACMAN_CONFIGS)); do install -Dm0644 $(BUILDDIR)/pacman.conf.d/$$conf $(DESTDIR)$(DATADIR)/pacman.conf.d/$${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 @@ -116,8 +123,8 @@ uninstall: for f in $(notdir $(BINPROGS)); do rm -f $(DESTDIR)$(PREFIX)/bin/$$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 conf in $(notdir $(MAKEPKG_CONFIGS)); do rm -f $(DESTDIR)$(DATADIR)/makepkg.conf.d/$${conf##*/}; done + for conf in $(notdir $(PACMAN_CONFIGS)); do rm -f $(DESTDIR)$(DATADIR)/pacman.conf.d/$${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 @@ -128,6 +135,8 @@ uninstall: for manfile in $(notdir $(MANS)); do rm -f $(DESTDIR)$(MANDIR)/man$${manfile##*.}/$${manfile}; done; rmdir --ignore-fail-on-non-empty \ $(DESTDIR)$(DATADIR)/setarch-aliases.d \ + $(DESTDIR)$(DATADIR)/makepkg.conf.d \ + $(DESTDIR)$(DATADIR)/pacman.conf.d \ $(DESTDIR)$(DATADIR) TODAY=$(shell date +"%Y%m%d") @@ -146,5 +155,5 @@ upload: check: $(BINPROGS_SRC) $(LIBRARY_SRC) contrib/completion/bash/devtools.in config/makepkg/x86_64.conf contrib/makepkg/PKGBUILD.proto shellcheck $^ -.PHONY: all binprogs library completion man clean install uninstall tag dist upload check +.PHONY: all binprogs library completion conf man clean install uninstall tag dist upload check .DELETE_ON_ERROR: diff --git a/doc/man/archbuild.1.asciidoc b/doc/man/archbuild.1.asciidoc index 777e3f2..2a2d843 100644 --- a/doc/man/archbuild.1.asciidoc +++ b/doc/man/archbuild.1.asciidoc @@ -23,7 +23,7 @@ Description * staging-x86_64-build * testing-x86_64-build -The symlink used to run it will be inspected by archbuild, to determine which target you want it to use. It will load the available pacman configuration from 'pacman-reponame-arch.conf' with a fallback to 'pacman-reponame.conf' from {pkgdatadir}. The makepkg configuration is loaded from 'makepkg-repo-arch.conf' with a fallback to 'makepkg-reponame.conf' from {pkgdatadir}. +The symlink used to run it will be inspected by archbuild, to determine which target you want it to use. It will load the available pacman configuration from 'reponame-arch.conf' with a fallback to 'reponame.conf' from {pkgdatadir}/pacman.conf.d. The makepkg configuration is loaded from 'repo-arch.conf' with a fallback to 'reponame.conf' from {pkgdatadir}/makepkg.conf.d. It will also load the bind mount configuration from 'mount.d/arch' in {pkgdatadir}. The file format is that each line starting with ro and rw will be used, other lines will be ignored, and the rest of the used line is out/path:in/path preceded by a space as a separator. ro means it is a read-only mount, rw means a read-write mount. diff --git a/src/archbuild.in b/src/archbuild.in index 3367011..a7e4231 100644 --- a/src/archbuild.in +++ b/src/archbuild.in @@ -46,13 +46,13 @@ done chroots='/var/lib/archbuild' clean_first=false -pacman_config="@pkgdatadir@/pacman-${repo}.conf" -if [[ -f @pkgdatadir@/pacman-${repo}-${arch}.conf ]]; then - pacman_config="@pkgdatadir@/pacman-${repo}-${arch}.conf" +pacman_config="@pkgdatadir@/pacman.conf.d/${repo}.conf" +if [[ -f @pkgdatadir@/pacman.conf.d/${repo}-${arch}.conf ]]; then + pacman_config="@pkgdatadir@/pacman.conf.d/${repo}-${arch}.conf" fi -makepkg_config="@pkgdatadir@/makepkg-${arch}.conf" -if [[ -f @pkgdatadir@/makepkg-${repo}-${arch}.conf ]]; then - makepkg_config="@pkgdatadir@/makepkg-${repo}-${arch}.conf" +makepkg_config="@pkgdatadir@/makepkg.conf.d/${arch}.conf" +if [[ -f @pkgdatadir@/makepkg.conf.d/${repo}-${arch}.conf ]]; then + makepkg_config="@pkgdatadir@/makepkg.conf.d/${repo}-${arch}.conf" fi usage() { diff --git a/src/makerepropkg.in b/src/makerepropkg.in index e0a5b85..f310c69 100644 --- a/src/makerepropkg.in +++ b/src/makerepropkg.in @@ -97,7 +97,9 @@ get_makepkg_conf() { return 1 fi msg2 "using makepkg.conf from ${fname}" - bsdtar xOqf "${buildtool_file/file:\/\//}" "usr/share/devtools/makepkg-${arch}.conf" > "${makepkg_conf}" + if ! bsdtar xOqf "${buildtool_file/file:\/\//}" "usr/share/devtools/makepkg.conf.d/${arch}.conf" > "${makepkg_conf}"; then + bsdtar xOqf "${buildtool_file/file:\/\//}" "usr/share/devtools/makepkg-${arch}.conf" > "${makepkg_conf}" + fi return 0 } @@ -228,7 +230,7 @@ elif [[ "${BUILDTOOL}" = devtools ]] && get_makepkg_conf "${BUILDTOOL}-${BUILDTO # fallback to current makepkg.conf else warning "Unknown buildtool (${BUILDTOOL}-${BUILDTOOLVER}), using fallback" - makepkg_conf=@pkgdatadir@/makepkg-${CARCH}.conf + makepkg_conf=@pkgdatadir@/makepkg.conf.d/${CARCH}.conf fi printf '%s\n' "${allpkgfiles[@]}" | mkarchroot -M "${makepkg_conf}" -U "${archroot_args[@]}" "${namespace}/root" - || exit 1 diff --git a/src/offload-build.in b/src/offload-build.in index 9e9d71e..027bad3 100644 --- a/src/offload-build.in +++ b/src/offload-build.in @@ -102,9 +102,9 @@ mapfile -t files < <( printf "\t%s\n" "$temp"/* } >&2 && makepkg_user_config="${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf" && - makepkg_config="/usr/share/devtools/makepkg-'"${arch}"'.conf" && - if [[ -f /usr/share/devtools/makepkg-'"${repo}"'-'"${arch}"'.conf ]]; then - makepkg_config="/usr/share/devtools/makepkg-'"${repo}"'-'"${arch}"'.conf" + makepkg_config="/usr/share/devtools/makepkg.conf.d/'"${arch}"'.conf" && + if [[ -f /usr/share/devtools/makepkg.conf.d/'"${repo}"'-'"${arch}"'.conf ]]; then + makepkg_config="/usr/share/devtools/makepkg.conf.d/'"${repo}"'-'"${arch}"'.conf" fi && makepkg --config <(cat "${makepkg_user_config}" "${makepkg_config}" 2>/dev/null) --packagelist && printf "%s\n" "${temp}/PKGBUILD" -- cgit v1.2.3-70-g09d2 From f1673c60adff196d9b1c7c97797c5775b3bdb56a Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Mon, 9 Jan 2023 21:40:45 +0100 Subject: build: replace m4 defines with sed scripts during build There is no reason anymore to use m4 since we got rid of the includes by using library files. Let's replace the last usage of m4 and completely red rid of it. Signed-off-by: Levente Polyak --- Makefile | 6 ++++-- src/lib/common.sh | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 96a76f5..faac812 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,9 @@ ifneq ($(wildcard setarch-aliases.d/*),) endif -edit = sed -e "s|@pkgdatadir[@]|$(DATADIR)|g" +edit = sed \ + -e "s|@pkgdatadir[@]|$(DATADIR)|g" \ + -e "s|@buildtoolver[@]|$(BUILDTOOLVER)|g" GEN_MSG = @echo "GEN $(patsubst $(BUILDDIR)/%,%,$@)" define buildInScript @@ -76,7 +78,7 @@ $(1)/%: $(2)%$(3) $$(GEN_MSG) @mkdir -p $$(dir $$@) @$(RM) "$$@" - @{ echo -n 'm4_changequote([[[,]]])'; cat $$<; } | m4 -P --define=m4_devtools_version=$$(BUILDTOOLVER) | $(edit) >$$@ + @cat $$< | $(edit) >$$@ @chmod $(4) "$$@" @bash -O extglob -n "$$@" endef diff --git a/src/lib/common.sh b/src/lib/common.sh index 1fe396c..51ab2fd 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -17,7 +17,7 @@ export LANG=C # Set buildtool properties export BUILDTOOL=devtools -export BUILDTOOLVER=m4_devtools_version +export BUILDTOOLVER=@buildtoolver@ # Set common properties export PACMAN_KEYRING_DIR=/etc/pacman.d/gnupg -- cgit v1.2.3-70-g09d2 From cddba60958d7aba15dac06acfc697b81e31581a1 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 12 Jan 2023 19:15:14 +0100 Subject: archrelease: add checks for valid remote and up-to-date branch ref It's safest to probe for the validity of the remote origin and abort early otherwise. This also allows to print some hints how to create or configure new repositories at appropriate times. Additionally fetch remote changes and check the local branch contains the remote branch ref, otherwise abort and print a hint how to pull and update the branch. This should add all check needed for the average failure case that may lead to a weird state or creation of a local tag that may not be pushable. Signed-off-by: Levente Polyak --- src/archrelease.in | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/archrelease.in b/src/archrelease.in index b89dad2..c3776e7 100644 --- a/src/archrelease.in +++ b/src/archrelease.in @@ -8,6 +8,8 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh # shellcheck source=src/lib/valid-tags.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh +set -e + # parse command line options FORCE= @@ -38,13 +40,36 @@ if [[ ! -f PKGBUILD ]]; then die 'archrelease: PKGBUILD not found' fi +# shellcheck source=contrib/makepkg/PKGBUILD.proto . ./PKGBUILD pkgbase=${pkgbase:-$pkgname} pkgver=$(get_full_version "$pkgbase") gittag=$(get_tag_from_pkgver "$pkgver") -if git rev-parse "$gittag" >/dev/null 2>&1; then - die "archrelease: the tag $gittag for version $pkgver already exists in the repository!" +# Check if releasing from a branch +if ! branchname=$(git symbolic-ref --short HEAD); then + die 'not on any branch' +fi +if [[ "${branchname}" != main ]]; then + die 'must be run from the main branch' +fi + +# Check if remote origin is setup properly +if ! giturl=$(git remote get-url origin) || [[ ${giturl} != *${GIT_PACKAGING_URL_SSH}* ]]; then + die "remote origin is not configured, run 'pkgctl repo configure'" +fi +if ! git ls-remote origin >/dev/null; then + die "configured remote origin may not exist, run 'pkgctl repo create ${pkgbase}' to create it" +fi + +msg 'Fetching remote changes' +git fetch --prune --prune-tags origin || die 'failed to fetch remote changes' + +# Check if local branch is up to date and contains the latest origin commit +if remoteref=$(git rev-parse "origin/${branchname}" 2>/dev/null); then + if [[ $(git branch "${branchname}" --contains "${remoteref}" --format '%(refname:short)') != "${branchname}" ]]; then + die "local branch is out of date, run 'git pull --rebase'" + fi fi # If the tag exists we check if it's properly signed and that it @@ -55,10 +80,11 @@ if git tag --verify "$gittag" &> /dev/null; then if [[ "$cwd_checksum" != "$tag_checksum" ]]; then die "tagged PKGBUILD is not the same as the working dir PKGBUILD" fi + git push --tags --set-upstream origin main || abort exit 0 fi stat_busy "Releasing package" git tag --sign --message="Package release ${pkgver}" "$gittag" || abort -git push --tags main || abort +git push --tags --set-upstream origin main || abort stat_done -- cgit v1.2.3-70-g09d2 From c839d52793bb6de66bbf5895faa8c293beea7ee0 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 12 Jan 2023 19:33:21 +0100 Subject: test: added pkgctl devel wrapper for convenient development testing For local development testing, there is a convenience wrapper for `pkgctl` that will automatically build the project using make and proxy all calls to the local build directory. Either `./test/bin/pkgctl` can be run directly or the `test/bin` directory can be added to the PATH. Signed-off-by: Levente Polyak --- README.md | 9 +++++++++ test/bin/pkgctl | 12 ++++++++++++ 2 files changed, 21 insertions(+) create mode 100755 test/bin/pkgctl diff --git a/README.md b/README.md index ef69f3b..46294d6 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,15 @@ files like `makepkg.conf`. BUILDTOOLVER="${pkgver}-${pkgrel}-${arch}" make all ``` +## Development + +For local development testing, there is a convenience wrapper for `pkgctl` that +will automatically build the project and proxy all calls to the local build directory: + +```sh +./test/bin/pkgctl --help +``` + ## Releasing 1. bump the version in the Makefile diff --git a/test/bin/pkgctl b/test/bin/pkgctl new file mode 100755 index 0000000..9641af3 --- /dev/null +++ b/test/bin/pkgctl @@ -0,0 +1,12 @@ +#!/usr/bin/bash +set -e + +root="$(dirname -- "$(readlink -f -- "$0")")/../.." + +# always build everything so we use an up-to-date state +make -C "${root}" -j --no-print-directory --silent + +# run pkgctl from the build directory +export PATH="${root}/build/bin:${PATH}" +export _DEVTOOLS_LIBRARY_DIR="${root}/build" +"${root}/build/bin/pkgctl" "$@" -- cgit v1.2.3-70-g09d2 From d402d5f3081d9e0a1f269e3209b52c23bd355ff3 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 12 Jan 2023 21:30:29 +0100 Subject: archrelease: print deprecation warning when executed directly --- src/archrelease.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/archrelease.in b/src/archrelease.in index c3776e7..d206ab8 100644 --- a/src/archrelease.in +++ b/src/archrelease.in @@ -11,6 +11,11 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh set -e +# Deprecation warning +if [[ -z $_DEVTOOLS_COMMAND ]]; then + warning "${0##*/} is deprecated and will be removed. Use 'pkgctl release' instead" +fi + # parse command line options FORCE= while getopts ':f' flag; do -- cgit v1.2.3-70-g09d2 From 1ae09b43af632c3a61135dc295c9c1b12b227669 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 12 Jan 2023 21:30:56 +0100 Subject: commitpkg: print deprecation warning when executed directly --- src/commitpkg.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/commitpkg.in b/src/commitpkg.in index f80a6cd..5f29881 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -55,6 +55,11 @@ fi cmd=${0##*/} +# Deprecation warning +if [[ -z $_DEVTOOLS_COMMAND ]]; then + warning "${cmd} is deprecated and will be removed. Use 'pkgctl release' instead" +fi + if [[ ! -f PKGBUILD ]]; then die 'No PKGBUILD file' fi -- cgit v1.2.3-70-g09d2 From 79543824011ba51ddad6a4dda8c8c585ea8e5e0a Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 20 Jan 2023 01:11:02 +0100 Subject: commitpkg: error out if the repo is not configured to latest specs This ensures the repository we try to commit and release from uses the latest distro specs for its local git config. The check errors out early before touching anything and prints a recommendation how to update the repo. Signed-off-by: Levente Polyak --- src/commitpkg.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/commitpkg.in b/src/commitpkg.in index 5f29881..7573d9b 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -64,6 +64,12 @@ if [[ ! -f PKGBUILD ]]; then die 'No PKGBUILD file' fi +if ! repo_spec=$(git config --local devtools.version) || [[ ${repo_spec} != "${GIT_REPO_SPEC_VERSION}" ]]; then + error "repository specs are out of date, try:" + msg2 'pkgctl repo configure' + exit 1 +fi + if [[ "$(git symbolic-ref --short HEAD)" != main ]]; then die 'must be run from the main branch' fi -- cgit v1.2.3-70-g09d2 From 1d7f9972151b0a52297880c8f9e5f28a1d7fe597 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 14 Jan 2023 18:20:29 +0100 Subject: build: command to build packages inside a clean chroot --- .gitignore | 2 +- contrib/completion/zsh/_devtools.in | 20 ++ doc/man/pkgctl-build.1.asciidoc | 80 ++++++++ doc/man/pkgctl.1.asciidoc | 4 + src/lib/build/build.sh | 387 ++++++++++++++++++++++++++++++++++++ src/lib/util/git.sh | 24 +++ src/pkgctl.in | 9 + 7 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 doc/man/pkgctl-build.1.asciidoc create mode 100644 src/lib/build/build.sh create mode 100644 src/lib/util/git.sh diff --git a/.gitignore b/.gitignore index f5d2d27..3e34a0c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ *~ devtools-*.tar.gz* -build/ +/build/ diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 2961f6f..c743667 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -34,6 +34,25 @@ _pkgctl_auth_status_args=( '(-h --help)'{-h,--help}'[Display usage]' ) +_pkgctl_build_args=( + "--arch=[Specify architectures to build for (disables auto-detection)]:arch:($_arch[*])" + "--repo=[Specify a target repository (disables auto-detection)]:repo:($_repos[*])" + '(-s --staging)'{-s,--staging}'[Build against the staging counterpart of the auto-detected repo]' + '(-t --testing)'{-t,--testing}'[Build against the testing counterpart of the auto-detected repo]' + '(-o --offload)'{-o,--offload}'[Build on a remote server and transfer artifacts afterwards]' + '(-c --clean)'{-c,--clean}'[Recreate the chroot before building]' + '(-I --install)'{-I,--install}'[Install a package into the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' + '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' + '--pkgrel=[Set pkgrel to a given value]:pkgrel:' + '--rebuild[Increment the pkgrel variable]' + '(-e --edit)'{-e,--edit}'[Edit the PKGBUILD before building]' + '(-r --release)'{-r,--release}'[Automatically commit, tag and release after building]' + '(-m --message=)'{-m,--message=}"[Use the given as the commit message]:message:" + '(-u --db-update)'{-u,--db-update}'[Automatically update the pacman database as last action]' + '(-h --help)'{-h,--help}'[Display usage]' + '*:git_dir:_files -/' +) + _pkgctl_db_cmds=( "pkgctl db command" "move[Move packages between pacman repositories]" @@ -213,6 +232,7 @@ _devtools_completions_all_packages() { _pkgctl_cmds=( "pkgctl command" "auth[Authenticate with services like GitLab]" + "build[Build packages inside a clean chroot]" "db[Pacman database modification for packge update, move etc]" "diff[Compare package files using different modes]" "release[Release step to commit, tag and upload build artifacts]" diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc new file mode 100644 index 0000000..132c0a4 --- /dev/null +++ b/doc/man/pkgctl-build.1.asciidoc @@ -0,0 +1,80 @@ +pkgctl-build(1) +=============== + +Name +---- +pkgctl-build - Build packages inside a clean chroot + +Synopsis +-------- +pkgctl build [OPTIONS] [PATH...] + +Description +----------- + +TODO + +Build Options +------------- + +*--arch* 'ARCH':: + Specify architectures to build for (disables auto-detection) + +*--repo* 'REPO':: + Specify a target repository (disables auto-detection) + +*-s, --staging*:: + Build against the staging counterpart of the auto-detected repo + +*-t, --testing*:: + Build against the testing counterpart of the auto-detected repo + +*-o, --offload*:: + Build on a remote server and transfer artifacts afterwards + +*-c, --clean*:: + Recreate the chroot before building + +*-I, --install* 'FILE':: + Install a package into the working copy of the chroot + +PKGBUILD Options +---------------- + +*--pkgver*='PKGVER':: + Set pkgver, reset pkgrel and update checksums + +*--pkgrel*='PKGREL':: + Set pkgrel to a given value + +*--rebuild*:: + Increment the current pkgrel variable + +*-e, --edit*:: + Edit the PKGBUILD before building + +Release Options +--------------- + +*-r, --release*:: + Automatically commit, tag and release after building + +*-m, --message* 'MSG':: + Use the given as the commit message + +*-u, --db-update*:: + Automatically update the pacman database as last action + +Options +------- + +*-h, --help*:: + Show a help text + +See Also +-------- + +linkman:pkgctl-release[1] +linkman:pkgctl-db-update[1] + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index 8da5d19..c5a6174 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -20,6 +20,9 @@ Subcommands pkgctl auth:: Authenticate with services like GitLab +pkgctl build:: + Build packages inside a clean chroot + pkgctl db:: Pacman database modification for packge update, move etc @@ -36,6 +39,7 @@ See Also -------- linkman:pkgctl-auth[1] +linkman:pkgctl-build[1] linkman:pkgctl-db[1] linkman:pkgctl-diff[1] linkman:pkgctl-release[1] diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh new file mode 100644 index 0000000..e32c79f --- /dev/null +++ b/src/lib/build/build.sh @@ -0,0 +1,387 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_BUILD_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_BUILD_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/db/update.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/update.sh +# shellcheck source=src/lib/release.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh +# shellcheck source=src/lib/util/git.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/git.sh +# shellcheck source=src/lib/util/pacman.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh +# shellcheck source=src/lib/valid-repos.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh +# shellcheck source=src/lib/valid-tags.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-tags.sh + +source /usr/share/makepkg/util/config.sh +source /usr/share/makepkg/util/message.sh + +set -e + + +pkgctl_build_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PATH]... + + Build packages inside a clean chroot + + When a new pkgver is set using the appropriate PKGBUILD options the + checksums are automatically updated. + + TODO + + BUILD OPTIONS + --arch ARCH Specify architectures to build for (disables auto-detection) + --repo REPO Specify a target repository (disables auto-detection) + -s, --staging Build against the staging counterpart of the auto-detected repo + -t, --testing Build against the testing counterpart of the auto-detected repo + -o, --offload Build on a remote server and transfer artifacts afterwards + -c, --clean Recreate the chroot before building + -I, --install FILE Install a package into the working copy of the chroot + + PKGBUILD OPTIONS + --pkgver=PKGVER Set pkgver, reset pkgrel and update checksums + --pkgrel=PKGREL Set pkgrel to a given value + --rebuild Increment the current pkgrel variable + -e, --edit Edit the PKGBUILD before building + + RELEASE OPTIONS + -r, --release Automatically commit, tag and release after building + -m, --message MSG Use the given as the commit message + -u, --db-update Automatically update the pacman database as last action + + OPTIONS + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} + $ ${COMMAND} --rebuild --staging --message 'libyay 0.42 rebuild' libfoo libbar + $ ${COMMAND} --pkgver 1.42 --release --db-update +_EOF_ +} + +pkgctl_build_check_option_group_repo() { + local option=$1 + local repo=$2 + local testing=$3 + local staging=$4 + if ( (( testing )) && (( staging )) ) || + ( [[ $repo =~ ^.*-(staging|testing)$ ]] && ( (( testing )) || (( staging )) )); then + die "The argument '%s' cannot be used with one or more of the other specified arguments" "${option}" + exit 1 + fi + return 0 +} + +pkgctl_build_check_option_group_ver() { + local option=$1 + local pkgver=$2 + local pkgrel=$3 + local rebuild=$4 + if [[ -n "${pkgver}" ]] || [[ -n "${pkgrel}" ]] || (( rebuild )); then + die "The argument '%s' cannot be used with one or more of the other specified arguments" "${option}" + exit 1 + fi + return 0 +} + +# TODO: import pgp keys +pkgctl_build() { + if (( $# < 1 )) && [[ ! -f PKGBUILD ]]; then + pkgctl_build_usage + exit 1 + fi + + local UPDPKGSUMS=0 + local EDIT=0 + local REBUILD=0 + local OFFLOAD=0 + local STAGING=0 + local TESTING=0 + local RELEASE=0 + local DB_UPDATE=0 + + local REPO= + local PKGVER= + local PKGREL= + local MESSAGE= + + local paths=() + local BUILD_ARCH=() + local BUILD_OPTIONS=() + local MAKECHROOT_OPTIONS=() + local RELEASE_OPTIONS=() + + local PTS + PTS="$(tty | sed 's|/dev/pts/||')" + local WORKER="${USER}-${PTS}" + + # variables + local path pkgbase pkgrepo source + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_build_usage + exit 0 + ;; + --repo) + (( $# <= 1 )) && die "missing argument for %s" "$1" + REPO="${2}" + pkgctl_build_check_option_group_repo '--repo' "${REPO}" "${TESTING}" "${STAGING}" + shift 2 + ;; + --arch) + (( $# <= 1 )) && die "missing argument for %s" "$1" + if [[ ${2} == all ]]; then + BUILD_ARCH=("${_arch[@]::${#_arch[@]}-1}") + elif [[ ${2} == any ]]; then + BUILD_ARCH=("${_arch[0]}") + elif ! in_array "${2}" "${BUILD_ARCH[@]}"; then + if ! in_array "${2}" "${_arch[@]}"; then + die 'invalid architecture: %s' "${2}" + fi + BUILD_ARCH+=("${2}") + fi + shift 2 + ;; + --pkgver=*) + pkgctl_build_check_option_group_ver '--pkgver' "${PKGVER}" "${PKGREL}" "${REBUILD}" + PKGVER="${1#*=}" + PKGREL=1 + UPDPKGSUMS=1 + shift + ;; + --pkgrel=*) + pkgctl_build_check_option_group_ver '--pkgrel' "${PKGVER}" "${PKGREL}" "${REBUILD}" + PKGREL="${1#*=}" + shift + ;; + --rebuild) + # shellcheck source=src/lib/util/git.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/git.sh + pkgctl_build_check_option_group_ver '--rebuild' "${PKGVER}" "${PKGREL}" "${REBUILD}" + REBUILD=1 + shift + ;; + -e|--edit) + EDIT=1 + shift + ;; + -o|--offload) + OFFLOAD=1 + shift + ;; + -s|--staging) + STAGING=1 + pkgctl_build_check_option_group_repo '--staging' "${REPO}" "${TESTING}" "${STAGING}" + shift + ;; + -t|--testing) + TESTING=1 + pkgctl_build_check_option_group_repo '--testing' "${REPO}" "${TESTING}" "${STAGING}" + shift + ;; + -c|--clean) + BUILD_OPTIONS+=("-c") + shift + ;; + -I|--install) + (( $# <= 1 )) && die "missing argument for %s" "$1" + MAKECHROOT_OPTIONS+=("-I" "$2") + warning 'installing packages into the chroot may break reproducible builds, use with caution!' + shift 2 + ;; + -r|--release) + # shellcheck source=src/lib/release.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh + RELEASE=1 + shift + ;; + -m|--message) + (( $# <= 1 )) && die "missing argument for %s" "$1" + MESSAGE=$2 + RELEASE_OPTIONS+=("--message" "${MESSAGE}") + shift 2 + ;; + -u|--db-update) + DB_UPDATE=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_build_usage + exit 1 + fi + fi + + # Update pacman cache for auto-detection + if [[ -z ${REPO} ]]; then + update_pacman_repo_cache + # Check valid repos if not resolved dynamically + elif ! in_array "${REPO}" "${_repos[@]}"; then + die "Invalid repository target: %s" "${REPO}" + fi + + for path in "${paths[@]}"; do + pushd "${path}" >/dev/null + + if [[ ! -f PKGBUILD ]]; then + die 'PKGBUILD not found in %s' "${path}" + fi + + source=() + # shellcheck source=contrib/makepkg/PKGBUILD.proto + . ./PKGBUILD + pkgbase=${pkgbase:-$pkgname} + pkgrepo=${REPO} + msg "Building ${pkgbase}" + + # auto-detection of build target + if [[ -z ${pkgrepo} ]]; then + if ! pkgrepo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then + die 'failed to get pacman repo' + fi + if [[ -z "${pkgrepo}" ]]; then + die 'unknown repo, please specify --repo for new packages' + fi + fi + + # special cases to resolve final build target + if (( TESTING )); then + pkgrepo="${pkgrepo}-testing" + elif (( STAGING )); then + pkgrepo="${pkgrepo}-staging" + elif [[ $pkgrepo == core ]]; then + pkgrepo="${pkgrepo}-testing" + fi + + # auto-detection of build architecture + if [[ $pkgrepo = multilib* ]]; then + BUILD_ARCH=("") + elif (( ${#BUILD_ARCH[@]} == 0 )); then + if in_array any "${arch[@]}"; then + BUILD_ARCH=("${_arch[0]}") + else + BUILD_ARCH+=("${arch[@]}") + fi + fi + + # print gathered build modes + msg2 "repo: ${pkgrepo}" + msg2 "arch: ${BUILD_ARCH[*]}" + + # increment pkgrel on rebuild + if (( REBUILD )); then + # try to figure out of pkgrel has been changed + if ! old_pkgrel=$(git_diff_tree HEAD PKGBUILD | grep --perl-regexp --only-matching --max-count=1 '^-pkgrel=\K\w+'); then + old_pkgrel=${pkgrel} + fi + # check if pkgrel conforms expectations + [[ ${pkgrel/.*} =~ ^[0-9]+$ ]] || die "Non-standard pkgrel declaration" + [[ ${old_pkgrel/.*} =~ ^[0-9]+$ ]] || die "Non-standard pkgrel declaration" + # increment pkgrel if it hasn't been changed yet + if [[ ${pkgrel} = "${old_pkgrel}" ]]; then + PKGREL=$((${pkgrel/.*}+1)) + else + warning 'ignoring --rebuild as pkgrel has already been incremented from %s to %s' "${old_pkgrel}" "${pkgrel}" + fi + fi + + # update pkgver + if [[ -n ${PKGVER} ]]; then + if [[ $(type -t pkgver) == function ]]; then + # TODO: check if die or warn, if we provide _commit _gitcommit setter maybe? + warning 'setting pkgver variable has no effect if the PKGBUILD has a pkgver() function' + fi + msg "Bumping pkgver to ${PKGVER}" + grep --extended-regexp --quiet --max-count=1 "^pkgver=${pkgver}$" PKGBUILD || die "Non-standard pkgver declaration" + sed --regexp-extended "s|^(pkgver=)${pkgver}$|\1${PKGVER}|g" -i PKGBUILD + fi + + # update pkgrel + if [[ -n ${PKGREL} ]]; then + msg "Bumping pkgrel to ${PKGREL}" + grep --extended-regexp --quiet --max-count=1 "^pkgrel=${pkgrel}$" PKGBUILD || die "Non-standard pkgrel declaration" + sed --regexp-extended "s|^(pkgrel=)${pkgrel}$|\1${PKGREL}|g" -i PKGBUILD + fi + + # edit PKGBUILD + if (( EDIT )); then + stat_busy 'Editing PKGBUILD' + if [[ -n $VISUAL ]]; then + $VISUAL PKGBUILD || die + elif [[ -n $EDITOR ]]; then + $EDITOR PKGBUILD || die + elif command -v vi &>/dev/null; then + vi PKGBUILD || die + else + die "need \$VISUAL or \$EDITOR to edit the PKGBUILD" + fi + stat_done + fi + + # update checksums if any sources are declared + if (( UPDPKGSUMS )) && (( ${#source[@]} >= 1 )); then + updpkgsums + fi + + # execute build + for arch in "${BUILD_ARCH[@]}"; do + if [[ -n $arch ]]; then + msg "Building ${pkgbase} for [${pkgrepo}] (${arch})" + BUILDTOOL="${pkgrepo}-${arch}-build" + else + msg "Building ${pkgbase} for [${pkgrepo}]" + BUILDTOOL="${pkgrepo}-build" + fi + + if (( OFFLOAD )); then + offload-build --repo "${pkgrepo}" -- "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" + else + "${BUILDTOOL}" "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" + fi + done + + # release the build + if (( RELEASE )); then + pkgctl_release --repo "${pkgrepo}" "${RELEASE_OPTIONS[@]}" + fi + + # reset common PKGBUILD variables + unset pkgbase pkgname arch pkgrepo source pkgver pkgrel validpgpkeys + popd >/dev/null + done + + # update the binary package repo db as last action + if (( RELEASE )) && (( DB_UPDATE )); then + # shellcheck disable=2119 + pkgctl_db_update + fi +} diff --git a/src/lib/util/git.sh b/src/lib/util/git.sh new file mode 100644 index 0000000..c4af662 --- /dev/null +++ b/src/lib/util/git.sh @@ -0,0 +1,24 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_UTIL_GIT_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_UTIL_GIT_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + + +git_diff_tree() { + local commit=$1 + local path=$2 + git \ + --no-pager \ + diff \ + --color=never \ + --color-moved=no \ + --unified=0 \ + --no-prefix \ + --no-ext-diff \ + "${commit}" \ + -- "${path}" +} diff --git a/src/pkgctl.in b/src/pkgctl.in index 47409de..40f9259 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -20,6 +20,7 @@ usage() { COMMANDS auth Authenticate with services like GitLab + build Build packages inside a clean chroot db Pacman database modification for packge update, move etc diff Compare package files using different modes release Release step to commit, tag and upload build artifacts @@ -46,6 +47,14 @@ while (( $# )); do usage exit 0 ;; + build) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/build/build.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/build/build.sh + pkgctl_build "$@" + exit 0 + ;; repo) _DEVTOOLS_COMMAND+=" $1" shift -- cgit v1.2.3-70-g09d2 From f669a71e847da88fefc1296dd2dd9ba82549a8c6 Mon Sep 17 00:00:00 2001 From: Levente Polyak 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 --- 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(-) 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 eda3a4aea00803d14400beff819d3b8be81774ce Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Mon, 30 Jan 2023 21:15:50 +0100 Subject: gitlab: add project path function to map special chars Automatic path conversion is limited to GitLab API v4 and will be removed in the future. It's expected that the caller does the path conversion on caller side and only passes a valid path to the API within its limitations. Hence convert project names to valid paths: 1. replace single '+' between word boundaries with '-' 2. replace any other '+' with literal 'plus' 3. replace any special chars other than '_', '-' and '.' with '-' 4. replace consecutive '_-' chars with a single '-' 5. replace 'tree' with 'unix-tree' due to GitLab reserved keyword Signed-off-by: Levente Polyak --- src/lib/api/gitlab.sh | 26 +++++++++++++++++++++++++- src/lib/repo/clone.sh | 6 +++++- src/lib/repo/configure.sh | 5 +++-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/lib/api/gitlab.sh b/src/lib/api/gitlab.sh index 649e205..e5f4237 100644 --- a/src/lib/api/gitlab.sh +++ b/src/lib/api/gitlab.sh @@ -81,16 +81,40 @@ gitlab_api_get_user() { return 0 } +# Convert arbitrary project names to GitLab valid path names. +# +# GitLab has several limitations on project and group names and also maintains +# a list of reserved keywords as documented on their docs. +# https://docs.gitlab.com/ee/user/reserved_names.html +# +# 1. replace single '+' between word boundaries with '-' +# 2. replace any other '+' with literal 'plus' +# 3. replace any special chars other than '_', '-' and '.' with '-' +# 4. replace consecutive '_-' chars with a single '-' +# 5. replace 'tree' with 'unix-tree' due to GitLab reserved keyword +gitlab_project_name_to_path() { + local name=$1 + printf "%s" "${name}" \ + | sed -E 's/([a-zA-Z0-9]+)\+([a-zA-Z]+)/\1-\2/g' \ + | sed -E 's/\+/plus/g' \ + | sed -E 's/[^a-zA-Z0-9_\-\.]/-/g' \ + | sed -E 's/[_\-]{2,}/-/g' \ + | sed -E 's/^tree$/unix-tree/g' +} + gitlab_api_create_project() { local pkgbase=$1 - local outfile data path + local outfile data path project_path [[ -z ${WORKDIR:-} ]] && setup_workdir outfile=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api.XXXXXXXXXX) + project_path=$(gitlab_project_name_to_path "${pkgbase}") + # create GitLab project data='{ "name": "'"${pkgbase}"'", + "path": "'"${project_path}"'", "namespace_id": "'"${GIT_PACKAGING_NAMESPACE_ID}"'", "request_access_enabled": "false" }' diff --git a/src/lib/repo/clone.sh b/src/lib/repo/clone.sh index 4b26fcf..dee4870 100644 --- a/src/lib/repo/clone.sh +++ b/src/lib/repo/clone.sh @@ -54,6 +54,9 @@ pkgctl_repo_clone() { local CONFIGURE_OPTIONS=() local pkgbases + # variables + local project_path + while (( $# )); do case $1 in -h|--help) @@ -126,7 +129,8 @@ pkgctl_repo_clone() { for pkgbase in "${pkgbases[@]}"; do if [[ ! -d ${pkgbase} ]]; then msg "Cloning ${pkgbase} ..." - remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git" + project_path=$(gitlab_project_name_to_path "${pkgbase}") + remote_url="${GIT_REPO_BASE_URL}/${project_path}.git" git clone --origin origin "${remote_url}" "${pkgbase}" else warning "Skip cloning ${pkgbase}: Directory exists" diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh index d6262b7..942876a 100644 --- a/src/lib/repo/configure.sh +++ b/src/lib/repo/configure.sh @@ -96,7 +96,7 @@ pkgctl_repo_configure() { local paths=() # variables - local path realpath pkgbase remote_url + local path realpath pkgbase remote_url project_path local PACKAGER GPGKEY packager_name packager_email while (( $# )); do @@ -174,7 +174,8 @@ pkgctl_repo_configure() { pushd "${path}" >/dev/null - remote_url="${GIT_REPO_BASE_URL}/${pkgbase}.git" + project_path=$(gitlab_project_name_to_path "${pkgbase}") + remote_url="${GIT_REPO_BASE_URL}/${project_path}.git" if ! git remote add origin "${remote_url}" &>/dev/null; then git remote set-url origin "${remote_url}" fi -- cgit v1.2.3-70-g09d2 From 4ae857e665181c8ba8d97637d41ef19062d85a12 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Mon, 30 Jan 2023 22:09:19 +0100 Subject: doc: update manpage footer for GitLab and remove static list of maintainers The list of all maintainers that have worked so far on devtools is exceeding a sane amount making each manpage convulsed. The authors can be pulled from GitLab directly without occupying lots of space on every manpage. We would like to express gratitude to all our maintainers. Signed-off-by: Levente Polyak --- doc/man/include/footer.asciidoc | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/doc/man/include/footer.asciidoc b/doc/man/include/footer.asciidoc index 14c5d36..e7b1827 100644 --- a/doc/man/include/footer.asciidoc +++ b/doc/man/include/footer.asciidoc @@ -1,27 +1,7 @@ -Bugs ----- -Bugs can be reported on the project's GitLab bug tracker 'https://gitlab.archlinux.org/archlinux/devtools' +Homepage +-------- +'https://gitlab.archlinux.org/archlinux/devtools' -Authors -------- - -Maintainers: - -* Aaron Griffin -* Allan McRae -* Bartłomiej Piotrowski -* Dan McGee -* Dave Reisner -* Evangelos Foutras -* Jan Alexander Steffens (heftig) -* Jelle van der Waa -* Levente Polyak -* Pierre Schmitz -* Sébastien Luttringer -* Sven-Hendrik Haase -* Thomas Bächler - -For additional contributors, use `git shortlog -s` on the devtools.git -repository. +Please report bugs and feature requests in the issue tracker. Please do your best to provide a reproducible test case for bugs. -- cgit v1.2.3-70-g09d2 From fe2eb3076df36c619c22bf65c68e68f38ab39b83 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Tue, 31 Jan 2023 00:01:37 +0100 Subject: rebuildpkgs: drop legacy script, will be replaced with a smarter UX Instead of trying to port this ancient script, which doesn't even seem to work with community, let's instead remove it. We will be adding a replacement script in pkgctl soon with a smarter and more convenient UX. --- contrib/completion/zsh/_devtools.in | 7 +-- src/rebuildpkgs.in | 114 ------------------------------------ 2 files changed, 1 insertion(+), 120 deletions(-) delete mode 100644 src/rebuildpkgs.in diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 5908bd6..39e9ac0 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -1,4 +1,4 @@ -#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 +#compdef archbuild arch-nspawn archrelease commitpkg pkgctl diffpkg finddeps makechrootpkg mkarchroot 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 @@ -186,11 +186,6 @@ _mkarchroot_args=( '*:packages:_devtools_completions_all_packages' ) -_rebuildpkgs_args=( - '1:chroot_dir:_files -/' - '*:packages:_devtools_completions_all_packages' -) - _checkpkg_args=( '(-r --rmdir)'{-r,--rmdir}'[Remove the temporary directory]' '(-w --warn)'{-w,--warn}'[Print a warning in case of differences]' diff --git a/src/rebuildpkgs.in b/src/rebuildpkgs.in deleted file mode 100644 index 7bf8b12..0000000 --- a/src/rebuildpkgs.in +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-3.0-or-later -# -# This script rebuilds a list of packages in order -# and reports anything that fails -# -# Due to sudo usage, it is recommended to allow makechrootpkg -# to be run with NOPASSWD in your sudoers file -# -# FIXME -# Currently uses $(pwd)/rebuilds as the directory for rebuilding... -# TODO make this work for community too - -_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 \n' "$(basename "${BASH_SOURCE[0]}")" - printf ' example: %s ~/chroot readline bash foo bar baz\n' "$(basename "${BASH_SOURCE[0]}")" - exit 1 -fi - -# Source makepkg.conf; fail if it is not found -if [[ -r '/etc/makepkg.conf' ]]; then - # shellcheck source=config/makepkg/x86_64.conf - source '/etc/makepkg.conf' -else - die '/etc/makepkg.conf not found!' -fi - -# Source user-specific makepkg.conf overrides -if [[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf" ]]; then - # shellcheck source=/dev/null - source "${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf" -elif [[ -r "$HOME/.makepkg.conf" ]]; then - # shellcheck source=/dev/null - source "$HOME/.makepkg.conf" -fi - -bump_pkgrel() { - # Get the current pkgrel from git and update the working copy with it - # This prevents us from incrementing out of control :) - pbuild='.svn/text-base/PKGBUILD.svn-base' - oldrel=$(grep 'pkgrel=' $pbuild | cut -d= -f2) - - #remove decimals - rel=${oldrel%%.*} - - newrel=$((rel + 1)) - - sed -i "s/pkgrel=$oldrel/pkgrel=$newrel/" PKGBUILD -} - -pkg_from_pkgbuild() { - # we want the sourcing to be done in a subshell so we don't pollute our current namespace - export CARCH PKGEXT - # shellcheck source=contrib/makepkg/PKGBUILD.proto - (source PKGBUILD; echo "$pkgname-$pkgver-$pkgrel-$CARCH$PKGEXT") -} - -chrootdir="$1"; shift -pkgs=("$@") - -SVNPATH='svn+ssh://repos.archlinux.org/srv/repos/svn-packages/svn' - -msg "Work will be done in %s" "$(pwd)/rebuilds" - -REBUILD_ROOT="$(pwd)/rebuilds" -mkdir -p "$REBUILD_ROOT" -cd "$REBUILD_ROOT" - -/usr/bin/svn co -N $SVNPATH - -FAILED="" -for pkg in "${pkgs[@]}"; do - cd "$REBUILD_ROOT/svn-packages" - - msg2 "Building '%s'" "$pkg" - /usr/bin/svn update "$pkg" - if [[ ! -d "$pkg/trunk" ]]; then - FAILED="$FAILED $pkg" - warning "%s does not exist in SVN" "$pkg" - continue - fi - cd "$pkg/trunk/" - - bump_pkgrel - - if ! sudo makechrootpkg -u -d -r "$chrootdir" -- --noconfirm; then - FAILED="$FAILED $pkg" - error "%s Failed!" "$pkg" - else - pkgfile=$(pkg_from_pkgbuild) - if [[ -e $pkgfile ]]; then - msg2 "%s Complete" "$pkg" - else - FAILED="$FAILED $pkg" - error "%s Failed, no package built!" "$pkg" - fi - fi -done - -cd "$REBUILD_ROOT" -if [[ -n $FAILED ]]; then - msg 'Packages failed:' - for pkg in $FAILED; do - msg2 "%s" "$pkg" - done -fi - -msg 'SVN pkgbumps in svn-packages/ - commit when ready' -- cgit v1.2.3-70-g09d2 From a981ef40e84398475cfe04ac49b8118385249a96 Mon Sep 17 00:00:00 2001 From: Campbell Jones Date: Sat, 25 Mar 2023 17:53:27 -0400 Subject: edit: improve editor presence checking Adds a check for the configured Git editor (git config core.editor) in both commitpkg and build.sh. Additionally, instead of blindly executing vi when all other options are exhausted, remove it instead as it is a none standard installed editor anyway. Closes #106 Signed-off-by: Levente Polyak --- src/commitpkg.in | 4 +++- src/lib/build/build.sh | 11 +++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/commitpkg.in b/src/commitpkg.in index 7573d9b..26117dc 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -198,8 +198,10 @@ if [[ -n $(git status --short --untracked-files=no) ]]; then $VISUAL "$msgfile" || die elif [[ -n $EDITOR ]]; then $EDITOR "$msgfile" || die + elif giteditor=$(git config --get core.editor); then + $giteditor "$msgfile" || die else - vi "$msgfile" || die + die "No usable editor found (tried \$GIT_EDITOR, \$VISUAL, \$EDITOR, git config [core.editor])." fi [[ -s $msgfile ]] || die stat_busy 'Committing changes' diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index e32c79f..72ee4fb 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -335,18 +335,21 @@ pkgctl_build() { # edit PKGBUILD if (( EDIT )); then stat_busy 'Editing PKGBUILD' - if [[ -n $VISUAL ]]; then + if [[ -n $GIT_EDITOR ]]; then + $GIT_EDITOR PKGBUILD || die + elif [[ -n $VISUAL ]]; then $VISUAL PKGBUILD || die elif [[ -n $EDITOR ]]; then $EDITOR PKGBUILD || die - elif command -v vi &>/dev/null; then - vi PKGBUILD || die + elif giteditor=$(git config --get core.editor); then + $giteditor PKGBUILD || die else - die "need \$VISUAL or \$EDITOR to edit the PKGBUILD" + die "No usable editor found (tried \$GIT_EDITOR, \$VISUAL, \$EDITOR, git config [core.editor])." fi stat_done fi + # update checksums if any sources are declared if (( UPDPKGSUMS )) && (( ${#source[@]} >= 1 )); then updpkgsums -- cgit v1.2.3-70-g09d2 From 5e22e4f81e61f4ad2228366439be00b691284894 Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Mon, 13 Feb 2023 14:58:42 +0100 Subject: config: allow suppying the gitlab token via env var This would allow to supply the gitlab tokens via the env var DEVTOOLS_GITLAB_TOKEN and therefore allow users to choose whatever program they want to fill this env var. Closes #113 Signed-off-by: Christian Heusel Signed-off-by: Levente Polyak --- doc/man/pkgctl-auth-login.1.asciidoc | 7 +++++++ src/lib/auth/login.sh | 8 ++++++++ src/lib/config.sh | 10 +++++++--- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/doc/man/pkgctl-auth-login.1.asciidoc b/doc/man/pkgctl-auth-login.1.asciidoc index 9c32ab2..eeeec4e 100644 --- a/doc/man/pkgctl-auth-login.1.asciidoc +++ b/doc/man/pkgctl-auth-login.1.asciidoc @@ -16,6 +16,13 @@ Interactively authenticate with the GitLab instance. The minimum required scopes for the token are: 'api', 'write_repository'. +The GitLab API token can either be stored in a plaintext file in +'$XDG_CONFIG_HOME/devtools/gitlab.conf', or supplied via the +'DEVTOOLS_GITLAB_TOKEN' environment variable using any command (gpg, vault, +password manager) by declaring a shell alias: + + $ alias pkgctl='DEVTOOLS_GITLAB_TOKEN="$(command to obtain token)" pkgctl' + Options ------- diff --git a/src/lib/auth/login.sh b/src/lib/auth/login.sh index 083e80a..d427676 100644 --- a/src/lib/auth/login.sh +++ b/src/lib/auth/login.sh @@ -27,6 +27,10 @@ pkgctl_auth_login_usage() { The minimum required scopes for the token are: 'api', 'write_repository'. + The GitLab API token can either be stored in a plaintext file, or + supplied via the DEVTOOLS_GITLAB_TOKEN environment variable using a + vault, see pkgctl-auth-login(1) for details. + OPTIONS -g, --gen-access-token Open the URL to generate a new personal access token -h, --help Show this help text @@ -66,6 +70,10 @@ pkgctl_auth_login() { Tip: you can generate a Personal Access Token here ${personal_access_token_url} The minimum required scopes are 'api' and 'write_repository'. + + If you do not want to store the token in a plaintext file, you can abort + the following prompt and supply the token via the DEVTOOLS_GITLAB_TOKEN + environment variable using a vault, see pkgctl-auth-login(1) for details. _EOF_ if (( GEN_ACESS_TOKEN )); then diff --git a/src/lib/config.sh b/src/lib/config.sh index 5034c6e..ba6532e 100644 --- a/src/lib/config.sh +++ b/src/lib/config.sh @@ -14,11 +14,15 @@ readonly XDG_DEVTOOLS_GITLAB_CONFIG="${XDG_DEVTOOLS_DIR}/gitlab.conf" export GITLAB_TOKEN="" load_devtools_config() { - if [[ ! -f "${XDG_DEVTOOLS_GITLAB_CONFIG}" ]]; then - GITLAB_TOKEN="" + if [[ -n "${DEVTOOLS_GITLAB_TOKEN}" ]]; then + GITLAB_TOKEN="${DEVTOOLS_GITLAB_TOKEN}" return fi - GITLAB_TOKEN=$(grep GITLAB_TOKEN "${XDG_DEVTOOLS_GITLAB_CONFIG}"|cut -d= -f2|cut -d\" -f2) + if [[ -f "${XDG_DEVTOOLS_GITLAB_CONFIG}" ]]; then + GITLAB_TOKEN=$(grep GITLAB_TOKEN "${XDG_DEVTOOLS_GITLAB_CONFIG}"|cut -d= -f2|cut -d\" -f2) + return + fi + GITLAB_TOKEN="" } save_devtools_config() { -- cgit v1.2.3-70-g09d2 From 6c2498750e158f49a0e4ebdf93b5991abf45c7d1 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 31 Mar 2023 23:34:28 +0200 Subject: doc: add dependency declaration to the README.md This will help to make sure dependencies are explicitly stated and reflected in the PKGBUILD. --- README.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/README.md b/README.md index 46294d6..95683a9 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,37 @@ will automatically build the project and proxy all calls to the local build dire 5. Upload the source tarball with ```make dist upload``` 6. Update the package +## Dependencies + +### Runtime Dependencies + +- arch-install-scripts +- awk +- bash +- binutils +- coreutils +- diffutils +- findutils +- grep +- jq +- ncurses +- openssh +- parallel +- rsync +- sed +- systemd +- util-linux +- bzr +- git +- mercurial +- subversion + +### Development Dependencies + +- asciidoc +- make +- shellcheck + ## License Devtools is licensed under the terms of the **GPL-3.0-or-later** (see [LICENSE](LICENSE)). -- cgit v1.2.3-70-g09d2 From f3518e248cc8be165009f2200ff3b6500bfc0476 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 1 Apr 2023 00:12:56 +0200 Subject: build: support nocheck for initial bootstrap builds Output a warning when this option is used to remind packagers to rebuild the packages with checks once the bootstrap cycle has been completed. --- contrib/completion/zsh/_devtools.in | 1 + doc/man/pkgctl-build.1.asciidoc | 3 +++ src/lib/build/build.sh | 11 +++++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 39e9ac0..e782fba 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -42,6 +42,7 @@ _pkgctl_build_args=( '(-o --offload)'{-o,--offload}'[Build on a remote server and transfer artifacts afterwards]' '(-c --clean)'{-c,--clean}'[Recreate the chroot before building]' '(-I --install)'{-I,--install}'[Install a package into the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' + '--nocheck[Do not run the check() function in the PKGBUILD]' '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' '--pkgrel=[Set pkgrel to a given value]:pkgrel:' '--rebuild[Increment the pkgrel variable]' diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index 132c0a4..6ae3872 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -38,6 +38,9 @@ Build Options *-I, --install* 'FILE':: Install a package into the working copy of the chroot +*--nocheck*:: + Do not run the check() function in the PKGBUILD + PKGBUILD Options ---------------- diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 72ee4fb..fff8125 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -47,6 +47,7 @@ pkgctl_build_usage() { -o, --offload Build on a remote server and transfer artifacts afterwards -c, --clean Recreate the chroot before building -I, --install FILE Install a package into the working copy of the chroot + --nocheck Do not run the check() function in the PKGBUILD PKGBUILD OPTIONS --pkgver=PKGVER Set pkgver, reset pkgrel and update checksums @@ -120,6 +121,7 @@ pkgctl_build() { local BUILD_OPTIONS=() local MAKECHROOT_OPTIONS=() local RELEASE_OPTIONS=() + local MAKEPKG_OPTIONS=() local PTS PTS="$(tty | sed 's|/dev/pts/||')" @@ -201,6 +203,11 @@ pkgctl_build() { warning 'installing packages into the chroot may break reproducible builds, use with caution!' shift 2 ;; + --nocheck) + MAKEPKG_OPTIONS+=("--nocheck") + warning 'not running checks is disallowed for official packages, except for bootstrapping. Please rebuild after bootstrapping is completed!' + shift + ;; -r|--release) # shellcheck source=src/lib/release.sh source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh @@ -366,9 +373,9 @@ pkgctl_build() { fi if (( OFFLOAD )); then - offload-build --repo "${pkgrepo}" -- "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" + offload-build --repo "${pkgrepo}" -- "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" -- "${MAKEPKG_OPTIONS[@]}" else - "${BUILDTOOL}" "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" + "${BUILDTOOL}" "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" -- "${MAKEPKG_OPTIONS[@]}" fi done -- cgit v1.2.3-70-g09d2 From bc182032eb4a1cbae573c9f09bdd9f8338b20d23 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Wed, 5 Apr 2023 22:58:49 +0200 Subject: config: fixup file permissions to be more strict Normally the default in Arch is that all home directories are private. However, this may have been changed locally. To make sure we never expose secrets, lets use a umask of 0077 when writing the config. Additionally add some temporary fixup code to migrate the file and directory permissions of already existing paths. Signed-off-by: Levente Polyak --- src/lib/config.sh | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/lib/config.sh b/src/lib/config.sh index ba6532e..b09479a 100644 --- a/src/lib/config.sh +++ b/src/lib/config.sh @@ -14,6 +14,13 @@ readonly XDG_DEVTOOLS_GITLAB_CONFIG="${XDG_DEVTOOLS_DIR}/gitlab.conf" export GITLAB_TOKEN="" load_devtools_config() { + # temporary permission fixup + if [[ -d "${XDG_DEVTOOLS_DIR}" ]]; then + chmod 700 "${XDG_DEVTOOLS_DIR}" + fi + if [[ -f "${XDG_DEVTOOLS_GITLAB_CONFIG}" ]]; then + chmod 600 "${XDG_DEVTOOLS_GITLAB_CONFIG}" + fi if [[ -n "${DEVTOOLS_GITLAB_TOKEN}" ]]; then GITLAB_TOKEN="${DEVTOOLS_GITLAB_TOKEN}" return @@ -26,6 +33,16 @@ load_devtools_config() { } save_devtools_config() { - mkdir -p "${XDG_DEVTOOLS_DIR}" - printf 'GITLAB_TOKEN="%s"\n' "${GITLAB_TOKEN}" > "${XDG_DEVTOOLS_GITLAB_CONFIG}" + # temporary permission fixup + if [[ -d "${XDG_DEVTOOLS_DIR}" ]]; then + chmod 700 "${XDG_DEVTOOLS_DIR}" + fi + if [[ -f "${XDG_DEVTOOLS_GITLAB_CONFIG}" ]]; then + chmod 600 "${XDG_DEVTOOLS_GITLAB_CONFIG}" + fi + ( + umask 0077 + mkdir -p "${XDG_DEVTOOLS_DIR}" + printf 'GITLAB_TOKEN="%s"\n' "${GITLAB_TOKEN}" > "${XDG_DEVTOOLS_GITLAB_CONFIG}" + ) } -- cgit v1.2.3-70-g09d2 From e1142935e508ac1f70ec3c074655124056dc7666 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 14 Apr 2023 18:30:10 +0200 Subject: completion: zsh: allow args even when the command has subcommands This allows to show arguments on root level of commands that themselves have subcommands available. Complete those when any - is used in the completion word. --- contrib/completion/zsh/_devtools.in | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index e782fba..cc8d5cf 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -233,6 +233,10 @@ _pkgctl_cmds=( "repo[Manage Git packaging repositories and their configuration]" ) +_pkgctl_args=( + '(-h --help)'{-h,--help}'[Display usage]' +) + _pkgctl_diff_args=("${_diffpkg_args[@]}") _handle_subcommands() { @@ -243,8 +247,13 @@ _handle_subcommands() { '*::arg:->args' case $state in cmds) - local service_cmds=${service_name}_cmds[@] - _values "${(P)service_cmds}" + if [[ "${line[-1]}" == -* ]] && typeset -p ${service_name}_args &> /dev/null; then + local argname="${service_name}_args[@]" + _arguments -s "${(P)argname}" + else + local service_cmds=${service_name}_cmds[@] + _values "${(P)service_cmds}" + fi ;; args) local service_sub=${service_name}_$line[1] -- cgit v1.2.3-70-g09d2 From 645a5a9f047ada2fd76d6149ed24aa888547a52d Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Thu, 13 Apr 2023 17:44:48 +0200 Subject: pkgctl: introduce the version subcommand Related to https://gitlab.archlinux.org/archlinux/devtools/-/issues/125 Closes #125 Signed-off-by: Christian Heusel Co-Authored-By: Levente Polyak --- contrib/completion/zsh/_devtools.in | 6 +++++ doc/man/pkgctl-version.1.asciidoc | 23 ++++++++++++++++++ doc/man/pkgctl.1.asciidoc | 13 ++++++++++ src/lib/version/version.sh | 47 +++++++++++++++++++++++++++++++++++++ src/pkgctl.in | 9 +++++++ 5 files changed, 98 insertions(+) create mode 100644 doc/man/pkgctl-version.1.asciidoc create mode 100644 src/lib/version/version.sh diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index cc8d5cf..20c37ce 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -231,9 +231,15 @@ _pkgctl_cmds=( "diff[Compare package files using different modes]" "release[Release step to commit, tag and upload build artifacts]" "repo[Manage Git packaging repositories and their configuration]" + "version[Show pkgctl version information]" ) _pkgctl_args=( + '(-V --version)'{-V,--version}'[Show pkgctl version information]' + '(-h --help)'{-h,--help}'[Display usage]' +) + +_pkgctl_version_args=( '(-h --help)'{-h,--help}'[Display usage]' ) diff --git a/doc/man/pkgctl-version.1.asciidoc b/doc/man/pkgctl-version.1.asciidoc new file mode 100644 index 0000000..9beebf5 --- /dev/null +++ b/doc/man/pkgctl-version.1.asciidoc @@ -0,0 +1,23 @@ +pkgctl-version(1) +================= + +Name +---- +pkgctl-version - Show pkgctl version information + +Synopsis +-------- +pkgctl version [OPTIONS] + +Description +----------- + +Shows the current version information of pkgctl. + +Options +------- + +*-h, --help*:: + Show a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl.1.asciidoc b/doc/man/pkgctl.1.asciidoc index c5a6174..72cda1e 100644 --- a/doc/man/pkgctl.1.asciidoc +++ b/doc/man/pkgctl.1.asciidoc @@ -14,6 +14,15 @@ Description TODO +Options +------- + +*-V, --version*:: + Show pkgctl version information + +*-h, --help*:: + Show a help text + Subcommands ----------- @@ -35,6 +44,9 @@ pkgctl release:: pkgctl repo:: Manage Git packaging repositories and their configuration +pkgctl version:: + Show pkgctl version information + See Also -------- @@ -44,5 +56,6 @@ linkman:pkgctl-db[1] linkman:pkgctl-diff[1] linkman:pkgctl-release[1] linkman:pkgctl-repo[1] +linkman:pkgctl-version[1] include::include/footer.asciidoc[] diff --git a/src/lib/version/version.sh b/src/lib/version/version.sh new file mode 100644 index 0000000..d00a460 --- /dev/null +++ b/src/lib/version/version.sh @@ -0,0 +1,47 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_VERSION_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_VERSION_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} + +source /usr/share/makepkg/util/message.sh + +set -e + + +pkgctl_version_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] + + Shows the current version information of pkgctl + + OPTIONS + -h, --help Show this help text +_EOF_ +} + +pkgctl_version_print() { + cat <<- _EOF_ + pkgctl @buildtoolver@ +_EOF_ +} + +pkgctl_version() { + while (( $# )); do + case $1 in + -h|--help) + pkgctl_version_usage + exit 0 + ;; + *) + die "invalid argument: %s" "$1" + ;; + esac + done + + pkgctl_version_print +} diff --git a/src/pkgctl.in b/src/pkgctl.in index 40f9259..1797b32 100644 --- a/src/pkgctl.in +++ b/src/pkgctl.in @@ -25,6 +25,7 @@ usage() { diff Compare package files using different modes release Release step to commit, tag and upload build artifacts repo Manage Git packaging repositories and their configuration + version Show pkgctl version information OPTIONS -h, --help Show this help text @@ -93,6 +94,14 @@ while (( $# )); do pkgctl_release "$@" exit 0 ;; + version|--version|-V) + _DEVTOOLS_COMMAND+=" $1" + shift + # shellcheck source=src/lib/version/version.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/version.sh + pkgctl_version "$@" + exit 0 + ;; *) die "invalid command: %s" "$1" ;; -- cgit v1.2.3-70-g09d2 From f961e2e94803dd46c4fa5941eb15a7d4612bd0f0 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Thu, 23 Mar 2023 23:37:58 +0100 Subject: completion: implemented structured declarative bash completions This will make it tremendously easier to add arguments, subcommands and special positional option handling. Instead of the need to code the nested structure via bash and switch cases, we can simply declare functions and arrays with the matching names according to the subcommands or argument labels. Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 506 ++++++++++++++++++++++++++++++------ 1 file changed, 424 insertions(+), 82 deletions(-) diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index a353b99..e3ae023 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -2,89 +2,431 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -_devtools_compgen() { - local i r - COMPREPLY=($(compgen -W '$*' -- "$cur")) - for ((i=1; i < ${#COMP_WORDS[@]}-1; i++)); do - for r in "${!COMPREPLY[@]}"; do - if [[ ${COMP_WORDS[i]} = "${COMPREPLY[r]}" ]]; then - unset 'COMPREPLY[r]'; break - fi - done - done -} - -_pkgrepo_pkg() { - _devtools_compgen "$( - command pacman "-$1" - )" -} - -_pkgrepo() { - local cur prev - COMPREPLY=() - cur=$(_get_cword) - prev=${COMP_WORDS[COMP_CWORD-1]} - - _pkgrepo_pkg Slq - true -} && -complete -F _pkgrepo pkgrepo - -_makechrootpkg() { - local cur - COMPREPLY=() - _get_comp_words_by_ref cur - - case $cur in - -*) - COMPREPLY=( $( compgen -W '-I -c -h -l -r -u' -- "$cur" ) ) - ;; - *) - _filedir - return 0 - ;; - esac - - true -} && +_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) + + +_makechrootpkg_args=( + -h + -c + -d + -D + -u + -r + -I + -l + -n + -T + -U +) +_makechrootpkg_args_d_opts() { _filedir -d; } +_makechrootpkg_args_D_opts() { _filedir -d; } +_makechrootpkg_args_r_opts() { _filedir -d; } +_makechrootpkg_args_I_opts() { _filedir '*.pkg.tar.*'; } +_makechrootpkg_args_l_opts() { _filedir -d; } +_makechrootpkg_args_U_opts() { :; } +_makechrootpkg() { __devtools_complete _makechrootpkg; } complete -F _makechrootpkg makechrootpkg -_mkarchroot() { - local cur - COMPREPLY=() - _get_comp_words_by_ref cur - - case $cur in - -*) - COMPREPLY=( $( compgen -W '-C -M -c -h' -- "$cur" ) ) - ;; - *) - _filedir - return 0 - ;; - esac - - true -} && + +_makerepropkg_args=( + -h + -d + -c + -M +) +_makerepropkg_args_c_opts() { _filedir -d; } +_makerepropkg_args_M_opts() { _filedir '*.conf'; } +_makerepropkg_opts() { _filedir '*.pkg.tar.*'; } +_makerepropkg() { __devtools_complete _makerepropkg; } +complete -F _makerepropkg makerepropkg + + +_mkarchroot_args=( + -U + -C + -M + -c + -h +) +_mkarchroot_args_U_opts() { _filedir '*.pkg.tar.*'; } +_mkarchroot_args_C_opts() { _filedir '*.conf'; } +_mkarchroot_args_M_opts() { _filedir '*.conf'; } +_mkarchroot_args_c_opts() { _filedir -d; } +_mkarchroot_opts() { + local args + args=$(__pkgctl_word_count_after_subcommand) + if (( args == 0 )); then + _filedir -d + elif (( args >= 1 )); then + _devtools_completions_all_packages + fi +} +_mkarchroot() { __devtools_complete _mkarchroot; } complete -F _mkarchroot mkarchroot -_arch-nspawn() { - local cur - COMPREPLY=() - _get_comp_words_by_ref cur - - case $cur in - -*) - COMPREPLY=( $( compgen -W '-C -M -c -h' -- "$cur" ) ) - ;; - *) - _filedir - return 0 - ;; - esac - - true -} && -complete -F _arch-nspawn arch-nspawn -# ex:et ts=2 sw=2 ft=sh + +_arch_nspawn_args=( + -C + -M + -c + -f + -s + -h +) +_arch_nspawn_args_C_opts() { _filedir '*.conf'; } +_arch_nspawn_args_M_opts() { _filedir '*.conf'; } +_arch_nspawn_args_c_opts() { _filedir -d; } +_arch_nspawn_args_f_opts() { _filedir; } +_arch_nspawn_opts() { + local args + args=$(__pkgctl_word_count_after_subcommand) + if (( args == 0 )); then + _filedir -d + fi +} +_arch_nspawn() { __devtools_complete _arch_nspawn; } +complete -F _arch_nspawn arch-nspawn + + +_sogrep_args=( + -v --verbose + -r --refresh + -h --help +) +_sogrep_opts() { + local args + args=$(__pkgctl_word_count_after_subcommand) + if (( args == 0 )); then + _devtools_completions_repo all + fi +} +_sogrep() { __devtools_complete _sogrep; } +complete -F _sogrep sogrep + + +_offload_build_args=( + -r --repo + -a --arch + -s --server + -h --help +) +_offload_build_args__repo_opts() { _devtools_completions_build_repo; } +_offload_build_args_r_opts() { _offload_build_args__repo_opts; } +_offload_build_args__arch_opts() { _devtools_completions_arch; } +_offload_build_args_a_opts() { _offload_build_args__arch_opts; } +_offload_build_args__server_opts() { :; } +_offload_build_args_s_opts() { _offload_build_args__server_opts; } +_offload_build() { __devtools_complete _offload_build; } +complete -F _offload_build offload-build + + +_pkgctl_cmds=( + auth + build + db + diff + release + repo + version +) +_pkgctl_args=( + -V --version + -h --help +) + + +_pkgctl_auth_cmds=( + login + status +) + + +_pkgctl_auth_login_args=( + -g --gen-access-token + -h --help +) + + +_pkgctl_auth_status_args=( + -t --show-token + -h --help +) + + +_pkgctl_build_args=( + --arch + --repo + + -s --staging + -t --testing + -o --offload + -c --clean + + --pkgver + --pkgrel + --rebuild + -e --edit + + -r --release + -m --message + -u --db-update + + -h --help +) +_pkgctl_build_args__arch_opts() { _devtools_completions_arch; } +_pkgctl_build_args__repo_opts() { _devtools_completions_repo; } +_pkgctl_build_args__pkgver_opts() { :; } +_pkgctl_build_args__pkgrel_opts() { :; } +_pkgctl_build_args__message_opts() { :; } +_pkgctl_build_args_m_opts() { _pkgctl_build_args__message_opts; } +_pkgctl_build_opts() { _filedir -d; } + + +_pkgctl_db_cmds=( + move + remove + update +) + + +_pkgctl_db_move_args=( + -h --help +) +_pkgctl_db_move_opts() { + local subcommand args + subcommand=(db move) + args=$(__pkgctl_word_count_after_subcommand "${subcommand[@]}") + + if (( args == 0 )); then + _devtools_completions_repo + elif (( args == 1 )); then + _devtools_completions_repo + elif (( args >= 2 )); then + _devtools_completions_all_packages + fi +} + + +_pkgctl_db_remove_args=( + -a --arch + -h --help +) +_pkgctl_db_remove_opts() { + local subcommand args + subcommand=(db remove) + args=$(__pkgctl_word_count_after_subcommand "${subcommand[@]}") + + if (( args == 0 )); then + _devtools_completions_repo + elif (( args >= 1 )); then + _devtools_completions_all_packages + fi +} + + +_pkgctl_db_update_args=( + -h --help +) + + +_pkgctl_release_args=( + -m --message + -r --repo + -s --staging + -t --testing + -u --db-update + -h --help +) +_pkgctl_release_args__message_opts() { :; } +_pkgctl_release_args_m_opts() { _pkgctl_release_args__message_opts; } +_pkgctl_release_args__repo_opts() { _devtools_completions_repo; } +_pkgctl_release_args_r_opts() { _pkgctl_release_args__repo_opts; } +_pkgctl_release_opts() { _filedir -d; } + + +_pkgctl_repo_cmds=( + clone + configure + create + web +) + + +_pkgctl_repo_clone_args=( + -m --maintainer + -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_opts() { _devtools_completions_all_packages; } + + +_pkgctl_repo_configure_args=( + -h --help +) +_pkgctl_repo_configure_opts() { _filedir -d; } + + +_pkgctl_repo_create_args=( + -c --clone + -h --help +) + + +_pkgctl_repo_web_args=( + -h --help +) +_pkgctl_repo_web_opts() { _filedir -d; } + + +_pkgctl_diff_args=( + -l --list + -d --diffoscope + -p --pkginfo + -b --buildinfo + -m --makepkg-config + -u -U --unified + -y --side-by-side + --color + -W --width + -P --pool + -v --verbose + -h --help +) +_pkgctl_diff_args__makepkg_config_opts() { _filedir '*.conf'; } +_pkgctl_diff_args_m_opts() { _pkgctl_diff_args__makepkg_config_opts; } +_pkgctl_diff_args__width_opts() { :; } +_pkgctl_diff_args_W_opts() { _pkgctl_diff_args__width_opts; } +_pkgctl_diff_args__color_opts() { _devtools_completions_color; } +_pkgctl_diff_args__pool_opts() { _filedir -d; } +_pkgctl_diff_args_P_opts() { _pkgctl_diff_args__pool_opts; } +_pkgctl_diff_opts() { _devtools_completions_all_packages; } + + +_pkgctl_version_args=( + -h --help +) + + +_devtools_completions_color() { + mapfile -t COMPREPLY < <(compgen -W "${_colors[*]}" -- "$cur") +} +_devtools_completions_arch() { + mapfile -t COMPREPLY < <(compgen -W "${_arch[*]}" -- "$cur") +} +_devtools_completions_repo() { + local optional=${1:-} + mapfile -t COMPREPLY < <(compgen -W "${optional} ${_repos[*]}" -- "$cur") +} +_devtools_completions_build_repo() { + mapfile -t COMPREPLY < <(compgen -W "${_build_repos[*]}" -- "$cur") +} +_devtools_completions_all_packages() { + mapfile -t COMPREPLY < <(compgen -W "$(pacman -Sql)" -- "$cur") +} + +__devtools_complete() { + local service=$1 + local cur prev + + # Don't break words at : and = + COMP_WORDBREAKS=${COMP_WORDBREAKS//[:=]} + + cur=$(_get_cword) + prev=${COMP_WORDS[COMP_CWORD-1]} + + __pkgctl_handle_subcommands "${service}" + return 0 +} + +__pkgctl_has_func() { + declare -f -- "${1}" &>/dev/null +} + +__pkgctl_has_array() { + declare -p -- "${1}" &>/dev/null +} + +__pkgctl_is_subcommand() { + __pkgctl_has_array "${1}"_args || \ + __pkgctl_has_array "${1}"_cmds +} + +__pkgctl_words_after_subcommand() { + local subcommand=("$@") + local subcommand_idx=0 + local word prev_word + for ((i = 1; i < ${#COMP_WORDS[@]}; ++i)); do + word=${COMP_WORDS[i]} + prev_word=${COMP_WORDS[i-1]} + # skip options and the current typing + if [[ ${word} == -* ]] || [[ ${word} == "${cur}" ]]; then + continue + fi + # skip until we resolved the passed subcommand + if (( subcommand_idx < ${#subcommand[@]} )); then + if [[ $word == "${subcommand[$subcommand_idx]}" ]]; then + subcommand_idx=$(( subcommand_idx + 1 )) + fi + continue + fi + # skip previous options as they belong to the argument + if [[ ${prev_word} == -* ]] && __pkgctl_has_func "${service_name}_args${prev_word//-/_}_opts"; then + continue + fi + printf "%s\n" "${word}" + done +} +__pkgctl_word_count_after_subcommand() { + local subcommand=("$@") + mapfile -t words < <(__pkgctl_words_after_subcommand "${subcommand[@]}") + echo "${#words[@]}" +} + +__pkgctl_handle_subcommands() { + local service_name=${1} + local index=${2:-0} + local word ref + + # recurse into nested subcommands + for ((i = index + 1; i < ${#COMP_WORDS[@]}; ++i)); do + word=${COMP_WORDS[i]} + if [[ ${word} == -* ]] || [[ ${word} == "${cur}" ]]; then + continue + fi + if __pkgctl_is_subcommand "${service_name}_${word}"; then + __pkgctl_handle_subcommands "${service_name}_${word}" "${i}" + return + fi + done + + # dynamic argument options + if [[ $prev == -* ]] && word=${prev//-/_} && __pkgctl_has_func "${service_name}_args${word}_opts"; then + "${service_name}_args${word}_opts" + # dynamic subcommand options + elif [[ $cur != -* ]] && __pkgctl_has_func "${service_name}_opts"; then + "${service_name}_opts" + # subcommand argument array + elif ( ! __pkgctl_has_array "${service_name}"_cmds || [[ $cur == -* ]] ) && __pkgctl_has_array "${service_name}_args"; then + declare -n ref="${service_name}_args" + mapfile -t COMPREPLY < <(compgen -W "${ref[*]}" -- "$cur") + # subcommand array + elif __pkgctl_has_array "${service_name}"_cmds; then + declare -n ref="${service_name}_cmds" + mapfile -t COMPREPLY < <(compgen -W "${ref[*]}" -- "$cur") + fi +} + + +_pkgctl() { __devtools_complete _pkgctl; } +complete -F _pkgctl pkgctl +# ex:noet ts=4 sw=4 ft=sh -- cgit v1.2.3-70-g09d2 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 From 4289be212b38cbd9a1676303224b6af5c00bd429 Mon Sep 17 00:00:00 2001 From: Christian Heusel Date: Tue, 18 Apr 2023 01:15:24 +0200 Subject: build: allow release options only in combination with --release It leads to weird expectations when using --db-update or --message without --release. Make the behavior more user friendly, by aborting the operation and explaining that release options only work in conjunction with the release option. Fixes #131 Signed-off-by: Christian Heusel --- doc/man/pkgctl-build.1.asciidoc | 4 +++- src/lib/build/build.sh | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index 6ae3872..489926e 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -60,7 +60,9 @@ Release Options --------------- *-r, --release*:: - Automatically commit, tag and release after building + Automatically commit, tag and release after building + + Specifying this option is required when using any of the following options + in this section *-m, --message* 'MSG':: Use the given as the commit message diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index fff8125..2153200 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -238,6 +238,16 @@ pkgctl_build() { esac done + # check if any release specific options were specified without releasing + if (( ! RELEASE )); then + if (( DB_UPDATE )); then + die "cannot use --db-update without --release" + fi + if [[ -n "${MESSAGE}" ]]; then + die "cannot use --message without --release" + fi + fi + # check if invoked without any path from within a packaging repo if (( ${#paths[@]} == 0 )); then if [[ -f PKGBUILD ]]; then -- cgit v1.2.3-70-g09d2 From 8e3b6bcc5b82b270f8d310865f14f2b0405eddd7 Mon Sep 17 00:00:00 2001 From: Christian Heusel 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 Signed-off-by: Levente Polyak --- 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(+) 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 93306718252d3f7ae9722d2f8b059a18c8a65b22 Mon Sep 17 00:00:00 2001 From: Alexander Epaneshnikov Date: Wed, 26 Apr 2023 21:26:16 +0300 Subject: archrelease: fix mangled release package status output Git push will print its status, hence switch from a busy line indicator to a single line message and allow Git to print its status accordingly. Otherwise we get: ==> Releasing package...Enumerating objects: 6, done. --- src/archrelease.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/archrelease.in b/src/archrelease.in index d206ab8..818b0ca 100644 --- a/src/archrelease.in +++ b/src/archrelease.in @@ -89,7 +89,6 @@ if git tag --verify "$gittag" &> /dev/null; then exit 0 fi -stat_busy "Releasing package" +msg "Releasing package" git tag --sign --message="Package release ${pkgver}" "$gittag" || abort git push --tags --set-upstream origin main || abort -stat_done -- cgit v1.2.3-70-g09d2 From 1da97a8b362addc1cf8b936d918bddfa92192aa6 Mon Sep 17 00:00:00 2001 From: Caleb Maclennan 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(-) 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 830dcde2d8353dbcce1e831adb7c7e8f538210a3 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Fri, 5 May 2023 20:21:38 +0200 Subject: pkgctl build: support worker slots for none tty builds Allow overriding the worker slot with a dedicated option. Furthermore detect if the current tty is no pts and fall back to choosing a random worker slot between 1 and number of available processing units. Fixes #137 Signed-off-by: Levente Polyak --- contrib/completion/bash/devtools.in | 3 +++ contrib/completion/zsh/_devtools.in | 1 + doc/man/pkgctl-build.1.asciidoc | 6 ++++++ src/lib/build/build.sh | 23 ++++++++++++++++++----- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index 31269dd..b0a90e5 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -168,6 +168,7 @@ _pkgctl_build_args=( -t --testing -o --offload -c --clean + -w --worker --pkgver --pkgrel @@ -182,6 +183,8 @@ _pkgctl_build_args=( ) _pkgctl_build_args__arch_opts() { _devtools_completions_arch; } _pkgctl_build_args__repo_opts() { _devtools_completions_repo; } +_pkgctl_build_args__worker_opts() { :; } +_pkgctl_build_args_w_opts() { _pkgctl_build_args__worker_opts; } _pkgctl_build_args__pkgver_opts() { :; } _pkgctl_build_args__pkgrel_opts() { :; } _pkgctl_build_args__message_opts() { :; } diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index ed52a22..45ffde3 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -42,6 +42,7 @@ _pkgctl_build_args=( '(-o --offload)'{-o,--offload}'[Build on a remote server and transfer artifacts afterwards]' '(-c --clean)'{-c,--clean}'[Recreate the chroot before building]' '(-I --install)'{-I,--install}'[Install a package into the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"' + '(-w --worker)'{-w,--worker}'[Name of the worker slot, useful for concurrent builds (disables auto-detection)]:slot:' '--nocheck[Do not run the check() function in the PKGBUILD]' '--pkgver=[Set pkgver, reset pkgrel and update checksums]:pkgver:' '--pkgrel=[Set pkgrel to a given value]:pkgrel:' diff --git a/doc/man/pkgctl-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc index 489926e..f68e7cf 100644 --- a/doc/man/pkgctl-build.1.asciidoc +++ b/doc/man/pkgctl-build.1.asciidoc @@ -38,6 +38,12 @@ Build Options *-I, --install* 'FILE':: Install a package into the working copy of the chroot +*-w, --worker* 'SLOT':: + Name of the worker slot, useful for concurrent builds. By default the slot + is automatically assigned to the current tty pts number. In case the caller + is not a tty, choose a random slot between 1 and number of available + processing units. + *--nocheck*:: Do not run the check() function in the PKGBUILD diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 2153200..191fded 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -25,6 +25,7 @@ source /usr/share/makepkg/util/config.sh source /usr/share/makepkg/util/message.sh set -e +set -o pipefail pkgctl_build_usage() { @@ -47,6 +48,7 @@ pkgctl_build_usage() { -o, --offload Build on a remote server and transfer artifacts afterwards -c, --clean Recreate the chroot before building -I, --install FILE Install a package into the working copy of the chroot + -w, --worker SLOT Name of the worker slot, useful for concurrent builds (disables automatic names) --nocheck Do not run the check() function in the PKGBUILD PKGBUILD OPTIONS @@ -123,9 +125,8 @@ pkgctl_build() { local RELEASE_OPTIONS=() local MAKEPKG_OPTIONS=() - local PTS - PTS="$(tty | sed 's|/dev/pts/||')" - local WORKER="${USER}-${PTS}" + local WORKER= + local WORKER_SLOT= # variables local path pkgbase pkgrepo source @@ -224,6 +225,11 @@ pkgctl_build() { DB_UPDATE=1 shift ;; + -w|--worker) + (( $# <= 1 )) && die "missing argument for %s" "$1" + WORKER_SLOT=$2 + shift 2 + ;; --) shift break @@ -258,6 +264,12 @@ pkgctl_build() { fi fi + # assign default worker slot + if [[ -z ${WORKER_SLOT} ]] && ! WORKER_SLOT="$(tty | sed 's|/dev/pts/||')"; then + WORKER_SLOT=$(( RANDOM % $(nproc) + 1 )) + fi + WORKER="${USER}-${WORKER_SLOT}" + # Update pacman cache for auto-detection if [[ -z ${REPO} ]]; then update_pacman_repo_cache @@ -311,8 +323,9 @@ pkgctl_build() { fi # print gathered build modes - msg2 "repo: ${pkgrepo}" - msg2 "arch: ${BUILD_ARCH[*]}" + msg2 " repo: ${pkgrepo}" + msg2 " arch: ${BUILD_ARCH[*]}" + msg2 "worker: ${WORKER}" # increment pkgrel on rebuild if (( REBUILD )); then -- cgit v1.2.3-70-g09d2 From 4d3ab0b489f05565cec0a741564f8ba6ec57a9d6 Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Wed, 3 May 2023 14:33:14 +0300 Subject: config: update pacman configs for new repository layout Signed-off-by: Levente Polyak --- Makefile | 12 ++-- config/pacman/core-staging-x86_64_v3.conf | 95 +++++++++++++++++++++++++++++ config/pacman/core-staging.conf | 95 +++++++++++++++++++++++++++++ config/pacman/core-testing-x86_64_v3.conf | 89 +++++++++++++++++++++++++++ config/pacman/core-testing.conf | 89 +++++++++++++++++++++++++++ config/pacman/extra-staging-x86_64_v3.conf | 95 +++++++++++++++++++++++++++++ config/pacman/extra-staging.conf | 95 +++++++++++++++++++++++++++++ config/pacman/extra-testing-x86_64_v3.conf | 89 +++++++++++++++++++++++++++ config/pacman/extra-testing.conf | 89 +++++++++++++++++++++++++++ config/pacman/extra-x86_64_v3.conf | 9 +-- config/pacman/extra.conf | 9 +-- config/pacman/gnome-unstable.conf | 9 +-- config/pacman/kde-unstable.conf | 9 +-- config/pacman/multilib-staging.conf | 13 ++-- config/pacman/multilib-testing.conf | 9 +-- config/pacman/multilib.conf | 9 +-- config/pacman/staging-x86_64_v3.conf | 98 ------------------------------ config/pacman/staging.conf | 98 ------------------------------ config/pacman/testing-x86_64_v3.conf | 92 ---------------------------- config/pacman/testing.conf | 92 ---------------------------- 20 files changed, 767 insertions(+), 428 deletions(-) create mode 100644 config/pacman/core-staging-x86_64_v3.conf create mode 100644 config/pacman/core-staging.conf create mode 100644 config/pacman/core-testing-x86_64_v3.conf create mode 100644 config/pacman/core-testing.conf create mode 100644 config/pacman/extra-staging-x86_64_v3.conf create mode 100644 config/pacman/extra-staging.conf create mode 100644 config/pacman/extra-testing-x86_64_v3.conf create mode 100644 config/pacman/extra-testing.conf delete mode 100644 config/pacman/staging-x86_64_v3.conf delete mode 100644 config/pacman/staging.conf delete mode 100644 config/pacman/testing-x86_64_v3.conf delete mode 100644 config/pacman/testing.conf diff --git a/Makefile b/Makefile index faac812..a19aef6 100644 --- a/Makefile +++ b/Makefile @@ -32,12 +32,16 @@ COMMITPKG_LINKS = \ gnome-unstablepkg ARCHBUILD_LINKS = \ + core-testing-x86_64-build \ + core-testing-x86_64_v3-build \ + core-staging-x86_64-build \ + core-staging-x86_64_v3-build \ extra-x86_64-build \ extra-x86_64_v3-build \ - testing-x86_64-build \ - testing-x86_64_v3-build \ - staging-x86_64-build \ - staging-x86_64_v3-build \ + extra-testing-x86_64-build \ + extra-testing-x86_64_v3-build \ + extra-staging-x86_64-build \ + extra-staging-x86_64_v3-build \ multilib-build \ multilib-testing-build \ multilib-staging-build \ diff --git a/config/pacman/core-staging-x86_64_v3.conf b/config/pacman/core-staging-x86_64_v3.conf new file mode 100644 index 0000000..f1eff4a --- /dev/null +++ b/config/pacman/core-staging-x86_64_v3.conf @@ -0,0 +1,95 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = x86_64_v3 x86_64 + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[core-staging] +Include = /etc/pacman.d/mirrorlist + +[core-testing] +Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra-staging] +Include = /etc/pacman.d/mirrorlist + +[extra-testing] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/config/pacman/core-staging.conf b/config/pacman/core-staging.conf new file mode 100644 index 0000000..552d51d --- /dev/null +++ b/config/pacman/core-staging.conf @@ -0,0 +1,95 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[core-staging] +Include = /etc/pacman.d/mirrorlist + +[core-testing] +Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra-staging] +Include = /etc/pacman.d/mirrorlist + +[extra-testing] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/config/pacman/core-testing-x86_64_v3.conf b/config/pacman/core-testing-x86_64_v3.conf new file mode 100644 index 0000000..112a40c --- /dev/null +++ b/config/pacman/core-testing-x86_64_v3.conf @@ -0,0 +1,89 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = x86_64_v3 x86_64 + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[core-testing] +Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra-testing] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/config/pacman/core-testing.conf b/config/pacman/core-testing.conf new file mode 100644 index 0000000..d8b8af3 --- /dev/null +++ b/config/pacman/core-testing.conf @@ -0,0 +1,89 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[core-testing] +Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra-testing] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/config/pacman/extra-staging-x86_64_v3.conf b/config/pacman/extra-staging-x86_64_v3.conf new file mode 100644 index 0000000..f1eff4a --- /dev/null +++ b/config/pacman/extra-staging-x86_64_v3.conf @@ -0,0 +1,95 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = x86_64_v3 x86_64 + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[core-staging] +Include = /etc/pacman.d/mirrorlist + +[core-testing] +Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra-staging] +Include = /etc/pacman.d/mirrorlist + +[extra-testing] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/config/pacman/extra-staging.conf b/config/pacman/extra-staging.conf new file mode 100644 index 0000000..552d51d --- /dev/null +++ b/config/pacman/extra-staging.conf @@ -0,0 +1,95 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[core-staging] +Include = /etc/pacman.d/mirrorlist + +[core-testing] +Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra-staging] +Include = /etc/pacman.d/mirrorlist + +[extra-testing] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/config/pacman/extra-testing-x86_64_v3.conf b/config/pacman/extra-testing-x86_64_v3.conf new file mode 100644 index 0000000..112a40c --- /dev/null +++ b/config/pacman/extra-testing-x86_64_v3.conf @@ -0,0 +1,89 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = x86_64_v3 x86_64 + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[core-testing] +Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra-testing] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/config/pacman/extra-testing.conf b/config/pacman/extra-testing.conf new file mode 100644 index 0000000..d8b8af3 --- /dev/null +++ b/config/pacman/extra-testing.conf @@ -0,0 +1,89 @@ +# +# /etc/pacman.conf +# +# See the pacman.conf(5) manpage for option and repository directives + +# +# GENERAL OPTIONS +# +[options] +# The following paths are commented out with their default values listed. +# If you wish to use different paths, uncomment and update the paths. +#RootDir = / +#DBPath = /var/lib/pacman/ +#CacheDir = /var/cache/pacman/pkg/ +#LogFile = /var/log/pacman.log +#GPGDir = /etc/pacman.d/gnupg/ +#HookDir = /etc/pacman.d/hooks/ +HoldPkg = pacman glibc +#XferCommand = /usr/bin/curl -L -C - -f -o %o %u +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +NoProgressBar +# We cannot check disk space from within a chroot environment +#CheckSpace +VerbosePkgLists +ParallelDownloads = 5 + +# By default, pacman accepts packages signed by keys that its local keyring +# trusts (see pacman-key and its man page), as well as unsigned packages. +SigLevel = Required DatabaseOptional +LocalFileSigLevel = Optional +#RemoteFileSigLevel = Required + +# NOTE: You must run `pacman-key --init` before first using pacman; the local +# keyring can then be populated with the keys of all official Arch Linux +# packagers with `pacman-key --populate archlinux`. + +# +# REPOSITORIES +# - can be defined here or included from another file +# - pacman will search repositories in the order defined here +# - local/custom mirrors can be added here or in separate files +# - repositories listed first will take precedence when packages +# have identical names, regardless of version number +# - URLs will have $repo replaced by the name of the current repo +# - URLs will have $arch replaced by the name of the architecture +# +# Repository entries are of the format: +# [repo-name] +# Server = ServerName +# Include = IncludePath +# +# The header [repo-name] is crucial - it must be present and +# uncommented to enable the repo. +# + +# The testing repositories are disabled by default. To enable, uncomment the +# repo name header and Include lines. You can add preferred servers immediately +# after the header, and they will be used before the default mirrors. + +[core-testing] +Include = /etc/pacman.d/mirrorlist + +[core] +Include = /etc/pacman.d/mirrorlist + +[extra-testing] +Include = /etc/pacman.d/mirrorlist + +[extra] +Include = /etc/pacman.d/mirrorlist + +# An example of a custom package repository. See the pacman manpage for +# tips on creating your own repositories. +#[custom] +#SigLevel = Optional TrustAll +#Server = file:///home/custompkgs diff --git a/config/pacman/extra-x86_64_v3.conf b/config/pacman/extra-x86_64_v3.conf index afb7a0c..1c248cd 100644 --- a/config/pacman/extra-x86_64_v3.conf +++ b/config/pacman/extra-x86_64_v3.conf @@ -70,19 +70,16 @@ LocalFileSigLevel = Optional # repo name header and Include lines. You can add preferred servers immediately # after the header, and they will be used before the default mirrors. -#[testing] +#[core-testing] #Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] -Include = /etc/pacman.d/mirrorlist - -#[community-testing] +#[extra-testing] #Include = /etc/pacman.d/mirrorlist -[community] +[extra] Include = /etc/pacman.d/mirrorlist # An example of a custom package repository. See the pacman manpage for diff --git a/config/pacman/extra.conf b/config/pacman/extra.conf index 768c96d..8c84772 100644 --- a/config/pacman/extra.conf +++ b/config/pacman/extra.conf @@ -70,19 +70,16 @@ LocalFileSigLevel = Optional # repo name header and Include lines. You can add preferred servers immediately # after the header, and they will be used before the default mirrors. -#[testing] +#[core-testing] #Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] -Include = /etc/pacman.d/mirrorlist - -#[community-testing] +#[extra-testing] #Include = /etc/pacman.d/mirrorlist -[community] +[extra] Include = /etc/pacman.d/mirrorlist # An example of a custom package repository. See the pacman manpage for diff --git a/config/pacman/gnome-unstable.conf b/config/pacman/gnome-unstable.conf index 93ce01b..7f1b3d8 100644 --- a/config/pacman/gnome-unstable.conf +++ b/config/pacman/gnome-unstable.conf @@ -73,19 +73,16 @@ LocalFileSigLevel = Optional [gnome-unstable] Include = /etc/pacman.d/mirrorlist -[testing] +[core-testing] Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] -Include = /etc/pacman.d/mirrorlist - -[community-testing] +[extra-testing] Include = /etc/pacman.d/mirrorlist -[community] +[extra] Include = /etc/pacman.d/mirrorlist # An example of a custom package repository. See the pacman manpage for diff --git a/config/pacman/kde-unstable.conf b/config/pacman/kde-unstable.conf index 7308b61..603fc80 100644 --- a/config/pacman/kde-unstable.conf +++ b/config/pacman/kde-unstable.conf @@ -73,19 +73,16 @@ LocalFileSigLevel = Optional [kde-unstable] Include = /etc/pacman.d/mirrorlist -[testing] +[core-testing] Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] -Include = /etc/pacman.d/mirrorlist - -[community-testing] +[extra-testing] Include = /etc/pacman.d/mirrorlist -[community] +[extra] Include = /etc/pacman.d/mirrorlist # An example of a custom package repository. See the pacman manpage for diff --git a/config/pacman/multilib-staging.conf b/config/pacman/multilib-staging.conf index be04ea2..82cf9e3 100644 --- a/config/pacman/multilib-staging.conf +++ b/config/pacman/multilib-staging.conf @@ -70,25 +70,22 @@ LocalFileSigLevel = Optional # repo name header and Include lines. You can add preferred servers immediately # after the header, and they will be used before the default mirrors. -[staging] +[core-staging] Include = /etc/pacman.d/mirrorlist -[testing] +[core-testing] Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] -Include = /etc/pacman.d/mirrorlist - -[community-staging] +[extra-staging] Include = /etc/pacman.d/mirrorlist -[community-testing] +[extra-testing] Include = /etc/pacman.d/mirrorlist -[community] +[extra] Include = /etc/pacman.d/mirrorlist # If you want to run 32 bit applications on your x86_64 system, diff --git a/config/pacman/multilib-testing.conf b/config/pacman/multilib-testing.conf index b7fcf71..b1d40b7 100644 --- a/config/pacman/multilib-testing.conf +++ b/config/pacman/multilib-testing.conf @@ -70,19 +70,16 @@ LocalFileSigLevel = Optional # repo name header and Include lines. You can add preferred servers immediately # after the header, and they will be used before the default mirrors. -[testing] +[core-testing] Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] -Include = /etc/pacman.d/mirrorlist - -[community-testing] +[extra-testing] Include = /etc/pacman.d/mirrorlist -[community] +[extra] Include = /etc/pacman.d/mirrorlist # If you want to run 32 bit applications on your x86_64 system, diff --git a/config/pacman/multilib.conf b/config/pacman/multilib.conf index 9f1906c..e09a9d5 100644 --- a/config/pacman/multilib.conf +++ b/config/pacman/multilib.conf @@ -70,19 +70,16 @@ LocalFileSigLevel = Optional # repo name header and Include lines. You can add preferred servers immediately # after the header, and they will be used before the default mirrors. -#[testing] +#[core-testing] #Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] -Include = /etc/pacman.d/mirrorlist - -#[community-testing] +#[extra-testing] #Include = /etc/pacman.d/mirrorlist -[community] +[extra] Include = /etc/pacman.d/mirrorlist # If you want to run 32 bit applications on your x86_64 system, diff --git a/config/pacman/staging-x86_64_v3.conf b/config/pacman/staging-x86_64_v3.conf deleted file mode 100644 index 46ba8f8..0000000 --- a/config/pacman/staging-x86_64_v3.conf +++ /dev/null @@ -1,98 +0,0 @@ -# -# /etc/pacman.conf -# -# See the pacman.conf(5) manpage for option and repository directives - -# -# GENERAL OPTIONS -# -[options] -# The following paths are commented out with their default values listed. -# If you wish to use different paths, uncomment and update the paths. -#RootDir = / -#DBPath = /var/lib/pacman/ -#CacheDir = /var/cache/pacman/pkg/ -#LogFile = /var/log/pacman.log -#GPGDir = /etc/pacman.d/gnupg/ -#HookDir = /etc/pacman.d/hooks/ -HoldPkg = pacman glibc -#XferCommand = /usr/bin/curl -L -C - -f -o %o %u -#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u -#CleanMethod = KeepInstalled -Architecture = x86_64_v3 x86_64 - -# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup -#IgnorePkg = -#IgnoreGroup = - -#NoUpgrade = -#NoExtract = - -# Misc options -#UseSyslog -#Color -NoProgressBar -# We cannot check disk space from within a chroot environment -#CheckSpace -VerbosePkgLists -ParallelDownloads = 5 - -# By default, pacman accepts packages signed by keys that its local keyring -# trusts (see pacman-key and its man page), as well as unsigned packages. -SigLevel = Required DatabaseOptional -LocalFileSigLevel = Optional -#RemoteFileSigLevel = Required - -# NOTE: You must run `pacman-key --init` before first using pacman; the local -# keyring can then be populated with the keys of all official Arch Linux -# packagers with `pacman-key --populate archlinux`. - -# -# REPOSITORIES -# - can be defined here or included from another file -# - pacman will search repositories in the order defined here -# - local/custom mirrors can be added here or in separate files -# - repositories listed first will take precedence when packages -# have identical names, regardless of version number -# - URLs will have $repo replaced by the name of the current repo -# - URLs will have $arch replaced by the name of the architecture -# -# Repository entries are of the format: -# [repo-name] -# Server = ServerName -# Include = IncludePath -# -# The header [repo-name] is crucial - it must be present and -# uncommented to enable the repo. -# - -# The testing repositories are disabled by default. To enable, uncomment the -# repo name header and Include lines. You can add preferred servers immediately -# after the header, and they will be used before the default mirrors. - -[staging] -Include = /etc/pacman.d/mirrorlist - -[testing] -Include = /etc/pacman.d/mirrorlist - -[core] -Include = /etc/pacman.d/mirrorlist - -[extra] -Include = /etc/pacman.d/mirrorlist - -[community-staging] -Include = /etc/pacman.d/mirrorlist - -[community-testing] -Include = /etc/pacman.d/mirrorlist - -[community] -Include = /etc/pacman.d/mirrorlist - -# An example of a custom package repository. See the pacman manpage for -# tips on creating your own repositories. -#[custom] -#SigLevel = Optional TrustAll -#Server = file:///home/custompkgs diff --git a/config/pacman/staging.conf b/config/pacman/staging.conf deleted file mode 100644 index 666d94d..0000000 --- a/config/pacman/staging.conf +++ /dev/null @@ -1,98 +0,0 @@ -# -# /etc/pacman.conf -# -# See the pacman.conf(5) manpage for option and repository directives - -# -# GENERAL OPTIONS -# -[options] -# The following paths are commented out with their default values listed. -# If you wish to use different paths, uncomment and update the paths. -#RootDir = / -#DBPath = /var/lib/pacman/ -#CacheDir = /var/cache/pacman/pkg/ -#LogFile = /var/log/pacman.log -#GPGDir = /etc/pacman.d/gnupg/ -#HookDir = /etc/pacman.d/hooks/ -HoldPkg = pacman glibc -#XferCommand = /usr/bin/curl -L -C - -f -o %o %u -#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u -#CleanMethod = KeepInstalled -Architecture = auto - -# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup -#IgnorePkg = -#IgnoreGroup = - -#NoUpgrade = -#NoExtract = - -# Misc options -#UseSyslog -#Color -NoProgressBar -# We cannot check disk space from within a chroot environment -#CheckSpace -VerbosePkgLists -ParallelDownloads = 5 - -# By default, pacman accepts packages signed by keys that its local keyring -# trusts (see pacman-key and its man page), as well as unsigned packages. -SigLevel = Required DatabaseOptional -LocalFileSigLevel = Optional -#RemoteFileSigLevel = Required - -# NOTE: You must run `pacman-key --init` before first using pacman; the local -# keyring can then be populated with the keys of all official Arch Linux -# packagers with `pacman-key --populate archlinux`. - -# -# REPOSITORIES -# - can be defined here or included from another file -# - pacman will search repositories in the order defined here -# - local/custom mirrors can be added here or in separate files -# - repositories listed first will take precedence when packages -# have identical names, regardless of version number -# - URLs will have $repo replaced by the name of the current repo -# - URLs will have $arch replaced by the name of the architecture -# -# Repository entries are of the format: -# [repo-name] -# Server = ServerName -# Include = IncludePath -# -# The header [repo-name] is crucial - it must be present and -# uncommented to enable the repo. -# - -# The testing repositories are disabled by default. To enable, uncomment the -# repo name header and Include lines. You can add preferred servers immediately -# after the header, and they will be used before the default mirrors. - -[staging] -Include = /etc/pacman.d/mirrorlist - -[testing] -Include = /etc/pacman.d/mirrorlist - -[core] -Include = /etc/pacman.d/mirrorlist - -[extra] -Include = /etc/pacman.d/mirrorlist - -[community-staging] -Include = /etc/pacman.d/mirrorlist - -[community-testing] -Include = /etc/pacman.d/mirrorlist - -[community] -Include = /etc/pacman.d/mirrorlist - -# An example of a custom package repository. See the pacman manpage for -# tips on creating your own repositories. -#[custom] -#SigLevel = Optional TrustAll -#Server = file:///home/custompkgs diff --git a/config/pacman/testing-x86_64_v3.conf b/config/pacman/testing-x86_64_v3.conf deleted file mode 100644 index 2eb463d..0000000 --- a/config/pacman/testing-x86_64_v3.conf +++ /dev/null @@ -1,92 +0,0 @@ -# -# /etc/pacman.conf -# -# See the pacman.conf(5) manpage for option and repository directives - -# -# GENERAL OPTIONS -# -[options] -# The following paths are commented out with their default values listed. -# If you wish to use different paths, uncomment and update the paths. -#RootDir = / -#DBPath = /var/lib/pacman/ -#CacheDir = /var/cache/pacman/pkg/ -#LogFile = /var/log/pacman.log -#GPGDir = /etc/pacman.d/gnupg/ -#HookDir = /etc/pacman.d/hooks/ -HoldPkg = pacman glibc -#XferCommand = /usr/bin/curl -L -C - -f -o %o %u -#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u -#CleanMethod = KeepInstalled -Architecture = x86_64_v3 x86_64 - -# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup -#IgnorePkg = -#IgnoreGroup = - -#NoUpgrade = -#NoExtract = - -# Misc options -#UseSyslog -#Color -NoProgressBar -# We cannot check disk space from within a chroot environment -#CheckSpace -VerbosePkgLists -ParallelDownloads = 5 - -# By default, pacman accepts packages signed by keys that its local keyring -# trusts (see pacman-key and its man page), as well as unsigned packages. -SigLevel = Required DatabaseOptional -LocalFileSigLevel = Optional -#RemoteFileSigLevel = Required - -# NOTE: You must run `pacman-key --init` before first using pacman; the local -# keyring can then be populated with the keys of all official Arch Linux -# packagers with `pacman-key --populate archlinux`. - -# -# REPOSITORIES -# - can be defined here or included from another file -# - pacman will search repositories in the order defined here -# - local/custom mirrors can be added here or in separate files -# - repositories listed first will take precedence when packages -# have identical names, regardless of version number -# - URLs will have $repo replaced by the name of the current repo -# - URLs will have $arch replaced by the name of the architecture -# -# Repository entries are of the format: -# [repo-name] -# Server = ServerName -# Include = IncludePath -# -# The header [repo-name] is crucial - it must be present and -# uncommented to enable the repo. -# - -# The testing repositories are disabled by default. To enable, uncomment the -# repo name header and Include lines. You can add preferred servers immediately -# after the header, and they will be used before the default mirrors. - -[testing] -Include = /etc/pacman.d/mirrorlist - -[core] -Include = /etc/pacman.d/mirrorlist - -[extra] -Include = /etc/pacman.d/mirrorlist - -[community-testing] -Include = /etc/pacman.d/mirrorlist - -[community] -Include = /etc/pacman.d/mirrorlist - -# An example of a custom package repository. See the pacman manpage for -# tips on creating your own repositories. -#[custom] -#SigLevel = Optional TrustAll -#Server = file:///home/custompkgs diff --git a/config/pacman/testing.conf b/config/pacman/testing.conf deleted file mode 100644 index 79fcaa1..0000000 --- a/config/pacman/testing.conf +++ /dev/null @@ -1,92 +0,0 @@ -# -# /etc/pacman.conf -# -# See the pacman.conf(5) manpage for option and repository directives - -# -# GENERAL OPTIONS -# -[options] -# The following paths are commented out with their default values listed. -# If you wish to use different paths, uncomment and update the paths. -#RootDir = / -#DBPath = /var/lib/pacman/ -#CacheDir = /var/cache/pacman/pkg/ -#LogFile = /var/log/pacman.log -#GPGDir = /etc/pacman.d/gnupg/ -#HookDir = /etc/pacman.d/hooks/ -HoldPkg = pacman glibc -#XferCommand = /usr/bin/curl -L -C - -f -o %o %u -#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u -#CleanMethod = KeepInstalled -Architecture = auto - -# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup -#IgnorePkg = -#IgnoreGroup = - -#NoUpgrade = -#NoExtract = - -# Misc options -#UseSyslog -#Color -NoProgressBar -# We cannot check disk space from within a chroot environment -#CheckSpace -VerbosePkgLists -ParallelDownloads = 5 - -# By default, pacman accepts packages signed by keys that its local keyring -# trusts (see pacman-key and its man page), as well as unsigned packages. -SigLevel = Required DatabaseOptional -LocalFileSigLevel = Optional -#RemoteFileSigLevel = Required - -# NOTE: You must run `pacman-key --init` before first using pacman; the local -# keyring can then be populated with the keys of all official Arch Linux -# packagers with `pacman-key --populate archlinux`. - -# -# REPOSITORIES -# - can be defined here or included from another file -# - pacman will search repositories in the order defined here -# - local/custom mirrors can be added here or in separate files -# - repositories listed first will take precedence when packages -# have identical names, regardless of version number -# - URLs will have $repo replaced by the name of the current repo -# - URLs will have $arch replaced by the name of the architecture -# -# Repository entries are of the format: -# [repo-name] -# Server = ServerName -# Include = IncludePath -# -# The header [repo-name] is crucial - it must be present and -# uncommented to enable the repo. -# - -# The testing repositories are disabled by default. To enable, uncomment the -# repo name header and Include lines. You can add preferred servers immediately -# after the header, and they will be used before the default mirrors. - -[testing] -Include = /etc/pacman.d/mirrorlist - -[core] -Include = /etc/pacman.d/mirrorlist - -[extra] -Include = /etc/pacman.d/mirrorlist - -[community-testing] -Include = /etc/pacman.d/mirrorlist - -[community] -Include = /etc/pacman.d/mirrorlist - -# An example of a custom package repository. See the pacman manpage for -# tips on creating your own repositories. -#[custom] -#SigLevel = Optional TrustAll -#Server = file:///home/custompkgs -- cgit v1.2.3-70-g09d2 From 41d4624879d01b1269d6af9c1440592a15ad7784 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 20 May 2023 00:20:41 +0200 Subject: fix(archroot): pass along the real command and argv by the caller Before modularizing the repo layout, we used m4_include to assemble together sources into a single file. Now, we properly use a library layout without assembling multiple files, which means we cannot anymore rely on BASH_SOURCE inside the library file. Hence, pass along the actual command and argv from the check_root caller. Fixes: src: modularize repo layout into a library Signed-off-by: Morten Linderud Signed-off-by: Levente Polyak --- src/arch-nspawn.in | 2 +- src/archbuild.in | 2 +- src/lib/archroot.sh | 5 +++-- src/makechrootpkg.in | 2 +- src/makerepropkg.in | 2 +- src/mkarchroot.in | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/arch-nspawn.in b/src/arch-nspawn.in index 77a27ad..b692817 100644 --- a/src/arch-nspawn.in +++ b/src/arch-nspawn.in @@ -46,7 +46,7 @@ done shift $((OPTIND - 1)) (( $# < 1 )) && die 'You must specify a directory.' -check_root +check_root "" "${BASH_SOURCE[0]}" "$@" working_dir=$(readlink -f "$1") shift 1 diff --git a/src/archbuild.in b/src/archbuild.in index a7e4231..2f3faf9 100644 --- a/src/archbuild.in +++ b/src/archbuild.in @@ -74,7 +74,7 @@ while getopts 'hcr:' arg; do esac done -check_root SOURCE_DATE_EPOCH,SRCDEST,SRCPKGDEST,PKGDEST,LOGDEST,MAKEFLAGS,PACKAGER,GNUPGHOME +check_root SOURCE_DATE_EPOCH,SRCDEST,SRCPKGDEST,PKGDEST,LOGDEST,MAKEFLAGS,PACKAGER,GNUPGHOME "${BASH_SOURCE[0]}" "$@" # Pass all arguments after -- right to makepkg makechrootpkg_args+=("${@:$OPTIND}") diff --git a/src/lib/archroot.sh b/src/lib/archroot.sh index d7917da..3f48dc1 100644 --- a/src/lib/archroot.sh +++ b/src/lib/archroot.sh @@ -9,13 +9,14 @@ CHROOT_VERSION='v4' ## # usage : check_root $keepenv ## -orig_argv=("${BASH_SOURCE[0]}" "$@") check_root() { local keepenv=$1 + shift + local orig_argv=("$@") (( EUID == 0 )) && return if type -P sudo >/dev/null; then - exec sudo --preserve-env=$keepenv -- "${orig_argv[@]}" + exec sudo --preserve-env="${keepenv}" -- "${orig_argv[@]}" else exec su root -c "$(printf ' %q' "${orig_argv[@]}")" fi diff --git a/src/makechrootpkg.in b/src/makechrootpkg.in index 8d3d093..2cfd849 100644 --- a/src/makechrootpkg.in +++ b/src/makechrootpkg.in @@ -301,7 +301,7 @@ done [[ -n $makepkg_user && -z $(id -u "$makepkg_user") ]] && die 'Invalid makepkg user.' makepkg_user=${makepkg_user:-${SUDO_USER:-$USER}} -check_root SOURCE_DATE_EPOCH,BUILDTOOL,BUILDTOOLVER,GNUPGHOME,SRCDEST,SRCPKGDEST,PKGDEST,LOGDEST,MAKEFLAGS,PACKAGER +check_root SOURCE_DATE_EPOCH,BUILDTOOL,BUILDTOOLVER,GNUPGHOME,SRCDEST,SRCPKGDEST,PKGDEST,LOGDEST,MAKEFLAGS,PACKAGER "${BASH_SOURCE[0]}" "$@" # Canonicalize chrootdir, getting rid of trailing / chrootdir=$(readlink -e "$passeddir") diff --git a/src/makerepropkg.in b/src/makerepropkg.in index f310c69..61ee9db 100644 --- a/src/makerepropkg.in +++ b/src/makerepropkg.in @@ -137,7 +137,7 @@ while getopts 'dM:c:l:h' arg; do done shift $((OPTIND - 1)) -check_root +check_root "" "${BASH_SOURCE[0]}" "$@" [[ -f PKGBUILD ]] || { error "No PKGBUILD in current directory."; exit 1; } diff --git a/src/mkarchroot.in b/src/mkarchroot.in index 6c8d8a2..610de16 100644 --- a/src/mkarchroot.in +++ b/src/mkarchroot.in @@ -52,7 +52,7 @@ shift $((OPTIND - 1)) (( $# < 2 )) && die 'You must specify a directory and one or more packages.' -check_root +check_root "" "${BASH_SOURCE[0]}" "$@" working_dir="$(readlink -f "$1")" shift 1 -- cgit v1.2.3-70-g09d2 From 80a8cdcba22f1a567efad19a487cb8ce28353dab Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 20 May 2023 12:10:06 +0200 Subject: chore(git): use default ssh port 22 url scheme We only need to specifically use ssh:// protocol prefix if we want to specify a special port. As we moved to support pulling directly over port 22 from out GitLab instance we can change the url scheme to the simple variant. Signed-off-by: Levente Polyak --- src/lib/common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/common.sh b/src/lib/common.sh index 51ab2fd..24479eb 100644 --- a/src/lib/common.sh +++ b/src/lib/common.sh @@ -25,7 +25,7 @@ export GITLAB_HOST=gitlab.archlinux.org export GIT_REPO_SPEC_VERSION=1 export GIT_PACKAGING_NAMESPACE=archlinux/packaging/packages export GIT_PACKAGING_NAMESPACE_ID=11323 -export GIT_PACKAGING_URL_SSH="ssh://git@${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}" +export GIT_PACKAGING_URL_SSH="git@${GITLAB_HOST}:${GIT_PACKAGING_NAMESPACE}" export GIT_PACKAGING_URL_HTTPS="https://${GITLAB_HOST}/${GIT_PACKAGING_NAMESPACE}" export PACKAGING_REPO_RELEASE_HOST=repos.archlinux.org -- cgit v1.2.3-70-g09d2 From bf61b8472a2e50a740229f007513dd663b9dddda Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 20 May 2023 14:55:46 +0200 Subject: chore(archroot): force build chroot recreation to adapt new configs Bumping the chroot version will result in the chroots checking against the local version and force recreation in case they do not match. Signed-off-by: Levente Polyak --- src/lib/archroot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/archroot.sh b/src/lib/archroot.sh index 3f48dc1..8386c6c 100644 --- a/src/lib/archroot.sh +++ b/src/lib/archroot.sh @@ -4,7 +4,7 @@ : # shellcheck disable=2034 -CHROOT_VERSION='v4' +CHROOT_VERSION='v5' ## # usage : check_root $keepenv -- cgit v1.2.3-70-g09d2 From 6ce666a1669235749c17d5c44d8a24dea4a135da Mon Sep 17 00:00:00 2001 From: Levente Polyak 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 --- 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(-) 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 edc14ef19c4de0133c8a0908459788d0b78a4c47 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 21 May 2023 12:25:44 +0200 Subject: Version 1.0.0 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a19aef6..cdd67d4 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ SHELL=/bin/bash -V=20230307 +V=1.0.0 BUILDTOOLVER ?= $(V) PREFIX = /usr/local -- cgit v1.2.3-70-g09d2 From 1c399778f9a52552f1bfe20eb7e08b89ef8abe12 Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Sun, 21 May 2023 17:06:22 +0200 Subject: fix(commitpkg): reliably check tree status regardless of configuration Check git status --porcelain, not --short. `--short` is influenced by user configuration like `status.branch` making it non-empty even on a clean tree. Use `--porcelain` to avoid this. --- src/commitpkg.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commitpkg.in b/src/commitpkg.in index 26117dc..e761d8e 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -173,7 +173,7 @@ done # check for PKGBUILD standards check_pkgbuild_validity -if [[ -n $(git status --short --untracked-files=no) ]]; then +if [[ -n $(git status --porcelain --untracked-files=no) ]]; then stat_busy 'Staging files' for f in $(git ls-files --modified); do git add "$f" -- cgit v1.2.3-70-g09d2 From d759eadb50409e83d8d58fa54812738c30ac626d Mon Sep 17 00:00:00 2001 From: "Jan Alexander Steffens (heftig)" Date: Sun, 21 May 2023 16:24:54 +0200 Subject: fix(diffpkg): Fix scoping of DIFFOPTIONS when comparing split pkgs `diff_pkgs` needs to use a local variable for its options, otherwise they will accumulate for each package diffed. Whem comparing split packages this lead to earlier mutated DIFFOPTIONS containing too many labels which resulted in a failure. --- src/diffpkg.in | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/diffpkg.in b/src/diffpkg.in index ab1a5af..160c4ba 100644 --- a/src/diffpkg.in +++ b/src/diffpkg.in @@ -215,7 +215,8 @@ diff_pkgs() { [[ -f $oldpkg ]] || die "No such file: %s" "${oldpkg}" [[ -f $newpkg ]] || die "No such file: %s" "${newpkg}" - DIFFOPTIONS+=(--label "${oldpkg}" --label "${newpkg}") + local -a diffoptions + diffoptions=("${DIFFOPTIONS[@]}" --label "${oldpkg}" --label "${newpkg}") if (( TARLIST )); then tar_list "$oldpkg" > "$TMPDIR/old" @@ -236,7 +237,7 @@ diff_pkgs() { # Resolve dynamic auto width one we know the content to diff if [[ $DIFFWIDTH == --width=auto ]]; then AUTOLENGTH=$(file_diff_columns "$TMPDIR/old" "$TMPDIR/new") - DIFFOPTIONS+=("--width=${AUTOLENGTH}") + diffoptions+=("--width=${AUTOLENGTH}") fi # Print a header for side-by-side view as it lacks labels @@ -244,7 +245,7 @@ diff_pkgs() { printf -- "--- %s\n+++ %s\n" "${oldpkg}" "${newpkg}" fi - diff "${DIFFOPTIONS[@]}" "$TMPDIR/old" "$TMPDIR/new" + diff "${diffoptions[@]}" "$TMPDIR/old" "$TMPDIR/new" fi if (( DIFFOSCOPE )); then -- cgit v1.2.3-70-g09d2 From f11cb9018e7d926b6b61660e418d8beb7b39ea62 Mon Sep 17 00:00:00 2001 From: Morten Linderud Date: Sun, 21 May 2023 14:20:11 +0200 Subject: feature(commitpkg): auto generate .SRCINFO if present This currently makes .SRCINFO files opt-in and helps to keep the file up to date if already present. Signed-off-by: Morten Linderud --- src/commitpkg.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/commitpkg.in b/src/commitpkg.in index e761d8e..c52e4fa 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -173,6 +173,14 @@ done # check for PKGBUILD standards check_pkgbuild_validity +# auto generate .SRCINFO if present +if [[ -f .SRCINFO ]]; then + stat_busy 'Generating .SRCINFO' + makepkg --printsrcinfo > .SRCINFO + git add .SRCINFO + stat_done +fi + if [[ -n $(git status --porcelain --untracked-files=no) ]]; then stat_busy 'Staging files' for f in $(git ls-files --modified); do -- cgit v1.2.3-70-g09d2 From a08bc2acf49c68061284c7991d41dc78c46ae2b4 Mon Sep 17 00:00:00 2001 From: Levente Polyak 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 --- 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(-) 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 From e4c40a980236f22e3d9e7ae292efd09a3a8c7af4 Mon Sep 17 00:00:00 2001 From: Chih-Hsuan Yen Date: Sun, 21 May 2023 00:46:12 +0800 Subject: fix(completion): incorporate repo layout into offload-build completion Use new repo names for build targets. This follows /usr/bin/*-build links other than x86_64_v3 ones. --- src/lib/valid-repos.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/valid-repos.sh b/src/lib/valid-repos.sh index 1f823f4..14f90ce 100644 --- a/src/lib/valid-repos.sh +++ b/src/lib/valid-repos.sh @@ -14,7 +14,8 @@ _repos=( # shellcheck disable=2034 _build_repos=( - extra staging testing + core-staging core-testing + extra extra-staging extra-testing multilib multilib-staging multilib-testing gnome-unstable kde-unstable -- cgit v1.2.3-70-g09d2 From 1b808b8e322effe8ca31a9c6d5be29e8a44e16e6 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Wed, 24 May 2023 03:16:13 +0200 Subject: chore(release): version v1.0.1 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index cdd67d4..3092b36 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ SHELL=/bin/bash -V=1.0.0 +V=1.0.1 BUILDTOOLVER ?= $(V) PREFIX = /usr/local -- cgit v1.2.3-70-g09d2 From 71cb9e97bb584bcb7142abde715237fb8d0fa69e Mon Sep 17 00:00:00 2001 From: Toolybird Date: Wed, 24 May 2023 16:31:57 +1000 Subject: fix(archroot): preserve original args for check_root before discarding arch-nspawn, mkarchroot, makerepropkg all call "shift" after getopts processing. Save the original args and pass on to check_root to prevent options being discarded. Fixes 41d4624879d01b1269d6af9c1440592a15ad7784 Fixes #149 Signed-off-by: Toolybird Signed-off-by: Levente Polyak --- src/arch-nspawn.in | 5 ++++- src/makerepropkg.in | 5 ++++- src/mkarchroot.in | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/arch-nspawn.in b/src/arch-nspawn.in index b692817..1453ba0 100644 --- a/src/arch-nspawn.in +++ b/src/arch-nspawn.in @@ -32,6 +32,9 @@ usage() { exit 1 } +# save all args for check_root +orig_args=("$@") + while getopts 'hC:M:c:f:s' arg; do case "$arg" in C) pac_conf="$OPTARG" ;; @@ -46,7 +49,7 @@ done shift $((OPTIND - 1)) (( $# < 1 )) && die 'You must specify a directory.' -check_root "" "${BASH_SOURCE[0]}" "$@" +check_root "" "${BASH_SOURCE[0]}" "${orig_args[@]}" working_dir=$(readlink -f "$1") shift 1 diff --git a/src/makerepropkg.in b/src/makerepropkg.in index 61ee9db..398d4af 100644 --- a/src/makerepropkg.in +++ b/src/makerepropkg.in @@ -125,6 +125,9 @@ OPTIONS __EOF__ } +# save all args for check_root +orig_args=("$@") + while getopts 'dM:c:l:h' arg; do case "$arg" in d) diffoscope=1 ;; @@ -137,7 +140,7 @@ while getopts 'dM:c:l:h' arg; do done shift $((OPTIND - 1)) -check_root "" "${BASH_SOURCE[0]}" "$@" +check_root "" "${BASH_SOURCE[0]}" "${orig_args[@]}" [[ -f PKGBUILD ]] || { error "No PKGBUILD in current directory."; exit 1; } diff --git a/src/mkarchroot.in b/src/mkarchroot.in index 610de16..fc60b4e 100644 --- a/src/mkarchroot.in +++ b/src/mkarchroot.in @@ -32,6 +32,9 @@ usage() { exit 1 } +# save all args for check_root +orig_args=("$@") + while getopts 'hUC:M:c:f:s' arg; do case "$arg" in U) umode=U ;; @@ -52,7 +55,7 @@ shift $((OPTIND - 1)) (( $# < 2 )) && die 'You must specify a directory and one or more packages.' -check_root "" "${BASH_SOURCE[0]}" "$@" +check_root "" "${BASH_SOURCE[0]}" "${orig_args[@]}" working_dir="$(readlink -f "$1")" shift 1 -- cgit v1.2.3-70-g09d2 From 3283b2ca59b06198118d5313a4b19e6119468b86 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sat, 27 May 2023 01:43:33 +0200 Subject: fix(commitpkg): only force existing files to be under version control Before porting commitpkg to Git, the code has checked the SVN status for none commited files. During the port this has changed by straight checking for any passed files if they were under version control or not. In general the whole logic is very brittle as variables are searched by regex and directly passed to eval while ignoring any function scoping. This leads to missing files when they reference the $pkgname inside a package function but also provide wrong ones when eval simply returns the first $pkgname while ignoring and function scopes. In the future this should completely be replaces by .SRCINFO processing. Fixes #145 Signed-off-by: Levente Polyak --- src/commitpkg.in | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/commitpkg.in b/src/commitpkg.in index c52e4fa..8a8087a 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -129,6 +129,10 @@ done # assert that they really are controlled by git if (( ${#needsversioning[*]} )); then for file in "${needsversioning[@]}"; do + # skip none existing files + if [[ ! -f "${file}" ]]; then + continue + fi if ! git ls-files --error-unmatch "$file"; then die "%s is not under version control" "$file" fi -- cgit v1.2.3-70-g09d2 From 9b11b16a7e6cdfdff142ff1c5184a760673988d2 Mon Sep 17 00:00:00 2001 From: "Daniel M. Capella" Date: Fri, 26 May 2023 22:41:37 -0400 Subject: chore(doc): remove duplicate subcommand from example help text --- src/lib/repo/configure.sh | 2 +- src/lib/repo/web.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh index 81b7d19..73300ae 100644 --- a/src/lib/repo/configure.sh +++ b/src/lib/repo/configure.sh @@ -38,7 +38,7 @@ pkgctl_repo_configure_usage() { -h, --help Show this help text EXAMPLES - $ ${COMMAND} configure * + $ ${COMMAND} * _EOF_ } diff --git a/src/lib/repo/web.sh b/src/lib/repo/web.sh index 3fa214d..45ea53b 100644 --- a/src/lib/repo/web.sh +++ b/src/lib/repo/web.sh @@ -26,7 +26,7 @@ pkgctl_repo_web_usage() { -h, --help Show this help text EXAMPLES - $ ${COMMAND} web linux + $ ${COMMAND} linux _EOF_ } -- cgit v1.2.3-70-g09d2 From e47035e74d87e2976e1a65e4b2a86476f8cd05ac Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Tue, 23 May 2023 11:48:54 +0200 Subject: chore(build): improve error wording if no package repo could be detected Not being in any official repo does not necessarily mean this is a new package. One could simply be building an AUR or custom local package. Make the message less confusing in such case. --- src/lib/build/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/build/build.sh b/src/lib/build/build.sh index 191fded..3394395 100644 --- a/src/lib/build/build.sh +++ b/src/lib/build/build.sh @@ -298,7 +298,7 @@ pkgctl_build() { die 'failed to get pacman repo' fi if [[ -z "${pkgrepo}" ]]; then - die 'unknown repo, please specify --repo for new packages' + die 'unknown repo, specify --repo for packages not currently in any official repo' fi fi -- cgit v1.2.3-70-g09d2 From c7d627165f4d399465c84a7f4a6a7805a526fbe4 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 28 May 2023 01:15:48 +0200 Subject: chore(release): adjust Makefile for new release schema Ask for the next release version and automatically create a signed tag. Furthermore add a simple release target to call glab for uploading the required artifacts. --- Makefile | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 3092b36..8733ecd 100644 --- a/Makefile +++ b/Makefile @@ -145,19 +145,20 @@ uninstall: $(DESTDIR)$(DATADIR)/pacman.conf.d \ $(DESTDIR)$(DATADIR) -TODAY=$(shell date +"%Y%m%d") tag: - @sed -E "s|^V=[0-9]{8}|V=$(TODAY)|" -i Makefile - @git commit --gpg-sign --message "Version $(TODAY)" Makefile - @git tag --sign --message "Version $(TODAY)" $(TODAY) + @echo "current version: v$(V)" + @read -r -p "tag version: v" VERSION && \ + sed -E "s|^V=.+|V=$$VERSION|" -i Makefile && \ + git commit --gpg-sign --message "chore(release): version v$$VERSION" Makefile && \ + git tag --sign --message "Version v$$VERSION" v$$VERSION + +release: dist + glab release create v$(RELEASE) devtools-$(RELEASE).tar.gz* dist: - git archive --format=tar --prefix=devtools-$(V)/ $(V) | gzip > devtools-$(V).tar.gz + git archive --format=tar --prefix=devtools-$(V)/ v$(V) | gzip > devtools-$(V).tar.gz gpg --detach-sign --use-agent devtools-$(V).tar.gz -upload: - scp devtools-$(V).tar.gz devtools-$(V).tar.gz.sig repos.archlinux.org:/srv/ftp/other/devtools/ - check: $(BINPROGS_SRC) $(LIBRARY_SRC) contrib/completion/bash/devtools.in config/makepkg/x86_64.conf contrib/makepkg/PKGBUILD.proto shellcheck $^ -- cgit v1.2.3-70-g09d2 From a07df0beeaeea1bf5665512bacc7a013eece4602 Mon Sep 17 00:00:00 2001 From: Levente Polyak Date: Sun, 28 May 2023 01:22:09 +0200 Subject: chore(release): version v1.0.2 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8733ecd..6c3aa63 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ SHELL=/bin/bash -V=1.0.1 +V=1.0.2 BUILDTOOLVER ?= $(V) PREFIX = /usr/local -- cgit v1.2.3-70-g09d2