Files
sablink-distro/eclass/sab-patches.eclass
T

172 lines
4.6 KiB
Bash

# Copyright 2014 Sabayon
# Distributed under the terms of the GNU General Public License v2
# $Id$
# @ECLASS: sab-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: SAB_PATCHES_SRC
# @DEFAULT_UNSET
# @DESCRIPTION:
# Array that contains URIs of patches to be added to SRC_URI. Mandatory!
# @ECLASS-VARIABLE: SAB_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 [[ ${#SAB_PATCHES_SRC[@]} -eq 0 ]]; then
die "SAB_PATCHES_SRC is not set"
fi
# @FUNCTION: sab-patches_update_SRC_URI
# @DESCRIPTION:
# Appends patches entries to SRC_URI. If it is not done, an error will
# occur later on.
sab-patches_update_SRC_URI() {
local p
for p in "${SAB_PATCHES_SRC[@]}"; do
SRC_URI+=${SRC_URI:+ }${p}
done
}
# @FUNCTION: sab-patches_apply_all
# @DESCRIPTION:
# Applies patches specified using SAB_PATCHES_SRC, skipping patches
# with names matched in SAB_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).
sab-patches_apply_all() {
local p
for p in "${SAB_PATCHES_SRC[@]}"; do
if [[ ${p} = *.tar* ]]; then
local dir=${p##*/}
dir=${dir%.tar*}
_sab-patches_apply_from_dir "${WORKDIR}/${dir}"
else
local name=${p##*/}
_sab-patches_apply_nonskipped "${DISTDIR}" "${name}"
fi
done
}
# @FUNCTION: sab-patches_apply
# @DESCRIPTION:
# Apply selected patches. Arguments are the directory containing
# the patch, followed by one or more patch names.
sab-patches_apply() {
[[ $# -lt 2 ]] && die "sab-patches_apply: missing arguments"
local dir=$1
shift
local patch
for patch; do
epatch "${dir}/${patch}"
done
}
# @FUNCTION: sab-patches_unpack
# @DESCRIPTION:
# Unpack every file provided in SAB_PATCHES_SRC.
sab-patches_unpack() {
local p
pushd "${WORKDIR}" > /dev/null || die
for p in "${SAB_PATCHES_SRC[@]}"; do
local name=${p##*/}
unpack "${name}"
done
popd > /dev/null || die
}
# @FUNCTION: _sab-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 sab-patches_apply and skip the unwanted ones.
_sab-patches_apply_nonskipped() {
if [[ $# -lt 2 ]]; then
die "_sab-patches_apply_nonskipped: missing arguments"
fi
local dir=$1
shift
local patch
for patch; do
if [[ ${patch} = */* ]]; then
die "_sab-patches_apply_nonskipped: '${patch}' contains slashes"
fi
if _sab-patches_is_skipped "${patch}"; then
einfo "(skipping ${patch})"
else
epatch "${dir}/${patch}"
fi
done
}
# @FUNCTION: _sab-patches_apply_from_dir
# @INTERNAL
# @DESCRIPTION:
# Apply all patches from a directory in order. Obeys SAB_PATCHES_SKIP.
_sab-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
_sab-patches_apply_nonskipped "${dir}" "${patch}"
done < "${order_file}"
[[ $? -ne 0 ]] && die "_sab-patches_apply_from_dir: loop failed"
}
# @FUNCTION: _sab-patches_is_skipped
# @INTERNAL
# @DESCRIPTION:
# Returns success if the patch should be skipped. O(n). :)
_sab-patches_is_skipped() {
local arg=$1
local p
for p in "${SAB_PATCHES_SKIP[@]}"; do
[[ ${arg} = ${p} ]] && return 0
done
return 1
}