[pacman-dev] [PATCH] Provides generation for files (a.k.a. rpm fileattrs for makepkg)

Carson Black uhhadd at gmail.com
Sun Mar 8 04:12:16 UTC 2020


Whenever I'm working in a relatively fresh Arch environment, my work
flow looks like this:

- cmake .. -DFLAGS=blahblahblah
- Wait a few seconds
- Package providing KF5whatever not found
- Try and deduce Arch package name from CMake package name

Often, trying to figure out the relation between the build system package names
and the Arch package names of missing dependencies ends up being the longest
part of whatever task I was working on, which isn't very efficient.

Compare this to me working in an RPM distro:

- cmake .. -DFLAGS=blahblahblah
- Wait a few seconds
- Package providing KF5whatever not found
- dnf install cmake(KF5whatever)

The latter workflow is a lot more efficient, and is exactly what this
commit introduces to packages generated by makepkg.

Every file is iterated over at the end of the build process to generate
additional provides without the packager needing to manually specify
them.

The code is architected in a manner designed to make it trivial to add
new provider autogenerators.

So far, there are autogenerated providers for:
- pkgconfig(package)
- cmake(package)
- desktop files
  * app(desktopfilename)
  * can-open-mimetype(mimetype)
  * can-open-file-extension(filetype)

While these automatically generated provides can be used for packaging,
this is intended more for interactive usage rather than an attempt to
change how Arch packaging works.

Signed-off-by: Carson Black <uhhadd at gmail.com>
---
 scripts/makepkg.sh.in | 108 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index ca3e7459..10703a91 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -520,6 +520,111 @@ find_libdepends() {
 	(( ${#libdepends[@]} )) && printf '%s\n' "${libdepends[@]}"
 }
 
+pkgconfig_fileattr() {
+	case $1 in
+		--generate-provides)
+			case $2 in
+				*.pc)
+					directory="`dirname ${2}`"
+					export PKG_CONFIG_PATH="$DIR:$DIR/../../share/pkgconfig"
+					pkg-config --print-provides "$2" 2>/dev/null | while read name _ _; do
+						[ -n "$name" ] || continue
+						echo "pkgconfig($name)"
+					done
+					;;
+			esac
+			;;
+		--generate-depends)
+			;;
+	esac
+}
+
+cmake_fileattr() {
+	case $1 in
+		--generate-provides)
+			case $2 in
+				*.cmake)
+					base="$(basename $2)"
+					case $2 in
+						*Config.cmake)
+							echo "cmake(${base%Config.cmake})"
+							;;
+						*-config.cmake)
+							echo "cmake(${base%-config.cmake})"
+							;;
+					esac
+					;;
+			esac
+			;;
+		--generate-depends)
+			;;
+	esac
+}
+
+desktop_file_attr() {
+	case $1 in
+		--generate-provides)
+			case "$2" in
+				*.desktop)
+					grep -q "Type=Application" "$2" || return
+					grep -q "Exec=" "$2" || return
+					base="$(basename $2)"
+					echo "app(${base%.desktop})"
+
+					IFS=';'
+					mimetypes=`grep MimeType= $2 | cut -d '=' -f 2`
+					for mimetype in $mimetypes; do
+						echo "can-open-mimetype($mimetype)"
+
+						IFS=' '
+						filetypes=`grep -v ^\# /etc/mime.types | grep $mimetype | cut -d ' ' | xargs`
+						for filetype in $filetypes; do
+							echo "can-open-file-extension($filetype)"
+						done
+					done
+					;;
+			esac
+			;;
+		--generate-depends)
+			;;
+	esac
+}
+
+check_pkg_dir() {
+	if [[ ! -d $pkgdir ]]; then
+		error "$(gettext "Missing %s directory.")" "\$pkgdir/"
+		plain "$(gettext "Aborting...")"
+		exit $E_MISSING_PKGDIR
+	fi
+}
+
+find_fileattrs_provides() {
+	check_pkg_dir
+
+	for file in `find $pkgdir`; do
+		for function in $(declare -F); do
+			case $function in
+				*_fileattr)
+					$function --generate-provides $file
+					;;
+			esac
+		done
+	done
+}
+
+find_fileattrs_depends() {
+	check_pkg_dir
+
+	for file in `find $pkgdir`; do
+		for function in $(declare -F); do
+			case $function in
+				*_fileattr)
+					$function --generate-depends $file
+					;;
+			esac
+		done
+	done
+}
 
 find_libprovides() {
 	local p libprovides missing
@@ -613,6 +718,9 @@ write_pkginfo() {
 	mapfile -t provides < <(find_libprovides)
 	mapfile -t depends < <(find_libdepends)
 
+	mapfile -t provides < <(find_fileattrs_provides)
+	mapfile -t depends < <(find_fileattrs_depends)
+
 	write_kv_pair "license"     "${license[@]}"
 	write_kv_pair "replaces"    "${replaces[@]}"
 	write_kv_pair "group"       "${groups[@]}"
-- 
2.25.1


More information about the pacman-dev mailing list