[PATCH v2 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]>
---

v2:

big rework of BDEPEND generation. The first version of this patch, never
posted, didn't include legacy lzma handling to split xz/lzma. I added it
at the last minute and broke >= dependencies on rpm, erasing
app-arch/rpm if it didn't work, etc. All this logic needed to be
reverted and reintegrated.

Apologies for submitting a rushed patch and never checking the results.
I saw the other competing proposal and said "I  better submit quickly".
:(

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

diff --git a/eclass/rpm.eclass b/eclass/rpm.eclass
index 3b7f9e64355b..1a7e001c46df 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 -

Range-diff against v1:
1:  462a58d518b9 ! 1:  64122fbf0ef2 rpm.eclass: rework app-arch/rpm support into pre-inherit variable
    @@ Commit message
     
         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.
    +    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
    @@ Commit message
         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]>
     
      ## eclass/rpm.eclass ##
    -@@ eclass/rpm.eclass: _RPM_ECLASS=1
    +@@ eclass/rpm.eclass: esac
    + if [[ -z ${_RPM_ECLASS} ]] ; then
    + _RPM_ECLASS=1
      
    - inherit estack
    +-inherit estack
    ++inherit estack toolchain-funcs
      
     -BDEPEND="
     -	|| (
    @@ eclass/rpm.eclass: _RPM_ECLASS=1
     +# - "" (empty -- the ebuild hasn't been updated to resolve deprecations)
     +
     +_rpm_set_globals() {
    -+	local rpmdep= rpm2tar="true" t= types=()
    ++	local rpmdep= rpmuse= rpm2tar="true" t= types=()
     +	IFS=, declare -a 'types=(${RPM_COMPRESS_TYPE})'
     +
     +	if [[ ${RPM_COMPRESS_TYPE} = none ]]; then
    -+		rpmdep=""
    ++		rpmdep=">=app-arch/rpm-4.19.0"
     +	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" ;;
    ++				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="[${rpmdep%,}]"
    ++		rpmdep=">=app-arch/rpm-4.19.0"
    ++		[[ ${rpmuse} ]] && rpmdep+="[${rpmuse%,}]"
     +	fi
     +
    -+	if [[ ${rpm2targz} = true ]]; then
    ++	if [[ ${rpm2tar} = true ]]; then
     +		BDEPEND="
     +			|| (
     +				app-arch/rpm2targz
    -+				app-arch/rpm${rpmdep}
    ++				${rpmdep}
     +			)
     +		"
     +	else
    -+		BDEPEND="app-arch/rpm${rpmdep}"
    ++		BDEPEND="${rpmdep}"
     +	fi
     +}
     +_rpm_set_globals
    @@ eclass/rpm.eclass: rpm_unpack() {
     +			payload=none
      		else
     -			# app-arch/rpm fallback
    -+			payload=$(strings "${a}" | grep -o 'PayloadIs[a-zA-Z]*'; pipestatus || die "failed to grep rpm payload")
    ++			payload=$($(tc-getSTRINGS) "${a}" | grep -o 'PayloadIs[a-zA-Z]*'; pipestatus || die "failed to grep rpm payload")
     +		fi
     +
     +		case ${payload} in
    @@ eclass/rpm.eclass: rpm_unpack() {
     +			# 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)
-- 
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.