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(-) (limited to 'src/commitpkg.in') 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(-) (limited to 'src/commitpkg.in') 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 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(+) (limited to 'src/commitpkg.in') 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(-) (limited to 'src/commitpkg.in') 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(+) (limited to 'src/commitpkg.in') 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(+) (limited to 'src/commitpkg.in') 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 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(-) (limited to 'src/commitpkg.in') 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 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(-) (limited to 'src/commitpkg.in') 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 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 (limited to 'src/commitpkg.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 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(-) (limited to 'src/commitpkg.in') 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 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(+) (limited to 'src/commitpkg.in') 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(+) (limited to 'src/commitpkg.in') 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 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(-) (limited to 'src/commitpkg.in') 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 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(-) (limited to 'src/commitpkg.in') 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 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(+) (limited to 'src/commitpkg.in') 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 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(+) (limited to 'src/commitpkg.in') 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