summaryrefslogtreecommitdiff
path: root/eclass/kog-patches.eclass
diff options
context:
space:
mode:
Diffstat (limited to 'eclass/kog-patches.eclass')
-rw-r--r--eclass/kog-patches.eclass171
1 files changed, 171 insertions, 0 deletions
diff --git a/eclass/kog-patches.eclass b/eclass/kog-patches.eclass
new file mode 100644
index 00000000..17807efd
--- /dev/null
+++ b/eclass/kog-patches.eclass
@@ -0,0 +1,171 @@
+# Copyright 2014 Sabayon
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+# @ECLASS: kog-patches.eclass
+# @MAINTAINER:
+# slawomir.nizio@sabayon.org
+# @AUTHOR:
+# SÅ‚awomir Nizio <slawomir.nizio@sabayon.org>
+# @BLURB: eclass that makes it easier to apply patches from multiple packages
+# @DESCRIPTION:
+# Makes it easy to apply patches stored in a remote location
+# with the intention to make the task easier for Sabayon split ebuilds.
+# (Plain patches kept in a VCS are very nice, but in the case of split
+# ebuilds, duplicating the patches is not effective.)
+# Patches are not added to SRC_URI by default, because it makes ebuilds
+# use "SRC_URI+=..." which makes them more diverged from the original
+# one than necessary.
+# The eclass does not define any phase function.
+
+# @ECLASS-VARIABLE: KOG_PATCHES_SRC
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# Array that contains URIs of patches to be added to SRC_URI. Mandatory!
+
+# @ECLASS-VARIABLE: KOG_PATCHES_SKIP
+# @DESCRIPTION:
+# Array that contains patterns of patch names to be skipped.
+# It does not need to be a global variable.
+
+inherit eutils
+
+if [[ ${#KOG_PATCHES_SRC[@]} -eq 0 ]]; then
+ die "KOG_PATCHES_SRC is not set"
+fi
+
+# @FUNCTION: kog-patches_update_SRC_URI
+# @DESCRIPTION:
+# Appends patches entries to SRC_URI. If it is not done, an error will
+# occur later on.
+kog-patches_update_SRC_URI() {
+ local p
+ for p in "${KOG_PATCHES_SRC[@]}"; do
+ SRC_URI+=${SRC_URI:+ }${p}
+ done
+}
+
+# @FUNCTION: kog-patches_apply_all
+# @DESCRIPTION:
+# Applies patches specified using KOG_PATCHES_SRC, skipping patches
+# with names matched in KOG_PATCHES_SKIP.
+# Two possible cases are supported.
+# 1. A patch path which is a tarball (assumed file name: *.tar*).
+# Such a tarball must unpack to ${WORKDIR}/<tarball name without *.tar*>
+# and must contain a file 'order,' which is used to determine order
+# of patches to apply.
+# 2. A patch which is not a tarball, which will be simply applied (if
+# it is not skipped).
+kog-patches_apply_all() {
+ local p
+ for p in "${KOG_PATCHES_SRC[@]}"; do
+ if [[ ${p} = *.tar* ]]; then
+ local dir=${p##*/}
+ dir=${dir%.tar*}
+ _kog-patches_apply_from_dir "${WORKDIR}/${dir}"
+ else
+ local name=${p##*/}
+ _kog-patches_apply_nonskipped "${DISTDIR}" "${name}"
+ fi
+ done
+}
+
+# @FUNCTION: kog-patches_apply
+# @DESCRIPTION:
+# Apply selected patches. Arguments are the directory containing
+# the patch, followed by one or more patch names.
+kog-patches_apply() {
+ [[ $# -lt 2 ]] && die "kog-patches_apply: missing arguments"
+ local dir=$1
+ shift
+ local patch
+ for patch; do
+ epatch "${dir}/${patch}"
+ done
+}
+
+# @FUNCTION: kog-patches_unpack
+# @DESCRIPTION:
+# Unpack every file provided in KOG_PATCHES_SRC.
+kog-patches_unpack() {
+ local p
+ pushd "${WORKDIR}" > /dev/null || die
+
+ for p in "${KOG_PATCHES_SRC[@]}"; do
+ local name=${p##*/}
+ unpack "${name}"
+ done
+
+ popd > /dev/null || die
+}
+
+# @FUNCTION: _kog-patches_apply_nonskipped
+# @INTERNAL
+# @DESCRIPTION:
+# Apply selected patches - only those which should not be skipped.
+# Arguments are the directory containing the patch, followed by
+# one or more patch names.
+# This function is not intended to be used by ebuilds because there
+# is a better way: use kog-patches_apply and skip the unwanted ones.
+_kog-patches_apply_nonskipped() {
+ if [[ $# -lt 2 ]]; then
+ die "_kog-patches_apply_nonskipped: missing arguments"
+ fi
+
+ local dir=$1
+ shift
+
+ local patch
+ for patch; do
+ if [[ ${patch} = */* ]]; then
+ die "_kog-patches_apply_nonskipped: '${patch}' contains slashes"
+ fi
+
+ if _kog-patches_is_skipped "${patch}"; then
+ einfo "(skipping ${patch})"
+ else
+ epatch "${dir}/${patch}"
+ fi
+ done
+}
+
+# @FUNCTION: _kog-patches_apply_from_dir
+# @INTERNAL
+# @DESCRIPTION:
+# Apply all patches from a directory in order. Obeys KOG_PATCHES_SKIP.
+_kog-patches_apply_from_dir() {
+ local dir=$1
+ local order_file=${dir}/order
+ if [[ ! -r ${order_file} ]] || [[ ! -f ${order_file} ]]; then
+ die "Problems with '${order_file}'... (Does it exist?)"
+ fi
+
+ local patch
+ while read patch; do
+ local patch_path=${dir}/${patch}
+ if \
+ [[ -z ${patch} ]] || \
+ [[ ${patch} = *\ * ]] || \
+ [[ ${patch} = */* ]] || \
+ [[ ! -f ${patch_path} ]]; then
+ die "Problems with the patch '${patch}', see ${order_file}."
+ fi
+
+ _kog-patches_apply_nonskipped "${dir}" "${patch}"
+ done < "${order_file}"
+
+ [[ $? -ne 0 ]] && die "_kog-patches_apply_from_dir: loop failed"
+}
+
+# @FUNCTION: _kog-patches_is_skipped
+# @INTERNAL
+# @DESCRIPTION:
+# Returns success if the patch should be skipped. O(n). :)
+_kog-patches_is_skipped() {
+ local arg=$1
+ local p
+ for p in "${KOG_PATCHES_SKIP[@]}"; do
+ [[ ${arg} = ${p} ]] && return 0
+ done
+ return 1
+}