diff options
-rw-r--r-- | eclass/kog-patches.eclass | 171 |
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 +} |