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