[PATCH] eapply_user: combine sort for all dirs (bug 608880)

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] eapply_user: combine sort for all dirs (bug 608880)

Zac Medico-2
Combine the patch basenames from all matched directories into a
list, and apply them in POSIX sorted order.  This allows patches in
more-specific directories to override patches of the same basename found
in less-specific directories. An empty patch (or /dev/null symlink)
negates a patch with the same basename found in a less-specific
directory.

This behavior is much more flexible and intuitive than the previous one,
while remaining backward-compatible to some extent.

NOTE: The implementation uses an associative array, which requires bash
version 4 or later.

X-Gentoo-bug: 608880
X-Gentoo-bug-url: https://bugs.gentoo.org/608880
---
 bin/phase-helpers.sh | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/bin/phase-helpers.sh b/bin/phase-helpers.sh
index 4b9b12b70..f8c2c34d4 100644
--- a/bin/phase-helpers.sh
+++ b/bin/phase-helpers.sh
@@ -1094,22 +1094,41 @@ if ___eapi_has_eapply_user; then
 
  local basedir=${PORTAGE_CONFIGROOT%/}/etc/portage/patches
 
- local d applied
+ local applied d f
+ local -A _eapply_user_patches
  local prev_shopt=$(shopt -p nullglob)
  shopt -s nullglob
 
- # possibilities:
+ # Patches from all matched directories are combined into a
+ # sorted (POSIX order) list of the patch basenames. Patches
+ # in more-specific directories override patches of the same
+ # basename found in less-specific directories. An empty patch
+ # (or /dev/null symlink) negates a patch with the same
+ # basename found in a less-specific directory.
+ #
+ # order of specificity:
  # 1. ${CATEGORY}/${P}-${PR} (note: -r0 desired to avoid applying
  #    ${P} twice)
  # 2. ${CATEGORY}/${P}
  # 3. ${CATEGORY}/${PN}
  # all of the above may be optionally followed by a slot
- for d in "${basedir}"/${CATEGORY}/{${P}-${PR},${P},${PN}}{,:${SLOT%/*}}; do
- if [[ -n $(echo "${d}"/*.diff) || -n $(echo "${d}"/*.patch) ]]; then
- eapply "${d}"
+ for d in "${basedir}"/${CATEGORY}/{${P}-${PR},${P},${PN}}{:${SLOT%/*},}; do
+ for f in "${d}"/*; do
+ if [[ ( ${f} == *.diff || ${f} == *.patch ) &&
+ -z ${_eapply_user_patches[${f##*/}]} ]]; then
+ _eapply_user_patches[${f##*/}]=${f}
+ fi
+ done
+ done
+
+ while read -r -d '' f; do
+ f=${_eapply_user_patches[${f}]}
+ if [[ -s ${f} ]]; then
+ eapply "${f}"
  applied=1
  fi
- done
+ done < <(printf -- "%s\0" "${!_eapply_user_patches[@]}" |
+ LC_ALL=C sort -z)
 
  ${prev_shopt}
 
--
2.13.0