mirror of
				https://gitlab.archlinux.org/archlinux/devtools.git
				synced 2025-11-04 09:44:42 +01:00 
			
		
		
		
	Compare commits
	
		
			123 Commits
		
	
	
		
			v1.0.3
			...
			support-of
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					a0c0c63a85 | ||
| 
						 | 
					e1401ce41c | ||
| 
						 | 
					8612b41a20 | ||
| 
						 | 
					fbb661645b | ||
| 
						 | 
					f1dc2e18f7 | ||
| 
						 | 
					c9d821448b | ||
| 
						 | 
					a620250535 | ||
| 
						 | 
					27eebe383d | ||
| 
						 | 
					d6d416b653 | ||
| 
						 | 
					9ff63503b9 | ||
| 
						 | 
					3f02a1a24c | ||
| 
						 | 
					1df0979da6 | ||
| 
						 | 
					c1a3ed224b | ||
| 
						 | 
					144f9a871e | ||
| 
						 | 
					44328cd9a3 | ||
| 
						 | 
					0e2b16b0ac | ||
| 
						 | 
					6f0a8c345d | ||
| 
						 | 
					5f19853414 | ||
| 
						 | 
					2b62ac660d | ||
| 
						 | 
					7cb72699f6 | ||
| 
						 | 
					d1790c295a | ||
| 
						 | 
					12a0d0c7b5 | ||
| 
						 | 
					952f483574 | ||
| 
						 | 
					c484a55cde | ||
| 
						 | 
					a46b2d4fb7 | ||
| 
						 | 
					e828111ff7 | ||
| 
						 | 
					35b417d226 | ||
| 
						 | 
					1d433f600e | ||
| 
						 | 
					7b553afcb2 | ||
| 
						 | 
					01614c6817 | ||
| 
						 | 
					dced77d23d | ||
| 
						 | 
					5780ba0e38 | ||
| 
						 | 
					9a5181db5b | ||
| 
						 | 
					55c2ca1312 | ||
| 
						 | 
					ccee85b2ab | ||
| 
						 | 
					05bea3e922 | ||
| 
						 | 
					de0ea3b2f8 | ||
| 
						 | 
					81f5e7b3b3 | ||
| 
						 | 
					01b6b0849e | ||
| 
						 | 
					7033554e45 | ||
| 
						 | 
					40f476c649 | ||
| 
						 | 
					509dd24bdc | ||
| 
						 | 
					7a9ef3bc57 | ||
| 
						 | 
					354c9dcd12 | ||
| 
						 | 
					39eaeaa4b2 | ||
| 
						 | 
					c79a993148 | ||
| 
						 | 
					6d0ac6b9a8 | ||
| 
						 | 
					66a4357f3e | ||
| 
						 | 
					db2f82bf19 | ||
| 
						 | 
					e0a84aefc3 | ||
| 
						 | 
					98bd7e3760 | ||
| 
						 | 
					3e79cb8f4a | ||
| 
						 | 
					1cf402eae9 | ||
| 
						 | 
					0469d3c902 | ||
| 
						 | 
					f6b1b1ba45 | ||
| 
						 | 
					36ece44b12 | ||
| 
						 | 
					fc05ea19d9 | ||
| 
						 | 
					3ecba314fc | ||
| 
						 | 
					5042dcaeb4 | ||
| 
						 | 
					67fdb58758 | ||
| 
						 | 
					eabb1a9313 | ||
| 
						 | 
					a7a2f25fb0 | ||
| 
						 | 
					800cf9b56b | ||
| 
						 | 
					4d72f4560c | ||
| 
						 | 
					e3edf25554 | ||
| 
						 | 
					b258bb3b7c | ||
| 
						 | 
					08ece1640b | ||
| 
						 | 
					fedfc80ca1 | ||
| 
						 | 
					66e83c950c | ||
| 
						 | 
					96f39525bf | ||
| 
						 | 
					03d5c928cf | ||
| 
						 | 
					6054c869e1 | ||
| 
						 | 
					313c5b4d32 | ||
| 
						 | 
					db8c157eea | ||
| 
						 | 
					343a2b5d4c | ||
| 
						 | 
					7a8f0eb47e | ||
| 
						 | 
					e6f7aa395f | ||
| 
						 | 
					e413b65df3 | ||
| 
						 | 
					ef04960b98 | ||
| 
						 | 
					d210079037 | ||
| 
						 | 
					b264c7f1c7 | ||
| 
						 | 
					2b8033b911 | ||
| 
						 | 
					8f45c65830 | ||
| 
						 | 
					d0dc0e1a32 | ||
| 
						 | 
					0e538cf498 | ||
| 
						 | 
					4673ad6c89 | ||
| 
						 | 
					78dd150996 | ||
| 
						 | 
					4425913e4f | ||
| 
						 | 
					2a1e8aebaf | ||
| 
						 | 
					3933f20001 | ||
| 
						 | 
					0f14d630bc | ||
| 
						 | 
					d00a2b9890 | ||
| 
						 | 
					c2d73d73ae | ||
| 
						 | 
					f2cafa3cb0 | ||
| 
						 | 
					c356995dc1 | ||
| 
						 | 
					1535a69af6 | ||
| 
						 | 
					9a356eae82 | ||
| 
						 | 
					ae14c246b8 | ||
| 
						 | 
					cc369e86d2 | ||
| 
						 | 
					c9de6a18b9 | ||
| 
						 | 
					9f8ca5df1a | ||
| 
						 | 
					7825f9fb02 | ||
| 
						 | 
					b7984c6073 | ||
| 
						 | 
					5e3ab4b321 | ||
| 
						 | 
					e7b82f36ef | ||
| 
						 | 
					4d7364ed1b | ||
| 
						 | 
					e0ab20d05c | ||
| 
						 | 
					5cbe9ad612 | ||
| 
						 | 
					6f106e7cd6 | ||
| 
						 | 
					0669315821 | ||
| 
						 | 
					a6d43aca01 | ||
| 
						 | 
					02bc8bfbc0 | ||
| 
						 | 
					f632659563 | ||
| 
						 | 
					7e41adf00b | ||
| 
						 | 
					a316b50f88 | ||
| 
						 | 
					547961681a | ||
| 
						 | 
					8190a22480 | ||
| 
						 | 
					f31ea3a48e | ||
| 
						 | 
					9f7808c26e | ||
| 
						 | 
					5f4fd52e38 | ||
| 
						 | 
					1b25190176 | ||
| 
						 | 
					030e6af880 | ||
| 
						 | 
					662d6c5274 | 
							
								
								
									
										15
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
# EditorConfig configuration for devtools
 | 
			
		||||
# https://editorconfig.org
 | 
			
		||||
 | 
			
		||||
# Top-most EditorConfig file
 | 
			
		||||
root = true
 | 
			
		||||
 | 
			
		||||
# Unix-style newlines without trailing whitespaces, but with a newline
 | 
			
		||||
# ending every file, utf-8 charset, set indent to tabs
 | 
			
		||||
[*]
 | 
			
		||||
end_of_line = lf
 | 
			
		||||
insert_final_newline = true
 | 
			
		||||
trim_trailing_whitespace = true
 | 
			
		||||
charset = utf-8
 | 
			
		||||
indent_style = tab
 | 
			
		||||
tab_width = 4
 | 
			
		||||
@@ -8,14 +8,37 @@ build:
 | 
			
		||||
  stage: build
 | 
			
		||||
  needs: []
 | 
			
		||||
  script:
 | 
			
		||||
    - pacman -Syu --noconfirm m4 make openssh subversion rsync arch-install-scripts git bzr mercurial diffutils asciidoc
 | 
			
		||||
    - pacman -Syu --noconfirm m4 make openssh subversion rsync arch-install-scripts git bzr mercurial diffutils asciidoctor
 | 
			
		||||
    - make PREFIX=/usr
 | 
			
		||||
    - make PREFIX=/usr DESTDIR=build install
 | 
			
		||||
 | 
			
		||||
check:
 | 
			
		||||
lint:
 | 
			
		||||
  stage: test
 | 
			
		||||
  needs: []
 | 
			
		||||
  script:
 | 
			
		||||
    - pacman -Syu --noconfirm m4 make openssh subversion rsync arch-install-scripts git bzr mercurial diffutils asciidoc shellcheck
 | 
			
		||||
    - pacman -Syu --noconfirm m4 make openssh subversion rsync arch-install-scripts git bzr mercurial diffutils asciidoctor shellcheck
 | 
			
		||||
    - make check || true
 | 
			
		||||
    - SHELLCHECK_OPTS="-S error" make check
 | 
			
		||||
 | 
			
		||||
test:
 | 
			
		||||
  stage: test
 | 
			
		||||
  needs: []
 | 
			
		||||
  script:
 | 
			
		||||
    - pacman -Syu --noconfirm m4 make openssh subversion rsync arch-install-scripts git bzr mercurial diffutils coreutils asciidoctor shellcheck nvchecker bats
 | 
			
		||||
    - make test BATS_EXTRA_ARGS='--formatter junit'
 | 
			
		||||
  artifacts:
 | 
			
		||||
    reports:
 | 
			
		||||
      junit: build/coverage/bats-report.xml
 | 
			
		||||
 | 
			
		||||
coverage:
 | 
			
		||||
  stage: test
 | 
			
		||||
  needs: []
 | 
			
		||||
  script:
 | 
			
		||||
    - pacman -Syu --noconfirm m4 make openssh subversion rsync arch-install-scripts git bzr mercurial diffutils coreutils asciidoctor shellcheck nvchecker bats kcov jq
 | 
			
		||||
    - make coverage
 | 
			
		||||
  coverage: '/Percent covered\s+\d+\.\d+/'
 | 
			
		||||
  artifacts:
 | 
			
		||||
    reports:
 | 
			
		||||
      coverage_report:
 | 
			
		||||
        coverage_format: cobertura
 | 
			
		||||
        path: build/coverage/bats.*/cobertura.xml
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
SHELL=/bin/bash
 | 
			
		||||
SHELL=/bin/bash -o pipefail
 | 
			
		||||
 | 
			
		||||
V=1.0.3
 | 
			
		||||
V=1.2.1
 | 
			
		||||
BUILDTOOLVER ?= $(V)
 | 
			
		||||
 | 
			
		||||
PREFIX = /usr/local
 | 
			
		||||
@@ -16,6 +16,7 @@ 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/*)
 | 
			
		||||
GIT_CONFIGS = $(wildcard config/git/*)
 | 
			
		||||
SETARCH_ALIASES = $(wildcard config/setarch-aliases.d/*)
 | 
			
		||||
MANS = $(addprefix $(BUILDDIR)/,$(patsubst %.asciidoc,%,$(wildcard doc/man/*.asciidoc)))
 | 
			
		||||
 | 
			
		||||
@@ -51,6 +52,13 @@ ARCHBUILD_LINKS = \
 | 
			
		||||
COMPLETIONS = $(addprefix $(BUILDDIR)/,$(patsubst %.in,%,$(wildcard contrib/completion/*/*)))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
CASES ?= test/case
 | 
			
		||||
JOBS ?= $(shell nproc)
 | 
			
		||||
BATS_EXTRA_ARGS ?=
 | 
			
		||||
BATS_ARGS ?= --jobs $(JOBS) $(BATS_EXTRA_ARGS) --verbose-run
 | 
			
		||||
COVERAGE_DIR ?= $(BUILDDIR)/coverage
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
all: binprogs library conf completion man
 | 
			
		||||
binprogs: $(BINPROGS)
 | 
			
		||||
library: $(LIBRARY)
 | 
			
		||||
@@ -91,15 +99,18 @@ $(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
 | 
			
		||||
$(BUILDDIR)/doc/man/%: doc/man/%.asciidoc 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=$(DATADIR) $<
 | 
			
		||||
	@asciidoctor --backend=manpage --destination-dir=$(BUILDDIR)/doc/man --attribute pkgdatadir=$(DATADIR) $<
 | 
			
		||||
 | 
			
		||||
conf:
 | 
			
		||||
	@install -d $(BUILDDIR)/makepkg.conf.d $(BUILDDIR)/pacman.conf.d
 | 
			
		||||
	@install -d $(BUILDDIR)/makepkg.conf.d
 | 
			
		||||
	@cp -a $(MAKEPKG_CONFIGS) $(BUILDDIR)/makepkg.conf.d
 | 
			
		||||
	@install -d $(BUILDDIR)/pacman.conf.d
 | 
			
		||||
	@cp -a $(PACMAN_CONFIGS) $(BUILDDIR)/pacman.conf.d
 | 
			
		||||
	@install -d $(BUILDDIR)/git.conf.d
 | 
			
		||||
	@cp -a $(GIT_CONFIGS) $(BUILDDIR)/git.conf.d
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	rm -rf $(BUILDDIR)
 | 
			
		||||
@@ -112,6 +123,7 @@ install: all
 | 
			
		||||
	install -m0755 ${BINPROGS} $(DESTDIR)$(PREFIX)/bin
 | 
			
		||||
	install -dm0755 $(DESTDIR)$(DATADIR)/lib
 | 
			
		||||
	cp -ra $(BUILDDIR)/lib/* $(DESTDIR)$(DATADIR)/lib
 | 
			
		||||
	cp -a $(BUILDDIR)/git.conf.d -t $(DESTDIR)$(DATADIR)
 | 
			
		||||
	for conf in $(notdir $(MAKEPKG_CONFIGS)); do install -Dm0644 $(BUILDDIR)/makepkg.conf.d/$$conf $(DESTDIR)$(DATADIR)/makepkg.conf.d/$${conf##*/}; done
 | 
			
		||||
	for conf in $(notdir $(PACMAN_CONFIGS)); do install -Dm0644 $(BUILDDIR)/pacman.conf.d/$$conf $(DESTDIR)$(DATADIR)/pacman.conf.d/$${conf##*/}; done
 | 
			
		||||
	for a in ${SETARCH_ALIASES}; do install -m0644 $$a -t $(DESTDIR)$(DATADIR)/setarch-aliases.d; done
 | 
			
		||||
@@ -129,6 +141,7 @@ uninstall:
 | 
			
		||||
	for f in $(notdir $(BINPROGS)); do rm -f $(DESTDIR)$(PREFIX)/bin/$$f; done
 | 
			
		||||
	for f in $(notdir $(LIBRARY)); do rm -f $(DESTDIR)$(DATADIR)/lib/$$f; done
 | 
			
		||||
	rm -rf $(DESTDIR)$(DATADIR)/lib
 | 
			
		||||
	rm -rf $(DESTDIR)$(DATADIR)/git.conf.d
 | 
			
		||||
	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
 | 
			
		||||
@@ -146,6 +159,7 @@ uninstall:
 | 
			
		||||
		$(DESTDIR)$(DATADIR)
 | 
			
		||||
 | 
			
		||||
tag:
 | 
			
		||||
	git cliff --strip=all --unreleased
 | 
			
		||||
	@echo "current version: v$(V)"
 | 
			
		||||
	@read -r -p "tag version: v" VERSION && \
 | 
			
		||||
	sed -E "s|^V=.+|V=$$VERSION|" -i Makefile && \
 | 
			
		||||
@@ -153,14 +167,25 @@ tag:
 | 
			
		||||
	git tag --sign --message "Version v$$VERSION" v$$VERSION
 | 
			
		||||
 | 
			
		||||
release: dist
 | 
			
		||||
	glab release create v$(RELEASE) devtools-$(RELEASE).tar.gz*
 | 
			
		||||
	git push --tags origin master
 | 
			
		||||
	git cliff --version >/dev/null
 | 
			
		||||
	GITLAB_HOST=gitlab.archlinux.org glab release create v$(V) devtools-$(V).tar.gz* --milestone v$(V) --notes-file <(git cliff --strip=all --latest)
 | 
			
		||||
 | 
			
		||||
dist:
 | 
			
		||||
	git archive --format=tar --prefix=devtools-$(V)/ v$(V) | gzip > devtools-$(V).tar.gz
 | 
			
		||||
	gpg --detach-sign --use-agent devtools-$(V).tar.gz
 | 
			
		||||
 | 
			
		||||
test: binprogs library conf completion man
 | 
			
		||||
	@mkdir -p $(COVERAGE_DIR)
 | 
			
		||||
	bats $(BATS_ARGS) $(CASES) | tee $(COVERAGE_DIR)/bats-report.xml
 | 
			
		||||
 | 
			
		||||
coverage: binprogs library conf completion man
 | 
			
		||||
	kcov --include-path=src $(COVERAGE_DIR) bats $(BATS_ARGS) $(CASES)
 | 
			
		||||
	jq -r '. | ["Percent covered", .percent_covered], ["Covered lines", .covered_lines], ["Total lines", .total_lines], ["Percent low", .percent_low], ["Percent high", .percent_high] | @tsv' \
 | 
			
		||||
		$(COVERAGE_DIR)/bats.*/coverage.json
 | 
			
		||||
 | 
			
		||||
check: $(BINPROGS_SRC) $(LIBRARY_SRC) contrib/completion/bash/devtools.in config/makepkg/x86_64.conf contrib/makepkg/PKGBUILD.proto
 | 
			
		||||
	shellcheck $^
 | 
			
		||||
 | 
			
		||||
.PHONY: all binprogs library completion conf man clean install uninstall tag dist upload check
 | 
			
		||||
.PHONY: all binprogs library completion conf man clean install uninstall tag dist upload test coverage check
 | 
			
		||||
.DELETE_ON_ERROR:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								README.md
									
									
									
									
									
								
							@@ -23,6 +23,34 @@ will automatically build the project and proxy all calls to the local build dire
 | 
			
		||||
./test/bin/pkgctl --help
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Commit messages
 | 
			
		||||
 | 
			
		||||
All commits must follow [conventional commits](https://www.conventionalcommits.org).
 | 
			
		||||
 | 
			
		||||
The following groups are allowed:
 | 
			
		||||
 | 
			
		||||
- chore
 | 
			
		||||
- feat
 | 
			
		||||
- fix
 | 
			
		||||
- doc
 | 
			
		||||
- perf
 | 
			
		||||
- test
 | 
			
		||||
 | 
			
		||||
To override the scope for the changelog entry use the `Component:` trailer.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
feat(db): yay mega cool feature
 | 
			
		||||
 | 
			
		||||
Very long and useful description.
 | 
			
		||||
 | 
			
		||||
Fixes #1
 | 
			
		||||
Fixes #2
 | 
			
		||||
 | 
			
		||||
Component: pkgctl db remove
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Releasing
 | 
			
		||||
 | 
			
		||||
1. bump the version in the Makefile
 | 
			
		||||
@@ -41,7 +69,9 @@ will automatically build the project and proxy all calls to the local build dire
 | 
			
		||||
- bash
 | 
			
		||||
- binutils
 | 
			
		||||
- coreutils
 | 
			
		||||
- curl
 | 
			
		||||
- diffutils
 | 
			
		||||
- expac
 | 
			
		||||
- fakeroot
 | 
			
		||||
- findutils
 | 
			
		||||
- grep
 | 
			
		||||
@@ -58,11 +88,17 @@ will automatically build the project and proxy all calls to the local build dire
 | 
			
		||||
- mercurial
 | 
			
		||||
- subversion
 | 
			
		||||
 | 
			
		||||
### Optional Dependencies
 | 
			
		||||
 | 
			
		||||
- bat (pretty printing)
 | 
			
		||||
- nvchecker (version checking)
 | 
			
		||||
 | 
			
		||||
### Development Dependencies
 | 
			
		||||
 | 
			
		||||
- asciidoc
 | 
			
		||||
- asciidoctor
 | 
			
		||||
- make
 | 
			
		||||
- shellcheck
 | 
			
		||||
- bats
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								cliff.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								cliff.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
[changelog]
 | 
			
		||||
header = "# Changelog\n\n"
 | 
			
		||||
body = """
 | 
			
		||||
{%- if version -%}
 | 
			
		||||
    ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
 | 
			
		||||
{%- else -%}
 | 
			
		||||
    ## [unreleased]
 | 
			
		||||
{%- endif %}
 | 
			
		||||
{% for group, commits in commits | group_by(attribute="group") %}
 | 
			
		||||
    ### {{ group | upper_first }}
 | 
			
		||||
    {% for commit in commits | sort(attribute="message") %}
 | 
			
		||||
		- {% set component = commit.footers | filter(attribute="token", value="Component") | map(attribute="value") | join(sep=", ") %}
 | 
			
		||||
		{%- if component %}{{ component }}: {% elif commit.scope %}{{ commit.scope }}: {% endif %}
 | 
			
		||||
		{{- commit.message | upper_first }}
 | 
			
		||||
		{%- if commit.breaking %} (breaking){% endif %}
 | 
			
		||||
		{%- set fixes = commit.footers | filter(attribute="token", value="Fixes") %}
 | 
			
		||||
		{%- for fix in fixes %}{% if fix.separator|trim == '#' %}{{ fix.separator }}{{ fix.value }}{% endif %}{% endfor %}
 | 
			
		||||
    {%- endfor %}
 | 
			
		||||
{% endfor %}
 | 
			
		||||
 | 
			
		||||
"""
 | 
			
		||||
footer = ""
 | 
			
		||||
 | 
			
		||||
# remove the leading and trailing whitespaces from the template
 | 
			
		||||
trim = true
 | 
			
		||||
 | 
			
		||||
[git]
 | 
			
		||||
# allow only conventional commits
 | 
			
		||||
# https://www.conventionalcommits.org
 | 
			
		||||
conventional_commits = true
 | 
			
		||||
# regex for parsing and grouping commits
 | 
			
		||||
commit_parsers = [
 | 
			
		||||
    { message = "^chore\\(release\\): version", skip = true},
 | 
			
		||||
    { message = "^feat", group = "Features"},
 | 
			
		||||
    { message = "^fix", group = "Bug Fixes"},
 | 
			
		||||
    { message = "^doc", group = "Documentation"},
 | 
			
		||||
    { message = "^perf", group = "Performance"},
 | 
			
		||||
    { message = "^test", group = "Testing"},
 | 
			
		||||
    { message = "^chore", group = "Miscellaneous Tasks"},
 | 
			
		||||
    { body = ".*security", group = "Security"},
 | 
			
		||||
]
 | 
			
		||||
# filter out the commits that are not matched by commit parsers
 | 
			
		||||
filter_commits = false
 | 
			
		||||
# regex for matching git tags
 | 
			
		||||
tag_pattern = "^v[0-9]+\\.[0-9]+\\.[0-9]+.*"
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/applypatch-msg
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/applypatch-msg
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/commit-msg
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/commit-msg
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/post-applypatch
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/post-applypatch
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/post-checkout
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/post-checkout
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/post-commit
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/post-commit
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/post-merge
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/post-merge
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/pre-applypatch
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/pre-applypatch
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/pre-commit
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/pre-commit
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/pre-merge-commit
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/pre-merge-commit
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/pre-push
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/pre-push
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/pre-rebase
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/pre-rebase
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										1
									
								
								config/git/template/hooks/prepare-commit-msg
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								config/git/template/hooks/prepare-commit-msg
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
							
								
								
									
										28
									
								
								config/git/template/info/exclude
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								config/git/template/info/exclude
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
/pkg
 | 
			
		||||
/src
 | 
			
		||||
/*/
 | 
			
		||||
!/keys/
 | 
			
		||||
 | 
			
		||||
/*.log
 | 
			
		||||
/*.tar.*
 | 
			
		||||
/*.tar
 | 
			
		||||
/*.tgz
 | 
			
		||||
/*.zst
 | 
			
		||||
/*.gz
 | 
			
		||||
/*.xz
 | 
			
		||||
/*.bz2
 | 
			
		||||
/*.zip
 | 
			
		||||
/*.xpi
 | 
			
		||||
/*.jar
 | 
			
		||||
/*.whl
 | 
			
		||||
/*.war
 | 
			
		||||
/*.deb
 | 
			
		||||
/*.ttf
 | 
			
		||||
/*.dat
 | 
			
		||||
/*.iso
 | 
			
		||||
/*.asc
 | 
			
		||||
/*.sig
 | 
			
		||||
/*.signature
 | 
			
		||||
/*.sign
 | 
			
		||||
/*.SHA256SUMS
 | 
			
		||||
/*.sha256
 | 
			
		||||
@@ -25,7 +25,7 @@ DLAGENTS=('file::/usr/bin/curl -qgC - -o %o %u'
 | 
			
		||||
 | 
			
		||||
#-- The package required by makepkg to download VCS sources
 | 
			
		||||
#  Format: 'protocol::package'
 | 
			
		||||
VCSCLIENTS=('bzr::bzr'
 | 
			
		||||
VCSCLIENTS=('bzr::breezy'
 | 
			
		||||
            'fossil::fossil'
 | 
			
		||||
            'git::git'
 | 
			
		||||
            'hg::mercurial'
 | 
			
		||||
@@ -41,12 +41,14 @@ CHOST="x86_64-pc-linux-gnu"
 | 
			
		||||
#-- Compiler and Linker Flags
 | 
			
		||||
#CPPFLAGS=""
 | 
			
		||||
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions \
 | 
			
		||||
        -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security \
 | 
			
		||||
        -fstack-clash-protection -fcf-protection"
 | 
			
		||||
        -Wp,-D_FORTIFY_SOURCE=3 -Wformat -Werror=format-security \
 | 
			
		||||
        -fstack-clash-protection -fcf-protection \
 | 
			
		||||
        -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"
 | 
			
		||||
CXXFLAGS="$CFLAGS -Wp,-D_GLIBCXX_ASSERTIONS"
 | 
			
		||||
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
 | 
			
		||||
LDFLAGS="-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now \
 | 
			
		||||
         -Wl,-z,pack-relative-relocs"
 | 
			
		||||
LTOFLAGS="-flto=auto"
 | 
			
		||||
RUSTFLAGS=""
 | 
			
		||||
RUSTFLAGS="-Cforce-frame-pointers=yes"
 | 
			
		||||
#-- Make Flags: change this for DistCC/SMP systems
 | 
			
		||||
#MAKEFLAGS="-j2"
 | 
			
		||||
#-- Debugging flags
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ DLAGENTS=('file::/usr/bin/curl -qgC - -o %o %u'
 | 
			
		||||
 | 
			
		||||
#-- The package required by makepkg to download VCS sources
 | 
			
		||||
#  Format: 'protocol::package'
 | 
			
		||||
VCSCLIENTS=('bzr::bzr'
 | 
			
		||||
VCSCLIENTS=('bzr::breezy'
 | 
			
		||||
            'fossil::fossil'
 | 
			
		||||
            'git::git'
 | 
			
		||||
            'hg::mercurial'
 | 
			
		||||
@@ -41,12 +41,14 @@ CHOST="x86_64-pc-linux-gnu"
 | 
			
		||||
#-- Compiler and Linker Flags
 | 
			
		||||
#CPPFLAGS=""
 | 
			
		||||
CFLAGS="-march=x86-64-v3 -mtune=generic -O2 -pipe -fno-plt -fexceptions \
 | 
			
		||||
        -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security \
 | 
			
		||||
        -fstack-clash-protection -fcf-protection"
 | 
			
		||||
        -Wp,-D_FORTIFY_SOURCE=3 -Wformat -Werror=format-security \
 | 
			
		||||
        -fstack-clash-protection -fcf-protection \
 | 
			
		||||
        -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"
 | 
			
		||||
CXXFLAGS="$CFLAGS -Wp,-D_GLIBCXX_ASSERTIONS"
 | 
			
		||||
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now"
 | 
			
		||||
LDFLAGS="-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now \
 | 
			
		||||
         -Wl,-z,pack-relative-relocs"
 | 
			
		||||
LTOFLAGS="-flto=auto"
 | 
			
		||||
RUSTFLAGS=""
 | 
			
		||||
RUSTFLAGS="-Cforce-frame-pointers=yes"
 | 
			
		||||
#-- Make Flags: change this for DistCC/SMP systems
 | 
			
		||||
#MAKEFLAGS="-j2"
 | 
			
		||||
#-- Debugging flags
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										112
									
								
								config/pacman/universe.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								config/pacman/universe.conf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,112 @@
 | 
			
		||||
#
 | 
			
		||||
# /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.
 | 
			
		||||
 | 
			
		||||
[gnome-unstable]
 | 
			
		||||
Include = /etc/pacman.d/mirrorlist
 | 
			
		||||
 | 
			
		||||
[kde-unstable]
 | 
			
		||||
Include = /etc/pacman.d/mirrorlist
 | 
			
		||||
 | 
			
		||||
[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
 | 
			
		||||
 | 
			
		||||
# If you want to run 32 bit applications on your x86_64 system,
 | 
			
		||||
# enable the multilib repositories as required here.
 | 
			
		||||
[multilib-staging]
 | 
			
		||||
Include = /etc/pacman.d/mirrorlist
 | 
			
		||||
 | 
			
		||||
[multilib-testing]
 | 
			
		||||
Include = /etc/pacman.d/mirrorlist
 | 
			
		||||
 | 
			
		||||
[multilib]
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										83
									
								
								config/pacman/unstable.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								config/pacman/unstable.conf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
#
 | 
			
		||||
# /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.
 | 
			
		||||
 | 
			
		||||
[gnome-unstable]
 | 
			
		||||
Include = /etc/pacman.d/mirrorlist
 | 
			
		||||
 | 
			
		||||
[kde-unstable]
 | 
			
		||||
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
 | 
			
		||||
@@ -3,12 +3,17 @@
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
 | 
			
		||||
# shellcheck source=src/lib/valid-build-install.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.sh
 | 
			
		||||
# 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
 | 
			
		||||
# shellcheck source=src/lib/valid-inspect.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh
 | 
			
		||||
# shellcheck source=src/lib/valid-search.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-search.sh
 | 
			
		||||
 | 
			
		||||
_binary_arch=${_arch[*]:0:-1}
 | 
			
		||||
_colors=(never always auto)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -22,15 +27,19 @@ _makechrootpkg_args=(
 | 
			
		||||
	-I
 | 
			
		||||
	-l
 | 
			
		||||
	-n
 | 
			
		||||
	-t
 | 
			
		||||
	-T
 | 
			
		||||
	-U
 | 
			
		||||
	-x
 | 
			
		||||
)
 | 
			
		||||
_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_t_opts() { _filedir -d; }
 | 
			
		||||
_makechrootpkg_args_U_opts() { :; }
 | 
			
		||||
_makechrootpkg_args_x_opts() { _devtools_completions_inspect; }
 | 
			
		||||
_makechrootpkg() { __devtools_complete _makechrootpkg; }
 | 
			
		||||
complete -F _makechrootpkg makechrootpkg
 | 
			
		||||
 | 
			
		||||
@@ -38,6 +47,7 @@ complete -F _makechrootpkg makechrootpkg
 | 
			
		||||
_makerepropkg_args=(
 | 
			
		||||
	-h
 | 
			
		||||
	-d
 | 
			
		||||
	-n
 | 
			
		||||
	-c
 | 
			
		||||
	-M
 | 
			
		||||
)
 | 
			
		||||
@@ -53,12 +63,14 @@ _mkarchroot_args=(
 | 
			
		||||
	-C
 | 
			
		||||
	-M
 | 
			
		||||
	-c
 | 
			
		||||
	-f
 | 
			
		||||
	-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_args_f_opts() { _filedir -d; }
 | 
			
		||||
_mkarchroot_opts() {
 | 
			
		||||
	local args
 | 
			
		||||
	args=$(__pkgctl_word_count_after_subcommand)
 | 
			
		||||
@@ -119,7 +131,7 @@ _offload_build_args=(
 | 
			
		||||
)
 | 
			
		||||
_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__arch_opts() { _devtools_completions_binary_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; }
 | 
			
		||||
@@ -128,12 +140,14 @@ complete -F _offload_build offload-build
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_pkgctl_cmds=(
 | 
			
		||||
	aur
 | 
			
		||||
	auth
 | 
			
		||||
	build
 | 
			
		||||
	db
 | 
			
		||||
	diff
 | 
			
		||||
	release
 | 
			
		||||
	repo
 | 
			
		||||
	search
 | 
			
		||||
	version
 | 
			
		||||
)
 | 
			
		||||
_pkgctl_args=(
 | 
			
		||||
@@ -169,10 +183,14 @@ _pkgctl_build_args=(
 | 
			
		||||
	-o --offload
 | 
			
		||||
	-c --clean
 | 
			
		||||
	-w --worker
 | 
			
		||||
	--inspect
 | 
			
		||||
	-I --install-to-chroot
 | 
			
		||||
	-i --install-to-host
 | 
			
		||||
 | 
			
		||||
	--pkgver
 | 
			
		||||
	--pkgrel
 | 
			
		||||
	--rebuild
 | 
			
		||||
	--update-checksums
 | 
			
		||||
	-e --edit
 | 
			
		||||
 | 
			
		||||
	-r --release
 | 
			
		||||
@@ -181,15 +199,23 @@ _pkgctl_build_args=(
 | 
			
		||||
 | 
			
		||||
	-h --help
 | 
			
		||||
)
 | 
			
		||||
_pkgctl_build_args__arch_opts() { _devtools_completions_arch; }
 | 
			
		||||
_pkgctl_build_args__arch_opts() { _devtools_completions_binary_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__inspect_opts() { _devtools_completions_inspect; }
 | 
			
		||||
_pkgctl_build_args__pkgver_opts() { :; }
 | 
			
		||||
_pkgctl_build_args__pkgrel_opts() { :; }
 | 
			
		||||
_pkgctl_build_args__install_to_host_opts() { _pkgctl_build_completions_install_mode; }
 | 
			
		||||
_pkgctl_build_args_i_opts() { _pkgctl_build_args__install_to_host_opts; }
 | 
			
		||||
_pkgctl_build_args__install_to_chroot_opts() { _makechrootpkg_args_I_opts; }
 | 
			
		||||
_pkgctl_build_args_I_opts() { _pkgctl_build_args__install_to_chroot_opts; }
 | 
			
		||||
_pkgctl_build_args__message_opts() { :; }
 | 
			
		||||
_pkgctl_build_args_m_opts() { _pkgctl_build_args__message_opts; }
 | 
			
		||||
_pkgctl_build_opts() { _filedir -d; }
 | 
			
		||||
_pkgctl_build_completions_install_mode() {
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_BUILD_INSTALL[*]}" -- "$cur")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_pkgctl_db_cmds=(
 | 
			
		||||
@@ -218,9 +244,13 @@ _pkgctl_db_move_opts() {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_pkgctl_db_remove_args=(
 | 
			
		||||
	--partial
 | 
			
		||||
	--noconfirm
 | 
			
		||||
	-a --arch
 | 
			
		||||
	-h --help
 | 
			
		||||
)
 | 
			
		||||
_pkgctl_db_remove_args__arch_opts() { _devtools_completions_binary_arch; }
 | 
			
		||||
_pkgctl_db_remove_args_a_opts() { _pkgctl_db_remove_args__arch_opts; }
 | 
			
		||||
_pkgctl_db_remove_opts() {
 | 
			
		||||
	local subcommand args
 | 
			
		||||
	subcommand=(db remove)
 | 
			
		||||
@@ -253,8 +283,20 @@ _pkgctl_release_args__repo_opts() { _devtools_completions_repo; }
 | 
			
		||||
_pkgctl_release_args_r_opts() { _pkgctl_release_args__repo_opts; }
 | 
			
		||||
_pkgctl_release_opts() { _filedir -d; }
 | 
			
		||||
 | 
			
		||||
_pkgctl_aur_cmds=(
 | 
			
		||||
	drop-from-repo
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_aur_drop_from_repo_args=(
 | 
			
		||||
	--no-disown
 | 
			
		||||
	-f --force
 | 
			
		||||
	-h --help
 | 
			
		||||
)
 | 
			
		||||
_pkgctl_aur_drop_from_repo_opts() { _filedir -d; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_pkgctl_repo_cmds=(
 | 
			
		||||
	clean
 | 
			
		||||
	clone
 | 
			
		||||
	configure
 | 
			
		||||
	create
 | 
			
		||||
@@ -280,6 +322,12 @@ _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_clean_args=(
 | 
			
		||||
	-i --interactive
 | 
			
		||||
	-n --dry-run
 | 
			
		||||
	-h --help
 | 
			
		||||
)
 | 
			
		||||
_pkgctl_repo_clean_opts() { _filedir -d; }
 | 
			
		||||
 | 
			
		||||
_pkgctl_repo_configure_args=(
 | 
			
		||||
	--protocol
 | 
			
		||||
@@ -297,7 +345,6 @@ _pkgctl_repo_create_args=(
 | 
			
		||||
	-h --help
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_pkgctl_repo_switch_args=(
 | 
			
		||||
	--discard-changes
 | 
			
		||||
	-f --force
 | 
			
		||||
@@ -315,13 +362,57 @@ _pkgctl_repo_switch_opts() {
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_cmds=(
 | 
			
		||||
	check
 | 
			
		||||
	setup
 | 
			
		||||
	upgrade
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_check_args=(
 | 
			
		||||
	-v --verbose
 | 
			
		||||
	-h --help
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_check_opts() { _filedir -d; }
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_setup_args=(
 | 
			
		||||
	--prefer-platform-api
 | 
			
		||||
	--url
 | 
			
		||||
	--no-check
 | 
			
		||||
	-f --force
 | 
			
		||||
	-h --help
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_setup_opts() { _filedir -d; }
 | 
			
		||||
_pkgctl_version_setup_args__url_opts() { :; }
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_upgrade_args=(
 | 
			
		||||
	--no-update-checksums
 | 
			
		||||
	-v --verbose
 | 
			
		||||
	-h --help
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_upgrade_opts() { _filedir -d; }
 | 
			
		||||
 | 
			
		||||
_pkgctl_repo_web_args=(
 | 
			
		||||
	--print
 | 
			
		||||
	-h --help
 | 
			
		||||
)
 | 
			
		||||
_pkgctl_repo_web_opts() { _filedir -d; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_pkgctl_search_args=(
 | 
			
		||||
	--no-default-filter
 | 
			
		||||
	--json
 | 
			
		||||
	-F --format
 | 
			
		||||
	-N --no-line-number
 | 
			
		||||
	-h --help
 | 
			
		||||
)
 | 
			
		||||
_pkgctl_search_opts() { :; }
 | 
			
		||||
_pkgctl_search_args__format_opts() { _devtools_completions_search_format; }
 | 
			
		||||
_pkgctl_search_args_F_opts() { _devtools_completions_search_format; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_pkgctl_diff_args=(
 | 
			
		||||
	-l --list
 | 
			
		||||
	-d --diffoscope
 | 
			
		||||
@@ -355,14 +446,17 @@ _devtools_completions_color() {
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${_colors[*]}" -- "$cur")
 | 
			
		||||
}
 | 
			
		||||
_devtools_completions_arch() {
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${_arch[*]}" -- "$cur")
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_ARCHES[*]}" -- "$cur")
 | 
			
		||||
}
 | 
			
		||||
_devtools_completions_binary_arch() {
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_BINARY_ARCHES[*]}" -- "$cur")
 | 
			
		||||
}
 | 
			
		||||
_devtools_completions_repo() {
 | 
			
		||||
	local optional=${1:-}
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${optional} ${_repos[*]}" -- "$cur")
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${optional} ${DEVTOOLS_VALID_REPOS[*]}" -- "$cur")
 | 
			
		||||
}
 | 
			
		||||
_devtools_completions_build_repo() {
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${_build_repos[*]}" -- "$cur")
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_BUILDREPOS[*]}" -- "$cur")
 | 
			
		||||
}
 | 
			
		||||
_devtools_completions_all_packages() {
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "$(pacman -Sql)" -- "$cur")
 | 
			
		||||
@@ -370,6 +464,12 @@ _devtools_completions_all_packages() {
 | 
			
		||||
_devtools_completions_protocol() {
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "https" -- "$cur")
 | 
			
		||||
}
 | 
			
		||||
_devtools_completions_inspect() {
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${DEVTOOLS_VALID_INSPECT_MODES[*]}" -- "$cur")
 | 
			
		||||
}
 | 
			
		||||
_devtools_completions_search_format() {
 | 
			
		||||
	mapfile -t COMPREPLY < <(compgen -W "${valid_search_output_format[*]}" -- "$cur")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__devtools_complete() {
 | 
			
		||||
	local service=$1
 | 
			
		||||
 
 | 
			
		||||
@@ -3,12 +3,17 @@
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
 | 
			
		||||
# shellcheck source=src/lib/valid-build-install.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.sh
 | 
			
		||||
# 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
 | 
			
		||||
# shellcheck source=src/lib/valid-inspect.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh
 | 
			
		||||
# shellcheck source=src/lib/valid-search.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-search.sh
 | 
			
		||||
 | 
			
		||||
_binary_arch=${_arch[*]:0:-1}
 | 
			
		||||
_colors=(never always auto)
 | 
			
		||||
 | 
			
		||||
_archbuild_args=(
 | 
			
		||||
@@ -35,18 +40,21 @@ _pkgctl_auth_status_args=(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_build_args=(
 | 
			
		||||
	"--arch=[Specify architectures to build for (disables auto-detection)]:arch:($_arch[*])"
 | 
			
		||||
	"--repo=[Specify a target repository (disables auto-detection)]:repo:($_repos[*])"
 | 
			
		||||
	"--arch[Specify architectures to build for (disables auto-detection)]:arch:($DEVTOOLS_VALID_BINARY_ARCHES[*])"
 | 
			
		||||
	"--repo[Specify a target repository (disables auto-detection)]:repo:($DEVTOOLS_VALID_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.*(.)"'
 | 
			
		||||
	"--inspect[Spawn an interactive shell to inspect the chroot (never, always, failure)]:inspect:($DEVTOOLS_VALID_INSPECT_MODES[*])"
 | 
			
		||||
	'*'{-I,--install-to-chroot}'[Install a package to the working copy of the chroot]:target:_files -g "*.pkg.tar.*(.)"'
 | 
			
		||||
	'*'{-i,--install-to-host}"[Install the built packages to the host system]:mode:($DEVTOOLS_VALID_BUILD_INSTALL[*])"
 | 
			
		||||
	'(-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]'
 | 
			
		||||
	'--update-checksums[Force computation and update of the checksums (disables auto-detection)]'
 | 
			
		||||
	'(-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:"
 | 
			
		||||
@@ -64,15 +72,17 @@ _pkgctl_db_cmds=(
 | 
			
		||||
 | 
			
		||||
_pkgctl_db_move_args=(
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
	"1:src-repo:($_repos[*])"
 | 
			
		||||
	"2:target-repo:($_repos[*])"
 | 
			
		||||
	"1:src-repo:($DEVTOOLS_VALID_REPOS[*])"
 | 
			
		||||
	"2:target-repo:($DEVTOOLS_VALID_REPOS[*])"
 | 
			
		||||
	'*:pkgbase:_devtools_completions_all_packages'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_db_remove_args=(
 | 
			
		||||
	'(-a --arch=)'{-a,--arch=}"[Override the architecture (disables auto-detection)]:arch:($_arch[*])"
 | 
			
		||||
	'--partial[Remove only partial pkgnames from a split package]'
 | 
			
		||||
	'--noconfirm[Bypass any confirmation messages, should only be used with caution]'
 | 
			
		||||
	'(-a --arch)'{-a,--arch}"[Override the architecture (disables auto-detection)]:arch:($DEVTOOLS_VALID_BINARY_ARCHES[*])"
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
	"1:repo:($_repos[*])"
 | 
			
		||||
	"1:repo:($DEVTOOLS_VALID_REPOS[*])"
 | 
			
		||||
	'*:pkgbase:_devtools_completions_all_packages'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -82,7 +92,7 @@ _pkgctl_db_update_args=(
 | 
			
		||||
 | 
			
		||||
_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[*])"
 | 
			
		||||
	'(-r --repo=)'{-r,--repo=}"[Specify a target repository for new packages]:repo:($DEVTOOLS_VALID_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]'
 | 
			
		||||
@@ -90,8 +100,21 @@ _pkgctl_release_args=(
 | 
			
		||||
	'*:git_dir:_files -/'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_aur_cmds=(
 | 
			
		||||
	"pkgctl aur command"
 | 
			
		||||
	"drop-from-repo[Drop a package from the official repository to the AUR]"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_aur_drop_from_repo_args=(
 | 
			
		||||
	'(-f --force)'{-f,--force}'[Force push to the AUR overwriting the remote repository]'
 | 
			
		||||
	'--no-disown[Do not disown the package on the AUR]'
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
	'*:git_dir:_files -/'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_repo_cmds=(
 | 
			
		||||
	"pkgctl repo command"
 | 
			
		||||
	"clean[Remove untracked files from the working tree]"
 | 
			
		||||
	"clone[Clone a package repository]"
 | 
			
		||||
	"configure[Configure a clone according to distro specs]"
 | 
			
		||||
	"create[Create a new GitLab package repository]"
 | 
			
		||||
@@ -106,6 +129,13 @@ _pkgctl_repo_switch_args=(
 | 
			
		||||
	'*:git_dir:_files -/'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_repo_clean_args=(
 | 
			
		||||
	'(-i --interactive)'{-i,--interactive}'[Show what would be done and clean files interactively]'
 | 
			
		||||
	'(-n --dry-run)'{-n,--dry-run}"[Don't remove anything, just show what would be done]"
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
	'*: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)'
 | 
			
		||||
@@ -130,15 +160,25 @@ _pkgctl_repo_create_args=(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_repo_web_args=(
 | 
			
		||||
	'--print[Print the url instead of opening it with xdg-open]'
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
	'*:git_dir:_files -/'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_search_args=(
 | 
			
		||||
	'--no-default-filter[Do not apply default filter (like -path:keys/pgp/*.asc)]'
 | 
			
		||||
	'--json[Enable printing results in JSON]'
 | 
			
		||||
	'(-F --format)'{-F,--format}"[Controls the formatting of the results]:format:($valid_search_output_format[*])"
 | 
			
		||||
	'(-N --no-line-number)'{-N,--no-line-number}"[Don't show line numbers when formatting results]"
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
	'1:query'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_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(.)"'
 | 
			
		||||
	'-c[Set pacman cache]:pacman_cache:_files -/'
 | 
			
		||||
	'-f[Copy file from the host to the chroot]:copy_file:_files'
 | 
			
		||||
	'*-c[Set pacman cache]:pacman_cache:_files -/'
 | 
			
		||||
	'*-f[Copy file from the host to the chroot]:copy_file:_files'
 | 
			
		||||
	'-s[Do not run setarch]'
 | 
			
		||||
	'-h[Display usage]'
 | 
			
		||||
	'1:chroot_dir:_files -/'
 | 
			
		||||
@@ -146,14 +186,14 @@ _arch_nspawn_args=(
 | 
			
		||||
 | 
			
		||||
_archrelease_args=(
 | 
			
		||||
	'-f[Force release without checks]'
 | 
			
		||||
	"*:arch:($_tags[*])"
 | 
			
		||||
	"*:arch:($DEVTOOLS_VALID_TAGS[*])"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_commitpkg_args=(
 | 
			
		||||
	'-f[Force release without checks]'
 | 
			
		||||
	'-s[Target repo server]'
 | 
			
		||||
	'-l[Set bandwidth limit]:limit'
 | 
			
		||||
	"-a[Release to a specific architecture only]:arch:($_arch[*])"
 | 
			
		||||
	"-a[Release to a specific architecture only]:arch:($DEVTOOLS_VALID_ARCHES[*])"
 | 
			
		||||
	'1:commit_msg'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -180,15 +220,17 @@ _finddeps_args=(
 | 
			
		||||
_makechrootpkg_args=(
 | 
			
		||||
	'-h[Display usage]'
 | 
			
		||||
	'-c[Clean the chroot before building]'
 | 
			
		||||
	'-d[Bind directory into build chroot as read-write]:bind_dir_rw:_files -/'
 | 
			
		||||
	'-D[Bind directory into build chroot as read-only]:bind_dir_ro:_files -/'
 | 
			
		||||
	'*-d[Bind directory into build chroot as read-write]:bind_dir_rw:_files -/'
 | 
			
		||||
	'*-D[Bind directory into build chroot as read-only]:bind_dir_ro:_files -/'
 | 
			
		||||
	'*-t[Mount a tmpfs at directory]:tmpfs_dir:_files -/'
 | 
			
		||||
	'-u[Update the working copy of the chroot before building]'
 | 
			
		||||
	'-r[The chroot dir to use]:chroot_dir:_files -/'
 | 
			
		||||
	'-I[Install a package into the working copy]:target:_files -g "*.pkg.tar.*(.)"'
 | 
			
		||||
	'*-I[Install a package into the working copy]:target:_files -g "*.pkg.tar.*(.)"'
 | 
			
		||||
	'-l[The directory to use as the working copy]:copy_dir:_files -/'
 | 
			
		||||
	'-n[Run namcap on the package]'
 | 
			
		||||
	'-T[Build in a temporary directory]'
 | 
			
		||||
	'-U[Run makepkg as a specified user]:makepkg_user'
 | 
			
		||||
	"-x[Spawn an interactive shell to inspect the chroot (never, always, failure)]:inspect:($DEVTOOLS_VALID_INSPECT_MODES[*])"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_mkarchroot_args=(
 | 
			
		||||
@@ -196,6 +238,7 @@ _mkarchroot_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(.)"'
 | 
			
		||||
	'-c[Set pacman cache]:pacman_cache:_files -/'
 | 
			
		||||
	'-f[Copy src file from the host to the chroot]:target:_files -/'
 | 
			
		||||
	'-h[Display usage]'
 | 
			
		||||
	'1:working_dir:_files -/'
 | 
			
		||||
	'*:packages:_devtools_completions_all_packages'
 | 
			
		||||
@@ -212,19 +255,20 @@ _sogrep_args=(
 | 
			
		||||
	'(-v --verbose)'{-v,--verbose}'[Show matched links in addition to pkgname]'
 | 
			
		||||
	'(-r --refresh)'{-r,--refresh}'[Refresh the links databases]'
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
	'1:repo:(all $_repos[*])'
 | 
			
		||||
	'1:repo:(all $DEVTOOLS_VALID_REPOS[*])'
 | 
			
		||||
	'2:libname'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_offload_build_args=(
 | 
			
		||||
	'(-r --repo)'{-r,--repo}'[Build against a specific repository]:repo:($_build_repos[*])'
 | 
			
		||||
	'(-a --arch)'{-a,--arch}'[Build against a specific architecture]:arch:(${_binary_arch[*]})'
 | 
			
		||||
	'(-r --repo)'{-r,--repo}'[Build against a specific repository]:repo:($DEVTOOLS_VALID_BUILDREPOS[*])'
 | 
			
		||||
	'(-a --arch)'{-a,--arch}'[Build against a specific architecture]:arch:(${DEVTOOLS_VALID_BINARY_ARCHES[*]})'
 | 
			
		||||
	'(-s --server)'{-s,--server}'[Offload to a specific Build server]:server:'
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_makerepropkg_args=(
 | 
			
		||||
	'-d[Run diffoscope if the package is unreproducible]'
 | 
			
		||||
	'-n[Do not run the check() function in the PKGBUILD]'
 | 
			
		||||
	'-c[Set pacman cache]:pacman_cache:_files -/'
 | 
			
		||||
	'-M[Location of a makepkg config file]:makepkg_config:_files -g "*.conf(.)"'
 | 
			
		||||
	'-h[Display usage]'
 | 
			
		||||
@@ -239,13 +283,15 @@ _devtools_completions_all_packages() {
 | 
			
		||||
 | 
			
		||||
_pkgctl_cmds=(
 | 
			
		||||
	"pkgctl command"
 | 
			
		||||
	"aur[Interact with the Arch User Repository (AUR)]"
 | 
			
		||||
	"auth[Authenticate with services like GitLab]"
 | 
			
		||||
	"build[Build packages inside a clean chroot]"
 | 
			
		||||
	"db[Pacman database modification for packge update, move etc]"
 | 
			
		||||
	"db[Pacman database modification for package 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]"
 | 
			
		||||
	"search[Search for an expression across the GitLab packaging group]"
 | 
			
		||||
	"version[Check and manage package versions against upstream]"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_args=(
 | 
			
		||||
@@ -253,8 +299,33 @@ _pkgctl_args=(
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_args=(
 | 
			
		||||
_pkgctl_version_cmds=(
 | 
			
		||||
	"pkgctl version command"
 | 
			
		||||
	"check[Compares local package versions against upstream versions]"
 | 
			
		||||
	"setup[Automatically detect and setup a basic nvchecker config]"
 | 
			
		||||
	"upgrade[Adjust the PKGBUILD to match the latest upstream version]"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_check_args=(
 | 
			
		||||
	'(-v --verbose)'{-v,--verbose}'[Display results including up-to-date versions]'
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
	'*:git_dir:_files -/'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_setup_args=(
 | 
			
		||||
	'(-f --force)'{-f,--force}'[Do not prompt before overwriting]'
 | 
			
		||||
	'--prefer-platform-api[Prefer platform specific GitHub/GitLab API for complex cases]'
 | 
			
		||||
	'--url[Derive check target from URL instead of source array]:url:'
 | 
			
		||||
	'--no-check[Do not run version check after setup]'
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
	'*:git_dir:_files -/'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_version_upgrade_args=(
 | 
			
		||||
	'--no-update-checksums[Disable computation and update of the checksums]'
 | 
			
		||||
	'(-v --verbose)'{-v,--verbose}'[Display results including up-to-date versions]'
 | 
			
		||||
	'(-h --help)'{-h,--help}'[Display usage]'
 | 
			
		||||
	'*:git_dir:_files -/'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
_pkgctl_diff_args=("${_diffpkg_args[@]}")
 | 
			
		||||
@@ -276,7 +347,7 @@ _handle_subcommands() {
 | 
			
		||||
				fi
 | 
			
		||||
				;;
 | 
			
		||||
			args)
 | 
			
		||||
				local service_sub=${service_name}_$line[1]
 | 
			
		||||
				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}"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,37 +0,0 @@
 | 
			
		||||
## linkman: macro
 | 
			
		||||
# Inspired by/borrowed from the GIT source tree at Documentation/asciidoc.conf
 | 
			
		||||
#
 | 
			
		||||
# Usage: linkman:command[manpage-section]
 | 
			
		||||
#
 | 
			
		||||
# Note, {0} is the manpage section, while {target} is the command.
 | 
			
		||||
#
 | 
			
		||||
# Show man link as: <command>(<section>); if section is defined, else just show
 | 
			
		||||
# the command.
 | 
			
		||||
 | 
			
		||||
[macros]
 | 
			
		||||
(?su)[\\]?(?P<name>linkman):(?P<target>\S*?)\[(?P<attrlist>.*?)\]=
 | 
			
		||||
 | 
			
		||||
[attributes]
 | 
			
		||||
asterisk=*
 | 
			
		||||
plus=+
 | 
			
		||||
caret=^
 | 
			
		||||
startsb=[
 | 
			
		||||
endsb=]
 | 
			
		||||
backslash=\
 | 
			
		||||
tilde=~
 | 
			
		||||
apostrophe='
 | 
			
		||||
backtick=`
 | 
			
		||||
litdd=--
 | 
			
		||||
 | 
			
		||||
ifdef::backend-docbook[]
 | 
			
		||||
[linkman-inlinemacro]
 | 
			
		||||
{0%{target}}
 | 
			
		||||
{0#<citerefentry>}
 | 
			
		||||
{0#<refentrytitle>{target}</refentrytitle><manvolnum>{0}</manvolnum>}
 | 
			
		||||
{0#</citerefentry>}
 | 
			
		||||
endif::backend-docbook[]
 | 
			
		||||
 | 
			
		||||
ifdef::backend-xhtml11[]
 | 
			
		||||
[linkman-inlinemacro]
 | 
			
		||||
<a href="{target}.{0}.html">{target}{0?({0})}</a>
 | 
			
		||||
endif::backend-xhtml11[]
 | 
			
		||||
@@ -28,8 +28,9 @@ Options
 | 
			
		||||
*-c* <dir>::
 | 
			
		||||
	Set pacman cache, if no directory is specified the passed pacman.conf's cachedir is used with a fallback to '/etc/pacman.conf'
 | 
			
		||||
 | 
			
		||||
*-f* <file>::
 | 
			
		||||
	Copy file from the host to the chroot
 | 
			
		||||
*-f* <src>[:<dst>]::
 | 
			
		||||
	Copy file from the host to the chroot.
 | 
			
		||||
	If 'dst' is not provided, it defaults to 'src' inside of the chroot.
 | 
			
		||||
 | 
			
		||||
*-s*::
 | 
			
		||||
	Do not run setarch
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,6 @@ Options
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:devtools[7]
 | 
			
		||||
devtools(7)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -38,6 +38,6 @@ Options
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:find-libprovides[1]
 | 
			
		||||
find-libprovides(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -21,47 +21,47 @@ Programs
 | 
			
		||||
The list below gives a short overview; see the respective documentation
 | 
			
		||||
for details.
 | 
			
		||||
 | 
			
		||||
linkman:pkgctl[1]
 | 
			
		||||
pkgctl(1)
 | 
			
		||||
	Unified command-line frontend for devtools
 | 
			
		||||
 | 
			
		||||
linkman:archbuild[1]
 | 
			
		||||
archbuild(1)
 | 
			
		||||
	Build an Arch Linux package inside a clean chroot
 | 
			
		||||
 | 
			
		||||
linkman:arch-nspawn[1]
 | 
			
		||||
arch-nspawn(1)
 | 
			
		||||
	Run a command or OS in a light-weight namespace container
 | 
			
		||||
 | 
			
		||||
linkman:checkpkg[1]
 | 
			
		||||
checkpkg(1)
 | 
			
		||||
	Compare the current build package with the repository version
 | 
			
		||||
 | 
			
		||||
linkman:diffpkg[1]
 | 
			
		||||
diffpkg(1)
 | 
			
		||||
	Compare package files using different modes
 | 
			
		||||
 | 
			
		||||
linkman:export-pkgbuild-keys[1]
 | 
			
		||||
export-pkgbuild-keys(1)
 | 
			
		||||
	Export valid source signing keys from a PKGBUILD
 | 
			
		||||
 | 
			
		||||
linkman:find-libdeps[1]
 | 
			
		||||
find-libdeps(1)
 | 
			
		||||
	Find soname dependencies for a package
 | 
			
		||||
 | 
			
		||||
linkman:find-libprovides[1]
 | 
			
		||||
find-libprovides(1)
 | 
			
		||||
	Find soname's which are provided by a package
 | 
			
		||||
 | 
			
		||||
linkman:lddd[1]
 | 
			
		||||
lddd(1)
 | 
			
		||||
	Find broken library links on your system
 | 
			
		||||
 | 
			
		||||
linkman:mkarchroot[1]
 | 
			
		||||
mkarchroot(1)
 | 
			
		||||
	Creates an arch chroot in a specified location with a specified set of
 | 
			
		||||
	packages
 | 
			
		||||
 | 
			
		||||
linkman:makechrootpkg[1]
 | 
			
		||||
makechrootpkg(1)
 | 
			
		||||
	Build a PKGBUILD in a given chroot environment
 | 
			
		||||
 | 
			
		||||
linkman:makerepropkg[1]
 | 
			
		||||
makerepropkg(1)
 | 
			
		||||
	Rebuild a package to see if it is reproducible
 | 
			
		||||
 | 
			
		||||
linkman:offload-build[1]
 | 
			
		||||
offload-build(1)
 | 
			
		||||
	Build a PKGBUILD on a remote server using makechrootpkg
 | 
			
		||||
 | 
			
		||||
linkman:sogrep[1]
 | 
			
		||||
sogrep(1)
 | 
			
		||||
	Find packages using a linked to a given shared library
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,6 @@ collected data is written to a temporary directory created by mktemp.
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:ldd[1]
 | 
			
		||||
ldd(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -45,6 +45,9 @@ Options
 | 
			
		||||
*-D* <dir>::
 | 
			
		||||
	Bind directory into build chroot as read-only
 | 
			
		||||
 | 
			
		||||
*-t* <dir>[:opts]::
 | 
			
		||||
	Mount a tmpfs at 'dir'. See the '--tmpfs' argument in systemd-nspawn(1) for more details.
 | 
			
		||||
 | 
			
		||||
*-u*::
 | 
			
		||||
	Update the working copy of the chroot before building
 | 
			
		||||
	This is useful for rebuilds without dirtying the pristine
 | 
			
		||||
@@ -73,4 +76,12 @@ Options
 | 
			
		||||
*-U*::
 | 
			
		||||
	Run makepkg as a specified user
 | 
			
		||||
 | 
			
		||||
*-x* <when>::
 | 
			
		||||
	Inspect chroot after build, possible modes are 'never' (default), 'always' or 'failure'
 | 
			
		||||
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
systemd-nspawn(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ Given the path to a built pacman package(s), attempt to rebuild it using the
 | 
			
		||||
PKGBUILD in the current directory. The package will be built in an environment
 | 
			
		||||
as closely matching the environment of the initial package as possible, by
 | 
			
		||||
building up a chroot to match the information exposed in the package's
 | 
			
		||||
linkman:BUILDINFO[5] manifest. On success, the resulting package will be
 | 
			
		||||
BUILDINFO(5) manifest. On success, the resulting package will be
 | 
			
		||||
compared to the input package, and makerepropkg will report whether the
 | 
			
		||||
artifacts are identical.
 | 
			
		||||
 | 
			
		||||
@@ -42,6 +42,9 @@ Options
 | 
			
		||||
*-d*::
 | 
			
		||||
	If packages are not reproducible, compare them using diffoscope.
 | 
			
		||||
 | 
			
		||||
*-n*::
 | 
			
		||||
	Do not run the check() function in the PKGBUILD.
 | 
			
		||||
 | 
			
		||||
*-c*::
 | 
			
		||||
	Set the pacman cache directory.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -32,8 +32,9 @@ Options
 | 
			
		||||
*-c* <dir>::
 | 
			
		||||
	Set pacman cache.
 | 
			
		||||
 | 
			
		||||
*-f* <file>::
 | 
			
		||||
*-f* <src>[:<dst>]::
 | 
			
		||||
	Copy file from the host to the chroot.
 | 
			
		||||
	If 'dst' is not provided, it defaults to 'src' inside of the chroot.
 | 
			
		||||
 | 
			
		||||
*-s*::
 | 
			
		||||
	Do not run setarch.
 | 
			
		||||
@@ -44,6 +45,6 @@ Options
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:pacman[1]
 | 
			
		||||
pacman(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								doc/man/pkgctl-aur-drop-from-repo.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								doc/man/pkgctl-aur-drop-from-repo.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
pkgctl-aur-drop-from-repo(1)
 | 
			
		||||
============================
 | 
			
		||||
 | 
			
		||||
Name
 | 
			
		||||
----
 | 
			
		||||
pkgctl-aur-drop-from-repo - Drop a package from the official repository to the AUR
 | 
			
		||||
 | 
			
		||||
Synopsis
 | 
			
		||||
--------
 | 
			
		||||
pkgctl aur drop-from-repo [OPTIONS] [PATH]...
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Drops a specified package from the official repositories to the Arch User
 | 
			
		||||
Repository.
 | 
			
		||||
 | 
			
		||||
This command requires a local Git clone of the package repository. It
 | 
			
		||||
reconfigures the repository for AUR compatibility and pushes it to the
 | 
			
		||||
AUR. Afterwards, the package is removed from the official repository.
 | 
			
		||||
 | 
			
		||||
By default, the package is automatically disowned in the AUR.
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
*--no-disown*::
 | 
			
		||||
	Do not disown the package on the AUR
 | 
			
		||||
 | 
			
		||||
*-f, --force*::
 | 
			
		||||
	Force push to the AUR overwriting the remote repository
 | 
			
		||||
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
	Show a help text
 | 
			
		||||
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
pkgctl-db-remove(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
							
								
								
									
										37
									
								
								doc/man/pkgctl-aur.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								doc/man/pkgctl-aur.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
pkgctl-aur(1)
 | 
			
		||||
=============
 | 
			
		||||
 | 
			
		||||
Name
 | 
			
		||||
----
 | 
			
		||||
pkgctl-aur - Interact with the Arch User Repository (AUR)
 | 
			
		||||
 | 
			
		||||
Synopsis
 | 
			
		||||
--------
 | 
			
		||||
pkgctl aur [OPTIONS] [SUBCOMMAND]
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Provides a suite of tools designed for managing and interacting with the Arch
 | 
			
		||||
User Repository (AUR). It simplifies various tasks related to AUR, including
 | 
			
		||||
importing repositories, managing packages, and transitioning packages between
 | 
			
		||||
the official repositories and the AUR.
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
	Show a help text
 | 
			
		||||
 | 
			
		||||
Subcommands
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
pkgctl aur drop-from-repo::
 | 
			
		||||
	Drop a package from the official repository to the AUR
 | 
			
		||||
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
pkgctl-aur-drop-from-repo(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
@@ -35,6 +35,6 @@ Options
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:pkgctl-auth-status[1]
 | 
			
		||||
pkgctl-auth-status(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,6 @@ Options
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:pkgctl-auth-login[1]
 | 
			
		||||
pkgctl-auth-login(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ pkgctl auth status::
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:pkgctl-auth-login[1]
 | 
			
		||||
linkman:pkgctl-auth-status[1]
 | 
			
		||||
pkgctl-auth-login(1)
 | 
			
		||||
pkgctl-auth-status(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,10 @@ pkgctl build [OPTIONS] [PATH...]
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
TODO
 | 
			
		||||
Build packages in clean chroot environment, offering various options
 | 
			
		||||
and functionalities to customize the package building process.
 | 
			
		||||
 | 
			
		||||
By default, chroot environments are located in '/var/lib/archbuild/'.
 | 
			
		||||
 | 
			
		||||
Build Options
 | 
			
		||||
-------------
 | 
			
		||||
@@ -21,7 +24,10 @@ Build Options
 | 
			
		||||
	Specify architectures to build for (disables auto-detection)
 | 
			
		||||
 | 
			
		||||
*--repo* 'REPO'::
 | 
			
		||||
	Specify a target repository (disables auto-detection)
 | 
			
		||||
	Specify target repository for new packages not in any official repo.
 | 
			
		||||
	Fallback to `'extra'` when building packages that are not present in any
 | 
			
		||||
	official repository yet. Using this option is disallowed if the package is
 | 
			
		||||
	already released, as it would circumvent the auto-detection safeguard.
 | 
			
		||||
 | 
			
		||||
*-s, --staging*::
 | 
			
		||||
	Build against the staging counterpart of the auto-detected repo
 | 
			
		||||
@@ -35,8 +41,9 @@ Build Options
 | 
			
		||||
*-c, --clean*::
 | 
			
		||||
	Recreate the chroot before building
 | 
			
		||||
 | 
			
		||||
*-I, --install* 'FILE'::
 | 
			
		||||
	Install a package into the working copy of the chroot
 | 
			
		||||
*--inspect* 'WHEN'::
 | 
			
		||||
	Spawn an interactive shell to inspect the chroot after building. Useful to ease the debugging of a package build. +
 | 
			
		||||
	Possible values for 'WHEN' are `'never'`, `'always'` or `'failure'`
 | 
			
		||||
 | 
			
		||||
*-w, --worker* 'SLOT'::
 | 
			
		||||
	Name of the worker slot, useful for concurrent builds. By default the slot
 | 
			
		||||
@@ -47,6 +54,17 @@ Build Options
 | 
			
		||||
*--nocheck*::
 | 
			
		||||
	Do not run the check() function in the PKGBUILD
 | 
			
		||||
 | 
			
		||||
Install Options
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
*-I, --install-to-chroot* 'FILE'::
 | 
			
		||||
	Install a package to the working copy of the chroot
 | 
			
		||||
 | 
			
		||||
*-i, --install-to-host* 'MODE'::
 | 
			
		||||
	Install the built packages to the host system. Useful when one wants to verify that the package works as intended.
 | 
			
		||||
	* When 'MODE' is 'all', this installs all built packages
 | 
			
		||||
	* When 'MODE' is 'auto', this installs all built packages which are currently installed
 | 
			
		||||
 | 
			
		||||
PKGBUILD Options
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
@@ -59,6 +77,13 @@ PKGBUILD Options
 | 
			
		||||
*--rebuild*::
 | 
			
		||||
	Increment the current pkgrel variable
 | 
			
		||||
 | 
			
		||||
*--update-checksums*::
 | 
			
		||||
	Force computation and update of the checksums by disabling auto-detection. +
 | 
			
		||||
	Should only be used in special circumstances, like when adding new patch
 | 
			
		||||
	files to the source array. During regular packaging operations, checksums
 | 
			
		||||
	are either automatically updated when upgrading a package using `--pkgver`
 | 
			
		||||
	or should remain immutable during rebuilds.
 | 
			
		||||
 | 
			
		||||
*-e, --edit*::
 | 
			
		||||
	Edit the PKGBUILD before building
 | 
			
		||||
 | 
			
		||||
@@ -85,7 +110,7 @@ Options
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:pkgctl-release[1]
 | 
			
		||||
linkman:pkgctl-db-update[1]
 | 
			
		||||
pkgctl-release(1)
 | 
			
		||||
pkgctl-db-update(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -3,17 +3,16 @@ pkgctl-db-move(1)
 | 
			
		||||
 | 
			
		||||
Name
 | 
			
		||||
----
 | 
			
		||||
pkgctl-db-update - Update the binary repository as final release step
 | 
			
		||||
pkgctl-db-move - Move packages between binary repositories.
 | 
			
		||||
 | 
			
		||||
Synopsis
 | 
			
		||||
--------
 | 
			
		||||
pkgctl db update [OPTIONS]
 | 
			
		||||
pkgctl db move [OPTIONS] [SOURCE_REPO] [TARGET_REPO] [PKGBASE]...
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Update the pacman database as final release step for packages that
 | 
			
		||||
have been transfered and staged on 'repos.archlinux.org'.
 | 
			
		||||
Move packages between binary repositories i.e. from 'extra-testing' to 'extra'.
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 
 | 
			
		||||
@@ -12,13 +12,27 @@ pkgctl db remove [OPTIONS] [REPO] [PKGBASE]...
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Remove packages from pacman repositories.
 | 
			
		||||
Remove packages from pacman repositories. By default passing a pkgbase removes
 | 
			
		||||
all split packages, debug packages as well as entries from the state repo for
 | 
			
		||||
all existing architectures.
 | 
			
		||||
 | 
			
		||||
Beware when using the `--partial` option, as it may most likely lead to
 | 
			
		||||
undesired effects by leaving debug packages behind as well as dangling entries
 | 
			
		||||
in the state repository.
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
*--partial*::
 | 
			
		||||
	Remove only partial pkgnames from a split package. This leaves debug
 | 
			
		||||
	packages behind and pkgbase entries in the state repo.
 | 
			
		||||
 | 
			
		||||
*-a, --arch* 'ARCH'::
 | 
			
		||||
	Override the architecture (disables auto-detection)
 | 
			
		||||
	Remove only one specific architecture (disables auto-detection).
 | 
			
		||||
	By default all architectures are removed when this option is not used.
 | 
			
		||||
 | 
			
		||||
*--noconfirm*::
 | 
			
		||||
	Bypass any confirmation messages, should only be used with caution.
 | 
			
		||||
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
	Show a help text
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,19 @@
 | 
			
		||||
pkgctl-db-move(1)
 | 
			
		||||
=================
 | 
			
		||||
pkgctl-db-update(1)
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
Name
 | 
			
		||||
----
 | 
			
		||||
pkgctl-db-move - Move packages between binary repositories
 | 
			
		||||
pkgctl-db-update - Update the binary repository as final release step
 | 
			
		||||
 | 
			
		||||
Synopsis
 | 
			
		||||
--------
 | 
			
		||||
pkgctl db move [OPTIONS] [SOURCE_REPO] [TARGET_REPO] [PKGBASE]...
 | 
			
		||||
pkgctl db update [OPTIONS]
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Move packages between pacman repositories.
 | 
			
		||||
Update the pacman database as final release step for packages that
 | 
			
		||||
have been transfered and staged on 'repos.archlinux.org'.
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								doc/man/pkgctl-db.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								doc/man/pkgctl-db.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
pkgctl-db(1)
 | 
			
		||||
============
 | 
			
		||||
 | 
			
		||||
NAME
 | 
			
		||||
----
 | 
			
		||||
pkgctl-db - Pacman database modification utility for package updates, moves, and more.
 | 
			
		||||
 | 
			
		||||
SYNOPSIS
 | 
			
		||||
--------
 | 
			
		||||
pkgctl db [OPTIONS] [SUBCOMMAND]
 | 
			
		||||
 | 
			
		||||
DESCRIPTION
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Managing the Pacman database and facilitate the modification of packages and their metadata
 | 
			
		||||
within the database
 | 
			
		||||
 | 
			
		||||
OPTIONS
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
    Display usage information and available options.
 | 
			
		||||
 | 
			
		||||
Subcommands
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
pkgctl db update::
 | 
			
		||||
    Update the binary repository as final release step
 | 
			
		||||
 | 
			
		||||
pkgctl db move::
 | 
			
		||||
    Move packages between binary repositories
 | 
			
		||||
 | 
			
		||||
pkgctl db remove::
 | 
			
		||||
    Remove packages from binary repositories
 | 
			
		||||
 | 
			
		||||
SEE ALSO
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
pkgctl-db-update(1)
 | 
			
		||||
pkgctl-db-move(1)
 | 
			
		||||
pkgctl-db-remove(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
@@ -27,7 +27,9 @@ Options
 | 
			
		||||
	Use the given <msg> as the commit message
 | 
			
		||||
 | 
			
		||||
*-r, --repo* 'REPO'::
 | 
			
		||||
	Specify a target repository (disables auto-detection)
 | 
			
		||||
	Specify target repository for new packages not in any official repo.
 | 
			
		||||
	Using this option is disallowed if the package is already released, as it
 | 
			
		||||
	would circumvent the auto-detection safeguard.
 | 
			
		||||
 | 
			
		||||
*-s, --staging*::
 | 
			
		||||
	Build against the staging counterpart of the auto-detected repo
 | 
			
		||||
@@ -44,6 +46,6 @@ Options
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:pkgctl-db-update[1]
 | 
			
		||||
pkgctl-db-update(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								doc/man/pkgctl-repo-clean.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								doc/man/pkgctl-repo-clean.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
pkgctl-repo-clean(1)
 | 
			
		||||
====================
 | 
			
		||||
 | 
			
		||||
Name
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
pkgctl-repo-clean - Remove untracked files from the working tree
 | 
			
		||||
 | 
			
		||||
Synopsis
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
pkgctl repo clean [OPTION] [PATH]...
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Cleans the working tree by recursively removing files that are not under
 | 
			
		||||
version control, starting from the current directory.
 | 
			
		||||
 | 
			
		||||
Files unknown to Git as well as ignored files are removed. This can, for
 | 
			
		||||
example, be useful to remove all build products.
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
*-i, --interactive*::
 | 
			
		||||
	Show what would be done and clean files interactively
 | 
			
		||||
 | 
			
		||||
*-n, --dry-run*::
 | 
			
		||||
	Don't actually remove anything, just show what would be done
 | 
			
		||||
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
	Show a help text
 | 
			
		||||
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
git-clean(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
@@ -46,7 +46,7 @@ Options
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:pkgctl-repo-configure[1]
 | 
			
		||||
linkman:pkgctl-repo-switch[1]
 | 
			
		||||
pkgctl-repo-configure(1)
 | 
			
		||||
pkgctl-repo-switch(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,8 @@ The remote protocol is automatically determined from the author email
 | 
			
		||||
address by choosing SSH for all official packager identities and
 | 
			
		||||
read-only HTTPS otherwise.
 | 
			
		||||
 | 
			
		||||
Git default excludes and hooks are applied to the configured repo.
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,8 +33,8 @@ Options
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
linkman:pkgctl-auth[1]
 | 
			
		||||
linkman:pkgctl-repo-clone[1]
 | 
			
		||||
linkman:pkgctl-repo-configure[1]
 | 
			
		||||
pkgctl-auth(1)
 | 
			
		||||
pkgctl-repo-clone(1)
 | 
			
		||||
pkgctl-repo-configure(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,9 @@ no arguments, open the package cloned in the current working directory.
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
*--print*::
 | 
			
		||||
	Print the url instead of opening it with xdg-open
 | 
			
		||||
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
	Show a help text
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,9 @@ Options
 | 
			
		||||
Subcommands
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
pkgctl repo clean::
 | 
			
		||||
	Remove untracked files from the working tree
 | 
			
		||||
 | 
			
		||||
pkgctl repo clone::
 | 
			
		||||
	Clone a package repository
 | 
			
		||||
 | 
			
		||||
@@ -50,10 +53,11 @@ pkgctl repo web::
 | 
			
		||||
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]
 | 
			
		||||
pkgctl-repo-clean(1)
 | 
			
		||||
pkgctl-repo-clone(1)
 | 
			
		||||
pkgctl-repo-configure(1)
 | 
			
		||||
pkgctl-repo-create(1)
 | 
			
		||||
pkgctl-repo-switch(1)
 | 
			
		||||
pkgctl-repo-web(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										71
									
								
								doc/man/pkgctl-search.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								doc/man/pkgctl-search.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
pkgctl-search(1)
 | 
			
		||||
================
 | 
			
		||||
 | 
			
		||||
Name
 | 
			
		||||
----
 | 
			
		||||
pkgctl-search - Search for an expression across the GitLab packaging group
 | 
			
		||||
 | 
			
		||||
Synopsis
 | 
			
		||||
--------
 | 
			
		||||
pkgctl search [OPTIONS] QUERY
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Search for an expression across the GitLab packaging group.
 | 
			
		||||
 | 
			
		||||
To use a filter, include it in your query. You may use wildcards (*) to
 | 
			
		||||
use glob matching.
 | 
			
		||||
 | 
			
		||||
Available filters for the blobs scope: path, extension
 | 
			
		||||
 | 
			
		||||
Every usage of the search command must be authenticated. Consult the
 | 
			
		||||
`'pkgctl auth'` command to authenticate with GitLab or view the authentication
 | 
			
		||||
status.
 | 
			
		||||
 | 
			
		||||
Search Tips
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
	Syntax  Description    Example
 | 
			
		||||
	───────────────────────────────────────
 | 
			
		||||
	"       Exact search   "gem sidekiq"
 | 
			
		||||
	~       Fuzzy search   J~ Doe
 | 
			
		||||
	|       Or             display | banner
 | 
			
		||||
	+       And            display +banner
 | 
			
		||||
	-       Exclude        display -banner
 | 
			
		||||
	*       Partial        bug error 50*
 | 
			
		||||
	\       Escape         \*md
 | 
			
		||||
	#       Issue ID       #23456
 | 
			
		||||
	!       Merge request  !23456
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
	Show a help text
 | 
			
		||||
 | 
			
		||||
Filter Options
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
*--no-default-filter*::
 | 
			
		||||
	Do not apply default filter (like -path:keys/pgp/*.asc)
 | 
			
		||||
 | 
			
		||||
Output Options
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
*--json*::
 | 
			
		||||
	Enable printing in JSON; Shorthand for `'--format json'`
 | 
			
		||||
 | 
			
		||||
*-F, --format* 'FORMAT'::
 | 
			
		||||
	Controls the formatting of the results; `FORMAT` is `'pretty'`, `'plain'`,
 | 
			
		||||
	or `'json'` (default `pretty`)
 | 
			
		||||
 | 
			
		||||
*-N, --no-line-number*::
 | 
			
		||||
	Don't show line numbers when formatting results
 | 
			
		||||
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
pkgctl-auth(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
							
								
								
									
										66
									
								
								doc/man/pkgctl-version-check.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								doc/man/pkgctl-version-check.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
pkgctl-version-check(1)
 | 
			
		||||
=======================
 | 
			
		||||
 | 
			
		||||
Name
 | 
			
		||||
----
 | 
			
		||||
pkgctl-version-check - Compares local package versions against upstream
 | 
			
		||||
 | 
			
		||||
Synopsis
 | 
			
		||||
--------
 | 
			
		||||
pkgctl version check [OPTIONS] [PKGBASE...]
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Compares the versions of packages in the local packaging repository against
 | 
			
		||||
their latest upstream versions.
 | 
			
		||||
 | 
			
		||||
Upon execution, it generates a grouped list that provides detailed insights
 | 
			
		||||
into each package's status. For each package, it displays the current local
 | 
			
		||||
version alongside the latest version available upstream.
 | 
			
		||||
 | 
			
		||||
Outputs a summary of up-to-date packages, out-of-date packages, and any check
 | 
			
		||||
failures.
 | 
			
		||||
 | 
			
		||||
This simplifies the maintenance of PKGBUILD files, reducing the manual effort
 | 
			
		||||
required to track version changes from upstream sources.
 | 
			
		||||
 | 
			
		||||
Configuration
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
Uses nvchecker(1) and a `.nvchecker.toml` file located alongside the
 | 
			
		||||
PKGBUILD. Refer to the configuration section in pkgctl-version(1).
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
*-v, --verbose*::
 | 
			
		||||
	Display results including up-to-date versions
 | 
			
		||||
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
	Show a help text
 | 
			
		||||
 | 
			
		||||
Exit Codes
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
On exit, return one of the following codes:
 | 
			
		||||
 | 
			
		||||
*0*::
 | 
			
		||||
	Normal exit condition, all checked versions are up-to-date
 | 
			
		||||
 | 
			
		||||
*1*::
 | 
			
		||||
	Unknown cause of failure
 | 
			
		||||
 | 
			
		||||
*2*::
 | 
			
		||||
	Normal exit condition, but there are out-of-date versions
 | 
			
		||||
 | 
			
		||||
*3*::
 | 
			
		||||
	Failed to run some version checks
 | 
			
		||||
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
pkgctl-version(1)
 | 
			
		||||
nvchecker(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
							
								
								
									
										120
									
								
								doc/man/pkgctl-version-setup.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								doc/man/pkgctl-version-setup.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,120 @@
 | 
			
		||||
pkgctl-version-setup(1)
 | 
			
		||||
=======================
 | 
			
		||||
 | 
			
		||||
Name
 | 
			
		||||
----
 | 
			
		||||
pkgctl-version-setup - Automatically detect and setup a basic nvchecker config
 | 
			
		||||
 | 
			
		||||
Synopsis
 | 
			
		||||
--------
 | 
			
		||||
pkgctl version setup [OPTIONS] [PKGBASE...]
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
This subcommand automates the creation of a basic nvchecker(1) configuration
 | 
			
		||||
file by analyzing the source array specified in the PKGBUILD(1) file of a
 | 
			
		||||
package. This command intelligently detects various platforms and APIs (e.g.,
 | 
			
		||||
GitHub, GitLab, PyPI) used by the package sources and generates a corresponding
 | 
			
		||||
`.nvchecker.toml` configuration based on its best guess.
 | 
			
		||||
 | 
			
		||||
This is particularly useful for initializing nvchecker(1) settings for a
 | 
			
		||||
package without manually crafting the `.nvchecker.toml` file. It simplifies the
 | 
			
		||||
process of setting up version checks, especially when transitioning a package's
 | 
			
		||||
monitoring from one source platform to another or starting version checks for a
 | 
			
		||||
new package.
 | 
			
		||||
 | 
			
		||||
If no `PKGBASE` is specified, the command defaults to using the current working
 | 
			
		||||
directory.
 | 
			
		||||
 | 
			
		||||
To obtain a list of supported sources and their expected URL formats, please
 | 
			
		||||
consult the sources section.
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
*-f, --force*::
 | 
			
		||||
	Overwrite existing nvchecker(1) configuration
 | 
			
		||||
 | 
			
		||||
*--prefer-platform-api*::
 | 
			
		||||
	Prefer platform specific GitHub/GitLab API over git for complex cases
 | 
			
		||||
 | 
			
		||||
*--url* 'URL'::
 | 
			
		||||
	Derive check target from the given URL instead of the source array entries
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
*--no-check*::
 | 
			
		||||
	Do not run pkgctl-version-check(1) after setup
 | 
			
		||||
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
	Show a help text
 | 
			
		||||
 | 
			
		||||
Sources
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
Here are the currently supported platforms and sources, along with examples of
 | 
			
		||||
URL formats that enable their automatic detection as specific source types:
 | 
			
		||||
 | 
			
		||||
*Git*::
 | 
			
		||||
	* https://github.com/example/project
 | 
			
		||||
	* https://gitlab.com/example/group/project
 | 
			
		||||
	* git://git.foobar.org/example
 | 
			
		||||
	* git+https://git.foobar.org/example
 | 
			
		||||
 | 
			
		||||
*GitHub*::
 | 
			
		||||
	* https://github.com/example/project
 | 
			
		||||
	* https://github.com/example/project/archive/v1.0/project-v1.0.tar.gz
 | 
			
		||||
 | 
			
		||||
*GitLab*::
 | 
			
		||||
	* https://gitlab.com/example/group/project
 | 
			
		||||
	* https://gitlab.archlinux.org/archlinux/devtools.git
 | 
			
		||||
	* https://gitlab.archlinux.org/archlinux/devtools/-/releases/v1.1.0/downloads/devtools-v1.1.0.tar.gz
 | 
			
		||||
 | 
			
		||||
*Hackage*::
 | 
			
		||||
	* https://hackage.haskell.org/package/xmonad
 | 
			
		||||
	* https://hackage.haskell.org/package/xmonad-0.18.0/xmonad-0.18.0.tar.gz
 | 
			
		||||
	* https://hackage.haskell.org/packages/archive/xmonad/0.18.0/xmonad-0.18.0.tar.gz
 | 
			
		||||
 | 
			
		||||
*NPM*::
 | 
			
		||||
	* https://registry.npmjs.org/node-gyp/-/node-gyp-10.0.1.tgz
 | 
			
		||||
	* https://www.npmjs.com/package/node-gyp
 | 
			
		||||
 | 
			
		||||
*PyPI*::
 | 
			
		||||
	* https://pypi.io/packages/source/p/pyflakes
 | 
			
		||||
	* https://pypi.org/packages/source/b/bleach
 | 
			
		||||
	* https://files.pythonhosted.org/packages/source/p/pyflakes
 | 
			
		||||
	* https://pypi.org/project/SQLAlchemy/
 | 
			
		||||
 | 
			
		||||
*RubyGems*::
 | 
			
		||||
	* https://rubygems.org/downloads/diff-lcs-1.5.1.gem
 | 
			
		||||
	* https://rubygems.org/gems/diff-lcs
 | 
			
		||||
 | 
			
		||||
*CPAN*::
 | 
			
		||||
	* https://search.cpan.org/CPAN/authors/id/C/CO/COSIMO/Locale-PO-0.27.tar.gz
 | 
			
		||||
	* https://cpan.metacpan.org/authors/id/C/CO/COSIMO/Locale-PO-0.27.tar.gz
 | 
			
		||||
 | 
			
		||||
*crates.io*::
 | 
			
		||||
	* https://static.crates.io/crates/shotgun/shotgun-1.0.crate
 | 
			
		||||
	* https://crates.io/api/v1/crates/shotgun/1.0/download
 | 
			
		||||
	* https://crates.io/crates/git-smash
 | 
			
		||||
 | 
			
		||||
Examples
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
*pkgctl version setup*::
 | 
			
		||||
	Detects the source from the current directory's PKGBUILD(1) and
 | 
			
		||||
	sets up a basic `.nvchecker.toml`.
 | 
			
		||||
 | 
			
		||||
*pkgctl version setup --url https://github.com/example/project*::
 | 
			
		||||
	Generates an `.nvchecker.toml` for the current PKGBUILD(1) but
 | 
			
		||||
	overrides the source URL with the specified GitHub project.
 | 
			
		||||
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
pkgctl-version(1)
 | 
			
		||||
pkgctl-version-check(1)
 | 
			
		||||
nvchecker(1)
 | 
			
		||||
PKGBUILD(5)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
							
								
								
									
										53
									
								
								doc/man/pkgctl-version-upgrade.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								doc/man/pkgctl-version-upgrade.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
pkgctl-version-upgrade(1)
 | 
			
		||||
=========================
 | 
			
		||||
 | 
			
		||||
Name
 | 
			
		||||
----
 | 
			
		||||
pkgctl-version-upgrade - Adjust the PKGBUILD to match the latest upstream version
 | 
			
		||||
 | 
			
		||||
Synopsis
 | 
			
		||||
--------
 | 
			
		||||
pkgctl version upgrade [OPTIONS] [PKGBASE...]
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Streamlines the process of keeping PKGBUILD files up-to-date with the latest
 | 
			
		||||
upstream versions.
 | 
			
		||||
 | 
			
		||||
Upon execution, it automatically adjusts the PKGBUILD file, ensuring that the
 | 
			
		||||
pkgver field is set to match the latest version available from the upstream
 | 
			
		||||
source. In addition to updating the pkgver, this command also resets the pkgrel
 | 
			
		||||
to 1 and updates checksums.
 | 
			
		||||
 | 
			
		||||
Outputs a summary of upgraded packages, up-to-date packages, and any check
 | 
			
		||||
failures.
 | 
			
		||||
 | 
			
		||||
This simplifies the maintenance of PKGBUILD files, reducing the manual effort
 | 
			
		||||
required to track and implement version changes from upstream sources.
 | 
			
		||||
 | 
			
		||||
Configuration
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
Uses nvchecker(1) and a `.nvchecker.toml` file located alongside the
 | 
			
		||||
PKGBUILD. Refer to the configuration section in pkgctl-version(1).
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
*--no-update-checksums*::
 | 
			
		||||
	Disable computation and update of the checksums
 | 
			
		||||
 | 
			
		||||
*-v, --verbose*::
 | 
			
		||||
	Display results including up-to-date versions
 | 
			
		||||
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
	Show a help text
 | 
			
		||||
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
pkgctl-version(1)
 | 
			
		||||
nvchecker(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
@@ -3,16 +3,41 @@ pkgctl-version(1)
 | 
			
		||||
 | 
			
		||||
Name
 | 
			
		||||
----
 | 
			
		||||
pkgctl-version - Show pkgctl version information
 | 
			
		||||
pkgctl-version - Check and manage package versions against upstream
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Synopsis
 | 
			
		||||
--------
 | 
			
		||||
pkgctl version [OPTIONS]
 | 
			
		||||
pkgctl version [OPTIONS] [SUBCOMMAND]
 | 
			
		||||
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Shows the current version information of pkgctl.
 | 
			
		||||
Commands related to package versions, including checks for outdated packages.
 | 
			
		||||
 | 
			
		||||
Uses nvchecker(1) and a `.nvchecker.toml` file located alongside the
 | 
			
		||||
PKGBUILD.
 | 
			
		||||
 | 
			
		||||
Configuration
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
The `.nvchecker.toml` file must contain a section that matches the
 | 
			
		||||
package's pkgbase. The pkgbase section within the `.nvchecker.toml` file
 | 
			
		||||
specifies the source and method for checking the latest version of the
 | 
			
		||||
corresponding package.
 | 
			
		||||
 | 
			
		||||
Use pkgctl-version-setup(1) to automatically detect and setup a basic nvchecker
 | 
			
		||||
config based on the source array of the package PKGBUILD.
 | 
			
		||||
 | 
			
		||||
For detailed information on the various configuration options available for the
 | 
			
		||||
`.nvchecker.toml` file, refer to the configuration files section in
 | 
			
		||||
nvchecker(1). This documentation provides insights into the possible
 | 
			
		||||
options that can be utilized to customize the version checking process.
 | 
			
		||||
 | 
			
		||||
To supply GitHub or GitLab tokens to nvchecker, a `keyfile.toml` should be
 | 
			
		||||
placed in the `$XDG_CONFIG_HOME`/nvchecker` directory. This keyfile is
 | 
			
		||||
used for providing the necessary authentication tokens required for
 | 
			
		||||
accessing the GitHub or GitLab API.
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
@@ -20,4 +45,23 @@ Options
 | 
			
		||||
*-h, --help*::
 | 
			
		||||
	Show a help text
 | 
			
		||||
 | 
			
		||||
Subcommands
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
pkgctl version check::
 | 
			
		||||
	Compares local package versions against upstream
 | 
			
		||||
 | 
			
		||||
pkgctl version setup::
 | 
			
		||||
	Automatically detect and setup a basic nvchecker config
 | 
			
		||||
 | 
			
		||||
pkgctl version upgrade::
 | 
			
		||||
	Adjust the PKGBUILD to match the latest upstream version
 | 
			
		||||
 | 
			
		||||
See Also
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
pkgctl-version-check(1)
 | 
			
		||||
pkgctl-version-setup(1)
 | 
			
		||||
pkgctl-version-upgrade(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,12 @@ pkgctl [SUBCOMMAND] [OPTIONS]
 | 
			
		||||
Description
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
TODO
 | 
			
		||||
Command-line utility serving as a unified interface for multiple development tools. 
 | 
			
		||||
This tool aims to simplify and optimize interactions with devtools by offering 
 | 
			
		||||
various subcommands for executing tasks related to package management, repository management, 
 | 
			
		||||
version control, among others.
 | 
			
		||||
 | 
			
		||||
Utilizing pkgctl enables users to efficiently administer their development workflows.
 | 
			
		||||
 | 
			
		||||
Options
 | 
			
		||||
-------
 | 
			
		||||
@@ -26,6 +31,9 @@ Options
 | 
			
		||||
Subcommands
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
pkgctl aur::
 | 
			
		||||
	Interact with the Arch User Repository
 | 
			
		||||
 | 
			
		||||
pkgctl auth::
 | 
			
		||||
	Authenticate with services like GitLab
 | 
			
		||||
 | 
			
		||||
@@ -33,7 +41,7 @@ pkgctl build::
 | 
			
		||||
	Build packages inside a clean chroot
 | 
			
		||||
 | 
			
		||||
pkgctl db::
 | 
			
		||||
	Pacman database modification for packge update, move etc
 | 
			
		||||
	Pacman database modification for package update, move etc
 | 
			
		||||
 | 
			
		||||
pkgctl diff::
 | 
			
		||||
	Compare package files using different modes
 | 
			
		||||
@@ -44,18 +52,23 @@ pkgctl release::
 | 
			
		||||
pkgctl repo::
 | 
			
		||||
	Manage Git packaging repositories and their configuration
 | 
			
		||||
 | 
			
		||||
pkgctl search::
 | 
			
		||||
	Search for an expression across the GitLab packaging group
 | 
			
		||||
 | 
			
		||||
pkgctl version::
 | 
			
		||||
	Show pkgctl version information
 | 
			
		||||
	Check and manage package versions against upstream
 | 
			
		||||
 | 
			
		||||
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]
 | 
			
		||||
pkgctl-aur(1)
 | 
			
		||||
pkgctl-auth(1)
 | 
			
		||||
pkgctl-build(1)
 | 
			
		||||
pkgctl-db(1)
 | 
			
		||||
pkgctl-diff(1)
 | 
			
		||||
pkgctl-release(1)
 | 
			
		||||
pkgctl-repo(1)
 | 
			
		||||
pkgctl-search(1)
 | 
			
		||||
pkgctl-version(1)
 | 
			
		||||
 | 
			
		||||
include::include/footer.asciidoc[]
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,6 @@ umask 0022
 | 
			
		||||
working_dir=''
 | 
			
		||||
 | 
			
		||||
files=()
 | 
			
		||||
mount_args=()
 | 
			
		||||
 | 
			
		||||
usage() {
 | 
			
		||||
	echo "Usage: ${0##*/} [options] working-dir [systemd-nspawn arguments]"
 | 
			
		||||
@@ -26,7 +25,8 @@ usage() {
 | 
			
		||||
	echo '    -C <file>           Location of a pacman config file'
 | 
			
		||||
	echo '    -M <file>           Location of a makepkg config file'
 | 
			
		||||
	echo '    -c <dir>            Set pacman cache'
 | 
			
		||||
	echo '    -f <file>     Copy file from the host to the chroot'
 | 
			
		||||
	echo '    -f <src>[:<dst>]    Copy src file from the host to the chroot.'
 | 
			
		||||
	echo '                        If dst file is not provided, it defaults to src'
 | 
			
		||||
	echo '    -s                  Do not run setarch'
 | 
			
		||||
	echo '    -h                  This message'
 | 
			
		||||
	exit 1
 | 
			
		||||
@@ -56,12 +56,24 @@ shift 1
 | 
			
		||||
 | 
			
		||||
[[ -z $working_dir ]] && die 'Please specify a working directory.'
 | 
			
		||||
 | 
			
		||||
nspawn_args=(
 | 
			
		||||
	--quiet
 | 
			
		||||
	--directory="$working_dir"
 | 
			
		||||
	--setenv="PATH=/usr/local/sbin:/usr/local/bin:/usr/bin"
 | 
			
		||||
	--register=no
 | 
			
		||||
	--slice="devtools-$(systemd-escape "${SUDO_USER:-$USER}")"
 | 
			
		||||
	--machine="arch-nspawn-$$"
 | 
			
		||||
	--as-pid2
 | 
			
		||||
	--console=autopipe
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if (( ${#cache_dirs[@]} == 0 )); then
 | 
			
		||||
	mapfile -t cache_dirs < <(pacman-conf --config "${pac_conf:-$working_dir/etc/pacman.conf}" CacheDir)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# shellcheck disable=2016
 | 
			
		||||
host_mirrors=($(pacman-conf --repo extra Server 2> /dev/null | sed -r 's#(.*/)extra/os/.*#\1$repo/os/$arch#'))
 | 
			
		||||
host_cachemirrors=($(pacman-conf --repo extra CacheServer 2> /dev/null | sed -r 's#(.*/)extra/os/.*#\1$repo/os/$arch#'))
 | 
			
		||||
 | 
			
		||||
for host_mirror in "${host_mirrors[@]}"; do
 | 
			
		||||
	if [[ $host_mirror == *file://* ]]; then
 | 
			
		||||
@@ -83,10 +95,10 @@ while read -r line; do
 | 
			
		||||
	done
 | 
			
		||||
done < <(pacman-conf --config "${pac_conf:-$working_dir/etc/pacman.conf}" --repo-list)
 | 
			
		||||
 | 
			
		||||
mount_args+=("--bind=${cache_dirs[0]//:/\\:}")
 | 
			
		||||
nspawn_args+=(--bind="${cache_dirs[0]//:/\\:}")
 | 
			
		||||
 | 
			
		||||
for cache_dir in "${cache_dirs[@]:1}"; do
 | 
			
		||||
	mount_args+=("--bind-ro=${cache_dir//:/\\:}")
 | 
			
		||||
	nspawn_args+=(--bind-ro="${cache_dir//:/\\:}")
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
# {{{ functions
 | 
			
		||||
@@ -96,13 +108,17 @@ copy_hostconf () {
 | 
			
		||||
 | 
			
		||||
	printf 'Server = %s\n' "${host_mirrors[@]}" >"$working_dir/etc/pacman.d/mirrorlist"
 | 
			
		||||
 | 
			
		||||
	[[ -n $host_cachemirrors ]] && printf 'CacheServer = %s\n' "${host_cachemirrors[@]}" >>"$working_dir/etc/pacman.d/mirrorlist"
 | 
			
		||||
 | 
			
		||||
	[[ -n $pac_conf ]] && cp "$pac_conf" "$working_dir/etc/pacman.conf"
 | 
			
		||||
	[[ -n $makepkg_conf ]] && cp "$makepkg_conf" "$working_dir/etc/makepkg.conf"
 | 
			
		||||
 | 
			
		||||
	local file
 | 
			
		||||
	for file in "${files[@]}"; do
 | 
			
		||||
		mkdir -p "$(dirname "$working_dir$file")"
 | 
			
		||||
		cp -T "$file" "$working_dir$file"
 | 
			
		||||
		src="${file%%:*}"
 | 
			
		||||
		dst="${file#*:}"
 | 
			
		||||
		mkdir -p "$(dirname "$working_dir$dst")"
 | 
			
		||||
		cp -T "$src" "$working_dir$dst"
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	sed -r "s|^#?\\s*CacheDir.+|CacheDir = ${cache_dirs[*]}|g" -i "$working_dir/etc/pacman.conf"
 | 
			
		||||
@@ -129,9 +145,4 @@ else
 | 
			
		||||
	set_arch="${CARCH}"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
exec ${CARCH:+setarch "$set_arch"} systemd-nspawn -q \
 | 
			
		||||
	-D "$working_dir" \
 | 
			
		||||
	-E "PATH=/usr/local/sbin:/usr/local/bin:/usr/bin" \
 | 
			
		||||
	--register=no --keep-unit --as-pid2 \
 | 
			
		||||
	"${mount_args[@]}" \
 | 
			
		||||
	"$@"
 | 
			
		||||
exec ${CARCH:+setarch "$set_arch"} systemd-nspawn "${nspawn_args[@]}" "$@"
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@ fi
 | 
			
		||||
# validate repo is really repo-arch
 | 
			
		||||
if [[ -z $FORCE ]]; then
 | 
			
		||||
	for tag in "$@"; do
 | 
			
		||||
		if ! in_array "$tag" "${_tags[@]}"; then
 | 
			
		||||
		if ! in_array "$tag" "${DEVTOOLS_VALID_TAGS[@]}"; then
 | 
			
		||||
			die "archrelease: Invalid tag: '%s' (use -f to force release)" "$tag"
 | 
			
		||||
		fi
 | 
			
		||||
	done
 | 
			
		||||
 
 | 
			
		||||
@@ -140,7 +140,7 @@ for _pkgname in "${pkgname[@]}"; do
 | 
			
		||||
	bsdtar tf "$TEMPDIR/$oldpkg" | sort > "$TEMPDIR/filelist-$_pkgname-old"
 | 
			
		||||
	bsdtar tf "$pkgfile" | sort > "$TEMPDIR/filelist-$_pkgname"
 | 
			
		||||
 | 
			
		||||
	sdiff -s "$TEMPDIR/filelist-$_pkgname-old" "$TEMPDIR/filelist-$_pkgname"
 | 
			
		||||
	diff --side-by-side --suppress-common-lines --width="$COLUMNS" --color=auto "$TEMPDIR/filelist-$_pkgname-old" "$TEMPDIR/filelist-$_pkgname"
 | 
			
		||||
 | 
			
		||||
	find-libprovides "$TEMPDIR/$oldpkg" 2>/dev/null | sort > "$TEMPDIR/libraries-$_pkgname-old"
 | 
			
		||||
	find-libprovides "$pkgfile" 2>/dev/null | sort > "$TEMPDIR/libraries-$_pkgname"
 | 
			
		||||
 
 | 
			
		||||
@@ -5,9 +5,13 @@
 | 
			
		||||
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
 | 
			
		||||
# shellcheck source=src/lib/common.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
 | 
			
		||||
# shellcheck source=src/lib/util/srcinfo.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/srcinfo.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/util.sh
 | 
			
		||||
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
check_pkgbuild_validity() {
 | 
			
		||||
	# shellcheck source=contrib/makepkg/PKGBUILD.proto
 | 
			
		||||
@@ -70,6 +74,12 @@ if ! repo_spec=$(git config --local devtools.version) || [[ ${repo_spec} != "${G
 | 
			
		||||
	exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if ! repo_variant=$(git config --local devtools.variant) || [[ ${repo_variant} != canonical ]]; then
 | 
			
		||||
	error "cannot release from a repository with none canonical specs (%s), try:" "${repo_variant:-development}"
 | 
			
		||||
	msg2 'pkgctl repo configure'
 | 
			
		||||
	exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ "$(git symbolic-ref --short HEAD)" != main ]]; then
 | 
			
		||||
	die 'must be run from the main branch'
 | 
			
		||||
fi
 | 
			
		||||
@@ -141,7 +151,7 @@ fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
server=${PACKAGING_REPO_RELEASE_HOST}
 | 
			
		||||
rsyncopts=(-e ssh -p '--chmod=ug=rw,o=r' -c -h -L --progress --partial -y)
 | 
			
		||||
rsyncopts=("${RSYNC_OPTS[@]}" --perms --chmod='ug=rw,o=r')
 | 
			
		||||
archreleaseopts=()
 | 
			
		||||
while getopts ':l:a:s:f' flag; do
 | 
			
		||||
	case $flag in
 | 
			
		||||
@@ -177,13 +187,10 @@ done
 | 
			
		||||
# check for PKGBUILD standards
 | 
			
		||||
check_pkgbuild_validity
 | 
			
		||||
 | 
			
		||||
# auto generate .SRCINFO if present
 | 
			
		||||
if [[ -f .SRCINFO ]]; then
 | 
			
		||||
	stat_busy 'Generating .SRCINFO'
 | 
			
		||||
	makepkg --printsrcinfo > .SRCINFO
 | 
			
		||||
	git add .SRCINFO
 | 
			
		||||
	stat_done
 | 
			
		||||
fi
 | 
			
		||||
# auto generate .SRCINFO
 | 
			
		||||
# shellcheck disable=SC2119
 | 
			
		||||
write_srcinfo_file
 | 
			
		||||
git add --force .SRCINFO
 | 
			
		||||
 | 
			
		||||
if [[ -n $(git status --porcelain --untracked-files=no) ]]; then
 | 
			
		||||
	stat_busy 'Staging files'
 | 
			
		||||
@@ -206,14 +213,14 @@ if [[ -n $(git status --porcelain --untracked-files=no) ]]; then
 | 
			
		||||
		echo "$msgtemplate" > "$msgfile"
 | 
			
		||||
		if [[ -n $GIT_EDITOR ]]; then
 | 
			
		||||
			$GIT_EDITOR "$msgfile" || die
 | 
			
		||||
		elif giteditor=$(git config --get core.editor); then
 | 
			
		||||
			$giteditor "$msgfile" || die
 | 
			
		||||
		elif [[ -n $VISUAL ]]; then
 | 
			
		||||
			$VISUAL "$msgfile" || die
 | 
			
		||||
		elif [[ -n $EDITOR ]]; then
 | 
			
		||||
			$EDITOR "$msgfile" || die
 | 
			
		||||
		elif giteditor=$(git config --get core.editor); then
 | 
			
		||||
			$giteditor "$msgfile" || die
 | 
			
		||||
		else
 | 
			
		||||
			die "No usable editor found (tried \$GIT_EDITOR, \$VISUAL, \$EDITOR, git config [core.editor])."
 | 
			
		||||
			die "No usable editor found (tried \$GIT_EDITOR, git config [core.editor], \$VISUAL, \$EDITOR)."
 | 
			
		||||
		fi
 | 
			
		||||
		[[ -s $msgfile ]] || die
 | 
			
		||||
		stat_busy 'Committing changes'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										57
									
								
								src/lib/api/archweb.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/lib/api/archweb.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
#!/hint/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_API_ARCHWEB_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_API_ARCHWEB_SH=1
 | 
			
		||||
 | 
			
		||||
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
 | 
			
		||||
# shellcheck source=src/lib/common.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
set -o pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
archweb_query_all_packages() {
 | 
			
		||||
	[[ -z ${WORKDIR:-} ]] && setup_workdir
 | 
			
		||||
 | 
			
		||||
	stat_busy "Query all released packages"
 | 
			
		||||
	mapfile -t pkgbases < <(
 | 
			
		||||
		curl --location --show-error --no-progress-meter --fail --retry 3 --retry-delay 3 \
 | 
			
		||||
			"${PKGBASE_MAINTAINER_URL}" 2> "${WORKDIR}/error" \
 | 
			
		||||
			| jq --raw-output --exit-status 'keys[]' 2> "${WORKDIR}/error"
 | 
			
		||||
	)
 | 
			
		||||
	if ! wait $!; then
 | 
			
		||||
		stat_failed
 | 
			
		||||
		print_workdir_error
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
	stat_done
 | 
			
		||||
 | 
			
		||||
	printf "%s\n" "${pkgbases[@]}"
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
archweb_query_maintainer_packages() {
 | 
			
		||||
	local maintainer=$1
 | 
			
		||||
 | 
			
		||||
	[[ -z ${WORKDIR:-} ]] && setup_workdir
 | 
			
		||||
 | 
			
		||||
	stat_busy "Query maintainer packages"
 | 
			
		||||
	mapfile -t pkgbases < <(
 | 
			
		||||
		curl --location --show-error --no-progress-meter --fail --retry 3 --retry-delay 3 \
 | 
			
		||||
			"${PKGBASE_MAINTAINER_URL}" 2> "${WORKDIR}/error" \
 | 
			
		||||
			| jq --raw-output --exit-status '. as $parent | keys[] | select(. as $key | $parent[$key] | index("'"${maintainer}"'"))' 2> "${WORKDIR}/error"
 | 
			
		||||
	)
 | 
			
		||||
	if ! wait $!; then
 | 
			
		||||
		stat_failed
 | 
			
		||||
		print_workdir_error
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
	stat_done
 | 
			
		||||
 | 
			
		||||
	printf "%s\n" "${pkgbases[@]}"
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
@@ -13,13 +13,63 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/config.sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
graphql_api_call() {
 | 
			
		||||
	local outfile=$1
 | 
			
		||||
	local request=$2
 | 
			
		||||
	local node_type=$3
 | 
			
		||||
	local data=$4
 | 
			
		||||
	local hasNextPage cursor
 | 
			
		||||
 | 
			
		||||
	# empty token
 | 
			
		||||
	if [[ -z "${GITLAB_TOKEN}" ]]; then
 | 
			
		||||
		msg_error "  api call failed: No token provided"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	[[ -z ${WORKDIR:-} ]] && setup_workdir
 | 
			
		||||
	api_workdir=$(mktemp --tmpdir="${WORKDIR}" --directory pkgctl-gitlab-api.XXXXXXXXXX)
 | 
			
		||||
 | 
			
		||||
	# normalize graphql data and prepare query
 | 
			
		||||
	data="${data//\"/\\\"}"
 | 
			
		||||
	data='{
 | 
			
		||||
		"query": "'"${data}"'"
 | 
			
		||||
	}'
 | 
			
		||||
	data="${data//$'\t'/ }"
 | 
			
		||||
	data="${data//$'\n'/}"
 | 
			
		||||
 | 
			
		||||
	cursor=""
 | 
			
		||||
	hasNextPage=true
 | 
			
		||||
	while [[ ${hasNextPage} == true ]]; do
 | 
			
		||||
		data=$(sed -E 's|after: \\"[a-zA-Z0-9]*\\"|after: \\"'"${cursor}"'\\"|' <<< "${data}")
 | 
			
		||||
		result="${api_workdir}/result.${cursor}"
 | 
			
		||||
 | 
			
		||||
		if ! curl --request "${request}" \
 | 
			
		||||
				--url "https://${GITLAB_HOST}/api/graphql" \
 | 
			
		||||
				--header "Authorization: Bearer ${GITLAB_TOKEN}" \
 | 
			
		||||
				--header "Content-Type: application/json" \
 | 
			
		||||
				--data "${data}" \
 | 
			
		||||
				--output "${result}" \
 | 
			
		||||
				--silent; then
 | 
			
		||||
			msg_error "  api call failed: $(cat "${outfile}")"
 | 
			
		||||
			return 1
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		hasNextPage=$(jq --raw-output ".data | .${node_type} | .pageInfo | .hasNextPage" < "${result}")
 | 
			
		||||
		cursor=$(jq --raw-output ".data | .${node_type} | .pageInfo | .endCursor" < "${result}")
 | 
			
		||||
 | 
			
		||||
		cp "${result}" "${api_workdir}/tmp"
 | 
			
		||||
		jq ".data.${node_type}.nodes" "${api_workdir}/tmp" > "${result}"
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	jq --slurp add "${api_workdir}"/result.* > "${outfile}"
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gitlab_api_call() {
 | 
			
		||||
	local outfile=$1
 | 
			
		||||
	local request=$2
 | 
			
		||||
	local endpoint=$3
 | 
			
		||||
	local data=${4:-}
 | 
			
		||||
	local error
 | 
			
		||||
 | 
			
		||||
	# empty token
 | 
			
		||||
	if [[ -z "${GITLAB_TOKEN}" ]]; then
 | 
			
		||||
@@ -38,27 +88,113 @@ gitlab_api_call() {
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if ! gitlab_check_api_errors "${outfile}"; then
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gitlab_api_call_paged() {
 | 
			
		||||
	local outfile=$1
 | 
			
		||||
	local status_file=$2
 | 
			
		||||
	local request=$3
 | 
			
		||||
	local endpoint=$4
 | 
			
		||||
	local data=${5:-}
 | 
			
		||||
	local result header
 | 
			
		||||
 | 
			
		||||
	# empty token
 | 
			
		||||
	if [[ -z "${GITLAB_TOKEN}" ]]; then
 | 
			
		||||
		msg_error "  api call failed: No token provided"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	[[ -z ${WORKDIR:-} ]] && setup_workdir
 | 
			
		||||
	api_workdir=$(mktemp --tmpdir="${WORKDIR}" --directory pkgctl-gitlab-api.XXXXXXXXXX)
 | 
			
		||||
	tmp_file=$(mktemp --tmpdir="${api_workdir}" spinner.tmp.XXXXXXXXXX)
 | 
			
		||||
 | 
			
		||||
	local next_page=1
 | 
			
		||||
	local total_pages=1
 | 
			
		||||
 | 
			
		||||
	while [[ -n "${next_page}" ]]; do
 | 
			
		||||
		percentage=$(( 100 * next_page / total_pages ))
 | 
			
		||||
		printf "📡 Querying GitLab: %s/%s [%s] %%spinner%%" \
 | 
			
		||||
			"${BOLD}${next_page}" "${total_pages}" "${percentage}%${ALL_OFF}"  \
 | 
			
		||||
			> "${tmp_file}"
 | 
			
		||||
		mv "${tmp_file}" "${status_file}"
 | 
			
		||||
 | 
			
		||||
		result="${api_workdir}/result.${next_page}"
 | 
			
		||||
		header="${api_workdir}/header"
 | 
			
		||||
		if ! curl --request "${request}" \
 | 
			
		||||
				--get \
 | 
			
		||||
				--url "https://${GITLAB_HOST}/api/v4/${endpoint}&per_page=100&page=${next_page}" \
 | 
			
		||||
				--header "PRIVATE-TOKEN: ${GITLAB_TOKEN}" \
 | 
			
		||||
				--header "Content-Type: application/json" \
 | 
			
		||||
				--data-urlencode "${data}" \
 | 
			
		||||
				--dump-header "${header}" \
 | 
			
		||||
				--output "${result}" \
 | 
			
		||||
				--silent; then
 | 
			
		||||
			msg_error "  api call failed: $(cat "${result}")"
 | 
			
		||||
			return 1
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		if ! gitlab_check_api_errors "${result}"; then
 | 
			
		||||
			return 1
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		next_page=$(grep "x-next-page" "${header}" | tr -d '\r' | awk '{ print $2 }')
 | 
			
		||||
		total_pages=$(grep "x-total-pages" "${header}" | tr -d '\r' | awk '{ print $2 }')
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	jq --slurp add "${api_workdir}"/result.* > "${outfile}"
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gitlab_check_api_errors() {
 | 
			
		||||
	local file=$1
 | 
			
		||||
	local error
 | 
			
		||||
 | 
			
		||||
	# search API only returns an array, no errors
 | 
			
		||||
	if [[ $(jq --raw-output 'type' < "${file}") == "array" ]]; then
 | 
			
		||||
		return 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# check for general purpose api error
 | 
			
		||||
	if error=$(jq --raw-output --exit-status '.error' < "${outfile}"); then
 | 
			
		||||
	if error=$(jq --raw-output --exit-status '.error' < "${file}"); 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
 | 
			
		||||
	if ! jq --raw-output --exit-status '.id' < "${file}" >/dev/null; then
 | 
			
		||||
		if jq --raw-output --exit-status '.message | keys[]' < "${file}" &>/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
 | 
			
		||||
			done < <(jq --raw-output --exit-status '.message|to_entries|map("\(.key) \(.value[])")[]' < "${file}")
 | 
			
		||||
		elif error=$(jq --raw-output --exit-status '.message' < "${file}"); then
 | 
			
		||||
			msg_error "  api call failed: ${error}"
 | 
			
		||||
		fi
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
graphql_check_api_errors() {
 | 
			
		||||
	local file=$1
 | 
			
		||||
	local error
 | 
			
		||||
 | 
			
		||||
	# early exit if we do not have errors
 | 
			
		||||
	if ! jq --raw-output --exit-status '.errors[]' < "${file}" &>/dev/null; then
 | 
			
		||||
		return 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# check for api specific error messages
 | 
			
		||||
	while read -r error; do
 | 
			
		||||
		msg_error "  api call failed: ${error}"
 | 
			
		||||
	done < <(jq --raw-output --exit-status '.errors[].message' < "${file}")
 | 
			
		||||
	return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gitlab_api_get_user() {
 | 
			
		||||
	local outfile username
 | 
			
		||||
 | 
			
		||||
@@ -81,6 +217,23 @@ gitlab_api_get_user() {
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gitlab_api_get_project_name_mapping() {
 | 
			
		||||
	local query=$1
 | 
			
		||||
	local outfile
 | 
			
		||||
 | 
			
		||||
	[[ -z ${WORKDIR:-} ]] && setup_workdir
 | 
			
		||||
	outfile=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api.XXXXXXXXXX)
 | 
			
		||||
 | 
			
		||||
	# query user details
 | 
			
		||||
	if ! graphql_api_call "${outfile}" POST projects "${query}"; then
 | 
			
		||||
		msg_warn "  Invalid token provided?"
 | 
			
		||||
		exit 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	cat "${outfile}"
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Convert arbitrary project names to GitLab valid path names.
 | 
			
		||||
#
 | 
			
		||||
# GitLab has several limitations on project and group names and also maintains
 | 
			
		||||
@@ -130,3 +283,22 @@ gitlab_api_create_project() {
 | 
			
		||||
	printf "%s" "${path}"
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# TODO: parallelize
 | 
			
		||||
# https://docs.gitlab.com/ee/api/search.html#scope-blobs
 | 
			
		||||
gitlab_api_search() {
 | 
			
		||||
	local search=$1
 | 
			
		||||
	local status_file=$2
 | 
			
		||||
	local outfile
 | 
			
		||||
 | 
			
		||||
	[[ -z ${WORKDIR:-} ]] && setup_workdir
 | 
			
		||||
	outfile=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api.XXXXXXXXXX)
 | 
			
		||||
 | 
			
		||||
	if ! gitlab_api_call_paged "${outfile}" "${status_file}" GET "/groups/archlinux%2fpackaging%2fpackages/search?scope=blobs" "search=${search}"; then
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	cat "${outfile}"
 | 
			
		||||
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										65
									
								
								src/lib/aur.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/lib/aur.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
#!/hint/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_AUR_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_AUR_SH=1
 | 
			
		||||
 | 
			
		||||
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
 | 
			
		||||
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pkgctl_aur_usage() {
 | 
			
		||||
	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
 | 
			
		||||
	cat <<- _EOF_
 | 
			
		||||
		Usage: ${COMMAND} [COMMAND] [OPTIONS]
 | 
			
		||||
 | 
			
		||||
		Interact with the Arch User Repository (AUR).
 | 
			
		||||
 | 
			
		||||
		Provides a suite of tools designed for managing and interacting with the Arch
 | 
			
		||||
		User Repository (AUR). It simplifies various tasks related to AUR, including
 | 
			
		||||
		importing repositories, managing packages, and transitioning packages between
 | 
			
		||||
		the official repositories and the AUR.
 | 
			
		||||
 | 
			
		||||
		COMMANDS
 | 
			
		||||
		    drop-from-repo    Drop a package from the official repository to the AUR
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    -h, --help        Show this help text
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND} drop-from-repo libfoo
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_aur() {
 | 
			
		||||
	if (( $# < 1 )); then
 | 
			
		||||
		pkgctl_aur_usage
 | 
			
		||||
		exit 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# option checking
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
		case $1 in
 | 
			
		||||
			-h|--help)
 | 
			
		||||
				pkgctl_aur_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			drop-from-repo)
 | 
			
		||||
				_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
				shift
 | 
			
		||||
				# shellcheck source=src/lib/aur/drop-from-repo.sh
 | 
			
		||||
				source "${_DEVTOOLS_LIBRARY_DIR}"/lib/aur/drop-from-repo.sh
 | 
			
		||||
				pkgctl_aur_drop_from_repo "$@"
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			-*)
 | 
			
		||||
				die "invalid argument: %s" "$1"
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				die "invalid command: %s" "$1"
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										173
									
								
								src/lib/aur/drop-from-repo.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								src/lib/aur/drop-from-repo.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,173 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_AUR_DROP_FROM_REPO_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_AUR_DROP_FROM_REPO_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/remove.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/remove.sh
 | 
			
		||||
# shellcheck source=src//lib/util/pacman.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/message.sh
 | 
			
		||||
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pkgctl_aur_drop_from_repo_usage() {
 | 
			
		||||
	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
 | 
			
		||||
	cat <<- _EOF_
 | 
			
		||||
		Usage: ${COMMAND} [OPTIONS] [PATH]...
 | 
			
		||||
 | 
			
		||||
		Drops a specified package from the official repositories to the Arch
 | 
			
		||||
		User Repository.
 | 
			
		||||
 | 
			
		||||
		This command requires a local Git clone of the package repository. It
 | 
			
		||||
		reconfigures the repository for AUR compatibility and pushes it to the
 | 
			
		||||
		AUR. Afterwards, the package is removed from the official repository.
 | 
			
		||||
 | 
			
		||||
		By default, the package is automatically disowned in the AUR.
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    --no-disown    Do not disown the package on the AUR
 | 
			
		||||
		    -f, --force    Force push to the AUR overwriting the remote repository
 | 
			
		||||
		    -h, --help     Show this help text
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND} foo
 | 
			
		||||
		    $ ${COMMAND} --no-disown --force
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_aur_drop_from_repo() {
 | 
			
		||||
	# options
 | 
			
		||||
	local paths=()
 | 
			
		||||
	local DISOWN=1
 | 
			
		||||
	local FORCE=0
 | 
			
		||||
 | 
			
		||||
	# variables
 | 
			
		||||
	local path realpath pkgbase pkgrepo remote_url
 | 
			
		||||
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
		case $1 in
 | 
			
		||||
			-h|--help)
 | 
			
		||||
				pkgctl_aur_drop_from_repo_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			--no-disown)
 | 
			
		||||
				DISOWN=0
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-f|--force)
 | 
			
		||||
				FORCE=1
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--)
 | 
			
		||||
				shift
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			-*)
 | 
			
		||||
				die "Invalid argument: %s" "$1"
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				paths=("$@")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# check if invoked without any path from within a packaging repo
 | 
			
		||||
	if (( ${#paths[@]} == 0 )); then
 | 
			
		||||
		if [[ -f PKGBUILD ]]; then
 | 
			
		||||
			paths=(".")
 | 
			
		||||
		else
 | 
			
		||||
			pkgctl_aur_drop_from_repo_usage
 | 
			
		||||
			exit 1
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	for path in "${paths[@]}"; do
 | 
			
		||||
		# resolve symlink for basename
 | 
			
		||||
		if ! realpath=$(realpath --canonicalize-existing -- "${path}"); then
 | 
			
		||||
			die "No such directory: ${path}"
 | 
			
		||||
		fi
 | 
			
		||||
		# skip paths that are not directories
 | 
			
		||||
		if [[ ! -d "${realpath}" ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		pkgbase=$(basename "${realpath}")
 | 
			
		||||
		pkgbase=${pkgbase%.git}
 | 
			
		||||
 | 
			
		||||
		if [[ ! -d "${realpath}/.git" ]]; then
 | 
			
		||||
			die "Not a Git repository: ${path}"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		pushd "${path}" >/dev/null
 | 
			
		||||
 | 
			
		||||
		if [[ ! -f PKGBUILD ]]; then
 | 
			
		||||
			die 'PKGBUILD not found in %s' "${path}"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		msg "Dropping ${pkgbase} to the AUR"
 | 
			
		||||
 | 
			
		||||
		remote_url="${AUR_URL_SSH}:${pkgbase}.git"
 | 
			
		||||
		if ! git remote add origin "${remote_url}" &>/dev/null; then
 | 
			
		||||
			git remote set-url origin "${remote_url}"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# move the main branch to master
 | 
			
		||||
		if [[ $(git symbolic-ref --quiet --short HEAD) == main ]]; then
 | 
			
		||||
			git branch --move master
 | 
			
		||||
			git config branch.master.merge refs/heads/master
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# auto generate .SRCINFO if not already present
 | 
			
		||||
		if [[ -z "$(git ls-tree -r HEAD --name-only .SRCINFO)" ]]; then
 | 
			
		||||
			stat_busy 'Generating .SRCINFO'
 | 
			
		||||
			makepkg --printsrcinfo > .SRCINFO
 | 
			
		||||
			stat_done
 | 
			
		||||
 | 
			
		||||
			git add --force -- .SRCINFO
 | 
			
		||||
			git commit --quiet --message "Adding .SRCINFO" -- .SRCINFO
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		msg "Pushing ${pkgbase} to the AUR"
 | 
			
		||||
		if (( FORCE )); then
 | 
			
		||||
			AUR_OVERWRITE=1 \
 | 
			
		||||
				GIT_SSH_COMMAND="ssh -o SendEnv=AUR_OVERWRITE" \
 | 
			
		||||
				git push --force --no-follow-tags origin master
 | 
			
		||||
		else
 | 
			
		||||
			git push --no-follow-tags origin master
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# update the local default branch in case this clone is used in the future
 | 
			
		||||
		git remote set-head origin master
 | 
			
		||||
 | 
			
		||||
		if (( DISOWN )); then
 | 
			
		||||
			msg "Disowning ${pkgbase} on the AUR"
 | 
			
		||||
			# shellcheck disable=SC2029
 | 
			
		||||
			ssh "${AUR_URL_SSH}" disown "${pkgbase}"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# auto-detection of the repo to remove from
 | 
			
		||||
		if ! pkgrepo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then
 | 
			
		||||
			die 'Failed to get pacman repo'
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		msg "Deleting ${pkgbase} from the official repository"
 | 
			
		||||
		if [[ -z "${pkgrepo}" ]]; then
 | 
			
		||||
			warning 'Did not find %s in any repository, please delete manually' "${pkgbase}"
 | 
			
		||||
		else
 | 
			
		||||
			msg2 "  repo: ${pkgrepo}"
 | 
			
		||||
			pkgctl_db_remove --noconfirm "${pkgrepo}" "${pkgbase}"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		popd >/dev/null
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
@@ -63,7 +63,7 @@ pkgctl_auth_login() {
 | 
			
		||||
		esac
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	personal_access_token_url="https://${GITLAB_HOST}/-/profile/personal_access_tokens?name=pkgctl+token&scopes=api,write_repository"
 | 
			
		||||
	personal_access_token_url="https://${GITLAB_HOST}/-/user_settings/personal_access_tokens?name=pkgctl+token&scopes=api,write_repository"
 | 
			
		||||
 | 
			
		||||
    cat <<- _EOF_
 | 
			
		||||
	Logging into ${BOLD}${GITLAB_HOST}${ALL_OFF}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,18 +14,25 @@ source "${_DEVTOOLS_LIBRARY_DIR}"/lib/db/update.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/srcinfo.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/srcinfo.sh
 | 
			
		||||
# shellcheck source=src/lib/util/pacman.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh
 | 
			
		||||
# shellcheck source=src/lib/util/pkgbuild.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pkgbuild.sh
 | 
			
		||||
# shellcheck source=src/lib/valid-build-install.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-build-install.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
 | 
			
		||||
# shellcheck source=src/lib/valid-inspect.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/config.sh
 | 
			
		||||
source /usr/share/makepkg/util/message.sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
set -o pipefail
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pkgctl_build_usage() {
 | 
			
		||||
@@ -42,19 +49,25 @@ pkgctl_build_usage() {
 | 
			
		||||
 | 
			
		||||
		BUILD OPTIONS
 | 
			
		||||
		    --arch ARCH          Specify architectures to build for (disables auto-detection)
 | 
			
		||||
		    --repo REPO          Specify a target repository (disables auto-detection)
 | 
			
		||||
		    --repo REPO          Specify target repository for new packages not in any official repo
 | 
			
		||||
		    -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
 | 
			
		||||
		    --inspect WHEN       Spawn an interactive shell to inspect the chroot (never, always, failure)
 | 
			
		||||
		    --offline MODE       Run a part of the build process offline (build, check)
 | 
			
		||||
		    -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
 | 
			
		||||
 | 
			
		||||
		INSTALL OPTIONS
 | 
			
		||||
		    -I, --install-to-chroot FILE   Install a package to the working copy of the chroot
 | 
			
		||||
		    -i, --install-to-host MODE     Install the built package to the host system, possible modes are 'all' and 'auto'
 | 
			
		||||
 | 
			
		||||
		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
 | 
			
		||||
		    --update-checksums   Force computation and update of the checksums (disables auto-detection)
 | 
			
		||||
		    -e, --edit           Edit the PKGBUILD before building
 | 
			
		||||
 | 
			
		||||
		RELEASE OPTIONS
 | 
			
		||||
@@ -67,8 +80,8 @@ pkgctl_build_usage() {
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND}
 | 
			
		||||
		    $ ${COMMAND} --rebuild --staging --message 'libyay 0.42 rebuild' libfoo libbar
 | 
			
		||||
		    $ ${COMMAND} --pkgver 1.42 --release --db-update
 | 
			
		||||
		    $ ${COMMAND} --rebuild --staging --release --message 'libyay 0.42 rebuild' libfoo libbar
 | 
			
		||||
		    $ ${COMMAND} --pkgver=1.42 --release --db-update
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -77,8 +90,7 @@ pkgctl_build_check_option_group_repo() {
 | 
			
		||||
	local repo=$2
 | 
			
		||||
	local testing=$3
 | 
			
		||||
	local staging=$4
 | 
			
		||||
	if ( (( testing )) && (( staging )) ) ||
 | 
			
		||||
		( [[ $repo =~ ^.*-(staging|testing)$ ]] && ( (( testing )) || (( staging )) )); then
 | 
			
		||||
	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
 | 
			
		||||
@@ -104,7 +116,7 @@ pkgctl_build() {
 | 
			
		||||
		exit 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	local UPDPKGSUMS=0
 | 
			
		||||
	local UPDATE_CHECKSUMS=0
 | 
			
		||||
	local EDIT=0
 | 
			
		||||
	local REBUILD=0
 | 
			
		||||
	local OFFLOAD=0
 | 
			
		||||
@@ -112,6 +124,7 @@ pkgctl_build() {
 | 
			
		||||
	local TESTING=0
 | 
			
		||||
	local RELEASE=0
 | 
			
		||||
	local DB_UPDATE=0
 | 
			
		||||
	local INSTALL_TO_HOST=none
 | 
			
		||||
 | 
			
		||||
	local REPO=
 | 
			
		||||
	local PKGVER=
 | 
			
		||||
@@ -124,12 +137,13 @@ pkgctl_build() {
 | 
			
		||||
	local MAKECHROOT_OPTIONS=()
 | 
			
		||||
	local RELEASE_OPTIONS=()
 | 
			
		||||
	local MAKEPKG_OPTIONS=()
 | 
			
		||||
	local INSTALL_HOST_PACKAGES=()
 | 
			
		||||
 | 
			
		||||
	local WORKER=
 | 
			
		||||
	local WORKER_SLOT=
 | 
			
		||||
 | 
			
		||||
	# variables
 | 
			
		||||
	local loop_arch path pkgbase pkgrepo source
 | 
			
		||||
	local _arch path pkgbase pkgrepo source pkgbuild_checksum current_checksum
 | 
			
		||||
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
		case $1 in
 | 
			
		||||
@@ -139,18 +153,19 @@ pkgctl_build() {
 | 
			
		||||
				;;
 | 
			
		||||
			--repo)
 | 
			
		||||
				(( $# <= 1 )) && die "missing argument for %s" "$1"
 | 
			
		||||
				REPO="${2}"
 | 
			
		||||
				pkgctl_build_check_option_group_repo '--repo' "${REPO}" "${TESTING}" "${STAGING}"
 | 
			
		||||
				REPO="${2}"
 | 
			
		||||
				RELEASE_OPTIONS+=("--repo" "${REPO}")
 | 
			
		||||
				shift 2
 | 
			
		||||
				;;
 | 
			
		||||
			--arch)
 | 
			
		||||
				(( $# <= 1 )) && die "missing argument for %s" "$1"
 | 
			
		||||
				if [[ ${2} == all ]]; then
 | 
			
		||||
					BUILD_ARCH=("${_arch[@]::${#_arch[@]}-1}")
 | 
			
		||||
					BUILD_ARCH=("${DEVTOOLS_VALID_ARCHES[@]::${#DEVTOOLS_VALID_ARCHES[@]}-1}")
 | 
			
		||||
				elif [[ ${2} == any ]]; then
 | 
			
		||||
					BUILD_ARCH=("${_arch[0]}")
 | 
			
		||||
					BUILD_ARCH=("${DEVTOOLS_VALID_ARCHES[0]}")
 | 
			
		||||
				elif ! in_array "${2}" "${BUILD_ARCH[@]}"; then
 | 
			
		||||
					if ! in_array "${2}" "${_arch[@]}"; then
 | 
			
		||||
					if ! in_array "${2}" "${DEVTOOLS_VALID_ARCHES[@]}"; then
 | 
			
		||||
						die 'invalid architecture: %s' "${2}"
 | 
			
		||||
					fi
 | 
			
		||||
					BUILD_ARCH+=("${2}")
 | 
			
		||||
@@ -161,7 +176,7 @@ pkgctl_build() {
 | 
			
		||||
				pkgctl_build_check_option_group_ver '--pkgver' "${PKGVER}" "${PKGREL}" "${REBUILD}"
 | 
			
		||||
				PKGVER="${1#*=}"
 | 
			
		||||
				PKGREL=1
 | 
			
		||||
				UPDPKGSUMS=1
 | 
			
		||||
				UPDATE_CHECKSUMS=1
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--pkgrel=*)
 | 
			
		||||
@@ -169,6 +184,10 @@ pkgctl_build() {
 | 
			
		||||
				PKGREL="${1#*=}"
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--update-checksums)
 | 
			
		||||
				UPDATE_CHECKSUMS=1
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--rebuild)
 | 
			
		||||
				# shellcheck source=src/lib/util/git.sh
 | 
			
		||||
				source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/git.sh
 | 
			
		||||
@@ -180,28 +199,46 @@ pkgctl_build() {
 | 
			
		||||
				EDIT=1
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--offline)
 | 
			
		||||
				MAKECHROOT_OPTIONS+=("-o" "$2")
 | 
			
		||||
				shift 2
 | 
			
		||||
				;;
 | 
			
		||||
			-o|--offload)
 | 
			
		||||
				OFFLOAD=1
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-s|--staging)
 | 
			
		||||
				STAGING=1
 | 
			
		||||
				pkgctl_build_check_option_group_repo '--staging' "${REPO}" "${TESTING}" "${STAGING}"
 | 
			
		||||
				STAGING=1
 | 
			
		||||
				RELEASE_OPTIONS+=("--staging")
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-t|--testing)
 | 
			
		||||
				TESTING=1
 | 
			
		||||
				pkgctl_build_check_option_group_repo '--testing' "${REPO}" "${TESTING}" "${STAGING}"
 | 
			
		||||
				TESTING=1
 | 
			
		||||
				RELEASE_OPTIONS+=("--testing")
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-c|--clean)
 | 
			
		||||
				BUILD_OPTIONS+=("-c")
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-I|--install)
 | 
			
		||||
			-I|--install-to-chroot)
 | 
			
		||||
				(( $# <= 1 )) && die "missing argument for %s" "$1"
 | 
			
		||||
				if (( OFFLOAD )); then
 | 
			
		||||
					MAKECHROOT_OPTIONS+=("-I" "$2")
 | 
			
		||||
				warning 'installing packages into the chroot may break reproducible builds, use with caution!'
 | 
			
		||||
				else
 | 
			
		||||
					MAKECHROOT_OPTIONS+=("-I" "$(realpath "$2")")
 | 
			
		||||
				fi
 | 
			
		||||
				warning 'installing packages to the chroot may break reproducible builds, use with caution!'
 | 
			
		||||
				shift 2
 | 
			
		||||
				;;
 | 
			
		||||
			-i|--install-to-host)
 | 
			
		||||
				(( $# <= 1 )) && die "missing argument for %s" "$1"
 | 
			
		||||
				if ! in_array "$2" "${DEVTOOLS_VALID_BUILD_INSTALL[@]}"; then
 | 
			
		||||
					die 'invalid install mode: %s' "${2}"
 | 
			
		||||
				fi
 | 
			
		||||
				INSTALL_TO_HOST=$2
 | 
			
		||||
				shift 2
 | 
			
		||||
				;;
 | 
			
		||||
			--nocheck)
 | 
			
		||||
@@ -209,6 +246,14 @@ pkgctl_build() {
 | 
			
		||||
				warning 'not running checks is disallowed for official packages, except for bootstrapping. Please rebuild after bootstrapping is completed!'
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--inspect)
 | 
			
		||||
				(( $# <= 1 )) && die "missing argument for %s" "$1"
 | 
			
		||||
				if ! in_array "${2}" "${DEVTOOLS_VALID_INSPECT_MODES[@]}"; then
 | 
			
		||||
					die "Invalid inspect mode: %s" "${2}"
 | 
			
		||||
				fi
 | 
			
		||||
				MAKECHROOT_OPTIONS+=("-x" "${2}")
 | 
			
		||||
				shift 2
 | 
			
		||||
				;;
 | 
			
		||||
			-r|--release)
 | 
			
		||||
				# shellcheck source=src/lib/release.sh
 | 
			
		||||
				source "${_DEVTOOLS_LIBRARY_DIR}"/lib/release.sh
 | 
			
		||||
@@ -272,13 +317,17 @@ pkgctl_build() {
 | 
			
		||||
 | 
			
		||||
	# Update pacman cache for auto-detection
 | 
			
		||||
	if [[ -z ${REPO} ]]; then
 | 
			
		||||
		update_pacman_repo_cache
 | 
			
		||||
		update_pacman_repo_cache multilib
 | 
			
		||||
	# Check valid repos if not resolved dynamically
 | 
			
		||||
	elif ! in_array "${REPO}" "${_repos[@]}"; then
 | 
			
		||||
	elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then
 | 
			
		||||
		die "Invalid repository target: %s" "${REPO}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	for path in "${paths[@]}"; do
 | 
			
		||||
		# skip paths that are not directories
 | 
			
		||||
		if [[ ! -d "${path}" ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
		pushd "${path}" >/dev/null
 | 
			
		||||
 | 
			
		||||
		if [[ ! -f PKGBUILD ]]; then
 | 
			
		||||
@@ -290,18 +339,32 @@ pkgctl_build() {
 | 
			
		||||
		. ./PKGBUILD
 | 
			
		||||
		pkgbase=${pkgbase:-$pkgname}
 | 
			
		||||
		pkgrepo=${REPO}
 | 
			
		||||
		pkgbuild_checksum=$(b2sum PKGBUILD | awk '{print $1}')
 | 
			
		||||
		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'
 | 
			
		||||
		# auto-detect target repository
 | 
			
		||||
		if ! repo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then
 | 
			
		||||
			die 'Failed to query pacman repo'
 | 
			
		||||
		fi
 | 
			
		||||
			if [[ -z "${pkgrepo}" ]]; then
 | 
			
		||||
				die 'unknown repo, specify --repo for packages not currently in any official repo'
 | 
			
		||||
 | 
			
		||||
		# fail if an existing package specifies --repo
 | 
			
		||||
		if [[ -n "${repo}" ]] && [[ -n ${pkgrepo} ]]; then
 | 
			
		||||
			# allow unstable to use --repo
 | 
			
		||||
			if [[ ${pkgrepo} == *unstable ]]; then
 | 
			
		||||
				repo=${pkgrepo}
 | 
			
		||||
			else
 | 
			
		||||
				die 'Using --repo for packages that exist in official repositories is disallowed'
 | 
			
		||||
			fi
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# assign auto-detected target repository
 | 
			
		||||
		if [[ -n ${repo} ]]; then
 | 
			
		||||
			pkgrepo=${repo}
 | 
			
		||||
		# fallback to extra for unreleased packages
 | 
			
		||||
		elif [[ -z ${pkgrepo} ]]; then
 | 
			
		||||
			pkgrepo=extra
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# special cases to resolve final build target
 | 
			
		||||
		if (( TESTING )); then
 | 
			
		||||
			pkgrepo="${pkgrepo}-testing"
 | 
			
		||||
@@ -316,13 +379,13 @@ pkgctl_build() {
 | 
			
		||||
			BUILD_ARCH=("")
 | 
			
		||||
		elif (( ${#BUILD_ARCH[@]} == 0 )); then
 | 
			
		||||
			if in_array any "${arch[@]}"; then
 | 
			
		||||
				BUILD_ARCH=("${_arch[0]}")
 | 
			
		||||
				BUILD_ARCH=("${DEVTOOLS_VALID_ARCHES[0]}")
 | 
			
		||||
			else
 | 
			
		||||
				for loop_arch in "${arch[@]}"; do 
 | 
			
		||||
					if in_array "${loop_arch}" "${_arch[@]}"; then
 | 
			
		||||
						BUILD_ARCH+=("$loop_arch")
 | 
			
		||||
				for _arch in "${arch[@]}"; do
 | 
			
		||||
					if in_array "${_arch}" "${DEVTOOLS_VALID_ARCHES[@]}"; then
 | 
			
		||||
						BUILD_ARCH+=("$_arch")
 | 
			
		||||
					else
 | 
			
		||||
						warning 'invalid architecture, not building for: %s' "${loop_arch}"
 | 
			
		||||
						warning 'invalid architecture, not building for: %s' "${_arch}"
 | 
			
		||||
					fi
 | 
			
		||||
				done
 | 
			
		||||
			fi
 | 
			
		||||
@@ -352,20 +415,14 @@ pkgctl_build() {
 | 
			
		||||
 | 
			
		||||
		# 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
 | 
			
		||||
			pkgbuild_set_pkgver "${PKGVER}"
 | 
			
		||||
		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
 | 
			
		||||
			pkgbuild_set_pkgrel "${PKGREL}"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# edit PKGBUILD
 | 
			
		||||
@@ -385,10 +442,19 @@ pkgctl_build() {
 | 
			
		||||
			stat_done
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		# update checksums if any sources are declared
 | 
			
		||||
		if (( UPDPKGSUMS )) && (( ${#source[@]} >= 1 )); then
 | 
			
		||||
			updpkgsums
 | 
			
		||||
		if (( UPDATE_CHECKSUMS )) && (( ${#source[@]} >= 1 )); then
 | 
			
		||||
			if ! result=$(pkgbuild_update_checksums /dev/stderr); then
 | 
			
		||||
				die "${result}"
 | 
			
		||||
			fi
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# re-source the PKGBUILD if it changed
 | 
			
		||||
		current_checksum="$(b2sum PKGBUILD | awk '{print $1}')"
 | 
			
		||||
		if [[ ${pkgbuild_checksum} != "${current_checksum}" ]]; then
 | 
			
		||||
			pkgbuild_checksum=${current_checksum}
 | 
			
		||||
			# shellcheck source=contrib/makepkg/PKGBUILD.proto
 | 
			
		||||
			. ./PKGBUILD
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# execute build
 | 
			
		||||
@@ -408,9 +474,41 @@ pkgctl_build() {
 | 
			
		||||
			fi
 | 
			
		||||
		done
 | 
			
		||||
 | 
			
		||||
		# re-source the PKGBUILD if it changed
 | 
			
		||||
		current_checksum="$(b2sum PKGBUILD | awk '{print $1}')"
 | 
			
		||||
		if [[ ${pkgbuild_checksum} != "${current_checksum}" ]]; then
 | 
			
		||||
			pkgbuild_checksum=${current_checksum}
 | 
			
		||||
			# shellcheck source=contrib/makepkg/PKGBUILD.proto
 | 
			
		||||
			. ./PKGBUILD
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# auto generate .SRCINFO
 | 
			
		||||
		# shellcheck disable=SC2119
 | 
			
		||||
		write_srcinfo_file
 | 
			
		||||
 | 
			
		||||
		# test-install (some of) the produced packages
 | 
			
		||||
		if [[ ${INSTALL_TO_HOST} == auto ]] || [[ ${INSTALL_TO_HOST} == all ]]; then
 | 
			
		||||
			# shellcheck disable=2119
 | 
			
		||||
			load_makepkg_config
 | 
			
		||||
 | 
			
		||||
			# this is inspired by print_all_package_names from libmakepkg
 | 
			
		||||
			local version pkg_architecture pkg pkgfile
 | 
			
		||||
			version=$(get_full_version)
 | 
			
		||||
 | 
			
		||||
			for pkg in "${pkgname[@]}"; do
 | 
			
		||||
				pkg_architecture=$(get_pkg_arch "$pkg")
 | 
			
		||||
				pkgfile=$(realpath "$(printf "%s/%s-%s-%s%s\n" "${PKGDEST:-.}" "$pkg" "$version" "$pkg_architecture" "$PKGEXT")")
 | 
			
		||||
 | 
			
		||||
				# check if we install all packages or if the (split-)package is already installed
 | 
			
		||||
				if [[ ${INSTALL_TO_HOST} == all ]] || ( [[ ${INSTALL_TO_HOST} == auto ]] && pacman -Qq -- "$pkg" &>/dev/null ); then
 | 
			
		||||
					INSTALL_HOST_PACKAGES+=("$pkgfile")
 | 
			
		||||
				fi
 | 
			
		||||
			done
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# release the build
 | 
			
		||||
		if (( RELEASE )); then
 | 
			
		||||
			pkgctl_release --repo "${pkgrepo}" "${RELEASE_OPTIONS[@]}"
 | 
			
		||||
			pkgctl_release "${RELEASE_OPTIONS[@]}"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# reset common PKGBUILD variables
 | 
			
		||||
@@ -418,6 +516,12 @@ pkgctl_build() {
 | 
			
		||||
		popd >/dev/null
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# install all collected packages to the host system
 | 
			
		||||
	if (( ${#INSTALL_HOST_PACKAGES[@]} )); then
 | 
			
		||||
		msg "Installing built packages to the host system"
 | 
			
		||||
		sudo pacman -U -- "${INSTALL_HOST_PACKAGES[@]}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# update the binary package repo db as last action
 | 
			
		||||
	if (( RELEASE )) && (( DB_UPDATE )); then
 | 
			
		||||
		# shellcheck disable=2119
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								src/lib/cache.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/lib/cache.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
#!/hint/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_CACHE_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_CACHE_SH=1
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
readonly XDG_DEVTOOLS_CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/devtools"
 | 
			
		||||
 | 
			
		||||
get_cache_file() {
 | 
			
		||||
	local filename=$1
 | 
			
		||||
	local path="${XDG_DEVTOOLS_CACHE_DIR}/${filename}"
 | 
			
		||||
 | 
			
		||||
	mkdir --parents -- "$(dirname -- "$path")"
 | 
			
		||||
	if [[ ! -f ${path} ]]; then
 | 
			
		||||
		touch -- "${path}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	printf '%s' "${path}"
 | 
			
		||||
}
 | 
			
		||||
@@ -13,7 +13,10 @@ set +u +o posix
 | 
			
		||||
$DEVTOOLS_INCLUDE_COMMON_SH
 | 
			
		||||
 | 
			
		||||
# Avoid any encoding problems
 | 
			
		||||
export LANG=C
 | 
			
		||||
export LANG=C.UTF-8
 | 
			
		||||
 | 
			
		||||
# Avoid systemd trying to color the terminal on systemd-nspawn
 | 
			
		||||
export SYSTEMD_TINT_BACKGROUND=no
 | 
			
		||||
 | 
			
		||||
# Set buildtool properties
 | 
			
		||||
export BUILDTOOL=devtools
 | 
			
		||||
@@ -22,19 +25,44 @@ 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_REPO_SPEC_VERSION=2
 | 
			
		||||
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
 | 
			
		||||
export PKGBASE_MAINTAINER_URL=https://archlinux.org/packages/pkgbase-maintainer
 | 
			
		||||
export AUR_URL_SSH=aur@aur.archlinux.org
 | 
			
		||||
 | 
			
		||||
export RSYNC_OPTS=(
 | 
			
		||||
  --rsh=ssh
 | 
			
		||||
  --checksum
 | 
			
		||||
  --copy-links
 | 
			
		||||
  --human-readable
 | 
			
		||||
  --progress
 | 
			
		||||
  --partial
 | 
			
		||||
  --partial-dir=.partial
 | 
			
		||||
  --delay-updates
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# ensure TERM is set with a fallback to dumb
 | 
			
		||||
export TERM=${TERM:-dumb}
 | 
			
		||||
 | 
			
		||||
# check if messages are to be printed using color
 | 
			
		||||
if [[ -t 2 && "$TERM" != dumb ]] || [[ ${DEVTOOLS_COLOR} == always ]]; then
 | 
			
		||||
	colorize
 | 
			
		||||
	if tput setaf 0 &>/dev/null; then
 | 
			
		||||
		PURPLE="$(tput setaf 5)"
 | 
			
		||||
		DARK_GREEN="$(tput setaf 2)"
 | 
			
		||||
		UNDERLINE="$(tput smul)"
 | 
			
		||||
	else
 | 
			
		||||
		PURPLE="\e[35m"
 | 
			
		||||
		DARK_GREEN="\e[32m"
 | 
			
		||||
		UNDERLINE="\e[4m"
 | 
			
		||||
	fi
 | 
			
		||||
else
 | 
			
		||||
	# shellcheck disable=2034
 | 
			
		||||
	declare -gr ALL_OFF='' BOLD='' BLUE='' GREEN='' RED='' YELLOW=''
 | 
			
		||||
	declare -gr ALL_OFF='' BOLD='' BLUE='' GREEN='' RED='' YELLOW='' PURPLE='' DARK_GREEN='' UNDERLINE=''
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
stat_busy() {
 | 
			
		||||
@@ -53,6 +81,11 @@ stat_done() {
 | 
			
		||||
	printf "${BOLD}done${ALL_OFF}\n" >&2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
stat_failed() {
 | 
			
		||||
	# shellcheck disable=2059
 | 
			
		||||
	printf "${BOLD}${RED}failed${ALL_OFF}\n" >&2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
msg_success() {
 | 
			
		||||
	local msg=$1
 | 
			
		||||
	local padding
 | 
			
		||||
@@ -77,7 +110,18 @@ msg_warn() {
 | 
			
		||||
	printf "%s %s\n" "${padding}${YELLOW}!${ALL_OFF}" "${msg}" >&2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
print_workdir_error() {
 | 
			
		||||
	if [[ ! -f "${WORKDIR}"/error ]]; then
 | 
			
		||||
		return
 | 
			
		||||
	fi
 | 
			
		||||
	while read -r LINE; do
 | 
			
		||||
		error '%s' "${LINE}"
 | 
			
		||||
	done < "${WORKDIR}/error"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_setup_workdir=false
 | 
			
		||||
# Ensure that there is no outside value for WORKDIR leaking in
 | 
			
		||||
unset WORKDIR
 | 
			
		||||
setup_workdir() {
 | 
			
		||||
	[[ -z ${WORKDIR:-} ]] && WORKDIR=$(mktemp -d --tmpdir "${0##*/}.XXXXXXXXXX")
 | 
			
		||||
	_setup_workdir=true
 | 
			
		||||
@@ -89,6 +133,9 @@ cleanup() {
 | 
			
		||||
	if [[ -n ${WORKDIR:-} ]] && $_setup_workdir; then
 | 
			
		||||
		rm -rf "$WORKDIR"
 | 
			
		||||
	fi
 | 
			
		||||
	if tput setaf 0 &>/dev/null; then
 | 
			
		||||
		tput cnorm >&2
 | 
			
		||||
	fi
 | 
			
		||||
	exit "${1:-0}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -120,7 +167,7 @@ lock() {
 | 
			
		||||
	# Only reopen the FD if it wasn't handed to us
 | 
			
		||||
	if ! [[ "/dev/fd/$1" -ef "$2" ]]; then
 | 
			
		||||
		mkdir -p -- "$(dirname -- "$2")"
 | 
			
		||||
		eval "exec $1>"'"$2"'
 | 
			
		||||
		eval "exec $1>>"'"$2"'
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if ! flock -n "$1"; then
 | 
			
		||||
@@ -311,3 +358,17 @@ is_debug_package() {
 | 
			
		||||
	pkgdesc="$(getpkgdesc "${pkgfile}")"
 | 
			
		||||
	[[ ${pkgdesc} == "Detached debugging symbols for "* && ${pkgbase}-debug = "${pkgname}" ]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Proxy function to check if a file exists. Using [[ -f ... ]] directly is not
 | 
			
		||||
# always wanted because we might want to expand bash globs first. This way we
 | 
			
		||||
# can pass unquoted globs to is_globfile() and have them expanded as function
 | 
			
		||||
# arguments before being checked.
 | 
			
		||||
is_globfile() {
 | 
			
		||||
	[[ -f $1 ]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
join_by() {
 | 
			
		||||
	local IFS="$1"
 | 
			
		||||
	shift
 | 
			
		||||
	echo "$*"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ pkgctl_db_usage() {
 | 
			
		||||
	cat <<- _EOF_
 | 
			
		||||
		Usage: ${COMMAND} [COMMAND] [OPTIONS]
 | 
			
		||||
 | 
			
		||||
		Pacman database modification for packge update, move etc
 | 
			
		||||
		Pacman database modification for package update, move etc
 | 
			
		||||
 | 
			
		||||
		COMMANDS
 | 
			
		||||
		    move      Move packages between pacman repositories
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,12 @@ 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
 | 
			
		||||
# shellcheck source=src/lib/util/pacman.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pacman.sh
 | 
			
		||||
# shellcheck source=src/lib/util/term.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/term.sh
 | 
			
		||||
# shellcheck source=src/lib/valid-repos.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-repos.sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
@@ -17,10 +23,19 @@ pkgctl_db_remove_usage() {
 | 
			
		||||
	cat <<- _EOF_
 | 
			
		||||
		Usage: ${COMMAND} [OPTIONS] [REPO] [PKGBASE]...
 | 
			
		||||
 | 
			
		||||
		Remove packages from binary repositories.
 | 
			
		||||
		Remove packages from pacman repositories. By default passing a pkgbase removes
 | 
			
		||||
		all split packages, debug packages as well as entries from the state repo for
 | 
			
		||||
		all existing architectures.
 | 
			
		||||
 | 
			
		||||
		Beware when using the --partial option, as it may most likely lead to
 | 
			
		||||
		undesired effects by leaving debug packages behind as well as dangling entries
 | 
			
		||||
		in the state repository.
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    -a, --arch    Override the architecture (disables auto-detection)
 | 
			
		||||
		    -a, --arch    Remove only one specific architecture (disables auto-detection)
 | 
			
		||||
		    --partial     Remove only partial pkgnames from a split package. This leaves
 | 
			
		||||
		                  debug packages behind and pkgbase entries in the state repo.
 | 
			
		||||
		    --noconfirm   Bypass any confirmation messages, should only be used with caution
 | 
			
		||||
		    -h, --help    Show this help text
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
@@ -31,8 +46,13 @@ _EOF_
 | 
			
		||||
 | 
			
		||||
pkgctl_db_remove() {
 | 
			
		||||
	local REPO=""
 | 
			
		||||
	local ARCH=any
 | 
			
		||||
	local PKGBASES=()
 | 
			
		||||
	local pkgnames=()
 | 
			
		||||
	local partial=0
 | 
			
		||||
	local confirm=1
 | 
			
		||||
	local dbscripts_options=()
 | 
			
		||||
	local lookup_repo=multilib
 | 
			
		||||
	local pkgname
 | 
			
		||||
 | 
			
		||||
	# option checking
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
@@ -41,11 +61,20 @@ pkgctl_db_remove() {
 | 
			
		||||
				pkgctl_db_remove_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			--partial)
 | 
			
		||||
				partial=1
 | 
			
		||||
				dbscripts_options+=(--partial)
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-a|--arch)
 | 
			
		||||
				(( $# <= 1 )) && die "missing argument for %s" "$1"
 | 
			
		||||
				ARCH=$2
 | 
			
		||||
				dbscripts_options+=(--arch "$2")
 | 
			
		||||
				shift 2
 | 
			
		||||
				;;
 | 
			
		||||
			--noconfirm)
 | 
			
		||||
				confirm=0
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-*)
 | 
			
		||||
				die "invalid argument: %s" "$1"
 | 
			
		||||
				;;
 | 
			
		||||
@@ -63,7 +92,62 @@ pkgctl_db_remove() {
 | 
			
		||||
	REPO=$1
 | 
			
		||||
	shift
 | 
			
		||||
	PKGBASES+=("$@")
 | 
			
		||||
	pkgnames=("${PKGBASES[@]}")
 | 
			
		||||
 | 
			
		||||
	# check if the target repo is valid
 | 
			
		||||
	if ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then
 | 
			
		||||
		die "Invalid repository target: %s" "${REPO}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# update pacman cache to query all pkgnames
 | 
			
		||||
	if (( ! partial )); then
 | 
			
		||||
		case ${REPO} in
 | 
			
		||||
			*-unstable)
 | 
			
		||||
				update_pacman_repo_cache unstable
 | 
			
		||||
				;;
 | 
			
		||||
			*-staging)
 | 
			
		||||
				update_pacman_repo_cache multilib-staging
 | 
			
		||||
				;;
 | 
			
		||||
			*-testing)
 | 
			
		||||
				update_pacman_repo_cache multilib-testing
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				update_pacman_repo_cache multilib
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
 | 
			
		||||
		# fetch the pkgnames of all pkgbase as present in the repo
 | 
			
		||||
		mapfile -t pkgnames < <(get_pkgnames_from_repo_pkgbase "${REPO}" "${PKGBASES[@]}")
 | 
			
		||||
		echo
 | 
			
		||||
 | 
			
		||||
		if (( ! ${#pkgnames[@]} )); then
 | 
			
		||||
			error "Packages not found in %s" "${REPO}"
 | 
			
		||||
			exit 1
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# print list of packages
 | 
			
		||||
	printf "%sRemoving packages from %s:%s\n" "${RED}" "${REPO}" "${ALL_OFF}"
 | 
			
		||||
	for pkgname in "${pkgnames[@]}"; do
 | 
			
		||||
		printf "• %s\n" "${pkgname}"
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# print explenation about partial removal
 | 
			
		||||
	if (( partial )); then
 | 
			
		||||
		echo
 | 
			
		||||
		msg_warn "${YELLOW}Removing only partial pkgnames from a split package.${ALL_OFF}"
 | 
			
		||||
		msg_warn "${YELLOW}This leaves debug packages and pkgbase entries in the state repo!${ALL_OFF}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# ask for confirmation
 | 
			
		||||
	if (( confirm )); then
 | 
			
		||||
		echo
 | 
			
		||||
		if ! prompt "${GREEN}${BOLD}?${ALL_OFF} Are you sure this is correct?"; then
 | 
			
		||||
			exit 1
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	echo
 | 
			
		||||
	# shellcheck disable=SC2029
 | 
			
		||||
	ssh "${PACKAGING_REPO_RELEASE_HOST}" db-remove "${REPO}" "${ARCH}" "${PKGBASES[@]}"
 | 
			
		||||
	ssh "${PACKAGING_REPO_RELEASE_HOST}" db-remove "${dbscripts_options[@]}" "${REPO}" "${PKGBASES[@]}"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@ pkgctl_release_usage() {
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    -m, --message MSG   Use the given <msg> as the commit message
 | 
			
		||||
		    -r, --repo REPO     Specify a target repository (disables auto-detection)
 | 
			
		||||
		    -r, --repo REPO     Specify target repository for new packages not in any official repo
 | 
			
		||||
		    -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
 | 
			
		||||
@@ -43,8 +43,8 @@ pkgctl_release_usage() {
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND}
 | 
			
		||||
		    $ ${COMMAND} --repo core-testing --message 'libyay 0.42 rebuild' libfoo libbar
 | 
			
		||||
		    $ ${COMMAND} --staging --db-update libfoo
 | 
			
		||||
		    $ ${COMMAND} --staging --message 'libyay 0.42 rebuild' libfoo libbar
 | 
			
		||||
		    $ ${COMMAND} --repo extra --db-update new-package
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -124,9 +124,9 @@ pkgctl_release() {
 | 
			
		||||
 | 
			
		||||
	# Update pacman cache for auto-detection
 | 
			
		||||
	if [[ -z ${REPO} ]]; then
 | 
			
		||||
		update_pacman_repo_cache
 | 
			
		||||
		update_pacman_repo_cache multilib
 | 
			
		||||
	# Check valid repos if not resolved dynamically
 | 
			
		||||
	elif ! in_array "${REPO}" "${_repos[@]}"; then
 | 
			
		||||
	elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then
 | 
			
		||||
		die "Invalid repository target: %s" "${REPO}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
@@ -134,15 +134,27 @@ pkgctl_release() {
 | 
			
		||||
		pushd "${path}" >/dev/null
 | 
			
		||||
		pkgbase=$(basename "${path}")
 | 
			
		||||
 | 
			
		||||
		if [[ -n ${REPO} ]]; then
 | 
			
		||||
		# auto-detect target repository
 | 
			
		||||
		if ! repo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then
 | 
			
		||||
			die 'Failed to query pacman repo'
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# fail if an existing package specifies --repo
 | 
			
		||||
		if [[ -n "${repo}" ]] && [[ -n ${REPO} ]]; then
 | 
			
		||||
			# allow unstable to use --repo
 | 
			
		||||
			if [[ ${REPO} == *unstable ]]; then
 | 
			
		||||
				repo=${REPO}
 | 
			
		||||
			else
 | 
			
		||||
			if ! repo=$(get_pacman_repo_from_pkgbuild PKGBUILD); then
 | 
			
		||||
				die 'Failed to get pacman repo'
 | 
			
		||||
				die 'Using --repo for packages that exist in official repositories is disallowed'
 | 
			
		||||
			fi
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# fail if a new package does not specify --repo
 | 
			
		||||
		if [[ -z "${repo}" ]]; then
 | 
			
		||||
				die 'Unknown repo, please specify --repo for new packages'
 | 
			
		||||
			if [[ -z ${REPO} ]]; then
 | 
			
		||||
				die 'Specify --repo for packages that do not yet exist in official repositories'
 | 
			
		||||
			fi
 | 
			
		||||
			repo=${REPO}
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		if (( TESTING )); then
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ pkgctl_repo_usage() {
 | 
			
		||||
		without SSH access using read-only HTTPS.
 | 
			
		||||
 | 
			
		||||
		COMMANDS
 | 
			
		||||
		    clean          Remove untracked files from the working tree
 | 
			
		||||
		    clone          Clone a package repository
 | 
			
		||||
		    configure      Configure a clone according to distro specs
 | 
			
		||||
		    create         Create a new GitLab package repository
 | 
			
		||||
@@ -37,6 +38,7 @@ pkgctl_repo_usage() {
 | 
			
		||||
		    -h, --help     Show this help text
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND} clean --interactive *
 | 
			
		||||
		    $ ${COMMAND} clone libfoo linux libbar
 | 
			
		||||
		    $ ${COMMAND} clone --maintainer mynickname
 | 
			
		||||
		    $ ${COMMAND} configure *
 | 
			
		||||
@@ -59,6 +61,14 @@ pkgctl_repo() {
 | 
			
		||||
				pkgctl_repo_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			clean)
 | 
			
		||||
				_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
				shift
 | 
			
		||||
				# shellcheck source=src/lib/repo/clean.sh
 | 
			
		||||
				source "${_DEVTOOLS_LIBRARY_DIR}"/lib/repo/clean.sh
 | 
			
		||||
				pkgctl_repo_clean "$@"
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			clone)
 | 
			
		||||
				_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
				shift
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										114
									
								
								src/lib/repo/clean.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/lib/repo/clean.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_REPO_CLEAN_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_REPO_CLEAN_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 -eo pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pkgctl_repo_clean_usage() {
 | 
			
		||||
	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
 | 
			
		||||
	cat <<- _EOF_
 | 
			
		||||
		Usage: ${COMMAND} [OPTION] [PATH]...
 | 
			
		||||
 | 
			
		||||
		Cleans the working tree by recursively removing files that are not under
 | 
			
		||||
		version control, starting from the current directory.
 | 
			
		||||
 | 
			
		||||
		Files unknown to Git as well as ignored files are removed. This can, for
 | 
			
		||||
		example, be useful to remove all build products.
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    -i, --interactive   Show what would be done and clean files interactively
 | 
			
		||||
		    -n, --dry-run       Don't remove anything, just show what would be done
 | 
			
		||||
		    -h, --help          Show this help text
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND} libfoo linux libbar
 | 
			
		||||
		    $ ${COMMAND} --interactive libfoo linux libbar
 | 
			
		||||
		    $ ${COMMAND} --dry-run *
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_repo_clean() {
 | 
			
		||||
	# options
 | 
			
		||||
	local git_clean_options=()
 | 
			
		||||
	local paths
 | 
			
		||||
 | 
			
		||||
	local path pkgbase
 | 
			
		||||
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
		case $1 in
 | 
			
		||||
			-i|--interactive)
 | 
			
		||||
				git_clean_options+=("$1")
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-n|--dry-run)
 | 
			
		||||
				git_clean_options+=("$1")
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-h|--help)
 | 
			
		||||
				pkgctl_repo_clean_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			--)
 | 
			
		||||
				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
 | 
			
		||||
		paths=(".")
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# print message about the work chunk
 | 
			
		||||
	printf "🗑️ Removing untracked files from %s working trees\n" "${BOLD}${#paths[@]}${ALL_OFF}"
 | 
			
		||||
 | 
			
		||||
	for path in "${paths[@]}"; do
 | 
			
		||||
		# skip paths that are not directories
 | 
			
		||||
		if [[ ! -d "${path}" ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		if [[ ! -f "${path}/PKGBUILD" ]]; then
 | 
			
		||||
			msg_error "Not a package repository: ${path}"
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		if [[ ! -d "${path}/.git" ]]; then
 | 
			
		||||
			msg_error "Not a Git repository: ${path}"
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		pkgbase=$(basename "$(realpath "${path}")")
 | 
			
		||||
		pkgbase=${pkgbase%.git}
 | 
			
		||||
 | 
			
		||||
		# run dry mode to see if git would clean any files
 | 
			
		||||
		if [[ ! $(git -C "${path}" clean -x -d --dry-run 2>&1) ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# git clean untracked files
 | 
			
		||||
		msg_success "Cleaning ${BOLD}${pkgbase}${ALL_OFF}"
 | 
			
		||||
		if ! git -C "${path}" clean -x -d --force "${git_clean_options[@]}"; then
 | 
			
		||||
			msg_error "Failed to remove untracked files"
 | 
			
		||||
		fi
 | 
			
		||||
		echo
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
@@ -8,14 +8,19 @@ 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/archweb.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/archweb.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
 | 
			
		||||
# shellcheck source=src/lib/util/git.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/git.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/message.sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
set -o pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pkgctl_repo_clone_usage() {
 | 
			
		||||
@@ -52,6 +57,7 @@ pkgctl_repo_clone() {
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# options
 | 
			
		||||
	local protocol=ssh
 | 
			
		||||
	local GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_SSH}
 | 
			
		||||
	local CLONE_ALL=0
 | 
			
		||||
	local MAINTAINER=
 | 
			
		||||
@@ -72,6 +78,7 @@ pkgctl_repo_clone() {
 | 
			
		||||
				;;
 | 
			
		||||
			--protocol=https)
 | 
			
		||||
				GIT_REPO_BASE_URL=${GIT_PACKAGING_URL_HTTPS}
 | 
			
		||||
				protocol=https
 | 
			
		||||
				CONFIGURE_OPTIONS+=("$1")
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
@@ -82,6 +89,7 @@ pkgctl_repo_clone() {
 | 
			
		||||
				else
 | 
			
		||||
					die "unsupported protocol: %s" "$2"
 | 
			
		||||
				fi
 | 
			
		||||
				protocol="$2"
 | 
			
		||||
				CONFIGURE_OPTIONS+=("$1" "$2")
 | 
			
		||||
				shift 2
 | 
			
		||||
				;;
 | 
			
		||||
@@ -132,33 +140,18 @@ pkgctl_repo_clone() {
 | 
			
		||||
 | 
			
		||||
	# 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
 | 
			
		||||
		mapfile -t pkgbases < <(archweb_query_maintainer_packages "${MAINTAINER}")
 | 
			
		||||
		if ! wait $!; then
 | 
			
		||||
			die "Failed to query maintainer 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&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"
 | 
			
		||||
		mapfile -t pkgbases < <(archweb_query_all_packages)
 | 
			
		||||
		if ! wait $!; then
 | 
			
		||||
			die "Failed to query all 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
 | 
			
		||||
@@ -171,6 +164,12 @@ pkgctl_repo_clone() {
 | 
			
		||||
		if [[ -n "${VERSION}" ]]; then
 | 
			
		||||
			command+=" --switch '${VERSION}'"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# warm up ssh connection as it may require user input (key unlock, hostkey verification etc)
 | 
			
		||||
		if [[ ${protocol} == ssh ]]; then
 | 
			
		||||
			git_warmup_ssh_connection
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		if ! parallel --bar --jobs "${jobs}" "${command}" ::: "${pkgbases[@]}"; then
 | 
			
		||||
			die 'Failed to clone some packages, please check the output'
 | 
			
		||||
			exit 1
 | 
			
		||||
 
 | 
			
		||||
@@ -10,11 +10,14 @@ _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
 | 
			
		||||
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/util/git.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/git.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/config.sh
 | 
			
		||||
source /usr/share/makepkg/util/message.sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
shopt -s nullglob
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pkgctl_repo_configure_usage() {
 | 
			
		||||
@@ -32,6 +35,8 @@ pkgctl_repo_configure_usage() {
 | 
			
		||||
		address by choosing SSH for all official packager identities and
 | 
			
		||||
		read-only HTTPS otherwise.
 | 
			
		||||
 | 
			
		||||
		Git default excludes and hooks are applied to the configured repo.
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    --protocol https     Configure remote url to use https
 | 
			
		||||
		    -j, --jobs N         Run up to N jobs in parallel (default: $(nproc))
 | 
			
		||||
@@ -102,7 +107,7 @@ pkgctl_repo_configure() {
 | 
			
		||||
 | 
			
		||||
	# variables
 | 
			
		||||
	local -r command=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
 | 
			
		||||
	local path realpath pkgbase remote_url project_path
 | 
			
		||||
	local path realpath pkgbase remote_url project_path hook
 | 
			
		||||
	local PACKAGER GPGKEY packager_name packager_email
 | 
			
		||||
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
@@ -188,6 +193,12 @@ pkgctl_repo_configure() {
 | 
			
		||||
		if [[ -n ${BOLD} ]]; then
 | 
			
		||||
			export DEVTOOLS_COLOR=always
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# warm up ssh connection as it may require user input (key unlock, hostkey verification etc)
 | 
			
		||||
		if [[ ${proto} == ssh ]]; then
 | 
			
		||||
			git_warmup_ssh_connection
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		if ! parallel --bar --jobs "${jobs}" "${command}" ::: "${paths[@]}"; then
 | 
			
		||||
			die 'Failed to configure some packages, please check the output'
 | 
			
		||||
			exit 1
 | 
			
		||||
@@ -196,9 +207,14 @@ pkgctl_repo_configure() {
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	for path in "${paths[@]}"; do
 | 
			
		||||
		if ! realpath=$(realpath -e "${path}"); then
 | 
			
		||||
		# resolve symlink for basename
 | 
			
		||||
		if ! realpath=$(realpath --canonicalize-existing -- "${path}"); then
 | 
			
		||||
			die "No such directory: ${path}"
 | 
			
		||||
		fi
 | 
			
		||||
		# skip paths that aren't directories
 | 
			
		||||
		if [[ ! -d "${realpath}" ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		pkgbase=$(basename "${realpath}")
 | 
			
		||||
		pkgbase=${pkgbase%.git}
 | 
			
		||||
@@ -222,7 +238,15 @@ pkgctl_repo_configure() {
 | 
			
		||||
			git config branch.main.merge refs/heads/main
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# configure spec version and variant to avoid using development hooks in production
 | 
			
		||||
		git config devtools.version "${GIT_REPO_SPEC_VERSION}"
 | 
			
		||||
		if [[ ${_DEVTOOLS_LIBRARY_DIR} == /usr/share/devtools ]]; then
 | 
			
		||||
			git config devtools.variant canonical
 | 
			
		||||
		else
 | 
			
		||||
			warning "Configuring with development version of pkgctl, do not use this repo in production"
 | 
			
		||||
			git config devtools.variant development
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		git config pull.rebase true
 | 
			
		||||
		git config branch.autoSetupRebase always
 | 
			
		||||
		git config branch.main.remote origin
 | 
			
		||||
@@ -247,8 +271,21 @@ pkgctl_repo_configure() {
 | 
			
		||||
		if [[ -n $GPGKEY ]]; then
 | 
			
		||||
			git config commit.gpgsign true
 | 
			
		||||
			git config user.signingKey "${GPGKEY}"
 | 
			
		||||
			git config gpg.format openpgp
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# set default git exclude
 | 
			
		||||
		mkdir -p .git/info
 | 
			
		||||
		ln -sf "${_DEVTOOLS_LIBRARY_DIR}/git.conf.d/template/info/exclude" \
 | 
			
		||||
			.git/info/exclude
 | 
			
		||||
 | 
			
		||||
		# set default git hooks
 | 
			
		||||
		mkdir -p .git/hooks
 | 
			
		||||
		rm -f .git/hooks/*.sample
 | 
			
		||||
		for hook in "${_DEVTOOLS_LIBRARY_DIR}"/git.conf.d/template/hooks/*; do
 | 
			
		||||
			ln -sf "${hook}" ".git/hooks/$(basename "${hook}")"
 | 
			
		||||
		done
 | 
			
		||||
 | 
			
		||||
		if ! git ls-remote origin &>/dev/null; then
 | 
			
		||||
			warning "configured remote origin may not exist, run:"
 | 
			
		||||
			msg2 "pkgctl repo create ${pkgbase}"
 | 
			
		||||
 
 | 
			
		||||
@@ -101,16 +101,21 @@ pkgctl_repo_switch() {
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	for path in "${paths[@]}"; do
 | 
			
		||||
		if ! realpath=$(realpath -e -- "${path}"); then
 | 
			
		||||
		# resolve symlink for basename
 | 
			
		||||
		if ! realpath=$(realpath --canonicalize-existing -- "${path}"); then
 | 
			
		||||
			die "No such directory: ${path}"
 | 
			
		||||
		fi
 | 
			
		||||
		pkgbase=$(basename "${realpath}")
 | 
			
		||||
 | 
			
		||||
		if [[ ! -d "${path}/.git" ]]; then
 | 
			
		||||
		# skip paths that are not directories
 | 
			
		||||
		if [[ ! -d "${realpath}" ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
		# skip paths that are not git repositories
 | 
			
		||||
		if [[ ! -d "${realpath}/.git" ]]; then
 | 
			
		||||
			error "Not a Git repository: ${path}"
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		pkgbase=$(basename "${realpath}")
 | 
			
		||||
		if ! git -C "${path}" checkout "${GIT_CHECKOUT_OPTIONS[@]}" "${GIT_REF}"; then
 | 
			
		||||
			die "Failed to switch ${pkgbase} to version ${VERSION}"
 | 
			
		||||
		fi
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@ pkgctl_repo_web_usage() {
 | 
			
		||||
		no arguments, open the package cloned in the current working directory.
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    --print       Print the url instead of opening it with xdg-open
 | 
			
		||||
		    -h, --help    Show this help text
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
@@ -32,7 +33,8 @@ _EOF_
 | 
			
		||||
 | 
			
		||||
pkgctl_repo_web() {
 | 
			
		||||
	local pkgbases=()
 | 
			
		||||
	local path giturl pkgbase
 | 
			
		||||
	local path giturl pkgbase url
 | 
			
		||||
	local mode=open
 | 
			
		||||
 | 
			
		||||
	# option checking
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
@@ -41,6 +43,10 @@ pkgctl_repo_web() {
 | 
			
		||||
				pkgctl_repo_web_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			--print)
 | 
			
		||||
				mode=print
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--)
 | 
			
		||||
				shift
 | 
			
		||||
				break
 | 
			
		||||
@@ -56,7 +62,7 @@ pkgctl_repo_web() {
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# Check if web mode has xdg-open
 | 
			
		||||
	if ! command -v xdg-open &>/dev/null; then
 | 
			
		||||
	if [[ ${mode} == open ]] && ! command -v xdg-open &>/dev/null; then
 | 
			
		||||
		die "The web command requires 'xdg-open'"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
@@ -78,7 +84,18 @@ pkgctl_repo_web() {
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	for pkgbase in "${pkgbases[@]}"; do
 | 
			
		||||
		pkgbase=$(basename "${pkgbase}")
 | 
			
		||||
		path=$(gitlab_project_name_to_path "${pkgbase}")
 | 
			
		||||
		xdg-open "${GIT_PACKAGING_URL_HTTPS}/${path}"
 | 
			
		||||
		url="${GIT_PACKAGING_URL_HTTPS}/${path}"
 | 
			
		||||
		case ${mode} in
 | 
			
		||||
			open)
 | 
			
		||||
				xdg-open "${url}"
 | 
			
		||||
				;;
 | 
			
		||||
			print)
 | 
			
		||||
				printf "%s\n" "${url}"
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				die "Unknown mode: ${mode}"
 | 
			
		||||
		esac
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										308
									
								
								src/lib/search.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								src/lib/search.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,308 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_SEARCH_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_SEARCH_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/cache.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/cache.sh
 | 
			
		||||
# shellcheck source=src/lib/api/gitlab.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/api/gitlab.sh
 | 
			
		||||
# shellcheck source=src/lib/valid-search.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-search.sh
 | 
			
		||||
# shellcheck source=src/lib/util/term.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/term.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/util.sh
 | 
			
		||||
source /usr/share/makepkg/util/message.sh
 | 
			
		||||
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pkgctl_search_usage() {
 | 
			
		||||
	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
 | 
			
		||||
	cat <<- _EOF_
 | 
			
		||||
		Usage: ${COMMAND} [OPTIONS] QUERY
 | 
			
		||||
 | 
			
		||||
		Search for an expression across the GitLab packaging group.
 | 
			
		||||
 | 
			
		||||
		To use a filter, include it in your query. You may use wildcards (*) to
 | 
			
		||||
		use glob matching.
 | 
			
		||||
 | 
			
		||||
		Available filters for the blobs scope: path, extension
 | 
			
		||||
 | 
			
		||||
		Every usage of the search command must be authenticated. Consult the
 | 
			
		||||
		'pkgctl auth' command to authenticate with GitLab or view the
 | 
			
		||||
		authentication status.
 | 
			
		||||
 | 
			
		||||
		SEARCH TIPS
 | 
			
		||||
		    Syntax  Description    Example
 | 
			
		||||
		    ───────────────────────────────────────
 | 
			
		||||
		    "       Exact search   "gem sidekiq"
 | 
			
		||||
		    ~       Fuzzy search   J~ Doe
 | 
			
		||||
		    |       Or             display | banner
 | 
			
		||||
		    +       And            display +banner
 | 
			
		||||
		    -       Exclude        display -banner
 | 
			
		||||
		    *       Partial        bug error 50*
 | 
			
		||||
		    \\       Escape         \\*md
 | 
			
		||||
		    #       Issue ID       #23456
 | 
			
		||||
		    !       Merge request  !23456
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    -h, --help            Show this help text
 | 
			
		||||
 | 
			
		||||
		FILTER OPTIONS
 | 
			
		||||
		    --no-default-filter   Do not apply default filter (like -path:keys/pgp/*.asc)
 | 
			
		||||
 | 
			
		||||
		OUTPUT OPTIONS
 | 
			
		||||
		    --json                Enable printing in JSON; Shorthand for '--format json'
 | 
			
		||||
		    -F, --format FORMAT   Controls the formatting of the results; FORMAT is 'pretty',
 | 
			
		||||
		                          'plain', or 'json' (default: pretty)
 | 
			
		||||
		    -N, --no-line-number  Don't show line numbers when formatting results
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND} linux
 | 
			
		||||
		    $ ${COMMAND} --json '"pytest -v" +PYTHONPATH'
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_search_check_option_group_format() {
 | 
			
		||||
	local option=$1
 | 
			
		||||
	local output_format=$2
 | 
			
		||||
	if [[ -n ${output_format} ]]; then
 | 
			
		||||
		die "The argument '%s' cannot be used with one or more of the other specified arguments" "${option}"
 | 
			
		||||
		exit 1
 | 
			
		||||
	fi
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_search() {
 | 
			
		||||
	if (( $# < 1 )); then
 | 
			
		||||
		pkgctl_search_usage
 | 
			
		||||
		exit 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# options
 | 
			
		||||
	local search
 | 
			
		||||
	local output_format=
 | 
			
		||||
	local use_default_filter=1
 | 
			
		||||
	local line_numbers=1
 | 
			
		||||
 | 
			
		||||
	# variables
 | 
			
		||||
	local bat_style="header,grid"
 | 
			
		||||
	local default_filter="-path:keys/pgp/*.asc"
 | 
			
		||||
	local graphql_lookup_batch=200
 | 
			
		||||
	local output result query entries from until length
 | 
			
		||||
	local project_name_cache_file project_name_lookup project_ids project_id project_name project_slice
 | 
			
		||||
	local mapping_output path startline currentline data line
 | 
			
		||||
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
		case $1 in
 | 
			
		||||
			-h|--help)
 | 
			
		||||
				pkgctl_search_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			--no-default-filter)
 | 
			
		||||
				use_default_filter=0
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--json)
 | 
			
		||||
				pkgctl_search_check_option_group_format "$1" "${output_format}"
 | 
			
		||||
				output_format=json
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-F|--format)
 | 
			
		||||
				(( $# <= 1 )) && die "missing argument for %s" "$1"
 | 
			
		||||
				pkgctl_search_check_option_group_format "$1" "${output_format}"
 | 
			
		||||
				output_format="${2}"
 | 
			
		||||
				if ! in_array "${output_format}" "${valid_search_output_format[@]}"; then
 | 
			
		||||
					die "Unknown output format: %s" "${output_format}"
 | 
			
		||||
				fi
 | 
			
		||||
				shift 2
 | 
			
		||||
				;;
 | 
			
		||||
			-N|--no-line-number)
 | 
			
		||||
				line_numbers=0
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--)
 | 
			
		||||
				shift
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			-*)
 | 
			
		||||
				die "invalid argument: %s" "$1"
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	if (( $# == 0 )); then
 | 
			
		||||
		pkgctl_search_usage
 | 
			
		||||
		exit 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# assign search parameter
 | 
			
		||||
	search="${*}"
 | 
			
		||||
	if (( use_default_filter )); then
 | 
			
		||||
		search+=" ${default_filter}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# assign default output format
 | 
			
		||||
	if [[ -z ${output_format} ]]; then
 | 
			
		||||
		output_format=pretty
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# check for optional dependencies
 | 
			
		||||
	if [[ ${output_format} == pretty ]] && ! command -v bat &>/dev/null; then
 | 
			
		||||
		warning "Failed to find optional dependency 'bat': falling back to plain output"
 | 
			
		||||
		output_format=plain
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# populate line numbers option
 | 
			
		||||
	if (( line_numbers )); then
 | 
			
		||||
		bat_style="numbers,${bat_style}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# call the gitlab search API
 | 
			
		||||
	status_dir=$(mktemp --tmpdir="${WORKDIR}" --directory pkgctl-gitlab-api.XXXXXXXXXX)
 | 
			
		||||
	printf "📡 Querying GitLab search API..." > "${status_dir}/status"
 | 
			
		||||
	term_spinner_start "${status_dir}"
 | 
			
		||||
	output=$(gitlab_api_search "${search}" "${status_dir}/status")
 | 
			
		||||
	term_spinner_stop "${status_dir}"
 | 
			
		||||
	msg_success "Querying GitLab search API"
 | 
			
		||||
 | 
			
		||||
	# collect project ids whose name needs to be looked up
 | 
			
		||||
	project_name_cache_file=$(get_cache_file gitlab/project_id_to_name)
 | 
			
		||||
	lock 11 "${project_name_cache_file}" "Locking project name cache"
 | 
			
		||||
	mapfile -t project_ids < <(
 | 
			
		||||
		jq --raw-output '[.[].project_id] | unique[]' <<< "${output}" | \
 | 
			
		||||
			grep --invert-match --file <(awk '{ print $1 }' < "${project_name_cache_file}" ))
 | 
			
		||||
 | 
			
		||||
	# look up project names
 | 
			
		||||
	tmp_file=$(mktemp --tmpdir="${WORKDIR}" pkgctl-gitlab-api-spinner.tmp.XXXXXXXXXX)
 | 
			
		||||
	printf "📡 Querying GitLab project names..." > "${status_dir}/status"
 | 
			
		||||
	term_spinner_start "${status_dir}"
 | 
			
		||||
	local entries="${#project_ids[@]}"
 | 
			
		||||
	local until=0
 | 
			
		||||
	while (( until < entries )); do
 | 
			
		||||
		from=${until}
 | 
			
		||||
		until=$(( until + graphql_lookup_batch ))
 | 
			
		||||
		if (( until > entries )); then
 | 
			
		||||
			until=${entries}
 | 
			
		||||
		fi
 | 
			
		||||
		length=$(( until - from ))
 | 
			
		||||
 | 
			
		||||
		percentage=$(( 100 * until / entries ))
 | 
			
		||||
		printf "📡 Querying GitLab project names: %s/%s [%s] %%spinner%%" \
 | 
			
		||||
			"${BOLD}${until}" "${entries}" "${percentage}%${ALL_OFF}"  \
 | 
			
		||||
			> "${tmp_file}"
 | 
			
		||||
		mv "${tmp_file}" "${status_dir}/status"
 | 
			
		||||
 | 
			
		||||
		project_slice=("${project_ids[@]:${from}:${length}}")
 | 
			
		||||
		printf -v projects '"gid://gitlab/Project/%s",' "${project_slice[@]}"
 | 
			
		||||
		query='{
 | 
			
		||||
			projects(after: "" ids: ['"${projects}"']) {
 | 
			
		||||
				pageInfo {
 | 
			
		||||
					startCursor
 | 
			
		||||
					endCursor
 | 
			
		||||
					hasNextPage
 | 
			
		||||
				}
 | 
			
		||||
				nodes {
 | 
			
		||||
					id
 | 
			
		||||
					name
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}'
 | 
			
		||||
		mapping_output=$(gitlab_api_get_project_name_mapping "${query}")
 | 
			
		||||
 | 
			
		||||
		# update cache
 | 
			
		||||
		while read -r project_id project_name; do
 | 
			
		||||
			printf "%s %s\n" "${project_id}" "${project_name}" >> "${project_name_cache_file}"
 | 
			
		||||
		done < <(jq --raw-output \
 | 
			
		||||
			'.[] | "\(.id | rindex("/") as $lastSlash | .[$lastSlash+1:]) \(.name)"' \
 | 
			
		||||
			<<< "${mapping_output}")
 | 
			
		||||
	done
 | 
			
		||||
	term_spinner_stop "${status_dir}"
 | 
			
		||||
	msg_success "Querying GitLab project names"
 | 
			
		||||
 | 
			
		||||
	# read project_id to name mapping from cache
 | 
			
		||||
	declare -A project_name_lookup=()
 | 
			
		||||
	while read -r project_id project_name; do
 | 
			
		||||
		project_name_lookup[${project_id}]=${project_name}
 | 
			
		||||
	done < "${project_name_cache_file}"
 | 
			
		||||
 | 
			
		||||
	# close project name cache lock
 | 
			
		||||
	lock_close 11
 | 
			
		||||
 | 
			
		||||
	# output mode JSON
 | 
			
		||||
	if [[ ${output_format} == json ]]; then
 | 
			
		||||
		jq --from-file <(
 | 
			
		||||
			for project_id in $(jq '.[].project_id' <<< "${output}"); do
 | 
			
		||||
				project_name=${project_name_lookup[${project_id}]}
 | 
			
		||||
				printf 'map(if .project_id == %s then . + {"project_name": "%s"} else . end) | ' \
 | 
			
		||||
					"${project_id}" "${project_name}"
 | 
			
		||||
			done
 | 
			
		||||
			printf .
 | 
			
		||||
		) <<< "${output}"
 | 
			
		||||
		exit 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# pretty print each result
 | 
			
		||||
	while read -r result; do
 | 
			
		||||
		# read properties from search result
 | 
			
		||||
		mapfile -t data < <(jq --raw-output ".data" <<< "${result}")
 | 
			
		||||
		{ read -r project_id; read -r path; read -r startline; } < <(
 | 
			
		||||
			jq --raw-output ".project_id, .path, .startline" <<< "${result}"
 | 
			
		||||
		)
 | 
			
		||||
		project_name=${project_name_lookup[${project_id}]}
 | 
			
		||||
 | 
			
		||||
		# remove trailing newline for multiline results
 | 
			
		||||
		if (( ${#data[@]} > 1 )) && [[ ${data[-1]} == "" ]]; then
 | 
			
		||||
			unset "data[${#data[@]}-1]"
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# output mode plain
 | 
			
		||||
		if [[ ${output_format} == plain ]]; then
 | 
			
		||||
			printf "%s%s%s\n" "${PURPLE}" "${project_name}/${path}" "${ALL_OFF}"
 | 
			
		||||
 | 
			
		||||
			currentline=${startline}
 | 
			
		||||
			for line in "${data[@]}"; do
 | 
			
		||||
				if (( line_numbers )); then
 | 
			
		||||
					line="${DARK_GREEN}${currentline}${ALL_OFF}: ${line}"
 | 
			
		||||
					currentline=$(( currentline + 1 ))
 | 
			
		||||
				fi
 | 
			
		||||
				printf "%s\n" "${line}"
 | 
			
		||||
			done
 | 
			
		||||
			printf "\n"
 | 
			
		||||
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# prepend empty lines to match startline
 | 
			
		||||
		if (( startline > 1 )); then
 | 
			
		||||
			mapfile -t data < <(
 | 
			
		||||
				printf '%.0s\n' $(seq 1 "$(( startline - 1 ))")
 | 
			
		||||
				printf "%s\n" "${data[@]}"
 | 
			
		||||
			)
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		bat \
 | 
			
		||||
			--file-name="${project_name}/${path}" \
 | 
			
		||||
			--line-range "${startline}:" \
 | 
			
		||||
			--paging=never \
 | 
			
		||||
			--force-colorization \
 | 
			
		||||
			--style "${bat_style}" \
 | 
			
		||||
			--map-syntax "PKGBUILD:Bourne Again Shell (bash)" \
 | 
			
		||||
			--map-syntax ".SRCINFO:INI" \
 | 
			
		||||
			--map-syntax "*install:Bourne Again Shell (bash)" \
 | 
			
		||||
			--map-syntax "*sysusers*:Bourne Again Shell (bash)" \
 | 
			
		||||
			--map-syntax "*tmpfiles*:Bourne Again Shell (bash)" \
 | 
			
		||||
			--map-syntax "*.hook:INI" \
 | 
			
		||||
			<(printf "%s\n" "${data[@]}")
 | 
			
		||||
	done < <(jq --compact-output '.[]' <<< "${output}")
 | 
			
		||||
}
 | 
			
		||||
@@ -7,6 +7,9 @@ DEVTOOLS_INCLUDE_UTIL_GIT_SH=1
 | 
			
		||||
 | 
			
		||||
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
 | 
			
		||||
 | 
			
		||||
# shellcheck source=src/lib/common.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
git_diff_tree() {
 | 
			
		||||
	local commit=$1
 | 
			
		||||
@@ -22,3 +25,10 @@ git_diff_tree() {
 | 
			
		||||
		"${commit}" \
 | 
			
		||||
		-- "${path}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
git_warmup_ssh_connection() {
 | 
			
		||||
	msg 'Establishing ssh connection to git@%s' "${GITLAB_HOST}"
 | 
			
		||||
	if ! ssh -T "git@${GITLAB_HOST}" >/dev/null; then
 | 
			
		||||
		die 'Failed to establish ssh connection to git@%s' "${GITLAB_HOST}"
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										57
									
								
								src/lib/util/makepkg.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/lib/util/makepkg.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
#!/hint/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_UTIL_MAKEPKG_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_UTIL_MAKEPKG_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/util/srcinfo.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/srcinfo.sh
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
makepkg_source_package() {
 | 
			
		||||
	if (( EUID != 0 )); then
 | 
			
		||||
		[[ -z ${WORKDIR:-} ]] && setup_workdir
 | 
			
		||||
		export WORKDIR DEVTOOLS_INCLUDE_COMMON_SH
 | 
			
		||||
		fakeroot -- bash -$- -c "source '${BASH_SOURCE[0]}' && ${FUNCNAME[0]}"
 | 
			
		||||
		return
 | 
			
		||||
	fi
 | 
			
		||||
	(
 | 
			
		||||
		# shellcheck disable=SC2030 disable=SC2031
 | 
			
		||||
		export LIBMAKEPKG_LINT_PKGBUILD_SH=1
 | 
			
		||||
		lint_pkgbuild() { :; }
 | 
			
		||||
 | 
			
		||||
		# shellcheck disable=SC2030 disable=SC2031
 | 
			
		||||
		export LIBMAKEPKG_SRCINFO_SH=1
 | 
			
		||||
		write_srcinfo() { print_srcinfo; }
 | 
			
		||||
 | 
			
		||||
		# explicitly instruct makepkg to not sign the source package, even when
 | 
			
		||||
		# the BUILDENV array in makepkg.conf contains 'sign'
 | 
			
		||||
		set +e -- -F --source --nosign
 | 
			
		||||
		# shellcheck source=/usr/bin/makepkg
 | 
			
		||||
		source "$(command -v makepkg)"
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
makepkg_generate_integrity() {
 | 
			
		||||
	if [[ -z ${DEVTOOLS_GENERATE_INTEGRITY} ]]; then
 | 
			
		||||
		[[ -z ${WORKDIR:-} ]] && setup_workdir
 | 
			
		||||
		export WORKDIR DEVTOOLS_INCLUDE_COMMON_SH
 | 
			
		||||
		bash -$- -c "DEVTOOLS_GENERATE_INTEGRITY=1; source '${BASH_SOURCE[0]}' && ${FUNCNAME[0]}"
 | 
			
		||||
		return
 | 
			
		||||
	fi
 | 
			
		||||
	(
 | 
			
		||||
		# shellcheck disable=SC2030 disable=SC2031
 | 
			
		||||
		export LIBMAKEPKG_LINT_PKGBUILD_SH=1
 | 
			
		||||
		lint_pkgbuild() { :; }
 | 
			
		||||
 | 
			
		||||
		set +e -- --geninteg
 | 
			
		||||
		# shellcheck source=/usr/bin/makepkg
 | 
			
		||||
		source "$(command -v makepkg)"
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
@@ -18,10 +18,12 @@ readonly _DEVTOOLS_MAKEPKG_CONF_DIR=${_DEVTOOLS_LIBRARY_DIR}/makepkg.conf.d
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
update_pacman_repo_cache() {
 | 
			
		||||
	local repo=${1:-multilib}
 | 
			
		||||
 | 
			
		||||
	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" \
 | 
			
		||||
	fakeroot -- pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/${repo}.conf" \
 | 
			
		||||
		--dbpath "${_DEVTOOLS_PACMAN_CACHE_DIR}" \
 | 
			
		||||
		-Sy
 | 
			
		||||
	lock_close 10
 | 
			
		||||
@@ -29,6 +31,7 @@ update_pacman_repo_cache() {
 | 
			
		||||
 | 
			
		||||
get_pacman_repo_from_pkgbuild() {
 | 
			
		||||
	local path=${1:-PKGBUILD}
 | 
			
		||||
	local repo=${2:-multilib}
 | 
			
		||||
 | 
			
		||||
	# shellcheck source=contrib/makepkg/PKGBUILD.proto
 | 
			
		||||
	mapfile -t pkgnames < <(source "${path}"; printf "%s\n" "${pkgname[@]}")
 | 
			
		||||
@@ -38,15 +41,50 @@ get_pacman_repo_from_pkgbuild() {
 | 
			
		||||
		return
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# update the pacman repo cache if it doesn't exist yet
 | 
			
		||||
	if [[ ! -d "${_DEVTOOLS_PACMAN_CACHE_DIR}" ]]; then
 | 
			
		||||
		update_pacman_repo_cache "${repo}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	slock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache"
 | 
			
		||||
	mapfile -t repos < <(pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/multilib.conf" \
 | 
			
		||||
	# query repo of passed pkgname, specify --nodeps twice to skip all dependency checks
 | 
			
		||||
	mapfile -t repos < <(pacman --config "${_DEVTOOLS_PACMAN_CONF_DIR}/${repo}.conf" \
 | 
			
		||||
		--dbpath "${_DEVTOOLS_PACMAN_CACHE_DIR}" \
 | 
			
		||||
		-S \
 | 
			
		||||
		--sync \
 | 
			
		||||
		--nodeps \
 | 
			
		||||
		--nodeps \
 | 
			
		||||
		--print \
 | 
			
		||||
		--print-format '%n %r' \
 | 
			
		||||
		"${pkgnames[0]}" | grep -E "^${pkgnames[0]} " | awk '{print $2}'
 | 
			
		||||
		"${pkgnames[0]}" 2>/dev/null | awk '$1=="'"${pkgnames[0]}"'"{print $2}'
 | 
			
		||||
	)
 | 
			
		||||
	lock_close 10
 | 
			
		||||
 | 
			
		||||
	printf "%s" "${repos[0]}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
get_pkgnames_from_repo_pkgbase() {
 | 
			
		||||
	local repo=$1
 | 
			
		||||
	shift
 | 
			
		||||
	local pkgbases=("$@")
 | 
			
		||||
 | 
			
		||||
	# update the pacman repo cache if it doesn't exist yet
 | 
			
		||||
	if [[ ! -d "${_DEVTOOLS_PACMAN_CACHE_DIR}" ]]; then
 | 
			
		||||
		update_pacman_repo_cache universe
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	slock 10 "${_DEVTOOLS_PACMAN_CACHE_DIR}.lock" "Locking pacman database cache"
 | 
			
		||||
	# query pkgnames of passed pkgbase inside a repo
 | 
			
		||||
	mapfile -t pkgnames < <(expac --config <(sed "s|#DBPath.*|DBPath = $(realpath "${_DEVTOOLS_PACMAN_CACHE_DIR}")|" < "${_DEVTOOLS_PACMAN_CONF_DIR}/universe.conf") \
 | 
			
		||||
		--sync '%r %e %n' 2>/dev/null \
 | 
			
		||||
		| sort | awk -v pkgbase="${pkgbases[*]}" \
 | 
			
		||||
			'BEGIN { split(pkgbase, array); for (item in array) filter[array[item]]=1 } $1=="'"${repo}"'" && $2 in filter {print $3}'
 | 
			
		||||
	)
 | 
			
		||||
	lock_close 10
 | 
			
		||||
 | 
			
		||||
	if (( ! ${#pkgnames[@]} )); then
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	printf "%s\n" "${pkgnames[@]}"
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										91
									
								
								src/lib/util/pkgbuild.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/lib/util/pkgbuild.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
			
		||||
#!/hint/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_UTIL_PKGBUILD_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_UTIL_PKGBUILD_SH=1
 | 
			
		||||
 | 
			
		||||
_DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
 | 
			
		||||
# shellcheck source=src/lib/util/makepkg.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/makepkg.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/message.sh
 | 
			
		||||
source /usr/share/makepkg/util/schema.sh
 | 
			
		||||
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# set the pkgver variable in a PKGBUILD
 | 
			
		||||
# assumes that the pkgbuild is sourced to detect the presence of a pkgver function
 | 
			
		||||
pkgbuild_set_pkgver() {
 | 
			
		||||
	local new_pkgver=$1
 | 
			
		||||
	local pkgver=${pkgver}
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
	if ! grep --extended-regexp --quiet --max-count=1 "^pkgver=${pkgver}$" PKGBUILD; then
 | 
			
		||||
		die "Non-standard pkgver declaration"
 | 
			
		||||
	fi
 | 
			
		||||
	sed --regexp-extended "s|^(pkgver=)${pkgver}$|\1${new_pkgver}|g" --in-place PKGBUILD
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# set the pkgrel variable in a PKGBUILD
 | 
			
		||||
# assumes that the pkgbuild is sourced so pkgrel is present
 | 
			
		||||
pkgbuild_set_pkgrel() {
 | 
			
		||||
	local new_pkgrel=$1
 | 
			
		||||
	local pkgrel=${pkgrel}
 | 
			
		||||
 | 
			
		||||
	if ! grep --extended-regexp --quiet --max-count=1 "^pkgrel=${pkgrel}$" PKGBUILD; then
 | 
			
		||||
		die "Non-standard pkgrel declaration"
 | 
			
		||||
	fi
 | 
			
		||||
	sed --regexp-extended "s|^(pkgrel=)${pkgrel}$|\1${new_pkgrel}|g" --in-place PKGBUILD
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgbuild_update_checksums() {
 | 
			
		||||
	local status_file=$1
 | 
			
		||||
	local builddir newbuildfile sumtypes newsums
 | 
			
		||||
 | 
			
		||||
	[[ -z ${WORKDIR:-} ]] && setup_workdir
 | 
			
		||||
 | 
			
		||||
	builddir=$(mktemp --tmpdir="${WORKDIR}" --directory update-checksums.XXXXXX)
 | 
			
		||||
	newbuildfile="${builddir}/PKGBUILD"
 | 
			
		||||
 | 
			
		||||
	# generate new integrity checksums
 | 
			
		||||
	if ! newsums=$(BUILDDIR=${builddir} makepkg_generate_integrity 2>"${status_file}"); then
 | 
			
		||||
		printf 'Failed to generate new checksums'
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# early exit if no integrity checksums are needed
 | 
			
		||||
	if [[ -z ${newsums} ]]; then
 | 
			
		||||
		return 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# replace the integrity sums and write it to a temporary file
 | 
			
		||||
	sumtypes=$(IFS='|'; echo "${known_hash_algos[*]}")
 | 
			
		||||
	if ! awk --assign=sumtypes="${sumtypes}" --assign=newsums="${newsums}" '
 | 
			
		||||
		$0 ~"^[[:blank:]]*(" sumtypes ")sums(_[^=]+)?\\+?=", $0 ~ "\\)[[:blank:]]*(#.*)?$" {
 | 
			
		||||
			if (!w) {
 | 
			
		||||
				print newsums
 | 
			
		||||
				w++
 | 
			
		||||
			}
 | 
			
		||||
			next
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		1
 | 
			
		||||
		END { if (!w) print newsums }' PKGBUILD > "${newbuildfile}"; then
 | 
			
		||||
		printf 'Failed to replace the generated checksums'
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# overwrite the original PKGBUILD while preserving permissions
 | 
			
		||||
	if ! cat -- "${newbuildfile}" > PKGBUILD; then
 | 
			
		||||
		printf "Failed to write to the PKGBUILD file"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										69
									
								
								src/lib/util/srcinfo.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/lib/util/srcinfo.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
			
		||||
#!/hint/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_UTIL_SRCINFO_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_UTIL_SRCINFO_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/util.sh
 | 
			
		||||
source /usr/share/makepkg/srcinfo.sh
 | 
			
		||||
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
print_srcinfo() {
 | 
			
		||||
	local pkgpath=${1:-.}
 | 
			
		||||
	local outdir pkg pid
 | 
			
		||||
	local pids=()
 | 
			
		||||
 | 
			
		||||
	# source the PKGBUILD
 | 
			
		||||
	# shellcheck source=contrib/makepkg/PKGBUILD.proto
 | 
			
		||||
	. "${pkgpath}"/PKGBUILD
 | 
			
		||||
 | 
			
		||||
	# run without parallelization for single packages
 | 
			
		||||
	if (( ${#pkgname[@]} == 1 )); then
 | 
			
		||||
		write_srcinfo_content
 | 
			
		||||
		return 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	[[ -z ${WORKDIR:-} ]] && setup_workdir
 | 
			
		||||
	outdir=$(mktemp --directory --tmpdir="${WORKDIR}" pkgctl-srcinfo.XXXXXXXXXX)
 | 
			
		||||
 | 
			
		||||
	# fork workload for each split pkgname
 | 
			
		||||
	for pkg in "${pkgname[@]}"; do
 | 
			
		||||
		(
 | 
			
		||||
			# deactivate errexit to avoid makepkg abort on grep_function
 | 
			
		||||
			set +e
 | 
			
		||||
			srcinfo_write_package "$pkg" > "${outdir}/${pkg}"
 | 
			
		||||
		)&
 | 
			
		||||
		pids+=($!)
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# join workload
 | 
			
		||||
	for pid in "${pids[@]}"; do
 | 
			
		||||
		if ! wait "${pid}"; then
 | 
			
		||||
			return 1
 | 
			
		||||
		fi
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# collect output
 | 
			
		||||
	srcinfo_write_global
 | 
			
		||||
	for pkg in "${pkgname[@]}"; do
 | 
			
		||||
		srcinfo_separate_section
 | 
			
		||||
		cat "${outdir}/${pkg}"
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
write_srcinfo_file() {
 | 
			
		||||
	local pkgpath=${1:-.}
 | 
			
		||||
	stat_busy 'Generating .SRCINFO'
 | 
			
		||||
	if ! print_srcinfo "${pkgpath}" > "${pkgpath}"/.SRCINFO; then
 | 
			
		||||
		error 'Failed to write .SRCINFO file'
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
	stat_done
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										198
									
								
								src/lib/util/term.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								src/lib/util/term.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,198 @@
 | 
			
		||||
#!/hint/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_UTIL_TERM_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_UTIL_TERM_SH=1
 | 
			
		||||
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
readonly PKGCTL_TERM_SPINNER_DOTS=Dots
 | 
			
		||||
export PKGCTL_TERM_SPINNER_DOTS
 | 
			
		||||
readonly PKGCTL_TERM_SPINNER_DOTS12=Dots12
 | 
			
		||||
export PKGCTL_TERM_SPINNER_DOTS12
 | 
			
		||||
readonly PKGCTL_TERM_SPINNER_LINE=Line
 | 
			
		||||
export PKGCTL_TERM_SPINNER_LINE
 | 
			
		||||
readonly PKGCTL_TERM_SPINNER_SIMPLE_DOTS_SCROLLING=SimpleDotsScrolling
 | 
			
		||||
export PKGCTL_TERM_SPINNER_SIMPLE_DOTS_SCROLLING
 | 
			
		||||
readonly PKGCTL_TERM_SPINNER_TRIANGLE=Triangle
 | 
			
		||||
export PKGCTL_TERM_SPINNER_TRIANGLE
 | 
			
		||||
readonly PKGCTL_TERM_SPINNER_RANDOM=Random
 | 
			
		||||
export PKGCTL_TERM_SPINNER_RANDOM
 | 
			
		||||
 | 
			
		||||
readonly PKGCTL_TERM_SPINNER_TYPES=(
 | 
			
		||||
	"${PKGCTL_TERM_SPINNER_DOTS}"
 | 
			
		||||
	"${PKGCTL_TERM_SPINNER_DOTS12}"
 | 
			
		||||
	"${PKGCTL_TERM_SPINNER_LINE}"
 | 
			
		||||
	"${PKGCTL_TERM_SPINNER_SIMPLE_DOTS_SCROLLING}"
 | 
			
		||||
	"${PKGCTL_TERM_SPINNER_TRIANGLE}"
 | 
			
		||||
)
 | 
			
		||||
export PKGCTL_TERM_SPINNER_TYPES
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
term_cursor_hide() {
 | 
			
		||||
	tput civis >&2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
term_cursor_show() {
 | 
			
		||||
	tput cnorm >&2
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
term_cursor_up() {
 | 
			
		||||
	tput cuu1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
term_carriage_return() {
 | 
			
		||||
	tput cr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
term_erase_line() {
 | 
			
		||||
	tput el
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
term_erase_lines() {
 | 
			
		||||
	local lines=$1
 | 
			
		||||
 | 
			
		||||
	local cursor_up erase_line
 | 
			
		||||
	cursor_up=$(term_cursor_up)
 | 
			
		||||
	erase_line="$(term_carriage_return)$(term_erase_line)"
 | 
			
		||||
 | 
			
		||||
	local prefix=''
 | 
			
		||||
	for _ in $(seq 1 "${lines}"); do
 | 
			
		||||
		printf '%s' "${prefix}${erase_line}"
 | 
			
		||||
		prefix="${cursor_up}"
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_pkgctl_spinner_type=${PKGCTL_TERM_SPINNER_RANDOM}
 | 
			
		||||
term_spinner_set_type() {
 | 
			
		||||
	_pkgctl_spinner_type=$1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# takes a status directory that can be used to dynamically update the spinner
 | 
			
		||||
# by writing to the `status` file inside that directory atomically.
 | 
			
		||||
# replace the placeholder %spinner% with the currently configured spinner type
 | 
			
		||||
term_spinner_start() {
 | 
			
		||||
	local status_dir=$1
 | 
			
		||||
	local parent_pid=$$
 | 
			
		||||
	(
 | 
			
		||||
		local spinner_type=${_pkgctl_spinner_type}
 | 
			
		||||
		local spinner_offset=0
 | 
			
		||||
		local frame_buffer=''
 | 
			
		||||
		local spinner status_message line
 | 
			
		||||
 | 
			
		||||
		local status_file="${status_dir}/status"
 | 
			
		||||
		local next_file="${status_dir}/next"
 | 
			
		||||
		local drawn_file="${status_dir}/drawn"
 | 
			
		||||
 | 
			
		||||
		# assign random spinner type
 | 
			
		||||
		if [[ ${spinner_type} == "${PKGCTL_TERM_SPINNER_RANDOM}" ]]; then
 | 
			
		||||
			spinner_type=${PKGCTL_TERM_SPINNER_TYPES[$((RANDOM % ${#PKGCTL_TERM_SPINNER_TYPES[@]}))]}
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# select spinner based on the named type
 | 
			
		||||
		case "${spinner_type}" in
 | 
			
		||||
			"${PKGCTL_TERM_SPINNER_DOTS}")
 | 
			
		||||
				spinner=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
 | 
			
		||||
				update_interval=0.08
 | 
			
		||||
				;;
 | 
			
		||||
			"${PKGCTL_TERM_SPINNER_DOTS12}")
 | 
			
		||||
				spinner=("⢀⠀" "⡀⠀" "⠄⠀" "⢂⠀" "⡂⠀" "⠅⠀" "⢃⠀" "⡃⠀" "⠍⠀" "⢋⠀" "⡋⠀" "⠍⠁" "⢋⠁" "⡋⠁" "⠍⠉" "⠋⠉" "⠋⠉" "⠉⠙" "⠉⠙" "⠉⠩" "⠈⢙" "⠈⡙" "⢈⠩" "⡀⢙" "⠄⡙" "⢂⠩" "⡂⢘" "⠅⡘" "⢃⠨" "⡃⢐" "⠍⡐" "⢋⠠" "⡋⢀" "⠍⡁" "⢋⠁" "⡋⠁" "⠍⠉" "⠋⠉" "⠋⠉" "⠉⠙" "⠉⠙" "⠉⠩" "⠈⢙" "⠈⡙" "⠈⠩" "⠀⢙" "⠀⡙" "⠀⠩" "⠀⢘" "⠀⡘" "⠀⠨" "⠀⢐" "⠀⡐" "⠀⠠" "⠀⢀" "⠀⡀")
 | 
			
		||||
				update_interval=0.08
 | 
			
		||||
				;;
 | 
			
		||||
			"${PKGCTL_TERM_SPINNER_LINE}")
 | 
			
		||||
				spinner=("⎯" "\\" "|" "/")
 | 
			
		||||
				update_interval=0.13
 | 
			
		||||
				;;
 | 
			
		||||
			"${PKGCTL_TERM_SPINNER_SIMPLE_DOTS_SCROLLING}")
 | 
			
		||||
				spinner=(".  " ".. " "..." " .." "  ." "   ")
 | 
			
		||||
				update_interval=0.2
 | 
			
		||||
				;;
 | 
			
		||||
			"${PKGCTL_TERM_SPINNER_TRIANGLE}")
 | 
			
		||||
				spinner=("◢" "◣" "◤" "◥")
 | 
			
		||||
				update_interval=0.05
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
 | 
			
		||||
		# hide the cursor while spinning
 | 
			
		||||
		term_cursor_hide
 | 
			
		||||
 | 
			
		||||
		# run the spinner as long as the parent process didn't terminate
 | 
			
		||||
		while ps -p "${parent_pid}" &>/dev/null; do
 | 
			
		||||
			# cache the new status template if it exists
 | 
			
		||||
			if mv "${status_file}" "${next_file}" &>/dev/null; then
 | 
			
		||||
				status_message="$(cat "$next_file")"
 | 
			
		||||
			elif [[ -z "${status_message}" ]]; then
 | 
			
		||||
				# wait until we either have a new or cached status
 | 
			
		||||
				sleep 0.05
 | 
			
		||||
			fi
 | 
			
		||||
 | 
			
		||||
			# fill the frame buffer with the current status
 | 
			
		||||
			local prefix=''
 | 
			
		||||
			while IFS= read -r line; do
 | 
			
		||||
				# replace spinner placeholder
 | 
			
		||||
				line=${line//%spinner%/${spinner[spinner_offset%${#spinner[@]}]}}
 | 
			
		||||
 | 
			
		||||
				# append the current line to the frame buffer
 | 
			
		||||
				frame_buffer+="${prefix}${line}"
 | 
			
		||||
				prefix=$'\n'
 | 
			
		||||
			done <<< "${status_message}"
 | 
			
		||||
 | 
			
		||||
			# print current frame buffer
 | 
			
		||||
			echo -n "${frame_buffer}" >&2
 | 
			
		||||
			mv "${next_file}" "${drawn_file}" &>/dev/null ||:
 | 
			
		||||
 | 
			
		||||
			# setup next frame buffer to clear current content
 | 
			
		||||
			frame_buffer=$(term_erase_lines "$(awk 'END {print NR}' <<< "${status_message}")")
 | 
			
		||||
 | 
			
		||||
			# advance the spinner animation offset
 | 
			
		||||
			(( ++spinner_offset ))
 | 
			
		||||
 | 
			
		||||
			# sleep for the spinner update interval
 | 
			
		||||
			sleep "${update_interval}"
 | 
			
		||||
		done
 | 
			
		||||
	)&
 | 
			
		||||
	_pkgctl_spinner_pid=$!
 | 
			
		||||
	disown
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
term_spinner_stop() {
 | 
			
		||||
	local status_dir=$1
 | 
			
		||||
	local frame_buffer status_file
 | 
			
		||||
 | 
			
		||||
	# kill the spinner process
 | 
			
		||||
	if ! kill "${_pkgctl_spinner_pid}" > /dev/null 2>&1; then
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
	unset _pkgctl_spinner_pid
 | 
			
		||||
 | 
			
		||||
	# acquire last drawn status
 | 
			
		||||
	status_file="${status_dir}/drawn"
 | 
			
		||||
	if [[ ! -f ${status_file} ]]; then
 | 
			
		||||
		return 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# clear terminal based on last status line
 | 
			
		||||
	frame_buffer=$(term_erase_lines "$(awk 'END {print NR}' < "${status_file}")")
 | 
			
		||||
	echo -n "${frame_buffer}" >&2
 | 
			
		||||
 | 
			
		||||
	# show the cursor after stopping the spinner
 | 
			
		||||
	term_cursor_show
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
prompt() {
 | 
			
		||||
	local message=$1
 | 
			
		||||
	local answer
 | 
			
		||||
 | 
			
		||||
	read -r -p "${message} (y/N) " answer
 | 
			
		||||
 | 
			
		||||
	case "${answer}" in
 | 
			
		||||
		y|Y|yes|Yes|YES)
 | 
			
		||||
			true
 | 
			
		||||
			;;
 | 
			
		||||
		*)
 | 
			
		||||
			false
 | 
			
		||||
			;;
 | 
			
		||||
	esac
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								src/lib/valid-build-install.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/lib/valid-build-install.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
#!/hint/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
:
 | 
			
		||||
 | 
			
		||||
# shellcheck disable=2034
 | 
			
		||||
DEVTOOLS_VALID_BUILD_INSTALL=(
 | 
			
		||||
	none
 | 
			
		||||
	auto
 | 
			
		||||
	all
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										10
									
								
								src/lib/valid-inspect.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/lib/valid-inspect.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
#!/hint/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
# shellcheck disable=2034
 | 
			
		||||
DEVTOOLS_VALID_INSPECT_MODES=(
 | 
			
		||||
	never
 | 
			
		||||
	always
 | 
			
		||||
	failure
 | 
			
		||||
)
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
:
 | 
			
		||||
 | 
			
		||||
# shellcheck disable=2034
 | 
			
		||||
_repos=(
 | 
			
		||||
DEVTOOLS_VALID_REPOS=(
 | 
			
		||||
	core core-staging core-testing
 | 
			
		||||
	extra extra-staging extra-testing
 | 
			
		||||
	multilib multilib-staging multilib-testing
 | 
			
		||||
@@ -13,7 +13,7 @@ _repos=(
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# shellcheck disable=2034
 | 
			
		||||
_build_repos=(
 | 
			
		||||
DEVTOOLS_VALID_BUILDREPOS=(
 | 
			
		||||
	core-staging core-testing
 | 
			
		||||
	extra extra-staging extra-testing
 | 
			
		||||
	multilib multilib-staging multilib-testing
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								src/lib/valid-search.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/lib/valid-search.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
#!/hint/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
:
 | 
			
		||||
 | 
			
		||||
# shellcheck disable=2034
 | 
			
		||||
valid_search_output_format=(
 | 
			
		||||
	pretty
 | 
			
		||||
	plain
 | 
			
		||||
	json
 | 
			
		||||
)
 | 
			
		||||
@@ -4,13 +4,18 @@
 | 
			
		||||
:
 | 
			
		||||
 | 
			
		||||
# shellcheck disable=2034
 | 
			
		||||
_arch=(
 | 
			
		||||
DEVTOOLS_VALID_BINARY_ARCHES=(
 | 
			
		||||
	x86_64
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# shellcheck disable=2034
 | 
			
		||||
DEVTOOLS_VALID_ARCHES=(
 | 
			
		||||
	"${DEVTOOLS_VALID_BINARY_ARCHES[@]}"
 | 
			
		||||
	any
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# shellcheck disable=2034
 | 
			
		||||
_tags=(
 | 
			
		||||
DEVTOOLS_VALID_TAGS=(
 | 
			
		||||
	core-x86_64 core-any
 | 
			
		||||
	core-staging-x86_64 core-staging-any
 | 
			
		||||
	core-testing-x86_64 core-testing-any
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										75
									
								
								src/lib/version.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/lib/version.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
#!/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@}
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pkgctl_version_usage() {
 | 
			
		||||
	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
 | 
			
		||||
    cat <<- _EOF_
 | 
			
		||||
		Usage: ${COMMAND} [COMMAND] [OPTIONS]
 | 
			
		||||
 | 
			
		||||
		Check and manage package versions against upstream.
 | 
			
		||||
 | 
			
		||||
		COMMANDS
 | 
			
		||||
		    check      Compares local package versions against upstream
 | 
			
		||||
		    setup      Automatically detect and setup a basic nvchecker config
 | 
			
		||||
		    upgrade    Adjust the PKGBUILD to match the latest upstream version
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    -h, --help    Show this help text
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND} check libfoo linux libbar
 | 
			
		||||
		    $ ${COMMAND} setup libfoo
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_version() {
 | 
			
		||||
	if (( $# < 1 )); then
 | 
			
		||||
		pkgctl_version_usage
 | 
			
		||||
		exit 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
		case $1 in
 | 
			
		||||
			-h|--help)
 | 
			
		||||
				pkgctl_version_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			check)
 | 
			
		||||
				_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
				shift
 | 
			
		||||
				# shellcheck source=src/lib/version/check.sh
 | 
			
		||||
				source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/check.sh
 | 
			
		||||
				pkgctl_version_check "$@"
 | 
			
		||||
				exit $?
 | 
			
		||||
				;;
 | 
			
		||||
			upgrade)
 | 
			
		||||
				_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
				shift
 | 
			
		||||
				# shellcheck source=src/lib/version/upgrade.sh
 | 
			
		||||
				source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/upgrade.sh
 | 
			
		||||
				pkgctl_version_upgrade "$@"
 | 
			
		||||
				exit $?
 | 
			
		||||
				;;
 | 
			
		||||
			setup)
 | 
			
		||||
				_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
				shift
 | 
			
		||||
				# shellcheck source=src/lib/version/setup.sh
 | 
			
		||||
				source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/setup.sh
 | 
			
		||||
				pkgctl_version_setup "$@"
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				die "invalid argument: %s" "$1"
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
	done
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										347
									
								
								src/lib/version/check.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										347
									
								
								src/lib/version/check.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,347 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
#
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_VERSION_CHECK_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_VERSION_CHECK_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/util/term.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/term.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/message.sh
 | 
			
		||||
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
readonly PKGCTL_VERSION_CHECK_EXIT_UP_TO_DATE=0
 | 
			
		||||
export PKGCTL_VERSION_CHECK_EXIT_UP_TO_DATE
 | 
			
		||||
readonly PKGCTL_VERSION_CHECK_EXIT_OUT_OF_DATE=2
 | 
			
		||||
export PKGCTL_VERSION_CHECK_EXIT_OUT_OF_DATE
 | 
			
		||||
readonly PKGCTL_VERSION_CHECK_EXIT_FAILURE=3
 | 
			
		||||
export PKGCTL_VERSION_CHECK_EXIT_FAILURE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pkgctl_version_check_usage() {
 | 
			
		||||
	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
 | 
			
		||||
	cat <<- _EOF_
 | 
			
		||||
		Usage: ${COMMAND} [OPTIONS] [PKGBASE]...
 | 
			
		||||
 | 
			
		||||
		Compares the versions of packages in the local packaging repository against
 | 
			
		||||
		their latest upstream versions.
 | 
			
		||||
 | 
			
		||||
		Upon execution, it generates a grouped list that provides detailed insights
 | 
			
		||||
		into each package's status. For each package, it displays the current local
 | 
			
		||||
		version alongside the latest version available upstream.
 | 
			
		||||
 | 
			
		||||
		Outputs a summary of up-to-date packages, out-of-date packages, and any
 | 
			
		||||
		check failures.
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    -v, --verbose    Display results including up-to-date versions
 | 
			
		||||
		    -h, --help       Show this help text
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND} neovim vim
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_version_check() {
 | 
			
		||||
	local pkgbases=()
 | 
			
		||||
	local verbose=0
 | 
			
		||||
 | 
			
		||||
	local path status_file path pkgbase upstream_version result
 | 
			
		||||
 | 
			
		||||
	local up_to_date=()
 | 
			
		||||
	local out_of_date=()
 | 
			
		||||
	local failure=()
 | 
			
		||||
	local current_item=0
 | 
			
		||||
	local section_separator=''
 | 
			
		||||
	local exit_code=${PKGCTL_VERSION_CHECK_EXIT_UP_TO_DATE}
 | 
			
		||||
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
		case $1 in
 | 
			
		||||
			-h|--help)
 | 
			
		||||
				pkgctl_version_check_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			-v|--verbose)
 | 
			
		||||
				verbose=1
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--)
 | 
			
		||||
				shift
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			-*)
 | 
			
		||||
				die "invalid argument: %s" "$1"
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				pkgbases=("$@")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	if ! command -v nvchecker &>/dev/null; then
 | 
			
		||||
		die "The \"$_DEVTOOLS_COMMAND\" command requires 'nvchecker'"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# Check if used without pkgbases in a packaging directory
 | 
			
		||||
	if (( ${#pkgbases[@]} == 0 )); then
 | 
			
		||||
		if [[ -f PKGBUILD ]]; then
 | 
			
		||||
			pkgbases=(".")
 | 
			
		||||
		else
 | 
			
		||||
			pkgctl_version_check_usage
 | 
			
		||||
			exit 1
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# enable verbose mode when we only have a single item to check
 | 
			
		||||
	if (( ${#pkgbases[@]} == 1 )); then
 | 
			
		||||
		verbose=1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# start a terminal spinner as checking versions takes time
 | 
			
		||||
	status_dir=$(mktemp --tmpdir="${WORKDIR}" --directory pkgctl-version-check-spinner.XXXXXXXXXX)
 | 
			
		||||
	term_spinner_start "${status_dir}"
 | 
			
		||||
 | 
			
		||||
	for path in "${pkgbases[@]}"; do
 | 
			
		||||
		# skip paths that are not directories
 | 
			
		||||
		if [[ ! -d "${path}" ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
		pushd "${path}" >/dev/null
 | 
			
		||||
 | 
			
		||||
		# update the current terminal spinner status
 | 
			
		||||
		(( ++current_item ))
 | 
			
		||||
		pkgctl_version_check_spinner \
 | 
			
		||||
			"${status_dir}" \
 | 
			
		||||
			"${#up_to_date[@]}" \
 | 
			
		||||
			"${#out_of_date[@]}" \
 | 
			
		||||
			"${#failure[@]}" \
 | 
			
		||||
			"${current_item}" \
 | 
			
		||||
			"${#pkgbases[@]}"
 | 
			
		||||
 | 
			
		||||
		if [[ ! -f "PKGBUILD" ]]; then
 | 
			
		||||
			result="${BOLD}${path}${ALL_OFF}: no PKGBUILD found"
 | 
			
		||||
			failure+=("${result}")
 | 
			
		||||
			popd >/dev/null
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# reset common PKGBUILD variables
 | 
			
		||||
		unset pkgbase pkgname arch source pkgver pkgrel validpgpkeys
 | 
			
		||||
		# shellcheck source=contrib/makepkg/PKGBUILD.proto
 | 
			
		||||
		. ./PKGBUILD
 | 
			
		||||
		pkgbase=${pkgbase:-$pkgname}
 | 
			
		||||
 | 
			
		||||
		if ! result=$(get_upstream_version); then
 | 
			
		||||
			result="${BOLD}${pkgbase}${ALL_OFF}: ${result}"
 | 
			
		||||
			failure+=("${result}")
 | 
			
		||||
			popd >/dev/null
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
		upstream_version=${result}
 | 
			
		||||
 | 
			
		||||
		if ! result=$(vercmp "${upstream_version}" "${pkgver}"); then
 | 
			
		||||
			result="${BOLD}${pkgbase}${ALL_OFF}: failed to compare version ${upstream_version} against ${pkgver}"
 | 
			
		||||
			failure+=("${result}")
 | 
			
		||||
			popd >/dev/null
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		if (( result == 0 )); then
 | 
			
		||||
			result="${BOLD}${pkgbase}${ALL_OFF}: current version ${PURPLE}${pkgver}${ALL_OFF} is latest"
 | 
			
		||||
			up_to_date+=("${result}")
 | 
			
		||||
		elif (( result < 0 )); then
 | 
			
		||||
			result="${BOLD}${pkgbase}${ALL_OFF}: current version ${PURPLE}${pkgver}${ALL_OFF} is newer than ${DARK_GREEN}${upstream_version}${ALL_OFF}"
 | 
			
		||||
			up_to_date+=("${result}")
 | 
			
		||||
		elif (( result > 0 )); then
 | 
			
		||||
			result="${BOLD}${pkgbase}${ALL_OFF}: upgrade from version ${PURPLE}${pkgver}${ALL_OFF} to ${DARK_GREEN}${upstream_version}${ALL_OFF}"
 | 
			
		||||
			out_of_date+=("${result}")
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		popd >/dev/null
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# stop the terminal spinner after all checks
 | 
			
		||||
	term_spinner_stop "${status_dir}"
 | 
			
		||||
 | 
			
		||||
	if (( verbose )) && (( ${#up_to_date[@]} > 0 )); then
 | 
			
		||||
		printf "%sUp-to-date%s\n" "${section_separator}${BOLD}${UNDERLINE}" "${ALL_OFF}"
 | 
			
		||||
		section_separator=$'\n'
 | 
			
		||||
		for result in "${up_to_date[@]}"; do
 | 
			
		||||
			msg_success " ${result}"
 | 
			
		||||
		done
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if (( ${#failure[@]} > 0 )); then
 | 
			
		||||
		exit_code=${PKGCTL_VERSION_CHECK_EXIT_FAILURE}
 | 
			
		||||
		printf "%sFailure%s\n" "${section_separator}${BOLD}${UNDERLINE}" "${ALL_OFF}"
 | 
			
		||||
		section_separator=$'\n'
 | 
			
		||||
		for result in "${failure[@]}"; do
 | 
			
		||||
			msg_error " ${result}"
 | 
			
		||||
		done
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if (( ${#out_of_date[@]} > 0 )); then
 | 
			
		||||
		exit_code=${PKGCTL_VERSION_CHECK_EXIT_OUT_OF_DATE}
 | 
			
		||||
		printf "%sOut-of-date%s\n" "${section_separator}${BOLD}${UNDERLINE}" "${ALL_OFF}"
 | 
			
		||||
		section_separator=$'\n'
 | 
			
		||||
		for result in "${out_of_date[@]}"; do
 | 
			
		||||
			msg_warn " ${result}"
 | 
			
		||||
		done
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# Show summary when processing multiple packages
 | 
			
		||||
	if (( ${#pkgbases[@]} > 1 )); then
 | 
			
		||||
		printf '%s' "${section_separator}"
 | 
			
		||||
		pkgctl_version_check_summary \
 | 
			
		||||
			"${#up_to_date[@]}" \
 | 
			
		||||
			"${#out_of_date[@]}" \
 | 
			
		||||
			"${#failure[@]}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# return status based on results
 | 
			
		||||
	return "${exit_code}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
get_upstream_version() {
 | 
			
		||||
	local config=.nvchecker.toml
 | 
			
		||||
	local output errors upstream_version
 | 
			
		||||
	local output
 | 
			
		||||
	local opts=()
 | 
			
		||||
	local keyfile="${XDG_CONFIG_HOME:-${HOME}/.config}/nvchecker/keyfile.toml"
 | 
			
		||||
 | 
			
		||||
	# check nvchecker config file
 | 
			
		||||
	if ! errors=$(nvchecker_check_config "${config}"); then
 | 
			
		||||
		printf "%s" "${errors}"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# populate keyfile to nvchecker opts
 | 
			
		||||
	if [[ -f ${keyfile} ]]; then
 | 
			
		||||
		opts+=(--keyfile "${keyfile}")
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if ! output=$(GIT_TERMINAL_PROMPT=0 nvchecker --file "${config}" --logger json "${opts[@]}" 2>&1 | \
 | 
			
		||||
			jq --raw-output 'select((.level != "debug") and (.event != "ignoring invalid version"))'); then
 | 
			
		||||
		printf "failed to run nvchecker: %s" "${output}"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if ! errors=$(nvchecker_check_error "${output}"); then
 | 
			
		||||
		printf "%s" "${errors}"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if ! upstream_version=$(jq --raw-output --exit-status '.version' <<< "${output}"); then
 | 
			
		||||
		printf "failed to select version from result"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	printf "%s" "${upstream_version}"
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nvchecker_check_config() {
 | 
			
		||||
	local config=$1
 | 
			
		||||
 | 
			
		||||
	local restricted_properties=(keyfile httptoken token)
 | 
			
		||||
	local property
 | 
			
		||||
 | 
			
		||||
	# check if the config file exists
 | 
			
		||||
	if [[ ! -f ${config} ]]; then
 | 
			
		||||
		printf "configuration file not found: %s" "${config}"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# check if config contains any restricted properties like secrets
 | 
			
		||||
	for property in "${restricted_properties[@]}"; do
 | 
			
		||||
		if grep --max-count=1 --quiet "^${property}" < "${config}"; then
 | 
			
		||||
			printf "restricted property in %s: %s" "${config}" "${property}"
 | 
			
		||||
			return 1
 | 
			
		||||
		fi
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# check if the config contains a pkgbase section
 | 
			
		||||
	if [[ -n ${pkgbase} ]] && ! grep --max-count=1 --extended-regexp --quiet "^\\[\"?${pkgbase//+/\\+}\"?\\]" < "${config}"; then
 | 
			
		||||
		printf "missing pkgbase section in %s: %s" "${config}" "${pkgbase}"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# check if the config contains any section other than pkgbase
 | 
			
		||||
	if [[ -n ${pkgbase} ]] && property=$(grep --max-count=1 --perl-regexp "^\\[(?!\"?${pkgbase//+/\\+}\"?\\]).+\\]" < "${config}"); then
 | 
			
		||||
		printf "non-pkgbase section not supported in %s: %s" "${config}" "${property}"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nvchecker_check_error() {
 | 
			
		||||
	local result=$1
 | 
			
		||||
	local errors
 | 
			
		||||
 | 
			
		||||
	if ! errors=$(jq --raw-output --exit-status \
 | 
			
		||||
			'select((.level == "error") and (.error != null)) | "\(.event)" + if .error then ": \(.error)" else "" end' \
 | 
			
		||||
			<<< "${result}"); then
 | 
			
		||||
		return 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	mapfile -t errors <<< "${errors}"
 | 
			
		||||
	printf "%s\n" "${errors[@]}"
 | 
			
		||||
	return 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_version_check_summary() {
 | 
			
		||||
	local up_to_date_count=$1
 | 
			
		||||
	local out_of_date_count=$2
 | 
			
		||||
	local failure_count=$3
 | 
			
		||||
 | 
			
		||||
	# print nothing if all stats are zero
 | 
			
		||||
	if (( up_to_date_count == 0 )) && \
 | 
			
		||||
			(( out_of_date_count == 0 )) && \
 | 
			
		||||
			(( failure_count == 0 )); then
 | 
			
		||||
		return 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# print summary for all none zero stats
 | 
			
		||||
	printf "%sSummary%s\n" "${BOLD}${UNDERLINE}" "${ALL_OFF}"
 | 
			
		||||
	if (( up_to_date_count > 0 )); then
 | 
			
		||||
		msg_success " Up-to-date: ${BOLD}${up_to_date_count}${ALL_OFF}" 2>&1
 | 
			
		||||
	fi
 | 
			
		||||
	if (( failure_count > 0 )); then
 | 
			
		||||
		msg_error " Failure: ${BOLD}${failure_count}${ALL_OFF}" 2>&1
 | 
			
		||||
	fi
 | 
			
		||||
	if (( out_of_date_count > 0 )); then
 | 
			
		||||
		msg_warn " Out-of-date: ${BOLD}${out_of_date_count}${ALL_OFF}" 2>&1
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_version_check_spinner() {
 | 
			
		||||
	local status_dir=$1
 | 
			
		||||
	local up_to_date_count=$2
 | 
			
		||||
	local out_of_date_count=$3
 | 
			
		||||
	local failure_count=$4
 | 
			
		||||
	local current=$5
 | 
			
		||||
	local total=$6
 | 
			
		||||
 | 
			
		||||
	local percentage=$(( 100 * current / total ))
 | 
			
		||||
	local tmp_file="${status_dir}/tmp"
 | 
			
		||||
	local status_file="${status_dir}/status"
 | 
			
		||||
 | 
			
		||||
	# print the current summary
 | 
			
		||||
	pkgctl_version_check_summary \
 | 
			
		||||
		"${up_to_date_count}" \
 | 
			
		||||
		"${out_of_date_count}" \
 | 
			
		||||
		"${failure_count}" > "${tmp_file}"
 | 
			
		||||
 | 
			
		||||
	# print the progress status
 | 
			
		||||
	printf "📡 Checking: %s/%s [%s] %%spinner%%" \
 | 
			
		||||
		"${BOLD}${current}" "${total}" "${percentage}%${ALL_OFF}"  \
 | 
			
		||||
		>> "${tmp_file}"
 | 
			
		||||
 | 
			
		||||
	# swap the status file
 | 
			
		||||
	mv "${tmp_file}" "${status_file}"
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										528
									
								
								src/lib/version/setup.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										528
									
								
								src/lib/version/setup.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,528 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
#
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_VERSION_SETUP_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_VERSION_SETUP_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/version/check.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/check.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/message.sh
 | 
			
		||||
source /usr/share/makepkg/util/source.sh
 | 
			
		||||
 | 
			
		||||
set -eo pipefail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pkgctl_version_setup_usage() {
 | 
			
		||||
	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
 | 
			
		||||
	cat <<- _EOF_
 | 
			
		||||
		Usage: ${COMMAND} [OPTIONS] [PKGBASE]...
 | 
			
		||||
 | 
			
		||||
		Automate the creation of a basic nvchecker configuration file by
 | 
			
		||||
		analyzing the source array specified in the PKGBUILD file of a package.
 | 
			
		||||
 | 
			
		||||
		If no PKGBASE is specified, the command defaults to using the current
 | 
			
		||||
		working directory.
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    -f, --force            Overwrite existing nvchecker configuration
 | 
			
		||||
		    --prefer-platform-api  Prefer platform specific GitHub/GitLab API for complex cases
 | 
			
		||||
		    --url URL              Derive check target from URL instead of source array
 | 
			
		||||
		    --no-check             Do not run version check after setup
 | 
			
		||||
		    -h, --help             Show this help text
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND} neovim vim
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_version_setup() {
 | 
			
		||||
	local pkgbases=()
 | 
			
		||||
	local override_url=
 | 
			
		||||
	local run_check=1
 | 
			
		||||
	local force=0
 | 
			
		||||
	local prefer_platform_api=0
 | 
			
		||||
 | 
			
		||||
	local path ret
 | 
			
		||||
	local checks=()
 | 
			
		||||
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
		case $1 in
 | 
			
		||||
			-h|--help)
 | 
			
		||||
				pkgctl_version_setup_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			-f|--force)
 | 
			
		||||
				force=1
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--prefer-platform-api)
 | 
			
		||||
				prefer_platform_api=1
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--url)
 | 
			
		||||
				(( $# <= 1 )) && die "missing argument for %s" "$1"
 | 
			
		||||
				override_url=$2
 | 
			
		||||
				shift 2
 | 
			
		||||
				;;
 | 
			
		||||
			--no-check)
 | 
			
		||||
				run_check=0
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--)
 | 
			
		||||
				shift
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			-*)
 | 
			
		||||
				die "invalid argument: %s" "$1"
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				pkgbases=("$@")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# Check if used without pkgbases in a packaging directory
 | 
			
		||||
	if (( ${#pkgbases[@]} == 0 )); then
 | 
			
		||||
		if [[ -f PKGBUILD ]]; then
 | 
			
		||||
			pkgbases=(".")
 | 
			
		||||
		else
 | 
			
		||||
			pkgctl_version_setup_usage
 | 
			
		||||
			exit 1
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	ret=0
 | 
			
		||||
	for path in "${pkgbases[@]}"; do
 | 
			
		||||
		# skip paths that are not directories
 | 
			
		||||
		if [[ ! -d "${path}" ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		pushd "${path}" >/dev/null
 | 
			
		||||
		if nvchecker_setup "${path}" "${force}" "${prefer_platform_api}" "${override_url}"; then
 | 
			
		||||
			checks+=("${path}")
 | 
			
		||||
		else
 | 
			
		||||
			ret=1
 | 
			
		||||
		fi
 | 
			
		||||
		popd >/dev/null
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# run checks on the setup targets
 | 
			
		||||
	if (( run_check )) && (( ${#checks[@]} >= 1 )); then
 | 
			
		||||
		echo
 | 
			
		||||
		pkgctl_version_check --verbose "${checks[@]}" || true
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	return $ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nvchecker_setup() {
 | 
			
		||||
	local path=$1
 | 
			
		||||
	local force=$2
 | 
			
		||||
	local prefer_platform_api=$3
 | 
			
		||||
	local override_url=$4
 | 
			
		||||
	local pkgbase pkgname source source_url proto domain url_parts section body
 | 
			
		||||
 | 
			
		||||
	if [[ ! -f PKGBUILD ]]; then
 | 
			
		||||
		msg_error "${BOLD}${path}:${ALL_OFF} no PKGBUILD found"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	unset body pkgbase pkgname source url
 | 
			
		||||
	# shellcheck source=contrib/makepkg/PKGBUILD.proto
 | 
			
		||||
	if ! . ./PKGBUILD; then
 | 
			
		||||
		msg_error "${BOLD}${path}:${ALL_OFF} failed to source PKGBUILD"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
	pkgbase=${pkgbase:-$pkgname}
 | 
			
		||||
 | 
			
		||||
	# try to guess from url as last try
 | 
			
		||||
	if [[ -n ${url} ]]; then
 | 
			
		||||
		source+=("${url}")
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# handle overwrite of existing config
 | 
			
		||||
	if [[ -f .nvchecker.toml ]] && (( ! force )); then
 | 
			
		||||
		msg_warn "${BOLD}${pkgbase}:${ALL_OFF} nvchecker already configured"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# override the source array with a passed URL
 | 
			
		||||
	if [[ -n ${override_url} ]]; then
 | 
			
		||||
		source=("${override_url}")
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# skip empty source array
 | 
			
		||||
	if (( ${#source[@]} == 0 )); then
 | 
			
		||||
		msg_error "${BOLD}${pkgbase}:${ALL_OFF} PKGBUILD has no source array"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	for source_url in "${source[@]}"; do
 | 
			
		||||
		# Strips out filename::http for example
 | 
			
		||||
		source_url=$(get_url "${source_url}")
 | 
			
		||||
		# discard query fragments
 | 
			
		||||
		source_url=${source_url%\?*}
 | 
			
		||||
		source_url=${source_url%#*}
 | 
			
		||||
 | 
			
		||||
		# skip patches
 | 
			
		||||
		if [[ ${source_url} == *.patch ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
		# skip signatures
 | 
			
		||||
		if [[ ${source_url} == *.asc ]] || [[ ${source_url} == *.sig ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
		# skip local files
 | 
			
		||||
		if [[ ${source_url} != *://* ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# split URL segments while avoiding empty element after protocol and newline at the end
 | 
			
		||||
		mapfile -td / url_parts <<< "${source_url/:\/\//\/}/"
 | 
			
		||||
		unset "url_parts[-1]"
 | 
			
		||||
 | 
			
		||||
		# extract protocol and domain to select the configuration type
 | 
			
		||||
		proto=${url_parts[0]}
 | 
			
		||||
		domain=${url_parts[1]}
 | 
			
		||||
 | 
			
		||||
		case "${domain}" in
 | 
			
		||||
			gitlab.*)
 | 
			
		||||
				if (( prefer_platform_api )); then
 | 
			
		||||
					body=$(nvchecker_setup_gitlab "${url_parts[@]}")
 | 
			
		||||
				else
 | 
			
		||||
					body=$(nvchecker_setup_git "${url_parts[@]}")
 | 
			
		||||
				fi
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			github.com)
 | 
			
		||||
				if (( prefer_platform_api )); then
 | 
			
		||||
					body=$(nvchecker_setup_github "${url_parts[@]}")
 | 
			
		||||
				else
 | 
			
		||||
					body=$(nvchecker_setup_git "${url_parts[@]}")
 | 
			
		||||
				fi
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			codeberg.org)
 | 
			
		||||
				body=$(nvchecker_setup_git "${url_parts[@]}")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			pypi.org|pypi.io|files.pythonhosted.org)
 | 
			
		||||
				body=$(nvchecker_setup_pypi "${url_parts[@]}")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			hackage.haskell.org)
 | 
			
		||||
				body=$(nvchecker_setup_hackage "${url_parts[@]}")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			registry.npmjs.org|npmjs.com|www.npmjs.com)
 | 
			
		||||
				body=$(nvchecker_setup_npm "${url_parts[@]}")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			rubygems.org)
 | 
			
		||||
				body=$(nvchecker_setup_rubygems "${url_parts[@]}")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			*.cpan.org|*.mcpan.org|*.metacpan.org)
 | 
			
		||||
				body=$(nvchecker_setup_cpan "${url_parts[@]}")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			crates.io|*.crates.io)
 | 
			
		||||
				body=$(nvchecker_setup_crates_io "${url_parts[@]}")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				if [[ ${proto} == git ]] || [[ ${proto} == git+https ]]; then
 | 
			
		||||
					body=$(nvchecker_setup_git "${url_parts[@]}")
 | 
			
		||||
				fi
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	if [[ -z "${body}" ]]; then
 | 
			
		||||
		msg_error "${BOLD}${pkgbase}:${ALL_OFF} unable to automatically setup nvchecker"
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# escape the section if it contains toml subsection chars
 | 
			
		||||
	section="${pkgbase}"
 | 
			
		||||
	if [[ ${section} == *.* ]] || [[ ${section} == *+* ]]; then
 | 
			
		||||
		section="\"${section}\""
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	msg_success "${BOLD}${pkgbase}:${ALL_OFF} successfully configured nvchecker"
 | 
			
		||||
	cat > .nvchecker.toml << EOF
 | 
			
		||||
[${section}]
 | 
			
		||||
${body}
 | 
			
		||||
EOF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
get_git_url_from_parts() {
 | 
			
		||||
	local url_parts=("$@")
 | 
			
		||||
	local proto=${url_parts[0]#*+}
 | 
			
		||||
	local domain=${url_parts[1]}
 | 
			
		||||
	local url
 | 
			
		||||
	url="${proto}://$(join_by / "${url_parts[@]:1}")"
 | 
			
		||||
 | 
			
		||||
	case "${domain}" in
 | 
			
		||||
		gitlab.*)
 | 
			
		||||
			url=${url%/-/*/*}
 | 
			
		||||
			[[ ${url} != *.git ]] && url+=.git
 | 
			
		||||
			;;
 | 
			
		||||
		github.com|codeberg.org)
 | 
			
		||||
			url="${proto}://$(join_by / "${url_parts[@]:1:3}")"
 | 
			
		||||
			[[ ${url} != *.git ]] && url+=.git
 | 
			
		||||
			;;
 | 
			
		||||
	esac
 | 
			
		||||
 | 
			
		||||
	printf '%s' "${url}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# PyPI
 | 
			
		||||
#
 | 
			
		||||
# As Arch python packages don't necessarily match the pypi name, when the
 | 
			
		||||
# provided source url comes from pypi.io or pypi.org try to extract the package
 | 
			
		||||
# name from the (predictable) tarball download url for example:
 | 
			
		||||
#
 | 
			
		||||
# https://pypi.io/packages/source/p/pyflakes/pyflakes-3.1.0.tar.gz
 | 
			
		||||
# https://pypi.io/packages/source/p/pyflakes
 | 
			
		||||
# https://pypi.org/packages/source/b/bleach
 | 
			
		||||
# https://files.pythonhosted.org/packages/source/p/pyflakes
 | 
			
		||||
# https://pypi.org/project/SQLAlchemy/
 | 
			
		||||
nvchecker_setup_pypi() {
 | 
			
		||||
	local url_parts=("$@")
 | 
			
		||||
	local pypi
 | 
			
		||||
 | 
			
		||||
	if [[ ${url_parts[2]} == packages ]]; then
 | 
			
		||||
		pypi=${url_parts[5]}
 | 
			
		||||
	elif [[ ${url_parts[2]} == project ]]; then
 | 
			
		||||
		pypi=${url_parts[3]}
 | 
			
		||||
	else
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	cat << EOF
 | 
			
		||||
source = "pypi"
 | 
			
		||||
pypi = "${pypi}"
 | 
			
		||||
EOF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Git
 | 
			
		||||
#
 | 
			
		||||
# Set up a generic Git source, while removing the proto specific part from makepkg
 | 
			
		||||
#
 | 
			
		||||
# git+https://github.com/prometheus/prometheus.git
 | 
			
		||||
# https://git.foobar.com/some/path/group/project.git
 | 
			
		||||
# https://gitlab.com/sub/group/project/-/archive/8.0.0/packages-8.0.0.tar.gz
 | 
			
		||||
nvchecker_setup_git() {
 | 
			
		||||
	local url_parts=("$@")
 | 
			
		||||
	local url
 | 
			
		||||
	url=$(get_git_url_from_parts "${url_parts[@]}")
 | 
			
		||||
 | 
			
		||||
	cat << EOF
 | 
			
		||||
source = "git"
 | 
			
		||||
git = "${url}"
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
	# best effort check if the tags are prefixed with v
 | 
			
		||||
	if git_tags_have_version_prefix "${url}"; then
 | 
			
		||||
		echo 'prefix = "v"'
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
git_tags_have_version_prefix() {
 | 
			
		||||
	local url=$1
 | 
			
		||||
	# best effort check if the tags are prefixed with v
 | 
			
		||||
	if ! grep --max-count=1 --quiet --extended-regex 'refs/tags/v[0-9]+[\.0-9]*$' \
 | 
			
		||||
		<(GIT_TERMINAL_PROMPT=0 git ls-remote --quiet --tags "${url}" 2>/dev/null); then
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
	return 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Github
 | 
			
		||||
#
 | 
			
		||||
# We want to know the $org/$project name from the url
 | 
			
		||||
#
 | 
			
		||||
# https://github.com/prometheus/prometheus/archive/v2.49.1.tar.gz
 | 
			
		||||
nvchecker_setup_github() {
 | 
			
		||||
	local url_parts=("$@")
 | 
			
		||||
	local url project
 | 
			
		||||
	if ! url=$(get_git_url_from_parts "${url_parts[@]}"); then
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
	project=${url#*://*/}
 | 
			
		||||
	project=${project%.git}
 | 
			
		||||
 | 
			
		||||
	cat << EOF
 | 
			
		||||
source = "github"
 | 
			
		||||
github = "${project}"
 | 
			
		||||
use_max_tag = true
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
	# best effort check if the tags are prefixed with v
 | 
			
		||||
	if git_tags_have_version_prefix "${url}"; then
 | 
			
		||||
		echo 'prefix = "v"'
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# GitLab
 | 
			
		||||
#
 | 
			
		||||
# We want to know the $org/$project name from the url
 | 
			
		||||
#
 | 
			
		||||
# git+https://gitlab.com/inkscape/inkscape.git#tag=091e20ef0f204eb40ecde54436e1ef934a03d894
 | 
			
		||||
nvchecker_setup_gitlab() {
 | 
			
		||||
	local url_parts=("$@")
 | 
			
		||||
	local url project host
 | 
			
		||||
	if ! url=$(get_git_url_from_parts "${url_parts[@]}"); then
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
	project=${url#*://*/}
 | 
			
		||||
	project=${project%.git}
 | 
			
		||||
	cat << EOF
 | 
			
		||||
source = "gitlab"
 | 
			
		||||
gitlab = "${project}"
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
	host=${url#*://}
 | 
			
		||||
	host=${host%%/*}
 | 
			
		||||
	if [[ ${host} != gitlab.com ]]; then
 | 
			
		||||
		echo "host = \"${host}\""
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	echo "use_max_tag = true"
 | 
			
		||||
 | 
			
		||||
	# best effort check if the tags are prefixed with v
 | 
			
		||||
	if git_tags_have_version_prefix "${url}"; then
 | 
			
		||||
		echo 'prefix = "v"'
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Hackage
 | 
			
		||||
#
 | 
			
		||||
# We want to know the project name
 | 
			
		||||
#
 | 
			
		||||
# https://hackage.haskell.org/package/xmonad
 | 
			
		||||
# https://hackage.haskell.org/package/xmonad-0.18.0/xmonad-0.18.0.tar.gz
 | 
			
		||||
# https://hackage.haskell.org/packages/archive/digits/0.3.1/digits-0.3.1.tar.gz
 | 
			
		||||
nvchecker_setup_hackage() {
 | 
			
		||||
	local url_parts=("$@")
 | 
			
		||||
	local hackage
 | 
			
		||||
 | 
			
		||||
	if [[ ${url_parts[2]} == packages ]]; then
 | 
			
		||||
		hackage=${url_parts[4]}
 | 
			
		||||
	elif [[ ${url_parts[2]} == package ]] && (( ${#url_parts[@]} == 4 )); then
 | 
			
		||||
		hackage=${url_parts[3]}
 | 
			
		||||
	elif [[ ${url_parts[2]} == package ]] && (( ${#url_parts[@]} >= 5 )); then
 | 
			
		||||
		hackage=${url_parts[3]%-*}
 | 
			
		||||
	else
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	cat << EOF
 | 
			
		||||
source = "hackage"
 | 
			
		||||
hackage = "${hackage}"
 | 
			
		||||
EOF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# NPM
 | 
			
		||||
#
 | 
			
		||||
# We want to know the project name
 | 
			
		||||
#
 | 
			
		||||
# https://registry.npmjs.org/eslint_d/-/eslint_d-12.1.0.tgz
 | 
			
		||||
# https://www.npmjs.com/package/node-gyp
 | 
			
		||||
nvchecker_setup_npm() {
 | 
			
		||||
	local url_parts=("$@")
 | 
			
		||||
	local npm
 | 
			
		||||
 | 
			
		||||
	if [[ ${url_parts[1]} == registry.npmjs.org ]]; then
 | 
			
		||||
		npm=${url_parts[2]}
 | 
			
		||||
	elif [[ ${url_parts[2]} == package ]] && (( ${#url_parts[@]} == 4 )); then
 | 
			
		||||
		npm=${url_parts[3]}
 | 
			
		||||
	else
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	cat << EOF
 | 
			
		||||
source = "npm"
 | 
			
		||||
npm = "${npm}"
 | 
			
		||||
EOF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# RubyGems
 | 
			
		||||
#
 | 
			
		||||
# We want to know the project name
 | 
			
		||||
#
 | 
			
		||||
# https://rubygems.org/downloads/polyglot-0.3.5.gem
 | 
			
		||||
# https://rubygems.org/gems/diff-lcs
 | 
			
		||||
nvchecker_setup_rubygems() {
 | 
			
		||||
	local url_parts=("$@")
 | 
			
		||||
	local gem
 | 
			
		||||
 | 
			
		||||
	if [[ ${url_parts[2]} == downloads ]]; then
 | 
			
		||||
		gem=${url_parts[-1]%-*}
 | 
			
		||||
	elif [[ ${url_parts[2]} == gems ]]; then
 | 
			
		||||
		gem=${url_parts[3]}
 | 
			
		||||
	else
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	cat << EOF
 | 
			
		||||
source = "gems"
 | 
			
		||||
gems = "${gem}"
 | 
			
		||||
EOF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# CPAN
 | 
			
		||||
#
 | 
			
		||||
# We want to know the project name
 | 
			
		||||
#
 | 
			
		||||
# source = https://search.cpan.org/CPAN/authors/id/C/CO/COSIMO/Locale-PO-1.2.3.tar.gz
 | 
			
		||||
nvchecker_setup_cpan() {
 | 
			
		||||
	local url_parts=("$@")
 | 
			
		||||
	local cpan=${url_parts[-1]}
 | 
			
		||||
	cpan=${cpan%-*}
 | 
			
		||||
 | 
			
		||||
	cat << EOF
 | 
			
		||||
source = "cpan"
 | 
			
		||||
cpan = "${cpan}"
 | 
			
		||||
EOF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# crates.io
 | 
			
		||||
#
 | 
			
		||||
# We want to know the crate name
 | 
			
		||||
#
 | 
			
		||||
# https://crates.io/api/v1/crates/${pkgname}/${pkgver}/download
 | 
			
		||||
# https://static.crates.io/crates/${pkgname}/$pkgname-$pkgver.crate
 | 
			
		||||
# https://crates.io/crates/git-smash
 | 
			
		||||
nvchecker_setup_crates_io() {
 | 
			
		||||
	local url_parts=("$@")
 | 
			
		||||
	local crate
 | 
			
		||||
 | 
			
		||||
	if [[ ${url_parts[2]} == crates ]]; then
 | 
			
		||||
		crate=${url_parts[3]}
 | 
			
		||||
	elif [[ ${url_parts[4]} == crates ]]; then
 | 
			
		||||
		crate=${url_parts[5]}
 | 
			
		||||
	else
 | 
			
		||||
		return 1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	for i in "${!url_parts[@]}"; do
 | 
			
		||||
		if [[ ${url_parts[i]} == crates ]]; then
 | 
			
		||||
			crate=${url_parts[(( i + 1 ))]}
 | 
			
		||||
		fi
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	cat << EOF
 | 
			
		||||
source = "cratesio"
 | 
			
		||||
cratesio = "${crate}"
 | 
			
		||||
EOF
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										286
									
								
								src/lib/version/upgrade.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								src/lib/version/upgrade.sh
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,286 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
			
		||||
#
 | 
			
		||||
[[ -z ${DEVTOOLS_INCLUDE_VERSION_UPGRADE_SH:-} ]] || return 0
 | 
			
		||||
DEVTOOLS_INCLUDE_VERSION_UPGRADE_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/version/check.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/check.sh
 | 
			
		||||
# shellcheck source=src/lib/util/pkgbuild.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/pkgbuild.sh
 | 
			
		||||
# shellcheck source=src/lib/util/term.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/term.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/message.sh
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
pkgctl_version_upgrade_usage() {
 | 
			
		||||
	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}}
 | 
			
		||||
	cat <<- _EOF_
 | 
			
		||||
		Usage: ${COMMAND} [OPTIONS] [PKGBASE]...
 | 
			
		||||
 | 
			
		||||
		Streamlines the process of keeping PKGBUILD files up-to-date with the latest
 | 
			
		||||
		upstream versions.
 | 
			
		||||
 | 
			
		||||
		Upon execution, it automatically adjusts the PKGBUILD file, ensuring that the
 | 
			
		||||
		pkgver field is set to match the latest version available from the upstream
 | 
			
		||||
		source. In addition to updating the pkgver, this command also resets the pkgrel
 | 
			
		||||
		to 1 and updates checksums.
 | 
			
		||||
 | 
			
		||||
		Outputs a summary of upgraded packages, up-to-date packages, and any check
 | 
			
		||||
		failures.
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    --no-update-checksums  Disable computation and update of the checksums
 | 
			
		||||
		    -v, --verbose          Display results including up-to-date versions
 | 
			
		||||
		    -h, --help             Show this help text
 | 
			
		||||
 | 
			
		||||
		EXAMPLES
 | 
			
		||||
		    $ ${COMMAND} neovim vim
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_version_upgrade() {
 | 
			
		||||
	local path upstream_version result
 | 
			
		||||
	local pkgbases=()
 | 
			
		||||
	local verbose=0
 | 
			
		||||
	local exit_code=0
 | 
			
		||||
	local current_item=0
 | 
			
		||||
	local update_checksums=1
 | 
			
		||||
 | 
			
		||||
	while (( $# )); do
 | 
			
		||||
		case $1 in
 | 
			
		||||
			-h|--help)
 | 
			
		||||
				pkgctl_version_upgrade_usage
 | 
			
		||||
				exit 0
 | 
			
		||||
				;;
 | 
			
		||||
			--no-update-checksums)
 | 
			
		||||
				update_checksums=0
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			-v|--verbose)
 | 
			
		||||
				verbose=1
 | 
			
		||||
				shift
 | 
			
		||||
				;;
 | 
			
		||||
			--)
 | 
			
		||||
				shift
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
			-*)
 | 
			
		||||
				die "invalid argument: %s" "$1"
 | 
			
		||||
				;;
 | 
			
		||||
			*)
 | 
			
		||||
				pkgbases=("$@")
 | 
			
		||||
				break
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	if ! command -v nvchecker &>/dev/null; then
 | 
			
		||||
		die "The \"$_DEVTOOLS_COMMAND\" command requires 'nvchecker'"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# Check if used without pkgbases in a packaging directory
 | 
			
		||||
	if (( ${#pkgbases[@]} == 0 )); then
 | 
			
		||||
		if [[ -f PKGBUILD ]]; then
 | 
			
		||||
			pkgbases=(".")
 | 
			
		||||
		else
 | 
			
		||||
			pkgctl_version_upgrade_usage
 | 
			
		||||
			exit 1
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# enable verbose mode when we only have a single item to check
 | 
			
		||||
	if (( ${#pkgbases[@]} == 1 )); then
 | 
			
		||||
		verbose=1
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# start a terminal spinner as checking versions takes time
 | 
			
		||||
	status_dir=$(mktemp --tmpdir="${WORKDIR}" --directory pkgctl-version-check-spinner.XXXXXXXXXX)
 | 
			
		||||
	term_spinner_start "${status_dir}"
 | 
			
		||||
 | 
			
		||||
	for path in "${pkgbases[@]}"; do
 | 
			
		||||
		# skip paths that aren't directories
 | 
			
		||||
		if [[ ! -d "${path}" ]]; then
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
		pushd "${path}" >/dev/null
 | 
			
		||||
 | 
			
		||||
		(( ++current_item ))
 | 
			
		||||
 | 
			
		||||
		if [[ ! -f "PKGBUILD" ]]; then
 | 
			
		||||
			result="${BOLD}${path}${ALL_OFF}: no PKGBUILD found"
 | 
			
		||||
			failure+=("${result}")
 | 
			
		||||
			popd >/dev/null
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		# reset common PKGBUILD variables
 | 
			
		||||
		unset pkgbase pkgname arch source pkgver pkgrel validpgpkeys
 | 
			
		||||
		# shellcheck source=contrib/makepkg/PKGBUILD.proto
 | 
			
		||||
		. ./PKGBUILD
 | 
			
		||||
		pkgbase=${pkgbase:-$pkgname}
 | 
			
		||||
 | 
			
		||||
		# update the current terminal spinner status
 | 
			
		||||
		pkgctl_version_upgrade_spinner \
 | 
			
		||||
			"${status_dir}" \
 | 
			
		||||
			"${#up_to_date[@]}" \
 | 
			
		||||
			"${#out_of_date[@]}" \
 | 
			
		||||
			"${#failure[@]}" \
 | 
			
		||||
			"${current_item}" \
 | 
			
		||||
			"${#pkgbases[@]}" \
 | 
			
		||||
			"${pkgbase}" \
 | 
			
		||||
			"query latest version"
 | 
			
		||||
 | 
			
		||||
		if ! result=$(get_upstream_version); then
 | 
			
		||||
			result="${BOLD}${pkgbase}${ALL_OFF}: ${result}"
 | 
			
		||||
			failure+=("${result}")
 | 
			
		||||
			popd >/dev/null
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
		upstream_version=${result}
 | 
			
		||||
 | 
			
		||||
		if ! result=$(vercmp "${upstream_version}" "${pkgver}"); then
 | 
			
		||||
			result="${BOLD}${pkgbase}${ALL_OFF}: failed to compare version ${upstream_version} against ${pkgver}"
 | 
			
		||||
			failure+=("${result}")
 | 
			
		||||
			popd >/dev/null
 | 
			
		||||
			continue
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		if (( result == 0 )); then
 | 
			
		||||
			result="${BOLD}${pkgbase}${ALL_OFF}: current version ${PURPLE}${pkgver}${ALL_OFF} is latest"
 | 
			
		||||
			up_to_date+=("${result}")
 | 
			
		||||
		elif (( result < 0 )); then
 | 
			
		||||
			result="${BOLD}${pkgbase}${ALL_OFF}: current version ${PURPLE}${pkgver}${ALL_OFF} is newer than ${DARK_GREEN}${upstream_version}${ALL_OFF}"
 | 
			
		||||
			up_to_date+=("${result}")
 | 
			
		||||
		elif (( result > 0 )); then
 | 
			
		||||
			result="${BOLD}${pkgbase}${ALL_OFF}: upgraded from version ${PURPLE}${pkgver}${ALL_OFF} to ${DARK_GREEN}${upstream_version}${ALL_OFF}"
 | 
			
		||||
			out_of_date+=("${result}")
 | 
			
		||||
 | 
			
		||||
			# change the PKGBUILD
 | 
			
		||||
			pkgbuild_set_pkgver "${upstream_version}"
 | 
			
		||||
			pkgbuild_set_pkgrel 1
 | 
			
		||||
 | 
			
		||||
			# download sources and update the checksums
 | 
			
		||||
			if (( update_checksums )); then
 | 
			
		||||
				pkgctl_version_upgrade_spinner \
 | 
			
		||||
					"${status_dir}" \
 | 
			
		||||
					"${#up_to_date[@]}" \
 | 
			
		||||
					"${#out_of_date[@]}" \
 | 
			
		||||
					"${#failure[@]}" \
 | 
			
		||||
					"${current_item}" \
 | 
			
		||||
					"${#pkgbases[@]}" \
 | 
			
		||||
					"${pkgbase}" \
 | 
			
		||||
					"updating checksums"
 | 
			
		||||
 | 
			
		||||
				if ! result=$(pkgbuild_update_checksums /dev/null); then
 | 
			
		||||
					result="${BOLD}${pkgbase}${ALL_OFF}: failed to update checksums for version ${DARK_GREEN}${upstream_version}${ALL_OFF}"
 | 
			
		||||
					failure+=("${result}")
 | 
			
		||||
				fi
 | 
			
		||||
			fi
 | 
			
		||||
		fi
 | 
			
		||||
 | 
			
		||||
		popd >/dev/null
 | 
			
		||||
	done
 | 
			
		||||
 | 
			
		||||
	# stop the terminal spinner after all checks
 | 
			
		||||
	term_spinner_stop "${status_dir}"
 | 
			
		||||
 | 
			
		||||
	if (( verbose )) && (( ${#up_to_date[@]} > 0 )); then
 | 
			
		||||
		printf "%sUp-to-date%s\n" "${section_separator}${BOLD}${UNDERLINE}" "${ALL_OFF}"
 | 
			
		||||
		section_separator=$'\n'
 | 
			
		||||
		for result in "${up_to_date[@]}"; do
 | 
			
		||||
			msg_success " ${result}"
 | 
			
		||||
		done
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if (( ${#failure[@]} > 0 )); then
 | 
			
		||||
		exit_code=1
 | 
			
		||||
		printf "%sFailure%s\n" "${section_separator}${BOLD}${UNDERLINE}" "${ALL_OFF}"
 | 
			
		||||
		section_separator=$'\n'
 | 
			
		||||
		for result in "${failure[@]}"; do
 | 
			
		||||
			msg_error " ${result}"
 | 
			
		||||
		done
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if (( ${#out_of_date[@]} > 0 )); then
 | 
			
		||||
		printf "%sUpgraded%s\n" "${section_separator}${BOLD}${UNDERLINE}" "${ALL_OFF}"
 | 
			
		||||
		section_separator=$'\n'
 | 
			
		||||
		for result in "${out_of_date[@]}"; do
 | 
			
		||||
			msg_warn " ${result}"
 | 
			
		||||
		done
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# Show summary when processing multiple packages
 | 
			
		||||
	if (( ${#pkgbases[@]} > 1 )); then
 | 
			
		||||
		printf '%s' "${section_separator}"
 | 
			
		||||
		pkgctl_version_upgrade_summary \
 | 
			
		||||
			"${#up_to_date[@]}" \
 | 
			
		||||
			"${#out_of_date[@]}" \
 | 
			
		||||
			"${#failure[@]}"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# return status based on results
 | 
			
		||||
	return "${exit_code}"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_version_upgrade_summary() {
 | 
			
		||||
	local up_to_date_count=$1
 | 
			
		||||
	local out_of_date_count=$2
 | 
			
		||||
	local failure_count=$3
 | 
			
		||||
 | 
			
		||||
	# print nothing if all stats are zero
 | 
			
		||||
	if (( up_to_date_count == 0 )) && \
 | 
			
		||||
			(( out_of_date_count == 0 )) && \
 | 
			
		||||
			(( failure_count == 0 )); then
 | 
			
		||||
		return 0
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	# print summary for all none zero stats
 | 
			
		||||
	printf "%sSummary%s\n" "${BOLD}${UNDERLINE}" "${ALL_OFF}"
 | 
			
		||||
	if (( up_to_date_count > 0 )); then
 | 
			
		||||
		msg_success " Up-to-date: ${BOLD}${up_to_date_count}${ALL_OFF}" 2>&1
 | 
			
		||||
	fi
 | 
			
		||||
	if (( failure_count > 0 )); then
 | 
			
		||||
		msg_error " Failure: ${BOLD}${failure_count}${ALL_OFF}" 2>&1
 | 
			
		||||
	fi
 | 
			
		||||
	if (( out_of_date_count > 0 )); then
 | 
			
		||||
		msg_warn " Upgraded: ${BOLD}${out_of_date_count}${ALL_OFF}" 2>&1
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pkgctl_version_upgrade_spinner() {
 | 
			
		||||
	local status_dir=$1
 | 
			
		||||
	local up_to_date_count=$2
 | 
			
		||||
	local out_of_date_count=$3
 | 
			
		||||
	local failure_count=$4
 | 
			
		||||
	local current=$5
 | 
			
		||||
	local total=$6
 | 
			
		||||
	local pkgbase=$7
 | 
			
		||||
	local message=$8
 | 
			
		||||
 | 
			
		||||
	local percentage=$(( 100 * current / total ))
 | 
			
		||||
	local tmp_file="${status_dir}/tmp"
 | 
			
		||||
	local status_file="${status_dir}/status"
 | 
			
		||||
 | 
			
		||||
	# print the current summary
 | 
			
		||||
	pkgctl_version_upgrade_summary \
 | 
			
		||||
		"${up_to_date_count}" \
 | 
			
		||||
		"${out_of_date_count}" \
 | 
			
		||||
		"${failure_count}" > "${tmp_file}"
 | 
			
		||||
 | 
			
		||||
	# print the progress status
 | 
			
		||||
	printf "📡 %s: %s\n" \
 | 
			
		||||
		"${pkgbase}" "${BOLD}${message}${ALL_OFF}" >> "${tmp_file}"
 | 
			
		||||
	printf "⌛ Upgrading: %s/%s [%s] %%spinner%%" \
 | 
			
		||||
		"${BOLD}${current}" "${total}" "${percentage}%${ALL_OFF}" \
 | 
			
		||||
		>> "${tmp_file}"
 | 
			
		||||
 | 
			
		||||
	# swap the status file
 | 
			
		||||
	mv "${tmp_file}" "${status_file}"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,47 +0,0 @@
 | 
			
		||||
#!/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
 | 
			
		||||
}
 | 
			
		||||
@@ -8,9 +8,12 @@ _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@}
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh
 | 
			
		||||
# shellcheck source=src/lib/archroot.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/archroot.sh
 | 
			
		||||
# shellcheck source=src/lib/valid-inspect.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/valid-inspect.sh
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/config.sh
 | 
			
		||||
source /usr/share/makepkg/util/util.sh
 | 
			
		||||
 | 
			
		||||
shopt -s nullglob
 | 
			
		||||
 | 
			
		||||
@@ -31,8 +34,13 @@ run_checkpkg=0
 | 
			
		||||
temp_chroot=0
 | 
			
		||||
tmp_opts="nosuid,nodev,size=50%,nr_inodes=2m"
 | 
			
		||||
 | 
			
		||||
inspect=never
 | 
			
		||||
 | 
			
		||||
bindmounts_ro=()
 | 
			
		||||
bindmounts_rw=()
 | 
			
		||||
bindmounts_tmpfs=()
 | 
			
		||||
 | 
			
		||||
offline_options=()
 | 
			
		||||
 | 
			
		||||
copy=$USER
 | 
			
		||||
[[ -n ${SUDO_USER:-} ]] && copy=$SUDO_USER
 | 
			
		||||
@@ -64,6 +72,7 @@ usage() {
 | 
			
		||||
	echo '-c                Clean the chroot before building'
 | 
			
		||||
	echo '-d <dir>          Bind directory into build chroot as read-write'
 | 
			
		||||
	echo '-D <dir>          Bind directory into build chroot as read-only'
 | 
			
		||||
	echo '-t <dir[:opts]>   Mount a tmpfs at directory'
 | 
			
		||||
	echo '-u                Update the working copy of the chroot before building'
 | 
			
		||||
	echo '                  This is useful for rebuilds without dirtying the pristine'
 | 
			
		||||
	echo '                  chroot'
 | 
			
		||||
@@ -73,9 +82,11 @@ usage() {
 | 
			
		||||
	echo '                  Useful for maintaining multiple copies'
 | 
			
		||||
	echo "                  Default: $copy"
 | 
			
		||||
	echo '-n                Run namcap on the package'
 | 
			
		||||
	echo '-o                Run given step offline'
 | 
			
		||||
	echo '-C                Run checkpkg on the package'
 | 
			
		||||
	echo '-T                Build in a temporary directory'
 | 
			
		||||
	echo '-U                Run makepkg as a specified user'
 | 
			
		||||
	echo '-x <when>         Inspect chroot after build (never, always, failure)'
 | 
			
		||||
	exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -97,7 +108,7 @@ sync_chroot() {
 | 
			
		||||
		"Locking clean chroot [%s]" "$chrootdir/root"
 | 
			
		||||
 | 
			
		||||
	stat_busy "Synchronizing chroot copy [%s] -> [%s]" "$chrootdir/root" "$copy"
 | 
			
		||||
	if is_btrfs "$chrootdir" && ! mountpoint -q "$copydir"; then
 | 
			
		||||
	if is_btrfs "$chrootdir" && is_subvolume "$chrootdir/root" && ! mountpoint -q "$copydir"; then
 | 
			
		||||
		subvolume_delete_recursive "$copydir" ||
 | 
			
		||||
			die "Unable to delete subvolume %s" "$copydir"
 | 
			
		||||
		btrfs subvolume snapshot "$chrootdir/root" "$copydir" >/dev/null ||
 | 
			
		||||
@@ -142,8 +153,8 @@ install_packages() {
 | 
			
		||||
	pkgnames=("${install_pkgs[@]##*/}")
 | 
			
		||||
 | 
			
		||||
	cp -- "${install_pkgs[@]}" "$copydir/root/"
 | 
			
		||||
	arch-nspawn "$copydir" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
 | 
			
		||||
		bash -c 'yes y | pacman -U -- "$@"' -bash "${pkgnames[@]/#//root/}"
 | 
			
		||||
	arch-nspawn "$copydir" "${bindmounts_ro[@]}" "${bindmounts_rw[@]}" "${bindmounts_tmpfs[@]}" \
 | 
			
		||||
		pacman -U --noconfirm --ask=4 -- "${pkgnames[@]/#//root/}"
 | 
			
		||||
	ret=$?
 | 
			
		||||
	rm -- "${pkgnames[@]/#/$copydir/root/}"
 | 
			
		||||
 | 
			
		||||
@@ -182,6 +193,11 @@ builduser ALL = NOPASSWD: /usr/bin/pacman
 | 
			
		||||
EOF
 | 
			
		||||
	chmod 440 "$copydir/etc/sudoers.d/builduser-pacman"
 | 
			
		||||
 | 
			
		||||
	cat > "$copydir/etc/gitconfig" <<EOF
 | 
			
		||||
[safe]
 | 
			
		||||
	directory = *
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
	# This is a little gross, but this way the script is recreated every time in the
 | 
			
		||||
	# working copy
 | 
			
		||||
	{
 | 
			
		||||
@@ -190,6 +206,7 @@ EOF
 | 
			
		||||
		declare -p SOURCE_DATE_EPOCH 2>/dev/null || true
 | 
			
		||||
		declare -p BUILDTOOL 2>/dev/null
 | 
			
		||||
		declare -p BUILDTOOLVER 2>/dev/null
 | 
			
		||||
		declare -p offline_options
 | 
			
		||||
		printf '_chrootbuild "$@" || exit\n'
 | 
			
		||||
 | 
			
		||||
		if (( run_namcap )); then
 | 
			
		||||
@@ -209,14 +226,52 @@ _chrootbuild() {
 | 
			
		||||
	# shellcheck source=/dev/null
 | 
			
		||||
	. /etc/profile
 | 
			
		||||
 | 
			
		||||
	# for in_array
 | 
			
		||||
	. /usr/share/makepkg/util.sh
 | 
			
		||||
 | 
			
		||||
	# Beware, there are some stupid arbitrary rules on how you can
 | 
			
		||||
	# use "$" in arguments to commands with "sudo -i".  ${foo} or
 | 
			
		||||
	# ${1} is OK, but $foo or $1 isn't.
 | 
			
		||||
	# https://bugzilla.sudo.ws/show_bug.cgi?id=765
 | 
			
		||||
 | 
			
		||||
	# Run prepare
 | 
			
		||||
	sudo --preserve-env=SOURCE_DATE_EPOCH \
 | 
			
		||||
		--preserve-env=BUILDTOOL \
 | 
			
		||||
		--preserve-env=BUILDTOOLVER \
 | 
			
		||||
		-iu builduser bash -c 'cd /startdir; makepkg "$@"' -bash "$@"
 | 
			
		||||
		-iu builduser bash -c 'cd /startdir; makepkg --nobuild "$@"' -bash "$@"
 | 
			
		||||
 | 
			
		||||
	if in_array "build" "${offline_options[@]}"; then
 | 
			
		||||
		msg "building offline"
 | 
			
		||||
		# Build offline
 | 
			
		||||
		unshare -n -- sudo --preserve-env=SOURCE_DATE_EPOCH \
 | 
			
		||||
			--preserve-env=BUILDTOOL \
 | 
			
		||||
			--preserve-env=BUILDTOOLVER \
 | 
			
		||||
			-iu builduser \
 | 
			
		||||
			bash -c 'cd /startdir; makepkg --noprepare --noextract --nocheck "$@"' -bash "$@"
 | 
			
		||||
	else
 | 
			
		||||
		sudo --preserve-env=SOURCE_DATE_EPOCH \
 | 
			
		||||
			--preserve-env=BUILDTOOL \
 | 
			
		||||
			--preserve-env=BUILDTOOLVER \
 | 
			
		||||
			-iu builduser \
 | 
			
		||||
			bash -c 'cd /startdir; makepkg --noprepare --noextract --nocheck "$@"' -bash "$@"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	if in_array "check" "${offline_options[@]}"; then
 | 
			
		||||
		msg "check offline"
 | 
			
		||||
		# Run tests online
 | 
			
		||||
		unshare -n -- sudo --preserve-env=SOURCE_DATE_EPOCH \
 | 
			
		||||
			--preserve-env=BUILDTOOL \
 | 
			
		||||
			--preserve-env=BUILDTOOLVER \
 | 
			
		||||
			-iu builduser \
 | 
			
		||||
			bash -c 'cd /startdir; makepkg --noprepare --noextract --nobuild "$@"' -bash "$@"
 | 
			
		||||
	else
 | 
			
		||||
		sudo --preserve-env=SOURCE_DATE_EPOCH \
 | 
			
		||||
			--preserve-env=BUILDTOOL \
 | 
			
		||||
			--preserve-env=BUILDTOOLVER \
 | 
			
		||||
			-iu builduser \
 | 
			
		||||
			bash -c 'cd /startdir; makepkg --noprepare --noextract --nobuild "$@"' -bash "$@"
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	ret=$?
 | 
			
		||||
	case $ret in
 | 
			
		||||
		0|14)
 | 
			
		||||
@@ -280,19 +335,22 @@ move_products() {
 | 
			
		||||
}
 | 
			
		||||
# }}}
 | 
			
		||||
 | 
			
		||||
while getopts 'hcur:I:l:nCTD:d:U:' arg; do
 | 
			
		||||
while getopts 'hcur:I:l:nCTD:o:d:U:x:t:' arg; do
 | 
			
		||||
	case "$arg" in
 | 
			
		||||
		c) clean_first=1 ;;
 | 
			
		||||
		D) bindmounts_ro+=("--bind-ro=$OPTARG") ;;
 | 
			
		||||
		d) bindmounts_rw+=("--bind=$OPTARG") ;;
 | 
			
		||||
		t) bindmounts_tmpfs+=("--tmpfs=$OPTARG") ;;
 | 
			
		||||
		u) update_first=1 ;;
 | 
			
		||||
		r) passeddir="$OPTARG" ;;
 | 
			
		||||
		I) install_pkgs+=("$OPTARG") ;;
 | 
			
		||||
		l) copy="$OPTARG" ;;
 | 
			
		||||
		n) run_namcap=1; makepkg_args+=(--install) ;;
 | 
			
		||||
		o) offline_options+=("$OPTARG") ;;
 | 
			
		||||
		C) run_checkpkg=1 ;;
 | 
			
		||||
		T) temp_chroot=1; copy+="-$$" ;;
 | 
			
		||||
		U) makepkg_user="$OPTARG" ;;
 | 
			
		||||
		x) inspect="$OPTARG" ;;
 | 
			
		||||
		h|*) usage ;;
 | 
			
		||||
	esac
 | 
			
		||||
done
 | 
			
		||||
@@ -314,6 +372,10 @@ else
 | 
			
		||||
	copydir="$chrootdir/$copy"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if ! in_array "${inspect}" "${DEVTOOLS_VALID_INSPECT_MODES[@]}"; then
 | 
			
		||||
	die "Invalid inspect mode: %s" "${inspect}"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Pass all arguments after -- right to makepkg
 | 
			
		||||
makepkg_args+=("${@:$OPTIND}")
 | 
			
		||||
 | 
			
		||||
@@ -349,7 +411,7 @@ if [[ ! -d $copydir ]] || (( clean_first )); then
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
(( update_first )) && arch-nspawn "$copydir" \
 | 
			
		||||
		"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
 | 
			
		||||
		"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" "${bindmounts_tmpfs[@]}" \
 | 
			
		||||
		pacman -Syuu --noconfirm
 | 
			
		||||
 | 
			
		||||
if [[ -n ${install_pkgs[*]:-} ]]; then
 | 
			
		||||
@@ -368,11 +430,17 @@ download_sources
 | 
			
		||||
 | 
			
		||||
prepare_chroot
 | 
			
		||||
 | 
			
		||||
nspawn_build_args=(
 | 
			
		||||
	--bind="${PWD//:/\\:}:/startdir"
 | 
			
		||||
	--bind="${SRCDEST//:/\\:}:/srcdest"
 | 
			
		||||
	--tmpfs="/tmp:${tmp_opts}"
 | 
			
		||||
	"${bindmounts_ro[@]}"
 | 
			
		||||
	"${bindmounts_rw[@]}"
 | 
			
		||||
	"${bindmounts_tmpfs[@]}"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if arch-nspawn "$copydir" \
 | 
			
		||||
	--bind="${PWD//:/\\:}:/startdir" \
 | 
			
		||||
	--bind="${SRCDEST//:/\\:}:/srcdest" \
 | 
			
		||||
	--tmpfs="/tmp:${tmp_opts}" \
 | 
			
		||||
	"${bindmounts_ro[@]}" "${bindmounts_rw[@]}" \
 | 
			
		||||
	"${nspawn_build_args[@]}" \
 | 
			
		||||
	/chrootbuild "${makepkg_args[@]}"
 | 
			
		||||
then
 | 
			
		||||
	mapfile -t pkgnames < <(sudo -u "$makepkg_user" bash -c 'source PKGBUILD; printf "%s\n" "${pkgname[@]}"')
 | 
			
		||||
@@ -382,6 +450,18 @@ else
 | 
			
		||||
	move_logfiles
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $inspect == always ]] || ( [[ $inspect == failure ]] && (( ret != 0 )) ); then
 | 
			
		||||
	if (( ret == 0 )); then
 | 
			
		||||
		msg "Build succeeded, inspecting %s" "$copydir"
 | 
			
		||||
	else
 | 
			
		||||
		error "Build failed, inspecting %s" "$copydir"
 | 
			
		||||
	fi
 | 
			
		||||
	arch-nspawn "$copydir" \
 | 
			
		||||
		"${nspawn_build_args[@]}" \
 | 
			
		||||
		--user=builduser \
 | 
			
		||||
		--chdir=/build
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
(( temp_chroot )) && delete_chroot "$copydir" "$copy"
 | 
			
		||||
 | 
			
		||||
if (( ret != 0 )); then
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ declare -a buildenv buildopts installed installpkgs
 | 
			
		||||
archiveurl='https://archive.archlinux.org/packages'
 | 
			
		||||
buildroot=/var/lib/archbuild/reproducible
 | 
			
		||||
diffoscope=0
 | 
			
		||||
makepkg_options=()
 | 
			
		||||
 | 
			
		||||
chroot=$USER
 | 
			
		||||
[[ -n ${SUDO_USER:-} ]] && chroot=$SUDO_USER
 | 
			
		||||
@@ -116,6 +117,7 @@ For more details see https://reproducible-builds.org/
 | 
			
		||||
 | 
			
		||||
OPTIONS
 | 
			
		||||
    -d            Run diffoscope if the package is unreproducible
 | 
			
		||||
    -n            Do not run the check() function in the PKGBUILD
 | 
			
		||||
    -c <dir>      Set pacman cache
 | 
			
		||||
    -M <file>     Location of a makepkg config file
 | 
			
		||||
    -l <chroot>   The directory name to use as the chroot namespace
 | 
			
		||||
@@ -128,9 +130,10 @@ __EOF__
 | 
			
		||||
# save all args for check_root
 | 
			
		||||
orig_args=("$@")
 | 
			
		||||
 | 
			
		||||
while getopts 'dM:c:l:h' arg; do
 | 
			
		||||
while getopts 'dnM:c:l:h' arg; do
 | 
			
		||||
    case "$arg" in
 | 
			
		||||
        d) diffoscope=1 ;;
 | 
			
		||||
        n) makepkg_options+=(--nocheck) ;;
 | 
			
		||||
        M) archroot_args+=(-M "$OPTARG") ;;
 | 
			
		||||
        c) cache_dirs+=("$OPTARG") ;;
 | 
			
		||||
        l) chroot="$OPTARG" ;;
 | 
			
		||||
@@ -254,7 +257,7 @@ install -d -o "${SUDO_UID:-$UID}" -g "$(id -g "${SUDO_UID:-$UID}")" "${namespace
 | 
			
		||||
arch-nspawn "${namespace}/build" \
 | 
			
		||||
    --bind="${PWD}:/startdir" \
 | 
			
		||||
    --bind="${SRCDEST}:/srcdest" \
 | 
			
		||||
    /chrootbuild -C --noconfirm --log --holdver --skipinteg
 | 
			
		||||
    /chrootbuild -C --noconfirm --log --holdver --skipinteg "${makepkg_options[@]}"
 | 
			
		||||
ret=$?
 | 
			
		||||
 | 
			
		||||
if (( ${ret} == 0 )); then
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,8 @@ usage() {
 | 
			
		||||
	echo '    -C <file>           Location of a pacman config file'
 | 
			
		||||
	echo '    -M <file>           Location of a makepkg config file'
 | 
			
		||||
	echo '    -c <dir>            Set pacman cache'
 | 
			
		||||
	echo '    -f <file>     Copy file from the host to the chroot'
 | 
			
		||||
	echo '    -f <src>[:<dst>]    Copy src file from the host to the chroot.'
 | 
			
		||||
	echo '                        If dst file is not provided, it defaults to src'
 | 
			
		||||
	echo '    -s                  Do not run setarch'
 | 
			
		||||
	echo '    -h                  This message'
 | 
			
		||||
	exit 1
 | 
			
		||||
@@ -84,8 +85,10 @@ if is_btrfs "$working_dir"; then
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
for file in "${files[@]}"; do
 | 
			
		||||
	mkdir -p "$(dirname "$working_dir$file")"
 | 
			
		||||
	cp "$file" "$working_dir$file"
 | 
			
		||||
	src="${file%%:*}"
 | 
			
		||||
	dst="${file#*:}"
 | 
			
		||||
	mkdir -p "$(dirname "$working_dir$dst")"
 | 
			
		||||
	cp "$src" "$working_dir$dst"
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
unshare --mount pacstrap -${umode}Mc ${pac_conf:+-C "$pac_conf"} "$working_dir" \
 | 
			
		||||
 
 | 
			
		||||
@@ -6,15 +6,24 @@
 | 
			
		||||
#
 | 
			
		||||
# 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/util/makepkg.sh
 | 
			
		||||
source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/makepkg.sh
 | 
			
		||||
 | 
			
		||||
source /usr/share/makepkg/util/config.sh
 | 
			
		||||
 | 
			
		||||
# Deprecation warning
 | 
			
		||||
if [[ -z $_DEVTOOLS_COMMAND ]]; then
 | 
			
		||||
	warning "${0##*/} is deprecated and will be removed. Use 'pkgctl build --offload' instead"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# global defaults suitable for use by Arch staff
 | 
			
		||||
repo=extra
 | 
			
		||||
arch=x86_64
 | 
			
		||||
server=build.archlinux.org
 | 
			
		||||
 | 
			
		||||
die() { printf "error: $1\n" "${@:2}"; exit 1; }
 | 
			
		||||
rsyncopts=("${RSYNC_OPTS[@]}")
 | 
			
		||||
 | 
			
		||||
usage() {
 | 
			
		||||
    cat <<- _EOF_
 | 
			
		||||
@@ -79,7 +88,7 @@ load_makepkg_config
 | 
			
		||||
# transferred, including local sources, install scripts, and changelogs.
 | 
			
		||||
export TEMPDIR=$(mktemp -d --tmpdir offload-build.XXXXXXXXXX)
 | 
			
		||||
export SRCPKGDEST=${TEMPDIR}
 | 
			
		||||
makepkg --source || die "unable to make source package"
 | 
			
		||||
makepkg_source_package || die "unable to make source package"
 | 
			
		||||
 | 
			
		||||
# Temporary cosmetic workaround makepkg if SRCDEST is set somewhere else
 | 
			
		||||
# but an empty src dir is created in PWD. Remove once fixed in makepkg.
 | 
			
		||||
@@ -91,12 +100,14 @@ mapfile -t files < <(
 | 
			
		||||
    # shellcheck disable=SC2145
 | 
			
		||||
    cat "$SRCPKGDEST"/*"$SRCEXT" |
 | 
			
		||||
        ssh $server '
 | 
			
		||||
            export TERM="'"${TERM}"'"
 | 
			
		||||
            temp="${XDG_CACHE_HOME:-$HOME/.cache}/offload-build" &&
 | 
			
		||||
            mkdir -p "$temp" &&
 | 
			
		||||
            temp=$(mktemp -d -p "$temp") &&
 | 
			
		||||
            cd "$temp" &&
 | 
			
		||||
            {
 | 
			
		||||
                bsdtar --strip-components 1 -xvf - &&
 | 
			
		||||
                export LOGDEST="" &&
 | 
			
		||||
                script -qefc "'"${archbuild_cmd[@]@Q}"'" /dev/null &&
 | 
			
		||||
                printf "%s\n" "" "-> build complete" &&
 | 
			
		||||
                printf "\t%s\n" "$temp"/*
 | 
			
		||||
@@ -106,16 +117,29 @@ mapfile -t files < <(
 | 
			
		||||
            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 &&
 | 
			
		||||
            while read -r file; do
 | 
			
		||||
                [[ -f "${file}" ]] && printf "%s\n" "${file}" ||:
 | 
			
		||||
            done < <(makepkg --config <(cat "${makepkg_user_config}" "${makepkg_config}" 2>/dev/null) --packagelist) &&
 | 
			
		||||
            printf "%s\n" "${temp}/PKGBUILD"
 | 
			
		||||
 | 
			
		||||
            find "${temp}" -name "*.log"
 | 
			
		||||
')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if (( ${#files[@]} )); then
 | 
			
		||||
    printf '%s\n' '' '-> copying files...'
 | 
			
		||||
    scp "${files[@]/#/$server:}" "${TEMPDIR}/"
 | 
			
		||||
    mv "${TEMPDIR}"/*.pkg.tar* "${PKGDEST:-${PWD}}/"
 | 
			
		||||
    msg 'Downloading files...'
 | 
			
		||||
    rsync "${rsyncopts[@]}" "${files[@]/#/$server:}" "${TEMPDIR}/" || die
 | 
			
		||||
 | 
			
		||||
    if is_globfile "${TEMPDIR}"/*.log; then
 | 
			
		||||
        mv "${TEMPDIR}"/*.log "${LOGDEST:-${PWD}}/"
 | 
			
		||||
    fi
 | 
			
		||||
    # missing PKGBUILD download means the build failed
 | 
			
		||||
    if [[ ! -f "${TEMPDIR}/PKGBUILD" ]]; then
 | 
			
		||||
        error "Build failed, check logs in ${LOGDEST:-${PWD}}"
 | 
			
		||||
        exit 1
 | 
			
		||||
    fi
 | 
			
		||||
    mv "${TEMPDIR}/PKGBUILD" "${PWD}/"
 | 
			
		||||
    mv "${TEMPDIR}"/*.pkg.tar* "${PKGDEST:-${PWD}}/"
 | 
			
		||||
else
 | 
			
		||||
    exit 1
 | 
			
		||||
fi
 | 
			
		||||
 
 | 
			
		||||
@@ -19,13 +19,15 @@ usage() {
 | 
			
		||||
		Unified command-line frontend for devtools.
 | 
			
		||||
 | 
			
		||||
		COMMANDS
 | 
			
		||||
		    aur     Interact with the Arch User Repository
 | 
			
		||||
		    auth    Authenticate with services like GitLab
 | 
			
		||||
		    build   Build packages inside a clean chroot
 | 
			
		||||
		    db      Pacman database modification for packge update, move etc
 | 
			
		||||
		    db      Pacman database modification for package 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
 | 
			
		||||
		    search  Search for an expression across the GitLab packaging group
 | 
			
		||||
		    version Check and manage package versions against upstream
 | 
			
		||||
 | 
			
		||||
		OPTIONS
 | 
			
		||||
		    -h, --help     Show this help text
 | 
			
		||||
@@ -37,8 +39,16 @@ if (( $# < 1 )); then
 | 
			
		||||
	exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
pkgctl_version_print() {
 | 
			
		||||
	cat <<- _EOF_
 | 
			
		||||
		pkgctl @buildtoolver@
 | 
			
		||||
_EOF_
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export _DEVTOOLS_COMMAND='pkgctl'
 | 
			
		||||
 | 
			
		||||
setup_workdir
 | 
			
		||||
 | 
			
		||||
load_devtools_config
 | 
			
		||||
 | 
			
		||||
# command checking
 | 
			
		||||
@@ -48,6 +58,14 @@ while (( $# )); do
 | 
			
		||||
			usage
 | 
			
		||||
			exit 0
 | 
			
		||||
			;;
 | 
			
		||||
		aur)
 | 
			
		||||
			_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
			shift
 | 
			
		||||
			# shellcheck source=src/lib/aur.sh
 | 
			
		||||
			source "${_DEVTOOLS_LIBRARY_DIR}"/lib/aur.sh
 | 
			
		||||
			pkgctl_aur "$@"
 | 
			
		||||
			exit 0
 | 
			
		||||
			;;
 | 
			
		||||
		build)
 | 
			
		||||
			_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
			shift
 | 
			
		||||
@@ -94,14 +112,28 @@ while (( $# )); do
 | 
			
		||||
			pkgctl_release "$@"
 | 
			
		||||
			exit 0
 | 
			
		||||
			;;
 | 
			
		||||
		version|--version|-V)
 | 
			
		||||
		search)
 | 
			
		||||
			_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
			shift
 | 
			
		||||
			# shellcheck source=src/lib/version/version.sh
 | 
			
		||||
			source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version/version.sh
 | 
			
		||||
			# shellcheck source=src/lib/release.sh
 | 
			
		||||
			source "${_DEVTOOLS_LIBRARY_DIR}"/lib/search.sh
 | 
			
		||||
			pkgctl_search "$@"
 | 
			
		||||
			exit 0
 | 
			
		||||
			;;
 | 
			
		||||
		version)
 | 
			
		||||
			_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
			shift
 | 
			
		||||
			# shellcheck source=src/lib/version.sh
 | 
			
		||||
			source "${_DEVTOOLS_LIBRARY_DIR}"/lib/version.sh
 | 
			
		||||
			pkgctl_version "$@"
 | 
			
		||||
			exit 0
 | 
			
		||||
			;;
 | 
			
		||||
		--version|-V)
 | 
			
		||||
			_DEVTOOLS_COMMAND+=" $1"
 | 
			
		||||
			shift
 | 
			
		||||
			pkgctl_version_print
 | 
			
		||||
			exit 0
 | 
			
		||||
			;;
 | 
			
		||||
		*)
 | 
			
		||||
			die "invalid command: %s" "$1"
 | 
			
		||||
			;;
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ recache() {
 | 
			
		||||
 | 
			
		||||
    (( VERBOSE )) && verbosity=--progress-bar
 | 
			
		||||
 | 
			
		||||
    for repo in "${_repos[@]}"; do
 | 
			
		||||
    for repo in "${DEVTOOLS_VALID_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
 | 
			
		||||
@@ -72,7 +72,7 @@ is_outdated_cache() {
 | 
			
		||||
    # links databases are generated at about the same time every day; we should
 | 
			
		||||
    # attempt to check for new database files if any of them are over a day old
 | 
			
		||||
 | 
			
		||||
    for repo in "${_repos[@]}"; do
 | 
			
		||||
    for repo in "${DEVTOOLS_VALID_REPOS[@]}"; do
 | 
			
		||||
        for arch in "${arches[@]}"; do
 | 
			
		||||
            local dbpath=${SOCACHE_DIR}/${arch}/${repo}.links.tar.gz
 | 
			
		||||
            if [[ ! -f ${dbpath} ]] || [[ $(find "${dbpath}" -mtime +0) ]]; then
 | 
			
		||||
@@ -85,10 +85,10 @@ is_outdated_cache() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
search() {
 | 
			
		||||
    local repo=$1 arch lib=$2 srepos=("${_repos[@]}")
 | 
			
		||||
    local repo=$1 arch lib=$2 srepos=("${DEVTOOLS_VALID_REPOS[@]}")
 | 
			
		||||
 | 
			
		||||
    if [[ $repo != all ]]; then
 | 
			
		||||
        if ! in_array "${repo}" "${_repos[@]}"; then
 | 
			
		||||
        if ! in_array "${repo}" "${DEVTOOLS_VALID_REPOS[@]}"; then
 | 
			
		||||
            echo "${BASH_SOURCE[0]##*/}: unrecognized repo '$repo'"
 | 
			
		||||
            echo "Try '${BASH_SOURCE[0]##*/} --help' for more information."
 | 
			
		||||
            exit 1
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user