index : devtools32 | |
Archlinux32 fork of devtools | gitolite user |
summaryrefslogtreecommitdiff |
@@ -1,48 +1,64 @@ V=$(shell git describe --exact-match) +SHELL=/bin/bash 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/*) MANS = $(addprefix $(BUILDDIR)/,$(patsubst %.asciidoc,%,$(wildcard doc/man/*.asciidoc))) -GENERATED_CONFIGS = \ - pacman-extra-i486.conf \ - pacman-extra-i686.conf \ - pacman-extra-pentium4.conf \ - pacman-testing-i486.conf \ - pacman-testing-i686.conf \ - pacman-testing-pentium4.conf \ - pacman-staging-i486.conf \ - pacman-staging-i686.conf \ - pacman-staging-pentium4.conf \ - pacman-staging-with-build-support-i486.conf \ - pacman-staging-with-build-support-i686.conf \ - pacman-staging-with-build-support-pentium4.conf \ - pacman-kde-unstable-i486.conf \ - pacman-kde-unstable-i686.conf \ - pacman-kde-unstable-pentium4.conf \ - pacman-gnome-unstable-i486.conf \ - pacman-gnome-unstable-i686.conf \ - pacman-gnome-unstable-pentium4.conf \ - makepkg-i486.conf \ - makepkg-i686.conf \ - makepkg-pentium4.conf -GENERATED_CONFIGS := $(addprefix $(BUILDDIR)/config/,$(GENERATED_CONFIGS)) +GENERATED_PACMAN_CONFIGS = \ + core-testing-i486.conf \ + core-testing-i686.conf \ + core-testing-pentium4.conf \ + core-staging-i486.conf \ + core-staging-i686.conf \ + core-staging-pentium4.conf \ + core-staging-with-build-support-i486.conf \ + core-staging-with-build-support-i686.conf \ + core-staging-with-build-support-pentium4.conf \ + extra-i486.conf \ + extra-i686.conf \ + extra-pentium4.conf \ + extra-testing-i486.conf \ + extra-testing-i686.conf \ + extra-testing-pentium4.conf \ + extra-staging-i486.conf \ + extra-staging-i686.conf \ + extra-staging-pentium4.conf \ + extra-staging-with-build-support-i486.conf \ + extra-staging-with-build-support-i686.conf \ + extra-staging-with-build-support-pentium4.conf \ + kde-unstable-i486.conf \ + kde-unstable-i686.conf \ + kde-unstable-pentium4.conf \ + gnome-unstable-i486.conf \ + gnome-unstable-i686.conf \ + gnome-unstable-pentium4.conf +GENERATED_MAKEPKG_CONFIGS = \ + i486.conf \ + i686.conf \ + pentium4.conf +GENERATED_PACMAN_CONFIGS := $(addprefix $(BUILDDIR)/pacman.conf.d/,$(GENERATED_PACMAN_CONFIGS)) +GENERATED_MAKEPKG_CONFIGS := $(addprefix $(BUILDDIR)/makepkg.conf.d/,$(GENERATED_MAKEPKG_CONFIGS)) COMMITPKG_LINKS = \ + core-testingpkg \ + core-stagingpkg \ extrapkg \ - testingpkg \ - stagingpkg \ - communitypkg \ - community-testingpkg \ - community-stagingpkg \ + extra-testingpkg \ + extra-stagingpkg \ multilibpkg \ multilib-testingpkg \ multilib-stagingpkg \ @@ -50,24 +66,38 @@ COMMITPKG_LINKS = \ gnome-unstablepkg ARCHBUILD_LINKS = \ + core-testing-i486-build \ + core-testing-i686-build \ + core-testing-pentium4-build \ + core-testing-x86_64-build \ + core-testing-x86_64_v3-build \ + core-staging-i486-build \ + core-staging-i686-build \ + core-staging-pentium4-build \ + core-staging-x86_64-build \ + core-staging-x86_64_v3-build \ + core-staging-x86_64-build \ + core-staging-with-build-support-i486-build \ + core-staging-with-build-support-i686-build \ + core-staging-with-build-support-pentium4-build \ extra-i486-build \ extra-i686-build \ extra-pentium4-build \ extra-x86_64-build \ extra-x86_64_v3-build \ - testing-i486-build \ - testing-i686-build \ - testing-pentium4-build \ - testing-x86_64-build \ - testing-x86_64_v3-build \ - staging-i486-build \ - staging-i686-build \ - staging-pentium4-build \ - staging-x86_64-build \ - staging-x86_64_v3-build \ - staging-with-build-support-i486-build \ - staging-with-build-support-i686-build \ - staging-with-build-support-pentium4-build \ + extra-testing-i486-build \ + extra-testing-i686-build \ + extra-testing-pentium4-build \ + extra-testing-x86_64-build \ + extra-testing-x86_64_v3-build \ + extra-staging-i486-build \ + extra-staging-i686-build \ + extra-staging-pentium4-build \ + extra-staging-x86_64-build \ + extra-staging-x86_64_v3-build \ + extra-staging-with-build-support-i486-build \ + extra-staging-with-build-support-i686-build \ + extra-staging-with-build-support-pentium4-build \ multilib-build \ multilib-testing-build \ multilib-staging-build \ @@ -80,20 +110,14 @@ ARCHBUILD_LINKS = \ gnome-unstable-pentium4-build \ gnome-unstable-x86_64-build -CROSSREPOMOVE_LINKS = \ - extra2community \ - community2extra - COMPLETIONS = $(addprefix $(BUILDDIR)/,$(patsubst %.in,%,$(wildcard contrib/completion/*/*))) -BASHCOMPLETION_LINKS = \ - archco \ - communityco -all: binprogs configfiles completion man +all: binprogs library conf completion man configfiles binprogs: $(BINPROGS) +library: $(LIBRARY) completion: $(COMPLETIONS) -configfiles: $(GENERATED_CONFIGS) +configfiles: $(GENERATED_MAKEPKG_CONFIGS) $(GENERATED_PACMAN_CONFIGS) man: $(MANS) @@ -111,10 +135,12 @@ ifneq ($(wildcard setarch-aliases.d/*),) endif -edit = sed -e "s|@pkgdatadir[@]|$(PREFIX)/share/devtools|g" +edit = sed \ + -e "s|@pkgdatadir[@]|$(DATADIR)|g" \ + -e "s|@buildtoolver[@]|$(BUILDTOOLVER)|g" GEN_MSG = @echo "GEN $(patsubst $(BUILDDIR)/%,%,$@)" -$(BUILDDIR)/config/makepkg-i486.conf: config/makepkg/x86_64.conf +$(BUILDDIR)/makepkg.conf.d/i486.conf: config/makepkg/x86_64.conf @echo "GEN $(notdir $@)" @mkdir -p $(dir $@) @sed " \ @@ -125,7 +151,7 @@ $(BUILDDIR)/config/makepkg-i486.conf: config/makepkg/x86_64.conf " "$<" > "$@" @sed -i 's/--ultra -20/--ultra -19/' "$@" -$(BUILDDIR)/config/makepkg-i686.conf: config/makepkg/x86_64.conf +$(BUILDDIR)/makepkg.conf.d/i686.conf: config/makepkg/x86_64.conf @echo "GEN $(notdir $@)" @mkdir -p $(dir $@) @sed " \ @@ -134,13 +160,13 @@ $(BUILDDIR)/config/makepkg-i686.conf: config/makepkg/x86_64.conf " "$<" > "$@" @sed -i 's/--ultra -20/--ultra -19/' "$@" -$(BUILDDIR)/config/makepkg-pentium4.conf: $(BUILDDIR)/config/makepkg-i686.conf +$(BUILDDIR)/makepkg.conf.d/pentium4.conf: $(BUILDDIR)/makepkg.conf.d/i686.conf @echo "GEN $(notdir $@)" @mkdir -p $(dir $@) @sed '/^CHOST=/ ! s,\(["=]\)i686\([-" ]\),\1pentium4\2,g' "$<" > "$@" @sed -i 's/--ultra -20/--ultra -19/' "$@" -$(BUILDDIR)/config/pacman-%-i486.conf: config/pacman/%.conf +$(BUILDDIR)/pacman.conf.d/%-i486.conf: config/pacman/%.conf @echo "GEN $(notdir $@)" @mkdir -p $(dir $@) @sed " \ @@ -148,7 +174,7 @@ $(BUILDDIR)/config/pacman-%-i486.conf: config/pacman/%.conf /^Architecture = / s/^.*\$$/Architecture = i486/; \ " "$<" > "$@" -$(BUILDDIR)/config/pacman-%-i686.conf: config/pacman/%.conf +$(BUILDDIR)/pacman.conf.d/%-i686.conf: config/pacman/%.conf @echo "GEN $(notdir $@)" @mkdir -p $(dir $@) @sed " \ @@ -156,7 +182,7 @@ $(BUILDDIR)/config/pacman-%-i686.conf: config/pacman/%.conf /^Architecture = / s/^.*$$/Architecture = i686/ \ " "$<" > "$@" -$(BUILDDIR)/config/pacman-%-pentium4.conf: config/pacman/%.conf +$(BUILDDIR)/pacman.conf.d/%-pentium4.conf: config/pacman/%.conf @echo "GEN $(notdir $@)" @mkdir -p $(dir $@) @sed " \ @@ -165,77 +191,94 @@ $(BUILDDIR)/config/pacman-%-pentium4.conf: config/pacman/%.conf " "$<" > "$@" 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) "$$@" - @bash -n "$$@" + @cat $$< | $(edit) >$$@ + @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) $< + +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)$(PREFIX)/share/devtools/setarch-aliases.d + 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 - 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 conf in ${GENERATED_CONFIGS}; do install -Dm0644 $$conf $(DESTDIR)$(PREFIX)/share/devtools/$${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 $(notdir $(MAKEPKG_CONFIGS)); do install -Dm0644 $(BUILDDIR)/makepkg.conf.d/$$conf $(DESTDIR)$(DATADIR)/makepkg.conf.d/$${conf##*/}; done + for conf in $(notdir $(GENERATED_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 conf in $(notdir $(GENERATED_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 - 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 + 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 - ln -sf archco $(DESTDIR)$(PREFIX)/bin/communityco for manfile in $(MANS); do \ install -Dm644 $$manfile -t $(DESTDIR)$(MANDIR)/man$${manfile##*.}; \ done; 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 $(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 - 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)/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)/makepkg.conf.d \ + $(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=devtools32-$(V)/ $(V) | gzip -9 > devtools32-$(V).tar.gz + git archive --format=tar --prefix=devtools32-$(V)/ v$(V) | gzip > devtools32-$(V).tar.gz gpg --detach-sign --use-agent devtools32-$(V).tar.gz upload: scp devtools32-$(V).tar.gz devtools32-$(V).tar.gz.sig sources.archlinux32.org:httpdocs/sources/ -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 conf man clean install uninstall tag dist upload check .DELETE_ON_ERROR: @@ -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 @@ -23,6 +32,37 @@ BUILDTOOLVER="${pkgver}-${pkgrel}-${arch}" make all 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)). 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 diff --git a/config/pacman/staging-with-build-support.conf b/config/pacman/core-staging-with-build-support.conf index 3d2c125..7b62e6f 100644 --- a/config/pacman/staging-with-build-support.conf +++ b/config/pacman/core-staging-with-build-support.conf @@ -73,25 +73,22 @@ LocalFileSigLevel = Optional [build-support] Include = /etc/pacman.d/mirrorlist -[staging] +[core-staging] Include = /etc/pacman.d/mirrorlist -[community-staging] +[extra-staging] Include = /etc/pacman.d/mirrorlist -[testing] -Include = /etc/pacman.d/mirrorlist - -[community-testing] +[core-testing] Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] +[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/staging-x86_64_v3.conf b/config/pacman/core-staging-x86_64_v3.conf index 46ba8f8..f1eff4a 100644 --- a/config/pacman/staging-x86_64_v3.conf +++ b/config/pacman/core-staging-x86_64_v3.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 # An example of a custom package repository. See the pacman manpage for diff --git a/config/pacman/staging.conf b/config/pacman/core-staging.conf index 321a4e8..552d51d 100644 --- a/config/pacman/staging.conf +++ b/config/pacman/core-staging.conf @@ -70,27 +70,24 @@ 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 -[community-staging] +[core-testing] Include = /etc/pacman.d/mirrorlist -[testing] +[core] Include = /etc/pacman.d/mirrorlist -[community-testing] +[extra-staging] Include = /etc/pacman.d/mirrorlist -[core] +[extra-testing] Include = /etc/pacman.d/mirrorlist [extra] 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] diff --git a/config/pacman/testing-x86_64_v3.conf b/config/pacman/core-testing-x86_64_v3.conf index 2eb463d..112a40c 100644 --- a/config/pacman/testing-x86_64_v3.conf +++ b/config/pacman/core-testing-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/testing.conf b/config/pacman/core-testing.conf index bf9003c..d8b8af3 100644 --- a/config/pacman/testing.conf +++ b/config/pacman/core-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] -Include = /etc/pacman.d/mirrorlist - -[community-testing] +[core-testing] Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] +[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-staging-with-build-support.conf b/config/pacman/extra-staging-with-build-support.conf new file mode 100644 index 0000000..7b62e6f --- /dev/null +++ b/config/pacman/extra-staging-with-build-support.conf @@ -0,0 +1,99 @@ +# +# /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 -C - -f %u > %o +#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u +#CleanMethod = KeepInstalled +#UseDelta = 0.7 +Architecture = auto + +# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup +#IgnorePkg = +#IgnoreGroup = + +#NoUpgrade = +#NoExtract = + +# Misc options +#UseSyslog +#Color +#TotalDownload +# We cannot check disk space from within a chroot environment +#CheckSpace +#VerbosePkgLists + +# 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. + +[build-support] +Include = /etc/pacman.d/mirrorlist + +[core-staging] +Include = /etc/pacman.d/mirrorlist + +[extra-staging] +Include = /etc/pacman.d/mirrorlist + +[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 e855f3c..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] -#Include = /etc/pacman.d/mirrorlist - -#[community-testing] +#[core-testing] #Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] -Include = /etc/pacman.d/mirrorlist +#[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 d7ae13b..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] -Include = /etc/pacman.d/mirrorlist - -[community-testing] +[core-testing] Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] +[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 6e6bfd8..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] -Include = /etc/pacman.d/mirrorlist - -[community-testing] +[core-testing] Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] +[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 5b300c0..82cf9e3 100644 --- a/config/pacman/multilib-staging.conf +++ b/config/pacman/multilib-staging.conf @@ -70,27 +70,24 @@ 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 -[community-staging] +[core-testing] Include = /etc/pacman.d/mirrorlist -[testing] +[core] Include = /etc/pacman.d/mirrorlist -[community-testing] +[extra-staging] Include = /etc/pacman.d/mirrorlist -[core] +[extra-testing] Include = /etc/pacman.d/mirrorlist [extra] Include = /etc/pacman.d/mirrorlist -[community] -Include = /etc/pacman.d/mirrorlist - # If you want to run 32 bit applications on your x86_64 system, # enable the multilib repositories as required here. [multilib-staging] diff --git a/config/pacman/multilib-testing.conf b/config/pacman/multilib-testing.conf index db5b9cc..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] -Include = /etc/pacman.d/mirrorlist - -[community-testing] +[core-testing] Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] +[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 1707f94..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] -#Include = /etc/pacman.d/mirrorlist - -#[community-testing] +#[core-testing] #Include = /etc/pacman.d/mirrorlist [core] Include = /etc/pacman.d/mirrorlist -[extra] -Include = /etc/pacman.d/mirrorlist +#[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/setarch-aliases.d/i486 b/config/setarch-aliases.d/i486 new file mode 100644 index 0000000..193dd70 --- /dev/null +++ b/config/setarch-aliases.d/i486 @@ -0,0 +1 @@ +i686 diff --git a/contrib/completion/bash/devtools.in b/contrib/completion/bash/devtools.in index e7925b3..3faad27 100644 --- a/contrib/completion/bash/devtools.in +++ b/contrib/completion/bash/devtools.in @@ -2,89 +2,468 @@ # # 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 -} - -_archco_pkg() { - _devtools_compgen "$( - command pacman "-$1" - )" -} - -_archco() { - local cur prev - COMPREPLY=() - cur=$(_get_cword) - prev=${COMP_WORDS[COMP_CWORD-1]} - - _archco_pkg Slq - true -} && -complete -F _archco archco communityco - -_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 + -w --worker + + --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__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() { :; } +_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 + switch + web +) + + +_pkgctl_repo_clone_args=( + -m --maintainer + --protocol + --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__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; } +_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; } + + +_pkgctl_repo_create_args=( + -c --clone + -h --help +) + + +_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 +) +_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_completions_protocol() { + mapfile -t COMPREPLY < <(compgen -W "https" -- "$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 diff --git a/contrib/completion/zsh/_devtools.in b/contrib/completion/zsh/_devtools.in index 48d3dfd..a473bc2 100644 --- a/contrib/completion/zsh/_devtools.in +++ b/contrib/completion/zsh/_devtools.in @@ -1,9 +1,12 @@ -#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 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 -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,10 +18,122 @@ _archbuild_args=( '--[Introduce makechrootpkg options]:*::makechrootpkg options:= _dispatch makechrootpkg makechrootpkg' ) -_archco_args=( +_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_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.*(.)"' + '(-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:' + '--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 <msg> 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]" + "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_release_args=( + '(-m --message=)'{-m,--message=}"[Use the given <msg> 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]" + "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:' + '--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:' + '(-h --help)'{-h,--help}'[Display usage]' '*:packages:_devtools_completions_all_packages' ) +_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 -/' +) + +_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 -/' +) + _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(.)"' @@ -86,11 +201,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]' @@ -127,9 +237,62 @@ _devtools_completions_all_packages() { compadd - "${(@)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]" + "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]' +) + +_pkgctl_diff_args=("${_diffpkg_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) + 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] + 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 + elif typeset -p ${service_name}_args &> /dev/null; then + local argname="${service_name}_args[@]" + _arguments -s "${(P)argname}" + fi +} + _devtools() { - local argname="_${service//-/_}_args[@]" - _arguments -s "${(P)argname}" + _handle_subcommands _${service//-/_} } _devtools diff --git a/doc/man/archbuild.1.asciidoc b/doc/man/archbuild.1.asciidoc index 6b00572..2a2d843 100644 --- a/doc/man/archbuild.1.asciidoc +++ b/doc/man/archbuild.1.asciidoc @@ -23,8 +23,9 @@ 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. Options ------- diff --git a/doc/man/devtools.7.asciidoc b/doc/man/devtools.7.asciidoc index 9062278..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 ('archco', 'extra2community') +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..35b2ded 100644 --- a/doc/man/diffpkg.1.asciidoc +++ b/doc/man/diffpkg.1.asciidoc @@ -1,5 +1,5 @@ diffpkg(1) -=========== +========== Name ---- @@ -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/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 <aaronmgriffin@gmail.com> -* Allan McRae <allan@archlinux.org> -* Bartłomiej Piotrowski <bpiotrowski@archlinux.org> -* Dan McGee <dan@archlinux.org> -* Dave Reisner <dreisner@archlinux.org> -* Evangelos Foutras <evangelos@foutrelis.com> -* Jan Alexander Steffens (heftig) <jan.steffens@gmail.com> -* Jelle van der Waa <jelle@archlinux.org> -* Levente Polyak <anthraxx@archlinux.org> -* Pierre Schmitz <pierre@archlinux.de> -* Sébastien Luttringer <seblu@seblu.net> -* Sven-Hendrik Haase <svenstaro@gmail.com> -* Thomas Bächler <thomas@archlinux.org> - -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. 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-auth-login.1.asciidoc b/doc/man/pkgctl-auth-login.1.asciidoc new file mode 100644 index 0000000..eeeec4e --- /dev/null +++ b/doc/man/pkgctl-auth-login.1.asciidoc @@ -0,0 +1,40 @@ +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'. + +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 +------- + +*-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-build.1.asciidoc b/doc/man/pkgctl-build.1.asciidoc new file mode 100644 index 0000000..f68e7cf --- /dev/null +++ b/doc/man/pkgctl-build.1.asciidoc @@ -0,0 +1,91 @@ +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 + +*-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 + +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 + + Specifying this option is required when using any of the following options + in this section + +*-m, --message* 'MSG':: + Use the given <msg> 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-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-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-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 <msg> 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-repo-clone.1.asciidoc b/doc/man/pkgctl-repo-clone.1.asciidoc new file mode 100644 index 0000000..421c71f --- /dev/null +++ b/doc/man/pkgctl-repo-clone.1.asciidoc @@ -0,0 +1,52 @@ +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 + +*--protocol* 'https':: + Clone the repository over https + +*--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. + +*-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 + +See Also +-------- + +linkman:pkgctl-repo-configure[1] +linkman:pkgctl-repo-switch[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..6bdea93 --- /dev/null +++ b/doc/man/pkgctl-repo-configure.1.asciidoc @@ -0,0 +1,39 @@ +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 remote protocol is automatically determined from the author email +address by choosing SSH for all official packager identities and +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 + needs to be passed with 1. + +*-h, --help*:: + Show a help text + +include::include/footer.asciidoc[] diff --git a/doc/man/pkgctl-repo-create.1.asciidoc b/doc/man/pkgctl-repo-create.1.asciidoc new file mode 100644 index 0000000..7c58776 --- /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-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-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..57be170 --- /dev/null +++ b/doc/man/pkgctl-repo.1.asciidoc @@ -0,0 +1,59 @@ +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 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 + +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/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 new file mode 100644 index 0000000..72cda1e --- /dev/null +++ b/doc/man/pkgctl.1.asciidoc @@ -0,0 +1,61 @@ +pkgctl(1) +========= + +Name +---- +pkgctl - Unified command-line frontend for devtools + +Synopsis +-------- +pkgctl [SUBCOMMAND] [OPTIONS] + +Description +----------- + +TODO + +Options +------- + +*-V, --version*:: + Show pkgctl version information + +*-h, --help*:: + Show a help text + +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 + +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 + +pkgctl version:: + Show pkgctl version information + +See Also +-------- + +linkman:pkgctl-auth[1] +linkman:pkgctl-build[1] +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/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 0e8366e..0000000 --- a/lib/valid-tags.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/hint/bash -# -# SPDX-License-Identifier: GPL-3.0-or-later -: - -# shellcheck disable=2034 -_arch=( - i686 - x86_64 - any -) - -# shellcheck disable=2034 -_tags=( - core-i686 core-x86_64 core-any - extra-i686 extra-x86_64 extra-any - multilib-x86_64 - staging-i686 staging-x86_64 staging-any - testing-i686 testing-x86_64 testing-any - multilib-testing-x86_64 - multilib-staging-x86_64 - community-i686 community-x86_64 community-any - community-staging-i686 community-staging-x86_64 community-staging-any - community-testing-i686 community-testing-x86_64 community-testing-any - kde-unstable-i686 kde-unstable-x86_64 kde-unstable-any - gnome-unstable-i686 gnome-unstable-x86_64 gnome-unstable-any -) diff --git a/src/arch-nspawn.in b/src/arch-nspawn.in index ae50043..11af616 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 @@ -28,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" ;; @@ -42,7 +49,7 @@ done shift $((OPTIND - 1)) (( $# < 1 )) && die 'You must specify a directory.' -check_root +check_root "" "${BASH_SOURCE[0]}" "${orig_args[@]}" working_dir=$(readlink -f "$1") shift 1 @@ -54,7 +61,7 @@ if (( ${#cache_dirs[@]} == 0 )); then fi # shellcheck disable=2016 -host_mirrors=($(pacman-conf --config "${pac_conf:-$working_dir/etc/pacman.conf}" --repo extra Server 2> /dev/null | sed -r 's#(.*/)extra/os/.*#\1$repo/os/$arch#;t;s#(.*/)[^/]+/extra(/?)$#\1$arch/$repo\2#')) +host_mirrors=($(pacman-conf --repo extra Server 2> /dev/null | sed -r 's#(.*/)extra/os/.*#\1$repo/os/$arch#')) for host_mirror in "${host_mirrors[@]}"; do if [[ $host_mirror == *file://* ]]; then diff --git a/src/archbuild.in b/src/archbuild.in index a5eb9a0..d023e0d 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) @@ -23,16 +27,32 @@ 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 -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() { @@ -54,7 +74,7 @@ while getopts 'hcr:' arg; do esac done -check_root SOURCE_DATE_EPOCH,SRCDEST,SRCPKGDEST,PKGDEST,LOGDEST,MAKEFLAGS,PACKAGER,GNUPGHOME,PKGEXT +check_root SOURCE_DATE_EPOCH,SRCDEST,SRCPKGDEST,PKGDEST,LOGDEST,MAKEFLAGS,PACKAGER,GNUPGHOME "${BASH_SOURCE[0]}" "$@" if [ "${arch}" = "x86_64" ]; then cache_dir='' diff --git a/src/archco.in b/src/archco.in deleted file mode 100644 index a93d819..0000000 --- a/src/archco.in +++ /dev/null @@ -1,26 +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 <package name>...\n' "$scriptname" - exit 1 -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";; - *) - die "Couldn't find svn url for %s" "$scriptname" - ;; -esac - -for i in "$@"; do - svn co "$SVNURL/$i" -done diff --git a/src/archrelease.in b/src/archrelease.in index 3490ee2..818b0ca 100644 --- a/src/archrelease.in +++ b/src/archrelease.in @@ -2,8 +2,19 @@ # # 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 + +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= @@ -34,54 +45,50 @@ if [[ ! -f PKGBUILD ]]; then die 'archrelease: PKGBUILD not found' fi -trunk=${PWD##*/} +# shellcheck source=contrib/makepkg/PKGBUILD.proto +. ./PKGBUILD +pkgbase=${pkgbase:-$pkgname} +pkgver=$(get_full_version "$pkgbase") +gittag=$(get_tag_from_pkgver "$pkgver") -# 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/)' +# Check if releasing from a branch +if ! branchname=$(git symbolic-ref --short HEAD); then + die 'not on any branch' fi -unset parts - -if [[ $(svn status -q) ]]; then - die 'archrelease: You have not committed your changes yet!' +if [[ "${branchname}" != main ]]; then + die 'must be run from the main branch' 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 +# 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 -for tag in "$@"; do - stat_busy "Copying %s to %s" "${trunk}" "${tag}" +msg 'Fetching remote changes' +git fetch --prune --prune-tags origin || die 'failed to fetch remote changes' - 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" +# 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 - # 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 -stat_done +# If the tag exists we check if it's properly signed and that it +# matches the working directory PKGBUILD. +if git tag --verify "$gittag" &> /dev/null; then + cwd_checksum=$(sha256sum PKGBUILD|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 + git push --tags --set-upstream origin main || abort + exit 0 +fi -popd >/dev/null +msg "Releasing package" +git tag --sign --message="Package release ${pkgver}" "$gittag" || abort +git push --tags --set-upstream origin main || abort 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 235d12b..8a8087a 100644 --- a/src/commitpkg.in +++ b/src/commitpkg.in @@ -2,7 +2,39 @@ # # 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 + . ./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 @@ -23,10 +55,25 @@ 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 +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 + source=() # shellcheck source=contrib/makepkg/PKGBUILD.proto . ./PKGBUILD @@ -60,7 +107,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 @@ -79,15 +126,21 @@ 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 + # 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 + 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 @@ -121,31 +174,50 @@ for _arch in "${arch[@]}"; do fi done -if [[ -z $server ]]; then - server='repos.archlinux.org' +# 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 $(svn status -q) ]]; then - msgtemplate="upgpkg: $pkgbase $(get_full_version)" +if [[ -n $(git status --porcelain --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: $(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 - msgfile="$(mktemp)" + [[ -z ${WORKDIR:-} ]] && setup_workdir + msgfile=$(mktemp --tmpdir="${WORKDIR}" commitpkg.XXXXXXXXXX) echo "$msgtemplate" > "$msgfile" - if [[ -n $SVN_EDITOR ]]; then - $SVN_EDITOR "$msgfile" + if [[ -n $GIT_EDITOR ]]; then + $GIT_EDITOR "$msgfile" || die elif [[ -n $VISUAL ]]; then - $VISUAL "$msgfile" + $VISUAL "$msgfile" || die elif [[ -n $EDITOR ]]; then - $EDITOR "$msgfile" + $EDITOR "$msgfile" || die + elif giteditor=$(git config --get core.editor); then + $giteditor "$msgfile" || die else - vi "$msgfile" + die "No usable editor found (tried \$GIT_EDITOR, \$VISUAL, \$EDITOR, git config [core.editor])." 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 @@ -219,23 +291,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/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 diff --git a/src/diffpkg.in b/src/diffpkg.in index 10b0904..160c4ba 100644 --- a/src/diffpkg.in +++ b/src/diffpkg.in @@ -2,11 +2,15 @@ # # 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_ - 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 +21,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 @@ -211,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" @@ -232,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 @@ -240,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 @@ -248,6 +253,7 @@ diff_pkgs() { fi } +shopt -s extglob fetch_pkg() { local pkg pkgdest pkgurl case $1 in @@ -295,10 +301,11 @@ fetch_pkg() { echo "$pkgdest" } +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/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 5a11580..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 @@ -40,6 +43,7 @@ else pushd "$WORKDIR" >/dev/null fi +shopt -s extglob process_sofile() { # extract the library name: libfoo.so shopt -s extglob nullglob @@ -56,6 +60,7 @@ process_sofile() { soobjects+=("${soname}=${soversion}-${soarch}") fi } +shopt -u extglob case $script_mode in deps) find_args=(-perm -u+x);; 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/api/gitlab.sh b/src/lib/api/gitlab.sh new file mode 100644 index 0000000..e5f4237 --- /dev/null +++ b/src/lib/api/gitlab.sh @@ -0,0 +1,132 @@ +#!/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 +} + +# 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 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" + }' + 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/lib/archroot.sh b/src/lib/archroot.sh index d7917da..8386c6c 100644 --- a/lib/archroot.sh +++ b/src/lib/archroot.sh @@ -4,18 +4,19 @@ : # shellcheck disable=2034 -CHROOT_VERSION='v4' +CHROOT_VERSION='v5' ## # 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/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..d427676 --- /dev/null +++ b/src/lib/auth/login.sh @@ -0,0 +1,101 @@ +#!/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'. + + 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 + + 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'. + + 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 + 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/lib/build/build.sh b/src/lib/build/build.sh new file mode 100644 index 0000000..3394395 --- /dev/null +++ b/src/lib/build/build.sh @@ -0,0 +1,420 @@ +#!/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 +set -o pipefail + + +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 + -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 + --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 <msg> 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 MAKEPKG_OPTIONS=() + + local WORKER= + local WORKER_SLOT= + + # 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 + ;; + --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 + 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 + ;; + -w|--worker) + (( $# <= 1 )) && die "missing argument for %s" "$1" + WORKER_SLOT=$2 + shift 2 + ;; + --) + shift + break + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + paths=("$@") + break + ;; + 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 + paths=(".") + else + pkgctl_build_usage + exit 1 + 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 + # 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, specify --repo for packages not currently in any official repo' + 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[*]}" + msg2 "worker: ${WORKER}" + + # 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 $GIT_EDITOR ]]; then + $GIT_EDITOR PKGBUILD || die + elif [[ -n $VISUAL ]]; then + $VISUAL PKGBUILD || die + elif [[ -n $EDITOR ]]; then + $EDITOR PKGBUILD || die + elif giteditor=$(git config --get core.editor); then + $giteditor PKGBUILD || die + else + 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 + 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}" -- "${MAKEPKG_OPTIONS[@]}" + else + "${BUILDTOOL}" "${BUILD_OPTIONS[@]}" -- "${MAKECHROOT_OPTIONS[@]}" -l "${WORKER}" -- "${MAKEPKG_OPTIONS[@]}" + 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/lib/common.sh b/src/lib/common.sh index a5e4616..3d1ee56 100644 --- a/lib/common.sh +++ b/src/lib/common.sh @@ -4,23 +4,33 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -[[ -z ${_INCLUDE_COMMON_SH:-} ]] || return 0 -_INCLUDE_COMMON_SH="$(set +o|grep nounset)" +[[ -z ${DEVTOOLS_INCLUDE_COMMON_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_COMMON_SH="$(set +o|grep nounset)" set +u +o posix # shellcheck disable=1091 . /usr/share/makepkg/util.sh -$_INCLUDE_COMMON_SH +$DEVTOOLS_INCLUDE_COMMON_SH # Avoid any encoding problems export LANG=C # 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 +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="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 +if [[ -t 2 && "$TERM" != dumb ]] || [[ ${DEVTOOLS_COLOR} == always ]]; then colorize else # shellcheck disable=2034 @@ -33,11 +43,40 @@ 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 } +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") @@ -137,6 +176,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 +231,7 @@ find_cached_package() { return 1 esac } - +shopt -u extglob check_package_validity(){ local pkgfile=$1 @@ -254,6 +294,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/lib/config.sh b/src/lib/config.sh new file mode 100644 index 0000000..b09479a --- /dev/null +++ b/src/lib/config.sh @@ -0,0 +1,48 @@ +#!/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() { + # 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 + fi + 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() { + # 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}" + ) +} 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/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 <msg> 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/repo.sh b/src/lib/repo.sh new file mode 100644 index 0000000..9f545e9 --- /dev/null +++ b/src/lib/repo.sh @@ -0,0 +1,110 @@ +#!/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 + create Create a new GitLab package repository + switch Switch a package repository to a specified version + 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} create libfoo + $ ${COMMAND} switch 2:1.19.5-1 libfoo + $ ${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 + ;; + 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 + ;; + 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 + # 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..08bded4 --- /dev/null +++ b/src/lib/repo/clone.sh @@ -0,0 +1,199 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +[[ -z ${DEVTOOLS_INCLUDE_REPO_CLONE_SH:-} ]] || return 0 +DEVTOOLS_INCLUDE_REPO_CLONE_SH=1 + +_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} +# shellcheck source=src/lib/common.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh +# shellcheck source=src/lib/api/gitlab.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh +# shellcheck source=src/lib/repo/configure.sh +source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/configure.sh + +source /usr/share/makepkg/util/message.sh + +set -e + + +pkgctl_repo_clone_usage() { + local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + cat <<- _EOF_ + Usage: ${COMMAND} [OPTIONS] [PKGBASE]... + + Clone Git packaging repositories from the canonical namespace. + + The configure command is subsequently invoked to synchronize the distro + specs and makepkg.conf settings. The protocol option can be used + for cloning packaging repositories without SSH access using read-only + HTTPS. + + OPTIONS + -m, --maintainer=NAME Clone all packages of the named maintainer + --protocol https Clone the repository over https + --switch VERSION Switch the current working tree to a specified version + --universe Clone all existing packages, useful for cache warming + -j, --jobs N Run up to N jobs in parallel (default: $(nproc)) + -h, --help Show this help text + + EXAMPLES + $ ${COMMAND} libfoo linux libbar + $ ${COMMAND} --maintainer mynickname + $ ${COMMAND} --switch 1:1.0-2 libfoo +_EOF_ +} + +pkgctl_repo_clone() { + if (( $# < 1 )); then + pkgctl_repo_clone_usage + exit 0 + fi + + # options + local GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} + local CLONE_ALL=0 + local MAINTAINER= + local VERSION= + local CONFIGURE_OPTIONS=() + local jobs= + jobs=$(nproc) + + # variables + local command=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} + local project_path + + while (( $# )); do + case $1 in + -h|--help) + pkgctl_repo_clone_usage + exit 0 + ;; + --protocol=https) + GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS} + CONFIGURE_OPTIONS+=("$1") + shift + ;; + --protocol) + (( $# <= 1 )) && die "missing argument for %s" "$1" + if [[ $2 == https ]]; then + GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS} + else + die "unsupported protocol: %s" "$2" + fi + CONFIGURE_OPTIONS+=("$1" "$2") + shift 2 + ;; + -m|--maintainer) + (( $# <= 1 )) && die "missing argument for %s" "$1" + MAINTAINER="$2" + shift 2 + ;; + --maintainer=*) + MAINTAINER="${1#*=}" + shift + ;; + --switch) + (( $# <= 1 )) && die "missing argument for %s" "$1" + # shellcheck source=src/lib/repo/switch.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/switch.sh + VERSION="$2" + shift 2 + ;; + --switch=*) + # shellcheck source=src/lib/repo/switch.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/switch.sh + VERSION="${1#*=}" + shift + ;; + --universe) + CLONE_ALL=1 + shift + ;; + -j|--jobs) + (( $# <= 1 )) && die "missing argument for %s" "$1" + jobs=$2 + shift 2 + ;; + --) + shift + break + ;; + -*) + die "invalid argument: %s" "$1" + ;; + *) + pkgbases=("$@") + break + ;; + esac + done + + # Query packages of a maintainer + if [[ -n ${MAINTAINER} ]]; then + stat_busy "Query packages" + max_pages=$(curl --silent --location --fail --retry 3 --retry-delay 3 "https://archlinux.org/packages/search/json/?sort=name&maintainer=${MAINTAINER}" | jq -r '.num_pages') + if [[ ! ${max_pages} =~ ([[:digit:]]) ]]; then + stat_done + warning "found no packages for maintainer ${MAINTAINER}" + exit 0 + fi + mapfile -t pkgbases < <(for page in $(seq "${max_pages}"); do + curl --silent --location --fail --retry 3 --retry-delay 3 "https://archlinux.org/packages/search/json/?sort=name&maintainer=${MAINTAINER}&page=${page}" | jq -r '.results[].pkgbase' + stat_progress + done | sort --unique) + stat_done + fi + + # Query all released packages + if (( CLONE_ALL )); then + stat_busy "Query all released packages" + max_pages=$(curl --silent --location --fail --retry 3 --retry-delay 3 "https://archlinux.org/packages/search/json/?sort=name" | jq -r '.num_pages') + if [[ ! ${max_pages} =~ ([[:digit:]]) ]]; then + stat_done + die "failed to query packages" + fi + mapfile -t pkgbases < <(for page in $(seq "${max_pages}"); do + curl --silent --location --fail --retry 3 --retry-delay 3 "https://archlinux.org/packages/search/json/?sort=name&page=${page}" | jq -r '.results[].pkgbase' + stat_progress + done | sort --unique) + stat_done + fi + + # parallelization + if [[ ${jobs} != 1 ]] && (( ${#pkgbases[@]} > 1 )); then + # force colors in parallel if parent process is colorized + if [[ -n ${BOLD} ]]; then + export DEVTOOLS_COLOR=always + fi + # assign command options + if [[ -n "${VERSION}" ]]; then + command+=" --switch '${VERSION}'" + fi + if ! parallel --bar --jobs "${jobs}" "${command}" ::: "${pkgbases[@]}"; then + die 'Failed to clone some packages, please check the output' + exit 1 + fi + exit 0 + fi + + for pkgbase in "${pkgbases[@]}"; do + if [[ ! -d ${pkgbase} ]]; then + msg "Cloning ${pkgbase} ..." + project_path=$(gitlab_project_name_to_path "${pkgbase}") + remote_url="${GIT_REPO_BASE_URL}/${project_path}.git" + if ! git clone --origin origin "${remote_url}" "${pkgbase}"; then + die 'failed to clone %s' "${pkgbase}" + fi + else + warning "Skip cloning ${pkgbase}: Directory exists" + fi + + pkgctl_repo_configure "${CONFIGURE_OPTIONS[@]}" "${pkgbase}" + + if [[ -n "${VERSION}" ]]; then + pkgctl_repo_switch "${VERSION}" "${pkgbase}" + fi + done +} diff --git a/src/lib/repo/configure.sh b/src/lib/repo/configure.sh new file mode 100644 index 0000000..73300ae --- /dev/null +++ b/src/lib/repo/configure.sh @@ -0,0 +1,259 @@ +#!/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 remote protocol is automatically determined from the author email + address by choosing SSH for all official packager identities and + 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 + + EXAMPLES + $ ${COMMAND} * +_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_HTTPS} + local official=0 + local proto=https + local proto_force=0 + 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 + + while (( $# )); do + case $1 in + -h|--help) + 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 + shift 2 + ;; + --) + 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 for packager identity + msg "Collecting packager identity from makepkg.conf" + # shellcheck disable=2119 + load_makepkg_config + 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 + if ! is_packager_name_valid "${packager_name}"; then + die "invalid PACKAGER '${PACKAGER}' in makepkg.conf" + fi + if is_packager_email_official "${packager_email}"; then + official=1 + if (( ! proto_force )); then + proto=ssh + GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH} + fi + fi + fi + + 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 + + # 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 + die "No such directory: ${path}" + fi + + pkgbase=$(basename "${realpath}") + pkgbase=${pkgbase%.git} + msg "Configuring ${pkgbase}" + + if [[ ! -d "${path}/.git" ]]; then + die "Not a Git repository: ${path}" + fi + + pushd "${path}" >/dev/null + + 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 + + # move the master branch to 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 + + # 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 +} 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 +} 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 +} diff --git a/src/lib/repo/web.sh b/src/lib/repo/web.sh new file mode 100644 index 0000000..45ea53b --- /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} 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/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/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/lib/valid-repos.sh b/src/lib/valid-repos.sh new file mode 100644 index 0000000..14f90ce --- /dev/null +++ b/src/lib/valid-repos.sh @@ -0,0 +1,22 @@ +#!/hint/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later +: + +# shellcheck disable=2034 +_repos=( + core core-staging core-testing + extra extra-staging extra-testing + multilib multilib-staging multilib-testing + gnome-unstable + kde-unstable +) + +# shellcheck disable=2034 +_build_repos=( + core-staging core-testing + extra extra-staging extra-testing + multilib multilib-staging multilib-testing + gnome-unstable + kde-unstable +) diff --git a/src/lib/valid-tags.sh b/src/lib/valid-tags.sh new file mode 100644 index 0000000..5382c5c --- /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=( + i686 + x86_64 + any +) + +# 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 + multilib-testing-x86_64 + multilib-staging-x86_64 + kde-unstable-x86_64 kde-unstable-any + gnome-unstable-x86_64 gnome-unstable-any +) 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/makechrootpkg.in b/src/makechrootpkg.in index e56e912..aac7a0b 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 @@ -24,6 +29,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=() @@ -304,7 +310,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") @@ -375,6 +381,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 diff --git a/src/makerepropkg.in b/src/makerepropkg.in index c58a923..398d4af 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 @@ -93,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 } @@ -119,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 ;; @@ -131,7 +140,7 @@ while getopts 'dM:c:l:h' arg; do done shift $((OPTIND - 1)) -check_root +check_root "" "${BASH_SOURCE[0]}" "${orig_args[@]}" [[ -f PKGBUILD ]] || { error "No PKGBUILD in current directory."; exit 1; } @@ -224,7 +233,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/mkarchroot.in b/src/mkarchroot.in index 5fac505..2abe001 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 @@ -28,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 ;; @@ -48,7 +55,7 @@ shift $((OPTIND - 1)) (( $# < 2 )) && die 'You must specify a directory and one or more packages.' -check_root +check_root "" "${BASH_SOURCE[0]}" "${orig_args[@]}" working_dir="$(readlink -f "$1")" shift 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" diff --git a/src/pkgctl.in b/src/pkgctl.in new file mode 100644 index 0000000..1797b32 --- /dev/null +++ b/src/pkgctl.in @@ -0,0 +1,109 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-3.0-or-later + +_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 + + +usage() { + local -r COMMAND=${BASH_SOURCE[0]##*/} + cat <<- _EOF_ + Usage: ${COMMAND} [COMMAND] [OPTIONS] + + Unified command-line frontend for devtools. + + 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 + repo Manage Git packaging repositories and their configuration + version Show pkgctl version information + + OPTIONS + -h, --help Show this help text +_EOF_ +} + +if (( $# < 1 )); then + usage + exit 1 +fi + +export _DEVTOOLS_COMMAND='pkgctl' + +load_devtools_config + +# command checking +while (( $# )); do + case $1 in + -h|--help) + 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 + # shellcheck source=src/lib/repo.sh + source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo.sh + 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 + ;; + 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 + 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 + ;; + 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" + ;; + esac +done diff --git a/src/rebuildpkgs.in b/src/rebuildpkgs.in deleted file mode 100644 index eddc17f..0000000 --- a/src/rebuildpkgs.in +++ /dev/null @@ -1,111 +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 - -m4_include(lib/common.sh) - -if (( $# < 1 )); then - printf 'Usage: %s <chrootdir> <packages to rebuild>\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 SVN 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' diff --git a/src/sogrep.in b/src/sogrep.in index d1ca1a1..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 -: ${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) arches=('x86_64') # options @@ -23,11 +27,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 +45,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 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" "$@" |