mirror of
				https://gitlab.archlinux.org/archlinux/devtools.git
				synced 2025-10-27 14:02:22 +01:00 
			
		
		
		
	Compare commits
	
		
			14 Commits
		
	
	
		
			fix/clean-
			...
			feat/ports
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | e70a0e69d2 | ||
|   | 3f0ebbc6d2 | ||
|   | fc56ebedf3 | ||
|   | 01757e6904 | ||
|   | c5fe8ff3e6 | ||
|   | ad7dd50bf3 | ||
|   | 5a381835e8 | ||
|   | b8c475b3f4 | ||
|   | 74cd46f092 | ||
|   | 40f31f98a3 | ||
|   | c6f5d72708 | ||
|   | b4a5e5dbd9 | ||
|   | 4926d9d8c5 | ||
|   | 7165e0d73e | 
							
								
								
									
										14
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| SHELL=/bin/bash -o pipefail | SHELL=/bin/bash -o pipefail | ||||||
|  |  | ||||||
| V=1.3.1 | V=1.4.0 | ||||||
| BUILDTOOLVER ?= $(V) | BUILDTOOLVER ?= $(V) | ||||||
|  |  | ||||||
| PREFIX = /usr/local | PREFIX = /usr/local | ||||||
| @@ -19,6 +19,7 @@ PACMAN_CONFIGS=$(wildcard config/pacman/*) | |||||||
| GIT_CONFIGS = $(wildcard config/git/*) | GIT_CONFIGS = $(wildcard config/git/*) | ||||||
| SETARCH_ALIASES = $(wildcard config/setarch-aliases.d/*) | SETARCH_ALIASES = $(wildcard config/setarch-aliases.d/*) | ||||||
| MANS = $(addprefix $(BUILDDIR)/,$(patsubst %.asciidoc,%,$(wildcard doc/man/*.asciidoc))) | MANS = $(addprefix $(BUILDDIR)/,$(patsubst %.asciidoc,%,$(wildcard doc/man/*.asciidoc))) | ||||||
|  | DATA_FILES = $(wildcard data/*) | ||||||
|  |  | ||||||
| COMMITPKG_LINKS = \ | COMMITPKG_LINKS = \ | ||||||
| 	core-testingpkg \ | 	core-testingpkg \ | ||||||
| @@ -59,7 +60,7 @@ BATS_ARGS ?= --jobs $(JOBS) $(BATS_EXTRA_ARGS) --verbose-run | |||||||
| COVERAGE_DIR ?= $(BUILDDIR)/coverage | COVERAGE_DIR ?= $(BUILDDIR)/coverage | ||||||
|  |  | ||||||
|  |  | ||||||
| all: binprogs library conf completion man | all: binprogs library conf completion man data | ||||||
| binprogs: $(BINPROGS) | binprogs: $(BINPROGS) | ||||||
| library: $(LIBRARY) | library: $(LIBRARY) | ||||||
| completion: $(COMPLETIONS) | completion: $(COMPLETIONS) | ||||||
| @@ -112,6 +113,10 @@ conf: | |||||||
| 	@install -d $(BUILDDIR)/git.conf.d | 	@install -d $(BUILDDIR)/git.conf.d | ||||||
| 	@cp -a $(GIT_CONFIGS) $(BUILDDIR)/git.conf.d | 	@cp -a $(GIT_CONFIGS) $(BUILDDIR)/git.conf.d | ||||||
|  |  | ||||||
|  | data: | ||||||
|  | 	@install -d $(BUILDDIR)/data | ||||||
|  | 	@cp -ra $(DATA_FILES) $(BUILDDIR)/data | ||||||
|  |  | ||||||
| clean: | clean: | ||||||
| 	rm -rf $(BUILDDIR) | 	rm -rf $(BUILDDIR) | ||||||
|  |  | ||||||
| @@ -122,9 +127,11 @@ install: all | |||||||
| 	install -dm0755 $(DESTDIR)$(DATADIR)/pacman.conf.d | 	install -dm0755 $(DESTDIR)$(DATADIR)/pacman.conf.d | ||||||
| 	install -m0755 ${BINPROGS} $(DESTDIR)$(PREFIX)/bin | 	install -m0755 ${BINPROGS} $(DESTDIR)$(PREFIX)/bin | ||||||
| 	install -dm0755 $(DESTDIR)$(DATADIR)/lib | 	install -dm0755 $(DESTDIR)$(DATADIR)/lib | ||||||
|  | 	install -dm0755 $(DESTDIR)$(DATADIR)/data | ||||||
| 	cp -ra $(BUILDDIR)/lib/* $(DESTDIR)$(DATADIR)/lib | 	cp -ra $(BUILDDIR)/lib/* $(DESTDIR)$(DATADIR)/lib | ||||||
| 	cp -a $(BUILDDIR)/git.conf.d -t $(DESTDIR)$(DATADIR) | 	cp -a $(BUILDDIR)/git.conf.d -t $(DESTDIR)$(DATADIR) | ||||||
| 	cp -ra $(BUILDDIR)/makepkg.conf.d -t $(DESTDIR)$(DATADIR) | 	cp -ra $(BUILDDIR)/makepkg.conf.d -t $(DESTDIR)$(DATADIR) | ||||||
|  | 	cp -ra $(BUILDDIR)/data -t $(DESTDIR)$(DATADIR) | ||||||
| 	for conf in $(notdir $(PACMAN_CONFIGS)); do install -Dm0644 $(BUILDDIR)/pacman.conf.d/$$conf $(DESTDIR)$(DATADIR)/pacman.conf.d/$${conf##*/}; done | 	for conf in $(notdir $(PACMAN_CONFIGS)); do install -Dm0644 $(BUILDDIR)/pacman.conf.d/$$conf $(DESTDIR)$(DATADIR)/pacman.conf.d/$${conf##*/}; done | ||||||
| 	for a in ${SETARCH_ALIASES}; do install -m0644 $$a -t $(DESTDIR)$(DATADIR)/setarch-aliases.d; done | 	for a in ${SETARCH_ALIASES}; do install -m0644 $$a -t $(DESTDIR)$(DATADIR)/setarch-aliases.d; done | ||||||
| 	for l in ${COMMITPKG_LINKS}; do ln -sf commitpkg $(DESTDIR)$(PREFIX)/bin/$$l; done | 	for l in ${COMMITPKG_LINKS}; do ln -sf commitpkg $(DESTDIR)$(PREFIX)/bin/$$l; done | ||||||
| @@ -143,6 +150,7 @@ uninstall: | |||||||
| 	rm -rf $(DESTDIR)$(DATADIR)/lib | 	rm -rf $(DESTDIR)$(DATADIR)/lib | ||||||
| 	rm -rf $(DESTDIR)$(DATADIR)/git.conf.d | 	rm -rf $(DESTDIR)$(DATADIR)/git.conf.d | ||||||
| 	rm -rf $(DESTDIR)$(DATADIR)/makepkg.conf.d | 	rm -rf $(DESTDIR)$(DATADIR)/makepkg.conf.d | ||||||
|  | 	rm -rf $(DESTDIR)$(DATADIR)/data | ||||||
| 	for conf in $(notdir $(PACMAN_CONFIGS)); do rm -f $(DESTDIR)$(DATADIR)/pacman.conf.d/$${conf##*/}; done | 	for conf in $(notdir $(PACMAN_CONFIGS)); do rm -f $(DESTDIR)$(DATADIR)/pacman.conf.d/$${conf##*/}; done | ||||||
| 	for f in $(notdir $(SETARCH_ALIASES)); do rm -f $(DESTDIR)$(DATADIR)/setarch-aliases.d/$$f; done | 	for f in $(notdir $(SETARCH_ALIASES)); do rm -f $(DESTDIR)$(DATADIR)/setarch-aliases.d/$$f; done | ||||||
| 	for l in ${COMMITPKG_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$l; done | 	for l in ${COMMITPKG_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$l; done | ||||||
| @@ -186,5 +194,5 @@ coverage: binprogs library conf completion man | |||||||
| check: $(BINPROGS_SRC) $(LIBRARY_SRC) contrib/completion/bash/devtools.in config/makepkg/x86_64.conf contrib/makepkg/PKGBUILD.proto | check: $(BINPROGS_SRC) $(LIBRARY_SRC) contrib/completion/bash/devtools.in config/makepkg/x86_64.conf contrib/makepkg/PKGBUILD.proto | ||||||
| 	shellcheck $^ | 	shellcheck $^ | ||||||
|  |  | ||||||
| .PHONY: all binprogs library completion conf man clean install uninstall tag dist upload test coverage check | .PHONY: all binprogs library completion conf man data clean install uninstall tag dist upload test coverage check | ||||||
| .DELETE_ON_ERROR: | .DELETE_ON_ERROR: | ||||||
|   | |||||||
| @@ -94,6 +94,7 @@ Component: pkgctl db remove | |||||||
|  |  | ||||||
| - bat (pretty printing) | - bat (pretty printing) | ||||||
| - nvchecker (version checking) | - nvchecker (version checking) | ||||||
|  | - reuse (license compliance) | ||||||
|  |  | ||||||
| ### Development Dependencies | ### Development Dependencies | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ | |||||||
| /src | /src | ||||||
| /*/ | /*/ | ||||||
| !/keys/ | !/keys/ | ||||||
|  | !/LICENSES/ | ||||||
|  |  | ||||||
| /*.log | /*.log | ||||||
| /*.tar.* | /*.tar.* | ||||||
|   | |||||||
| @@ -1,4 +1,6 @@ | |||||||
| #!/hint/bash | #!/hint/bash | ||||||
|  | # shellcheck disable=2034 | ||||||
|  |  | ||||||
| # | # | ||||||
| # /etc/makepkg.conf.d/fortran.conf | # /etc/makepkg.conf.d/fortran.conf | ||||||
| # | # | ||||||
| @@ -9,10 +11,12 @@ | |||||||
|  |  | ||||||
| # Flags used for the Fortran compiler, similar in spirit to CFLAGS. Read | # Flags used for the Fortran compiler, similar in spirit to CFLAGS. Read | ||||||
| # linkman:gfortran[1] for more details on the available flags. | # linkman:gfortran[1] for more details on the available flags. | ||||||
| #FFLAGS="-O2 -pipe" | FFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt \ | ||||||
| #FCFLAGS="$FFLAGS" |         -Wp,-D_FORTIFY_SOURCE=3 -fstack-clash-protection -fcf-protection \ | ||||||
|  |         -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer" | ||||||
|  | FCFLAGS="$FFLAGS" | ||||||
|  |  | ||||||
| # Additional compiler flags appended to `FFLAGS` and `FCFLAGS` for use in debugging. Usually | # Additional compiler flags appended to `FFLAGS` and `FCFLAGS` for use in debugging. Usually | ||||||
| # this would include: ``-g''. Read linkman:gfortran[1] for more details on the wide | # this would include: ``-g''. Read linkman:gfortran[1] for more details on the wide | ||||||
| # variety of compiler flags available. | # variety of compiler flags available. | ||||||
| #DEBUG_FFLAGS="-g" | DEBUG_FFLAGS="-g" | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ | |||||||
|  |  | ||||||
| # Flags used for the Rust compiler, similar in spirit to CFLAGS. Read | # Flags used for the Rust compiler, similar in spirit to CFLAGS. Read | ||||||
| # linkman:rustc[1] for more details on the available flags. | # linkman:rustc[1] for more details on the available flags. | ||||||
| RUSTFLAGS="-Cforce-frame-pointers=yes" | RUSTFLAGS="-C force-frame-pointers=yes" | ||||||
|  |  | ||||||
| # Additional compiler flags appended to `RUSTFLAGS` for use in debugging. | # Additional compiler flags appended to `RUSTFLAGS` for use in debugging. | ||||||
| # Usually this would include: ``-C debuginfo=2''. Read linkman:rustc[1] for | # Usually this would include: ``-C debuginfo=2''. Read linkman:rustc[1] for | ||||||
|   | |||||||
| @@ -150,6 +150,7 @@ _pkgctl_cmds=( | |||||||
| 	db | 	db | ||||||
| 	diff | 	diff | ||||||
| 	issue | 	issue | ||||||
|  | 	license | ||||||
| 	release | 	release | ||||||
| 	repo | 	repo | ||||||
| 	search | 	search | ||||||
| @@ -367,6 +368,25 @@ _pkgctl_repo_switch_opts() { | |||||||
| 	fi | 	fi | ||||||
| } | } | ||||||
|  |  | ||||||
|  | _pkgctl_license_cmds=( | ||||||
|  | 	check | ||||||
|  | 	setup | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | _pkgctl_license_check_args=( | ||||||
|  | 	-h --help | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | _pkgctl_license_check_opts() { _filedir -d; } | ||||||
|  |  | ||||||
|  | _pkgctl_license_setup_args=( | ||||||
|  | 	--no-check | ||||||
|  | 	-f --force | ||||||
|  | 	-h --help | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | _pkgctl_license_setup_opts() { _filedir -d; } | ||||||
|  |  | ||||||
| _pkgctl_version_cmds=( | _pkgctl_version_cmds=( | ||||||
| 	check | 	check | ||||||
| 	setup | 	setup | ||||||
|   | |||||||
| @@ -61,7 +61,7 @@ _pkgctl_build_args=( | |||||||
| 	'--update-checksums[Force computation and update of the checksums (disables auto-detection)]' | 	'--update-checksums[Force computation and update of the checksums (disables auto-detection)]' | ||||||
| 	'(-e --edit)'{-e,--edit}'[Edit the PKGBUILD before building]' | 	'(-e --edit)'{-e,--edit}'[Edit the PKGBUILD before building]' | ||||||
| 	'(-r --release)'{-r,--release}'[Automatically commit, tag and release after 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:" | 	'(-m --message)'{-m,--message}"[Use the given <msg> as the commit message]:message:" | ||||||
| 	'(-u --db-update)'{-u,--db-update}'[Automatically update the pacman database as last action]' | 	'(-u --db-update)'{-u,--db-update}'[Automatically update the pacman database as last action]' | ||||||
| 	'(-h --help)'{-h,--help}'[Display usage]' | 	'(-h --help)'{-h,--help}'[Display usage]' | ||||||
| 	'*:git_dir:_files -/' | 	'*:git_dir:_files -/' | ||||||
| @@ -201,7 +201,7 @@ _pkgctl_issue_view_args=( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| _pkgctl_release_args=( | _pkgctl_release_args=( | ||||||
| 	'(-m --message=)'{-m,--message=}"[Use the given <msg> as the commit message]:message:" | 	'(-m --message)'{-m,--message}"[Use the given <msg> as the commit message]:message:" | ||||||
| 	'(-r --repo)'{-r,--repo}"[Specify a target repository for new packages]:repo:($DEVTOOLS_VALID_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]' | 	'(-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]' | 	'(-t --testing)'{-t,--testing}'[Release to the testing counterpart of the auto-detected repo]' | ||||||
| @@ -399,6 +399,7 @@ _pkgctl_cmds=( | |||||||
| 	"db[Pacman database modification for package update, move etc]" | 	"db[Pacman database modification for package update, move etc]" | ||||||
| 	"diff[Compare package files using different modes]" | 	"diff[Compare package files using different modes]" | ||||||
| 	"issue[Work with GitLab packaging issues]" | 	"issue[Work with GitLab packaging issues]" | ||||||
|  | 	"license[Check and manage package license compliance]" | ||||||
| 	"release[Release step to commit, tag and upload build artifacts]" | 	"release[Release step to commit, tag and upload build artifacts]" | ||||||
| 	"repo[Manage Git packaging repositories and their configuration]" | 	"repo[Manage Git packaging repositories and their configuration]" | ||||||
| 	"search[Search for an expression across the GitLab packaging group]" | 	"search[Search for an expression across the GitLab packaging group]" | ||||||
| @@ -410,6 +411,24 @@ _pkgctl_args=( | |||||||
| 	'(-h --help)'{-h,--help}'[Display usage]' | 	'(-h --help)'{-h,--help}'[Display usage]' | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | _pkgctl_license_cmds=( | ||||||
|  | 	"pkgctl license command" | ||||||
|  | 	"check[Checks package licensing compliance using REUSE]" | ||||||
|  | 	"setup[Automatically detect and setup a basic REUSE config]" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | _pkgctl_license_check_args=( | ||||||
|  | 	'(-h --help)'{-h,--help}'[Display usage]' | ||||||
|  | 	'*:git_dir:_files -/' | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | _pkgctl_license_setup_args=( | ||||||
|  | 	'(-f --force)'{-f,--force}'[Overwrite existing REUSE config]' | ||||||
|  | 	'--no-check[Do not run license check after setup]' | ||||||
|  | 	'(-h --help)'{-h,--help}'[Display usage]' | ||||||
|  | 	'*:git_dir:_files -/' | ||||||
|  | ) | ||||||
|  |  | ||||||
| _pkgctl_version_cmds=( | _pkgctl_version_cmds=( | ||||||
| 	"pkgctl version command" | 	"pkgctl version command" | ||||||
| 	"check[Compares local package versions against upstream versions]" | 	"check[Compares local package versions against upstream versions]" | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								data/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								data/LICENSE
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | Copyright Arch Linux Contributors | ||||||
|  |  | ||||||
|  | Permission to use, copy, modify, and/or distribute this software for | ||||||
|  | any purpose with or without fee is hereby granted. | ||||||
|  |  | ||||||
|  | THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL | ||||||
|  | WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES | ||||||
|  | OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE | ||||||
|  | FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY | ||||||
|  | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | ||||||
|  | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | ||||||
|  | OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||
							
								
								
									
										54
									
								
								doc/man/pkgctl-license-check.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								doc/man/pkgctl-license-check.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | pkgctl-license-check(1) | ||||||
|  | ======================= | ||||||
|  |  | ||||||
|  | Name | ||||||
|  | ---- | ||||||
|  | pkgctl-license-check - Checks package licensing compliance using REUSE | ||||||
|  |  | ||||||
|  | Synopsis | ||||||
|  | -------- | ||||||
|  | pkgctl license check [OPTIONS] [PKGBASE...] | ||||||
|  |  | ||||||
|  | Description | ||||||
|  | ----------- | ||||||
|  |  | ||||||
|  | Checks package licensing compliance using REUSE and also verifies whether | ||||||
|  | a LICENSE file with the expected Arch Linux-specific 0BSD license text exists. | ||||||
|  |  | ||||||
|  | Configuration | ||||||
|  | ------------- | ||||||
|  |  | ||||||
|  | Uses reuse(1) and a `REUSE.toml` file located alongside the PKGBUILD(5). Refer | ||||||
|  | to the configuration section in pkgctl-license(1). | ||||||
|  |  | ||||||
|  | If no `PKGBASE` is specified, the command defaults to using the current working | ||||||
|  | directory. | ||||||
|  |  | ||||||
|  | Options | ||||||
|  | ------- | ||||||
|  |  | ||||||
|  | *-h, --help*:: | ||||||
|  | 	Show a help text | ||||||
|  |  | ||||||
|  | Exit Codes | ||||||
|  | ---------- | ||||||
|  |  | ||||||
|  | On exit, return one of the following codes: | ||||||
|  |  | ||||||
|  | *0*:: | ||||||
|  | 	Normal exit condition, all checked packages are compliant | ||||||
|  |  | ||||||
|  | *1*:: | ||||||
|  | 	Unknown cause of failure | ||||||
|  |  | ||||||
|  | *2*:: | ||||||
|  | 	Normal exit condition, but some packages are not compliant | ||||||
|  |  | ||||||
|  | See Also | ||||||
|  | -------- | ||||||
|  |  | ||||||
|  | pkgctl-license(1) | ||||||
|  | reuse(1) | ||||||
|  | PKGBUILD(5) | ||||||
|  |  | ||||||
|  | include::include/footer.asciidoc[] | ||||||
							
								
								
									
										55
									
								
								doc/man/pkgctl-license-setup.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								doc/man/pkgctl-license-setup.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | pkgctl-license-setup(1) | ||||||
|  | ======================= | ||||||
|  |  | ||||||
|  | Name | ||||||
|  | ---- | ||||||
|  | pkgctl-license-setup - Automatically detect and setup a basic REUSE | ||||||
|  | configuration | ||||||
|  |  | ||||||
|  | Synopsis | ||||||
|  | -------- | ||||||
|  | pkgctl license setup [OPTIONS] [PKGBASE...] | ||||||
|  |  | ||||||
|  | Description | ||||||
|  | ----------- | ||||||
|  |  | ||||||
|  | This subcommand automates the creation of the Arch Linux 0BSD package license | ||||||
|  | file as well as a basic reuse(1) configuration by applying simple heuristics. | ||||||
|  | It comes in especially handy when initially setting up licensing for a package | ||||||
|  | without the need to manually write a `REUSE.toml` file. | ||||||
|  |  | ||||||
|  | If any `.patch` files are detected and the PKGBUILD(5) has only a single entry | ||||||
|  | in the `license=()` array, this subcommand assumes the patches are licensed | ||||||
|  | under that license and generates annotations for them. | ||||||
|  |  | ||||||
|  | In case there are no patches, no additional annotations are generated. | ||||||
|  |  | ||||||
|  | Manual annotations are necessary in case the subcommand can't generate a | ||||||
|  | configuration that accounts for all files. In this case, `reuse lint` will fail | ||||||
|  | with a descriptive error of which files are missing an annotation. | ||||||
|  |  | ||||||
|  | If no `PKGBASE` is specified, the command defaults to using the current working | ||||||
|  | directory. | ||||||
|  |  | ||||||
|  | Options | ||||||
|  | ------- | ||||||
|  |  | ||||||
|  | *-f, --force*:: | ||||||
|  | 	Overwrite existing reuse(1) configuration | ||||||
|  |  | ||||||
|  | *--no-check*:: | ||||||
|  | 	Do not run pkgctl-license-check(1) after setup | ||||||
|  |  | ||||||
|  | *-h, --help*:: | ||||||
|  | 	Show a help text | ||||||
|  |  | ||||||
|  |  | ||||||
|  | See Also | ||||||
|  | -------- | ||||||
|  |  | ||||||
|  | pkgctl-license(1) | ||||||
|  | pkgctl-license-check(1) | ||||||
|  | reuse(1) | ||||||
|  | PKGBUILD(5) | ||||||
|  |  | ||||||
|  | include::include/footer.asciidoc[] | ||||||
							
								
								
									
										54
									
								
								doc/man/pkgctl-license.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								doc/man/pkgctl-license.1.asciidoc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | pkgctl-license(1) | ||||||
|  | ================= | ||||||
|  |  | ||||||
|  | Name | ||||||
|  | ---- | ||||||
|  | pkgctl-license - Check and manage package license compliance | ||||||
|  |  | ||||||
|  | Synopsis | ||||||
|  | -------- | ||||||
|  | pkgctl license [OPTIONS] [SUBCOMMAND] | ||||||
|  |  | ||||||
|  | Description | ||||||
|  | ----------- | ||||||
|  |  | ||||||
|  | Commands related to package licenses, including checks for compliance. | ||||||
|  |  | ||||||
|  | Uses reuse(1) and a `REUSE.toml` file located alongside the PKGBUILD(5). | ||||||
|  |  | ||||||
|  | Configuration | ||||||
|  | ------------- | ||||||
|  |  | ||||||
|  | The `REUSE.toml` file must contain annotations for all regular files expected | ||||||
|  | to be present in an Arch Linux package repository. | ||||||
|  |  | ||||||
|  | Use pkgctl-license-setup(1) to automatically detect and setup a basic REUSE | ||||||
|  | config file based on the files in the package repository. | ||||||
|  |  | ||||||
|  | For detailed information on the various configuration options available for the | ||||||
|  | `REUSE.toml` file, refer to the REUSE Specification (https://reuse.software/spec). | ||||||
|  |  | ||||||
|  | Options | ||||||
|  | ------- | ||||||
|  |  | ||||||
|  | *-h, --help*:: | ||||||
|  | 	Show a help text | ||||||
|  |  | ||||||
|  | Subcommands | ||||||
|  | ----------- | ||||||
|  |  | ||||||
|  | pkgctl license check:: | ||||||
|  | 	Checks package licensing compliance using REUSE | ||||||
|  |  | ||||||
|  | pkgctl license setup:: | ||||||
|  | 	Automatically detect and setup a basic REUSE config | ||||||
|  |  | ||||||
|  | See Also | ||||||
|  | -------- | ||||||
|  |  | ||||||
|  | pkgctl-license-check(1) | ||||||
|  | pkgctl-license-setup(1) | ||||||
|  | reuse(1) | ||||||
|  | PKGBUILD(5) | ||||||
|  |  | ||||||
|  | include::include/footer.asciidoc[] | ||||||
| @@ -116,9 +116,6 @@ copy_hostconf () { | |||||||
| 		cp "$makepkg_conf" "$working_dir/etc/makepkg.conf" | 		cp "$makepkg_conf" "$working_dir/etc/makepkg.conf" | ||||||
| 		if [[ -d "${makepkg_conf}.d" ]] && is_globfile "${makepkg_conf}.d"/*.conf; then | 		if [[ -d "${makepkg_conf}.d" ]] && is_globfile "${makepkg_conf}.d"/*.conf; then | ||||||
| 			mkdir --parents "$working_dir/etc/makepkg.conf.d/" | 			mkdir --parents "$working_dir/etc/makepkg.conf.d/" | ||||||
| 			if is_globfile "$working_dir/etc/makepkg.conf.d"/*.conf; then |  | ||||||
| 				rm --force "$working_dir/etc/makepkg.conf.d"/*.conf |  | ||||||
| 			fi |  | ||||||
| 			cp "${makepkg_conf}.d/"*.conf "$working_dir/etc/makepkg.conf.d/" | 			cp "${makepkg_conf}.d/"*.conf "$working_dir/etc/makepkg.conf.d/" | ||||||
| 		fi | 		fi | ||||||
| 	fi | 	fi | ||||||
|   | |||||||
| @@ -120,8 +120,20 @@ if (( ${#validpgpkeys[@]} != 0 )); then | |||||||
| 	git add --force -- keys/pgp/* | 	git add --force -- keys/pgp/* | ||||||
| fi | fi | ||||||
|  |  | ||||||
|  | needsversioning=() | ||||||
|  |  | ||||||
|  | if [[ ! -e REUSE.toml || ! -e LICENSE || ! -d LICENSES ]]; then | ||||||
|  | 	# TODO: Make this a hard failure in the future after packagers have had | ||||||
|  | 	# some time to add licenses to all packages. | ||||||
|  | 	warning "package doesn't have proper licensing information, set it up using:" | ||||||
|  | 	msg2 'pkgctl license setup' | ||||||
|  | else | ||||||
|  | 	pkgctl license check | ||||||
|  | 	needsversioning+=(REUSE.toml LICENSE LICENSES/*) | ||||||
|  | fi | ||||||
|  |  | ||||||
| # find files which should be under source control | # find files which should be under source control | ||||||
| needsversioning=(PKGBUILD) | needsversioning+=(PKGBUILD) | ||||||
| for s in "${source[@]}"; do | for s in "${source[@]}"; do | ||||||
| 	[[ $s != *://* ]] && needsversioning+=("$s") | 	[[ $s != *://* ]] && needsversioning+=("$s") | ||||||
| done | done | ||||||
| @@ -143,7 +155,7 @@ if (( ${#needsversioning[*]} )); then | |||||||
| 		if [[ ! -f "${file}" ]]; then | 		if [[ ! -f "${file}" ]]; then | ||||||
| 			continue | 			continue | ||||||
| 		fi | 		fi | ||||||
| 		if ! git ls-files --error-unmatch "$file"; then | 		if ! git ls-files --error-unmatch "$file" >/dev/null; then | ||||||
| 			die "%s is not under version control" "$file" | 			die "%s is not under version control" "$file" | ||||||
| 		fi | 		fi | ||||||
| 	done | 	done | ||||||
|   | |||||||
| @@ -42,10 +42,10 @@ pkgctl_build_usage() { | |||||||
|  |  | ||||||
| 		Build packages inside a clean chroot | 		Build packages inside a clean chroot | ||||||
|  |  | ||||||
| 		When a new pkgver is set using the appropriate PKGBUILD options the | 		Build packages in clean chroot environment, offering various options | ||||||
| 		checksums are automatically updated. | 		and functionalities to customize the package building process. | ||||||
|  |  | ||||||
| 		TODO | 		By default, chroot environments are located in /var/lib/archbuild/. | ||||||
|  |  | ||||||
| 		BUILD OPTIONS | 		BUILD OPTIONS | ||||||
| 		    --arch ARCH          Specify architectures to build for (disables auto-detection) | 		    --arch ARCH          Specify architectures to build for (disables auto-detection) | ||||||
| @@ -312,7 +312,7 @@ pkgctl_build() { | |||||||
|  |  | ||||||
| 	# Update pacman cache for auto-detection | 	# Update pacman cache for auto-detection | ||||||
| 	if [[ -z ${REPO} ]]; then | 	if [[ -z ${REPO} ]]; then | ||||||
| 		update_pacman_repo_cache multilib | 		update_pacman_repo_cache stable | ||||||
| 	# Check valid repos if not resolved dynamically | 	# Check valid repos if not resolved dynamically | ||||||
| 	elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then | 	elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then | ||||||
| 		die "Invalid repository target: %s" "${REPO}" | 		die "Invalid repository target: %s" "${REPO}" | ||||||
|   | |||||||
| @@ -18,6 +18,9 @@ export LANG=C.UTF-8 | |||||||
| # Avoid systemd trying to color the terminal on systemd-nspawn | # Avoid systemd trying to color the terminal on systemd-nspawn | ||||||
| export SYSTEMD_TINT_BACKGROUND=no | export SYSTEMD_TINT_BACKGROUND=no | ||||||
|  |  | ||||||
|  | # Avoid diffoscope looking at remote debug info through readelf | ||||||
|  | unset DEBUGINFOD_URLS | ||||||
|  |  | ||||||
| # Set buildtool properties | # Set buildtool properties | ||||||
| export BUILDTOOL=devtools | export BUILDTOOL=devtools | ||||||
| export BUILDTOOLVER=@buildtoolver@ | export BUILDTOOLVER=@buildtoolver@ | ||||||
|   | |||||||
| @@ -51,7 +51,6 @@ pkgctl_db_remove() { | |||||||
| 	local partial=0 | 	local partial=0 | ||||||
| 	local confirm=1 | 	local confirm=1 | ||||||
| 	local dbscripts_options=() | 	local dbscripts_options=() | ||||||
| 	local lookup_repo=multilib |  | ||||||
| 	local pkgname | 	local pkgname | ||||||
|  |  | ||||||
| 	# option checking | 	# option checking | ||||||
| @@ -106,13 +105,13 @@ pkgctl_db_remove() { | |||||||
| 				update_pacman_repo_cache unstable | 				update_pacman_repo_cache unstable | ||||||
| 				;; | 				;; | ||||||
| 			*-staging) | 			*-staging) | ||||||
| 				update_pacman_repo_cache multilib-staging | 				update_pacman_repo_cache staging | ||||||
| 				;; | 				;; | ||||||
| 			*-testing) | 			*-testing) | ||||||
| 				update_pacman_repo_cache multilib-testing | 				update_pacman_repo_cache testing | ||||||
| 				;; | 				;; | ||||||
| 			*) | 			*) | ||||||
| 				update_pacman_repo_cache multilib | 				update_pacman_repo_cache stable | ||||||
| 				;; | 				;; | ||||||
| 		esac | 		esac | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										66
									
								
								src/lib/license.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/lib/license.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | #!/hint/bash | ||||||
|  | # | ||||||
|  | # SPDX-License-Identifier: GPL-3.0-or-later | ||||||
|  |  | ||||||
|  | [[ -z ${DEVTOOLS_INCLUDE_LICENSE_SH:-} ]] || return 0 | ||||||
|  | DEVTOOLS_INCLUDE_LICENSE_SH=1 | ||||||
|  |  | ||||||
|  | _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  |  | ||||||
|  | pkgctl_license_usage() { | ||||||
|  | 	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} | ||||||
|  |     cat <<- _EOF_ | ||||||
|  | 		Usage: ${COMMAND} [COMMAND] [OPTIONS] | ||||||
|  |  | ||||||
|  | 		Check and manage package license compliance. | ||||||
|  |  | ||||||
|  | 		COMMANDS | ||||||
|  | 		    check      Check package license compliance | ||||||
|  | 		    setup      Automatically detect and setup a basic REUSE config | ||||||
|  |  | ||||||
|  | 		OPTIONS | ||||||
|  | 		    -h, --help    Show this help text | ||||||
|  |  | ||||||
|  | 		EXAMPLES | ||||||
|  | 		    $ ${COMMAND} check libfoo linux libbar | ||||||
|  | 		    $ ${COMMAND} setup libfoo | ||||||
|  | _EOF_ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pkgctl_license() { | ||||||
|  | 	if (( $# < 1 )); then | ||||||
|  | 		pkgctl_license_usage | ||||||
|  | 		exit 0 | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	while (( $# )); do | ||||||
|  | 		case $1 in | ||||||
|  | 			-h|--help) | ||||||
|  | 				pkgctl_license_usage | ||||||
|  | 				exit 0 | ||||||
|  | 				;; | ||||||
|  | 			check) | ||||||
|  | 				_DEVTOOLS_COMMAND+=" $1" | ||||||
|  | 				shift | ||||||
|  | 				# shellcheck source=src/lib/license/check.sh | ||||||
|  | 				source "${_DEVTOOLS_LIBRARY_DIR}"/lib/license/check.sh | ||||||
|  | 				pkgctl_license_check "$@" | ||||||
|  | 				exit $? | ||||||
|  | 				;; | ||||||
|  | 			setup) | ||||||
|  | 				_DEVTOOLS_COMMAND+=" $1" | ||||||
|  | 				shift | ||||||
|  | 				# shellcheck source=src/lib/license/setup.sh | ||||||
|  | 				source "${_DEVTOOLS_LIBRARY_DIR}"/lib/license/setup.sh | ||||||
|  | 				pkgctl_license_setup "$@" | ||||||
|  | 				exit 0 | ||||||
|  | 				;; | ||||||
|  | 			*) | ||||||
|  | 				die "invalid argument: %s" "$1" | ||||||
|  | 				;; | ||||||
|  | 		esac | ||||||
|  | 	done | ||||||
|  | } | ||||||
							
								
								
									
										147
									
								
								src/lib/license/check.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								src/lib/license/check.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,147 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | # | ||||||
|  | # SPDX-License-Identifier: GPL-3.0-or-later | ||||||
|  | # | ||||||
|  | [[ -z ${DEVTOOLS_INCLUDE_LICENSE_CHECK_SH:-} ]] || return 0 | ||||||
|  | DEVTOOLS_INCLUDE_LICENSE_CHECK_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 | ||||||
|  |  | ||||||
|  | readonly PKGCTL_LICENSE_CHECK_EXIT_COMPLIANT=0 | ||||||
|  | export PKGCTL_LICENSE_CHECK_EXIT_COMPLIANT | ||||||
|  | readonly PKGCTL_LICENSE_CHECK_EXIT_FAILURE=2 | ||||||
|  | export PKGCTL_LICENSE_CHECK_EXIT_FAILURE | ||||||
|  |  | ||||||
|  |  | ||||||
|  | pkgctl_license_check_usage() { | ||||||
|  | 	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} | ||||||
|  | 	cat <<- _EOF_ | ||||||
|  | 		Usage: ${COMMAND} [OPTIONS] [PKGBASE]... | ||||||
|  |  | ||||||
|  | 		Checks package licensing compliance using REUSE and also verifies | ||||||
|  | 		whether a LICENSE file with the expected Arch Linux-specific 0BSD | ||||||
|  | 		license text exists. | ||||||
|  |  | ||||||
|  | 		Upon execution, it runs 'reuse lint'. | ||||||
|  |  | ||||||
|  | 		OPTIONS | ||||||
|  | 		    -h, --help   Show this help text | ||||||
|  |  | ||||||
|  | 		EXAMPLES | ||||||
|  | 		    $ ${COMMAND} neovim vim | ||||||
|  | _EOF_ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pkgctl_license_check() { | ||||||
|  | 	local pkgbases=() | ||||||
|  | 	local verbose=0 | ||||||
|  |  | ||||||
|  | 	local license_text | ||||||
|  | 	license_text=$(< "${_DEVTOOLS_LIBRARY_DIR}"/data/LICENSE) | ||||||
|  |  | ||||||
|  | 	local exit_code=${PKGCTL_LICENSE_CHECK_EXIT_COMPLIANT} | ||||||
|  |  | ||||||
|  | 	while (( $# )); do | ||||||
|  | 		case $1 in | ||||||
|  | 			-h|--help) | ||||||
|  | 				pkgctl_license_check_usage | ||||||
|  | 				exit 0 | ||||||
|  | 				;; | ||||||
|  | 			--) | ||||||
|  | 				shift | ||||||
|  | 				break | ||||||
|  | 				;; | ||||||
|  | 			-*) | ||||||
|  | 				die "invalid argument: %s" "$1" | ||||||
|  | 				;; | ||||||
|  | 			*) | ||||||
|  | 				pkgbases=("$@") | ||||||
|  | 				break | ||||||
|  | 				;; | ||||||
|  | 		esac | ||||||
|  | 	done | ||||||
|  |  | ||||||
|  | 	if ! command -v reuse &>/dev/null; then | ||||||
|  | 		die "The \"$_DEVTOOLS_COMMAND\" command requires the 'reuse' CLI tool" | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	# Check if used without pkgbases in a packaging directory | ||||||
|  | 	if (( ${#pkgbases[@]} == 0 )); then | ||||||
|  | 		if [[ -f PKGBUILD ]]; then | ||||||
|  | 			pkgbases=(".") | ||||||
|  | 		else | ||||||
|  | 			pkgctl_license_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 | ||||||
|  |  | ||||||
|  | 	for path in "${pkgbases[@]}"; do | ||||||
|  | 		# skip paths that are not directories | ||||||
|  | 		if [[ ! -d "${path}" ]]; then | ||||||
|  | 			continue | ||||||
|  | 		fi | ||||||
|  | 		pushd "${path}" >/dev/null | ||||||
|  |  | ||||||
|  | 		if [[ ! -f PKGBUILD ]]; then | ||||||
|  | 			msg_error "${BOLD}${pkgbase}:${ALL_OFF} no PKGBUILD found" | ||||||
|  | 			return 1 | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		# reset common PKGBUILD variables | ||||||
|  | 		unset pkgbase | ||||||
|  |  | ||||||
|  | 		# shellcheck source=contrib/makepkg/PKGBUILD.proto | ||||||
|  | 		if ! . ./PKGBUILD; then | ||||||
|  | 			msg_error "${BOLD}${pkgbase}:${ALL_OFF} failed to source PKGBUILD" | ||||||
|  | 			return 1 | ||||||
|  | 		fi | ||||||
|  | 		pkgbase=${pkgbase:-$pkgname} | ||||||
|  |  | ||||||
|  | 		if [[ ! -e LICENSE ]]; then | ||||||
|  | 			msg_error "${BOLD}${pkgbase}:${ALL_OFF} is missing the LICENSE file" | ||||||
|  | 			return "${PKGCTL_LICENSE_CHECK_EXIT_FAILURE}" | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		if [[ ! -L LICENSES/0BSD.txt ]]; then | ||||||
|  | 			msg_error "${BOLD}${pkgbase}:${ALL_OFF} LICENSES/0BSD should be a symlink to LICENSE but it isn't" | ||||||
|  | 			return "${PKGCTL_LICENSE_CHECK_EXIT_FAILURE}" | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		# Check if the local LICENSE file mismatches our expectations | ||||||
|  | 		if [[ $license_text != $(< LICENSE) ]]; then | ||||||
|  | 			msg_error "${BOLD}${pkgbase}:${ALL_OFF} LICENSE file doesn't have the expected Arch Linux-specific license text" | ||||||
|  | 			return "${PKGCTL_LICENSE_CHECK_EXIT_FAILURE}" | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		# Check for REUSE compliance | ||||||
|  | 		if ! reuse lint --json | jq --exit-status '.summary.compliant' &>/dev/null; then | ||||||
|  | 			msg_error "${BOLD}${pkgbase}:${ALL_OFF} repository is not REUSE compliant" | ||||||
|  | 			exit_code=${PKGCTL_LICENSE_CHECK_EXIT_FAILURE} | ||||||
|  |  | ||||||
|  | 			# re-execute reuse lint for human readable output | ||||||
|  | 			if (( verbose )); then | ||||||
|  | 				reuse lint | ||||||
|  | 			fi | ||||||
|  |  | ||||||
|  | 			popd >/dev/null | ||||||
|  | 			continue | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		msg_success "${BOLD}${pkgbase}:${ALL_OFF} repository is REUSE compliant" | ||||||
|  | 		popd >/dev/null | ||||||
|  | 	done | ||||||
|  |  | ||||||
|  | 	# return status based on results | ||||||
|  | 	return "${exit_code}" | ||||||
|  | } | ||||||
							
								
								
									
										272
									
								
								src/lib/license/setup.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								src/lib/license/setup.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,272 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | # | ||||||
|  | # SPDX-License-Identifier: GPL-3.0-or-later | ||||||
|  | # | ||||||
|  | [[ -z ${DEVTOOLS_INCLUDE_LICENSE_SETUP_SH:-} ]] || return 0 | ||||||
|  | DEVTOOLS_INCLUDE_LICENSE_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/license/check.sh | ||||||
|  | source "${_DEVTOOLS_LIBRARY_DIR}"/lib/license/check.sh | ||||||
|  |  | ||||||
|  | source /usr/share/makepkg/util/message.sh | ||||||
|  |  | ||||||
|  | set -eo pipefail | ||||||
|  | shopt -s nullglob | ||||||
|  |  | ||||||
|  |  | ||||||
|  | pkgctl_license_setup_usage() { | ||||||
|  | 	local -r COMMAND=${_DEVTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} | ||||||
|  | 	cat <<- _EOF_ | ||||||
|  | 		Usage: ${COMMAND} [OPTIONS] [PKGBASE]... | ||||||
|  |  | ||||||
|  | 		Automate the creation of a basic REUSE configuration by analyzing the | ||||||
|  | 		license 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 REUSE configuration | ||||||
|  | 		    -h, --help    Show this help text | ||||||
|  | 		    --no-check    Do not run license check after setup | ||||||
|  |  | ||||||
|  | 		EXAMPLES | ||||||
|  | 		    $ ${COMMAND} neovim vim | ||||||
|  | _EOF_ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pkgctl_license_setup() { | ||||||
|  | 	local pkgbases=() | ||||||
|  | 	local force=0 | ||||||
|  | 	local run_check=1 | ||||||
|  |  | ||||||
|  | 	local path exit_code | ||||||
|  | 	local checks=() | ||||||
|  |  | ||||||
|  | 	while (( $# )); do | ||||||
|  | 		case $1 in | ||||||
|  | 			-h|--help) | ||||||
|  | 				pkgctl_license_setup_usage | ||||||
|  | 				exit 0 | ||||||
|  | 				;; | ||||||
|  | 			-f|--force) | ||||||
|  | 				force=1 | ||||||
|  | 				shift | ||||||
|  | 				;; | ||||||
|  | 			--no-check) | ||||||
|  | 				run_check=0 | ||||||
|  | 				shift | ||||||
|  | 				;; | ||||||
|  | 			--) | ||||||
|  | 				shift | ||||||
|  | 				break | ||||||
|  | 				;; | ||||||
|  | 			-*) | ||||||
|  | 				die "invalid argument: %s" "$1" | ||||||
|  | 				;; | ||||||
|  | 			*) | ||||||
|  | 				pkgbases=("$@") | ||||||
|  | 				break | ||||||
|  | 				;; | ||||||
|  | 		esac | ||||||
|  | 	done | ||||||
|  |  | ||||||
|  | 	if ! command -v reuse &>/dev/null; then | ||||||
|  | 		die "The \"$_DEVTOOLS_COMMAND\" command requires the 'reuse' CLI tool" | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	# Check if used without pkgbases in a packaging directory | ||||||
|  | 	if (( ${#pkgbases[@]} == 0 )); then | ||||||
|  | 		if [[ -f PKGBUILD ]]; then | ||||||
|  | 			pkgbases=(".") | ||||||
|  | 		else | ||||||
|  | 			pkgctl_license_setup_usage | ||||||
|  | 			exit 1 | ||||||
|  | 		fi | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	exit_code=0 | ||||||
|  | 	for path in "${pkgbases[@]}"; do | ||||||
|  | 		# skip paths that are not directories | ||||||
|  | 		if [[ ! -d "${path}" ]]; then | ||||||
|  | 			continue | ||||||
|  | 		fi | ||||||
|  |  | ||||||
|  | 		pushd "${path}" >/dev/null | ||||||
|  | 		if license_setup "${path}" "${force}"; then | ||||||
|  | 			checks+=("${path}") | ||||||
|  | 		else | ||||||
|  | 			exit_code=1 | ||||||
|  | 		fi | ||||||
|  | 		popd >/dev/null | ||||||
|  | 	done | ||||||
|  |  | ||||||
|  | 	# run checks on the setup targets | ||||||
|  | 	if (( run_check )) && (( ${#checks[@]} >= 1 )); then | ||||||
|  | 		echo | ||||||
|  | 		echo 📡 Running checks... | ||||||
|  | 		pkgctl_license_check "${checks[@]}" || true | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	return "$exit_code" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | license_setup() { | ||||||
|  | 	local path=$1 | ||||||
|  | 	local force=$2 | ||||||
|  | 	local pkgbase pkgname license | ||||||
|  |  | ||||||
|  | 	if [[ ! -f PKGBUILD ]]; then | ||||||
|  | 		msg_error "${BOLD}${path}:${ALL_OFF} no PKGBUILD found" | ||||||
|  | 		return 1 | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	# 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} | ||||||
|  |  | ||||||
|  | 	# setup LICENSE file | ||||||
|  | 	if ! license_file_setup "${pkgbase}" "${force}"; then | ||||||
|  | 		return 1 | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	# setup REUSE.toml | ||||||
|  | 	if ! reuse_setup "${pkgbase}" "${force}" "${license[@]}"; then | ||||||
|  | 		return 1 | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | is_valid_license() { | ||||||
|  | 	local license_name=$1 | ||||||
|  | 	local supported_licenses | ||||||
|  | 	supported_licenses=$(reuse supported-licenses | awk '{print $1}') | ||||||
|  | 	if grep --quiet "^${license_name}$" <<< "$supported_licenses"; then | ||||||
|  | 		return 0 | ||||||
|  | 	else | ||||||
|  | 		return 1 | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | license_file_setup() { | ||||||
|  | 	local pkgbase=$1 | ||||||
|  | 	local force=$2 | ||||||
|  |  | ||||||
|  | 	local license_text | ||||||
|  | 	license_text=$(< "${_DEVTOOLS_LIBRARY_DIR}"/data/LICENSE) | ||||||
|  |  | ||||||
|  | 	# Write LICENSE file, or check if it mismatches | ||||||
|  | 	if (( force )) || [[ ! -f LICENSE ]]; then | ||||||
|  | 		printf "%s\n" "${license_text}" > LICENSE | ||||||
|  | 		msg_success "${BOLD}${pkgbase}:${ALL_OFF} successfully configured LICENSE" | ||||||
|  | 	elif [[ -f LICENSE ]]; then | ||||||
|  | 		# if there is a license file, check whether it has the text we expect | ||||||
|  | 		existing_license="$(< LICENSE)" | ||||||
|  | 		if [[ "${license_text}" != "${existing_license}" ]]; then | ||||||
|  | 			msg_error "${BOLD}${pkgbase}:${ALL_OFF} existing LICENSE file doesn't have expected content, use --force to overwrite" | ||||||
|  | 			return 1 | ||||||
|  | 		fi | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	# make sure the LICENSE file is found by REUSE | ||||||
|  | 	mkdir --parents LICENSES | ||||||
|  | 	ln --symbolic --force ../LICENSE LICENSES/0BSD.txt | ||||||
|  | } | ||||||
|  |  | ||||||
|  | reuse_default_annotations() { | ||||||
|  | 	cat << EOF | ||||||
|  | version = 1 | ||||||
|  |  | ||||||
|  | [[annotations]] | ||||||
|  | path = [ | ||||||
|  |     "PKGBUILD", | ||||||
|  |     "README.md", | ||||||
|  |     "keys/**", | ||||||
|  |     ".SRCINFO", | ||||||
|  |     ".gitignore", | ||||||
|  |     ".nvchecker.toml", | ||||||
|  |     "*.install", | ||||||
|  |     "*.sysusers", | ||||||
|  |     "*sysusers.conf", | ||||||
|  |     "*.tmpfiles", | ||||||
|  |     "*tmpfiles.conf", | ||||||
|  |     "*.logrotate", | ||||||
|  |     "*.pam", | ||||||
|  |     "*.service", | ||||||
|  |     "*.socket", | ||||||
|  |     "*.timer", | ||||||
|  |     "*.desktop", | ||||||
|  |     "*.hook", | ||||||
|  | ] | ||||||
|  | SPDX-FileCopyrightText = "Arch Linux contributors" | ||||||
|  | SPDX-License-Identifier = "0BSD" | ||||||
|  | EOF | ||||||
|  | } | ||||||
|  |  | ||||||
|  | reuse_setup() { | ||||||
|  | 	local pkgbase=$1 | ||||||
|  | 	local force=$2 | ||||||
|  | 	shift 2 | ||||||
|  | 	local license=("$@") | ||||||
|  |  | ||||||
|  | 	# Check if REUSE.toml already exists | ||||||
|  | 	if (( ! force )) && [[ -f REUSE.toml ]]; then | ||||||
|  | 		msg_error "${BOLD}${pkgbase}:${ALL_OFF} REUSE.toml already exists, use --force to overwrite" | ||||||
|  | 		return 1 | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	reuse_default_annotations > REUSE.toml | ||||||
|  |  | ||||||
|  | 	local warning_occurred=0 | ||||||
|  | 	local patches=(*.patch) | ||||||
|  | 	# If there are patches and there's only a single well-known license listed in the package, | ||||||
|  | 	# we can generate the annotations for the patches, otherwise we will fail to do so and warn | ||||||
|  | 	# the user. | ||||||
|  | 	if (( ${#patches} )); then | ||||||
|  | 		# If there are multiple licenses, we can't make a good guess about which license the | ||||||
|  | 		# patches should have. In case the first element contains a space, we are dealing with | ||||||
|  | 		# a complex SPDX license identifier. | ||||||
|  | 		if (( ${#license[@]} > 1 )) || [[ ${license[0]} =~ [[:space:]] ]]; then | ||||||
|  | 			msg_warn "${BOLD}${pkgbase}:${ALL_OFF} .patch files were found but couldn't automatically guess a suitable license because PKGBUILD has multiple licenses" | ||||||
|  | 			patch_annotations "${pkgbase}" "TODO-Choose-a-license" "${patches[@]}" >> REUSE.toml | ||||||
|  | 			warning_occurred=1 | ||||||
|  | 		elif ! is_valid_license "${license[0]}"; then | ||||||
|  | 			msg_warn "${BOLD}${pkgbase}:${ALL_OFF} .patch files were found but couldn't automatically guess a suitable license because the PKGBUILD license '${license[0]}' is not a recognized SPDX license" | ||||||
|  | 			patch_annotations "${pkgbase}" "TODO-Choose-a-license" "${patches[@]}" >> REUSE.toml | ||||||
|  | 			warning_occurred=1 | ||||||
|  | 		else | ||||||
|  | 			patch_annotations "${pkgbase}" "${license[0]}" "${patches[@]}" >> REUSE.toml | ||||||
|  | 		fi | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	if (( warning_occurred )); then | ||||||
|  | 		msg_warn "${BOLD}${pkgbase}:${ALL_OFF} configured REUSE but a warning occurred, manually edit and fix REUSE.toml" | ||||||
|  | 		return 1 | ||||||
|  | 	else | ||||||
|  | 		reuse download --all | ||||||
|  | 		msg_success "${BOLD}${pkgbase}:${ALL_OFF} successfully configured REUSE.toml" | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  |  | ||||||
|  | patch_annotations() { | ||||||
|  | 	local pkgbase=$1 | ||||||
|  | 	local license_identifier=$2 | ||||||
|  | 	shift 2 | ||||||
|  | 	local patches=("$@") | ||||||
|  |  | ||||||
|  | 	local annotations | ||||||
|  | 	annotations+="\n[[annotations]]\n" | ||||||
|  | 	annotations+="path = [\n" | ||||||
|  | 	for patch in "${patches[@]}"; do | ||||||
|  | 		annotations+="    \"$(basename "${patch}")\",\n" | ||||||
|  | 	done | ||||||
|  | 	annotations+="]\n" | ||||||
|  | 	annotations+="SPDX-FileCopyrightText = \"${pkgbase} contributors\"\n" | ||||||
|  | 	annotations+="SPDX-License-Identifier = \"${license_identifier}\"" | ||||||
|  | 	echo -e "${annotations}" | ||||||
|  | } | ||||||
| @@ -124,7 +124,7 @@ pkgctl_release() { | |||||||
|  |  | ||||||
| 	# Update pacman cache for auto-detection | 	# Update pacman cache for auto-detection | ||||||
| 	if [[ -z ${REPO} ]]; then | 	if [[ -z ${REPO} ]]; then | ||||||
| 		update_pacman_repo_cache multilib | 		update_pacman_repo_cache stable | ||||||
| 	# Check valid repos if not resolved dynamically | 	# Check valid repos if not resolved dynamically | ||||||
| 	elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then | 	elif ! in_array "${REPO}" "${DEVTOOLS_VALID_REPOS[@]}"; then | ||||||
| 		die "Invalid repository target: %s" "${REPO}" | 		die "Invalid repository target: %s" "${REPO}" | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								src/lib/util/machine.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/lib/util/machine.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | |||||||
|  | #!/hint/bash | ||||||
|  | # | ||||||
|  | # SPDX-License-Identifier: GPL-3.0-or-later | ||||||
|  |  | ||||||
|  | [[ -z ${DEVTOOLS_INCLUDE_UTIL_MACHINE_SH:-} ]] || return 0 | ||||||
|  | DEVTOOLS_INCLUDE_UTIL_MACHINE_SH=1 | ||||||
|  |  | ||||||
|  | _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} | ||||||
|  | # shellcheck source=src/lib/common.sh | ||||||
|  | source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh | ||||||
|  |  | ||||||
|  |  | ||||||
|  | set -eo pipefail | ||||||
|  |  | ||||||
|  | machine_get_hardware_name() { | ||||||
|  | 	uname --machine | ||||||
|  | } | ||||||
|  |  | ||||||
|  | machine_has_multilib() { | ||||||
|  | 	case "$(machine_get_hardware_name)" in | ||||||
|  | 		x86_64*) | ||||||
|  | 			return 0 | ||||||
|  | 			;; | ||||||
|  | 	esac | ||||||
|  | 	return 1 | ||||||
|  | } | ||||||
| @@ -8,6 +8,8 @@ DEVTOOLS_INCLUDE_UTIL_PACMAN_SH=1 | |||||||
| _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} | _DEVTOOLS_LIBRARY_DIR=${_DEVTOOLS_LIBRARY_DIR:-@pkgdatadir@} | ||||||
| # shellcheck source=src/lib/common.sh | # shellcheck source=src/lib/common.sh | ||||||
| source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh | source "${_DEVTOOLS_LIBRARY_DIR}"/lib/common.sh | ||||||
|  | # shellcheck source=src/lib/util/machine.sh | ||||||
|  | source "${_DEVTOOLS_LIBRARY_DIR}"/lib/util/machine.sh | ||||||
|  |  | ||||||
| set -e | set -e | ||||||
|  |  | ||||||
| @@ -18,7 +20,8 @@ readonly _DEVTOOLS_MAKEPKG_CONF_DIR=${_DEVTOOLS_LIBRARY_DIR}/makepkg.conf.d | |||||||
|  |  | ||||||
|  |  | ||||||
| update_pacman_repo_cache() { | update_pacman_repo_cache() { | ||||||
| 	local repo=${1:-multilib} | 	local repo=${1:-stable} | ||||||
|  | 	repo=$(pacman_resolve_virtual_repo_name "${repo}") | ||||||
|  |  | ||||||
| 	mkdir -p "${_DEVTOOLS_PACMAN_CACHE_DIR}" | 	mkdir -p "${_DEVTOOLS_PACMAN_CACHE_DIR}" | ||||||
| 	msg "Updating pacman database cache" | 	msg "Updating pacman database cache" | ||||||
| @@ -32,7 +35,8 @@ update_pacman_repo_cache() { | |||||||
|  |  | ||||||
| get_pacman_repo_from_pkgbuild() { | get_pacman_repo_from_pkgbuild() { | ||||||
| 	local path=${1:-PKGBUILD} | 	local path=${1:-PKGBUILD} | ||||||
| 	local repo=${2:-multilib} | 	local repo=${2:-stable} | ||||||
|  | 	repo=$(pacman_resolve_virtual_repo_name "${repo}") | ||||||
| 	local -a pkgnames | 	local -a pkgnames | ||||||
|  |  | ||||||
| 	# shellcheck source=contrib/makepkg/PKGBUILD.proto | 	# shellcheck source=contrib/makepkg/PKGBUILD.proto | ||||||
| @@ -72,6 +76,7 @@ get_pkgnames_from_repo_pkgbase() { | |||||||
|  |  | ||||||
| 	# update the pacman repo cache if it doesn't exist yet | 	# update the pacman repo cache if it doesn't exist yet | ||||||
| 	if [[ ! -d "${_DEVTOOLS_PACMAN_CACHE_DIR}" ]]; then | 	if [[ ! -d "${_DEVTOOLS_PACMAN_CACHE_DIR}" ]]; then | ||||||
|  | 		# TODO: universe includes multilib, switch for architecture | ||||||
| 		update_pacman_repo_cache universe | 		update_pacman_repo_cache universe | ||||||
| 	fi | 	fi | ||||||
|  |  | ||||||
| @@ -91,3 +96,23 @@ get_pkgnames_from_repo_pkgbase() { | |||||||
| 	printf "%s\n" "${pkgnames[@]}" | 	printf "%s\n" "${pkgnames[@]}" | ||||||
| 	return 0 | 	return 0 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | pacman_resolve_virtual_repo_name() { | ||||||
|  | 	local repo=$1 | ||||||
|  |  | ||||||
|  | 	local repo_class=extra | ||||||
|  | 	if machine_has_multilib; then | ||||||
|  | 		repo_class=multilib | ||||||
|  | 	fi | ||||||
|  |  | ||||||
|  | 	case "${repo}" in | ||||||
|  | 		stable) | ||||||
|  | 			repo=${repo_class} | ||||||
|  | 			;; | ||||||
|  | 		testing|staging) | ||||||
|  | 			repo="${repo_class}-${repo}" | ||||||
|  | 			;; | ||||||
|  | 	esac | ||||||
|  |  | ||||||
|  | 	printf "%s" "${repo}" | ||||||
|  | } | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ | |||||||
| # shellcheck disable=2034 | # shellcheck disable=2034 | ||||||
| DEVTOOLS_VALID_BINARY_ARCHES=( | DEVTOOLS_VALID_BINARY_ARCHES=( | ||||||
| 	x86_64 | 	x86_64 | ||||||
|  | 	aarch64 | ||||||
| ) | ) | ||||||
|  |  | ||||||
| # shellcheck disable=2034 | # shellcheck disable=2034 | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ usage() { | |||||||
| 		    db      Pacman database modification for package update, move etc | 		    db      Pacman database modification for package update, move etc | ||||||
| 		    diff    Compare package files using different modes | 		    diff    Compare package files using different modes | ||||||
| 		    issue   Work with GitLab packaging issues | 		    issue   Work with GitLab packaging issues | ||||||
|  | 		    license Check and manage package licenses | ||||||
| 		    release Release step to commit, tag and upload build artifacts | 		    release Release step to commit, tag and upload build artifacts | ||||||
| 		    repo    Manage Git packaging repositories and their configuration | 		    repo    Manage Git packaging repositories and their configuration | ||||||
| 		    search  Search for an expression across the GitLab packaging group | 		    search  Search for an expression across the GitLab packaging group | ||||||
| @@ -113,6 +114,14 @@ while (( $# )); do | |||||||
| 			pkgctl_issue "$@" | 			pkgctl_issue "$@" | ||||||
| 			exit 0 | 			exit 0 | ||||||
| 			;; | 			;; | ||||||
|  | 		license) | ||||||
|  | 			_DEVTOOLS_COMMAND+=" $1" | ||||||
|  | 			shift | ||||||
|  | 			# shellcheck source=src/lib/license.sh | ||||||
|  | 			source "${_DEVTOOLS_LIBRARY_DIR}"/lib/license.sh | ||||||
|  | 			pkgctl_license "$@" | ||||||
|  | 			exit 0 | ||||||
|  | 			;; | ||||||
| 		release) | 		release) | ||||||
| 			_DEVTOOLS_COMMAND+=" $1" | 			_DEVTOOLS_COMMAND+=" $1" | ||||||
| 			shift | 			shift | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user