[PATCH v3 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, i.e. PayloadIsLzma rather than PayloadIsXz, is not
supported by rpm2targz at all (despite bug 321439 implying it *was*
added? the one instance I found in-tree fails). 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
Bug: https://bugs.gentoo.org/321439
Signed-off-by: Eli Schwartz <[email protected]>
---

v3: add (+) to all USE flags, to handle app-arch/rpm-4.19 that
unconditionally enabled them.

 eclass/rpm.eclass | 101 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 90 insertions(+), 11 deletions(-)

diff --git a/eclass/rpm.eclass b/eclass/rpm.eclass
index 3b7f9e64355b..6a096aba78bd 100644
--- a/eclass/rpm.eclass
+++ b/eclass/rpm.eclass
@@ -15,14 +15,62 @@ esac
 if [[ -z ${_RPM_ECLASS} ]] ; then
 _RPM_ECLASS=1
 
-inherit estack
+inherit estack toolchain-funcs
 
-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= rpmuse= rpm2tar="true" t= types=()
+	IFS=, declare -a 'types=(${RPM_COMPRESS_TYPE})'
+
+	if [[ ${RPM_COMPRESS_TYPE} = none ]]; then
+		rpmdep=">=app-arch/rpm-4.19.0"
+	elif [[ "${#types[@]}" -gt 0 ]]; then
+		for t in "${types[@]}"; do
+			case ${t} in
+				bzip2|zstd) rpmuse+="${t}(+)," ;;
+				lzma) rpmuse+="${t}(+),"; rpm2tar="false" ;;
+				xz) rpmuse+="lzma(+)," ;;
+				none) die "RPM_COMPRESS_TYPE: 'none' cannot be combined with other values" ;;
+				*) die "invalid RPM_COMPRESS_TYPE: ${RPM_COMPRESS_TYPE} (found: ${t})" ;;
+			esac
+		done
+		rpmdep=">=app-arch/rpm-4.19.0"
+		[[ ${rpmuse} ]] && rpmdep+="[${rpmuse%,}]"
+	fi
+
+	if [[ ${rpm2tar} = true ]]; then
+		BDEPEND="
+			|| (
+				app-arch/rpm2targz
+				${rpmdep}
+			)
+		"
+	else
+		BDEPEND="${rpmdep}"
+	fi
+}
+_rpm_set_globals
+unset -f _rpm_set_globals
 
 # @FUNCTION: rpm_unpack
 # @USAGE: <rpms>
@@ -30,7 +78,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 +94,39 @@ 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=$($(tc-getSTRINGS) "${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
+			# bug 321439
+			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.