[PATCH 1/5] rpm.eclass: rework app-arch/rpm support into pre-inherit variable

Eli Schwartz <[email protected]>
Newsgroups gmane.linux.gentoo.devel
Message-ID <[email protected]>
app-arch/rpm supports various compression types, but usually via USE
flags. We need ugly strings|grep to see which one is needed. rpm2targz
dynamically detects `@system` set tools which is why it has worked
forever.

To solve this we add RPM_COMPRESS_TYPE="" before inheriting the eclass,
which controls if app-arch/rpm is used. While testing this it also turns
out legacy lzma is not supported by rpm2targz at all, so exclude it in
such cases.

The eclass now has effectively a "mandatory for proper support" eclass
pre-inherit variable which nothing ever set before. Emit an eqawarn if
it is being "held wrong", to encourage people to set this variable.

Closes: https://bugs.gentoo.org/973073
Closes: https://bugs.gentoo.org/971578
Bug: https://bugs.gentoo.org/971600
Signed-off-by: Eli Schwartz <[email protected]>
---
 eclass/rpm.eclass | 97 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 87 insertions(+), 10 deletions(-)

diff --git a/eclass/rpm.eclass b/eclass/rpm.eclass
index 3b7f9e64355b..8ee248703aa1 100644
--- a/eclass/rpm.eclass
+++ b/eclass/rpm.eclass
@@ -17,12 +17,59 @@ _RPM_ECLASS=1
 
 inherit estack
 
-BDEPEND="
-	|| (
-		app-arch/rpm2targz
-		>=app-arch/rpm-4.19.0
-	)
-"
+# @ECLASS_VARIABLE: RPM_COMPRESS_TYPE
+# @PRE_INHERIT
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Comma-separated list of app-arch/rpm compression formats. If set,
+# app-arch/rpm will be allowed as a BDEPEND to unpack distfiles. Supported
+# types:
+#
+# - none (rpm is supported but distfile is uncompressed or builtin zlib)
+#
+# - bzip2 (.bz2)
+#
+# - lzma (deprecated pre-xz iteration of the lzma SDK. rpm2targz doesn't
+#   support it)
+#
+# - xz (.xz)
+#
+# - zstd (.zst)
+#
+# - "" (empty -- the ebuild hasn't been updated to resolve deprecations)
+
+_rpm_set_globals() {
+	local rpmdep= rpm2tar="true" t= types=()
+	IFS=, declare -a 'types=(${RPM_COMPRESS_TYPE})'
+
+	if [[ ${RPM_COMPRESS_TYPE} = none ]]; then
+		rpmdep=""
+	elif [[ "${#types[@]}" -gt 0 ]]; then
+		for t in "${types[@]}"; do
+			case ${t} in
+				bzip2|zstd) rpmdep+="${t}," ;;
+				lzma) rpmdep+="${t},"; rpm2tar="false" ;;
+				xz) rpmdep+="lzma," ;;
+				none) die "RPM_COMPRESS_TYPE=none must be used alone" ;;
+				*) die "invalid RPM_COMPRESS_TYPE: ${RPM_COMPRESS_TYPE} (found: ${t})" ;;
+			esac
+		done
+		rpmdep="[${rpmdep%,}]"
+	fi
+
+	if [[ ${rpm2targz} = true ]]; then
+		BDEPEND="
+			|| (
+				app-arch/rpm2targz
+				app-arch/rpm${rpmdep}
+			)
+		"
+	else
+		BDEPEND="app-arch/rpm${rpmdep}"
+	fi
+}
+_rpm_set_globals
+unset -f _rpm_set_globals
 
 # @FUNCTION: rpm_unpack
 # @USAGE: <rpms>
@@ -30,7 +77,10 @@ BDEPEND="
 # Unpack the contents of the specified rpms like the unpack() function.
 rpm_unpack() {
 	[[ $# -eq 0 ]] && set -- ${A}
-	local a
+	local a noticed=()
+
+	IFS=, declare -a 'types=(${RPM_COMPRESS_TYPE})'
+
 	for a in "$@" ; do
 		echo ">>> Unpacking ${a} to ${PWD}"
 		if [[ ${a} == ./* ]] ; then
@@ -43,11 +93,38 @@ rpm_unpack() {
 			a="${DISTDIR}/${a}"
 		fi
 
-		if command -v rpm2tar >/dev/null; then
-			local extracttool=(rpm2tar -O)
+		local payload= usedep=""
+		if [[ ${a} = *.src.rpm ]]; then
+			payload=none
 		else
-			# app-arch/rpm fallback
+			payload=$(strings "${a}" | grep -o 'PayloadIs[a-zA-Z]*'; pipestatus || die "failed to grep rpm payload")
+		fi
+
+		case ${payload} in
+			"") payload=none;; # gzip/uncompressed
+			PayloadIsBzip) payload=bzip2 usedep="[bzip2]";;
+			PayloadIsXz) payload=xz usedep="[lzma]";;
+			PayloadIsLzma) payload=lzma usedep="[lzma]";;
+			PayloadIsZstd) payload=zstd usedep="[zstd]";;
+		esac
+
+		local use_rpm=
+		if [[ ${RPM_COMPRESS_TYPE} = *${payload}* ||
+			  ( ${payload} = none && ${RPM_COMPRESS_TYPE} ) ]]; then
+			use_rpm=true
+		elif ! has "${payload}" "${noticed[@]}"; then
+			eqawarn "QA Notice: rpm_unpack called without supporting app-arch/rpm."
+			eqawarn "\${RPM_COMPRESS_TYPE} should include '${payload}'."
+			noticed+=("${payload}")
+		fi
+
+		if [[ ${use_rpm} = true ]] && has_version -b "app-arch/rpm${usedep}"; then
+			# prefer it if correct USE is in BDEPEND and installed
 			local extracttool=(rpm2archive -n)
+		elif [[ ${payload} = lzma ]]; then
+			die "rpm_unpack called with legacy lzma compression that rpm2targz doesn't support"
+		else
+			local extracttool=(rpm2tar -O)
 		fi
 
 		"${extracttool[@]}" "${a}" | tar xf -
-- 
2.52.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.