# autoepatch - Automatic patch scripting # Copyright (C) 2006 Gentoo Foundation # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with autoepatch; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Check for gpatch present and use that if available; if not # and patch is not GNU patch, warn that autoepatch might not # work as intended gpatch() { if [[ -n ${GNU_PATCH} ]]; then "${GNU_PATCH}" "$@" return $? fi GNU_PATCH=$(type -p gpatch) if [[ -z ${GNU_PATCH} ]]; then if ! type -p patch; then eerror "Unable to find a patch command to use" return 1 fi GNU_PATCH=$(type -p patch) if ! "${GNU_PATCH}" --version /dev/null; then ewarn "The ${GNU_PATCH} binary is not a GNU patch version, autoepatch might misbehave" fi fi gpatch "${@}" return $? } # Alias a working find(1), so that we can make sure the -exec {} + works. # OpenBSD find(1) is stone age. find() { local findcmd="@findcmd@" # We assume that if no find is specified, then we're using a decent # version of find(1). [[ "${findcmd//@/|}" == "|findcmd|" ]] && findcmd="$(type -P find)" "${findcmd}" "$@" return $? } # Simple wrapper around debianutils mktemp and BSD mktemp, # based on the emktemp function in eutils.eclass by # Mike Frysinger (vapier@gentoo.org) # # Takes just 1 optional parameter (the directory to create tmpfile in) emktemp() { local exe="touch" if [[ $1 == -d ]]; then exe="mkdir" shift fi local topdir=$1 if [[ -z ${topdir} ]] ; then # ${T} is an ebuild variable, respect it [[ -z ${T} ]] \ && topdir="/tmp" \ || topdir=${T} fi if [[ -z $(type -p mktemp) ]] ; then local tmp=/ while [[ -e ${tmp} ]] ; do tmp=${topdir}/tmp.${RANDOM}.${RANDOM}.${RANDOM} done ${exe} "${tmp}" || ${exe} -p "${tmp}" echo "${tmp}" else local mktemptype mktemp -V &>/dev/null && \ mktemptype="debianutils" || \ mktemptype="bsd" if [[ ${exe} == "touch" ]] ; then [[ ${mktemptype} == "debianutils" ]] \ && mktemp -p "${topdir}" \ || TMPDIR="${topdir}" mktemp -t tmp else [[ ${mktemptype} == "debianutils" ]] \ && mktemp -d "${topdir}" \ || TMPDIR="${topdir}" mktemp -dt tmp fi fi } # # See if we can apply $2 on $1, and if so, do it # try_patch() { local target=$1 local patch=$2 local ret local patchname="$(basename "$(dirname "${patch}")")-${patch##*/}" if [[ -d "${target}" ]]; then pushd "${target}" &>/dev/null gpatch -g0 -p0 --dry-run <"${patch}" &> "${T}/autoepatch.$$.${patchname}.log" || \ return 1 ebegin " Applying ${patchname} ..." patch -g0 -p0 --no-backup-if-mismatch "${patch}" &> "${T}/autoepatch.$$.${patchname}.log" ret=$? eend ${ret} popd &>/dev/null return ${ret} else gpatch -g0 --dry-run "${target}" "${patch}" &> "${T}/autoepatch.$$.${patchname}.log" || \ return 1 ebegin " Applying ${patchname} ..." patch -g0 --no-backup-if-mismatch "${target}" "${patch}" &> "${T}/autoepatch.$$.${patchname}.log" ret=$? eend ${ret} popd &>/dev/null return ${ret} fi # Should never happen return 1 }