From b815207e7ff9c3a380c897698891f38a57125351 Mon Sep 17 00:00:00 2001 From: Diego Elio Pettenò Date: Mon, 18 Dec 2006 09:45:47 +0000 Subject: Add first implementation of autoepatch; patches define a function to find which targets are to be patched, and autoepatch tries all the patches on them. There's a long list of TODOs to handle though. svn path=/trunk/; revision=5 --- autoepatch.sh | 63 ++++++++++++++++++++++++++++ lib/functions.sh | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+) create mode 100755 autoepatch.sh create mode 100644 lib/functions.sh diff --git a/autoepatch.sh b/autoepatch.sh new file mode 100755 index 0000000..3b43d87 --- /dev/null +++ b/autoepatch.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# 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 + +main() { + # To allow installing on any prefix, make sure that + # the prefix is actually set + local PREFIX="@PREFIX@" + [[ ${PREFIX//@/|} == "|PREFIX|" ]] && PREFIX="/usr" + + # When running out of SVN, load local modules and + # libraries only. + local basedir="$(dirname $0)" + [[ $0 == "${PREFIX}/bin/autoepatch.sh" ]] && \ + basedir="${PREFIX}/share/autoepatch" + + # Source baselayout functions.sh for einfo/ewarn and similar + # functions. If on an offset prefix, use the prefixed path. + [[ ${PREFIX} == "/usr" ]] && \ + source "/sbin/functions.sh" || \ + source "${PREFIX}/sbin/functions.sh" + + source "${basedir}/lib/functions.sh" + + [[ -z ${CHOST} ]] && CHOST="$(portageq envvar CHOST)" + [[ -z ${WORKDIR} ]] && WORKDIR="$(pwd)" + [[ -z ${T} ]] && T="/tmp" + + for patchset in "${basedir}"/patches/*; do + ( + source "${patchset}/${patchset##*/}.sh" + targets="$(patch_targets)" + [[ -z ${targets} ]] && exit 0 + + while read target; do + for patch in "${patchset}"/*.patch; do + echo $patch + try_patch "${target}" "${patch}" && break; + done + done <<<"${targets}" + + exit 0 + ) || eerror "Error in subshell" + done + + IFS="${save_IFS}" +} + +main diff --git a/lib/functions.sh b/lib/functions.sh new file mode 100644 index 0000000..0eaef13 --- /dev/null +++ b/lib/functions.sh @@ -0,0 +1,126 @@ +# 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 $? +} + +# 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}/autepatch.$$.${patchname}.log" || \ + return 1 + + ebegin " Applying ${patchname} ..." + patch -g0 -p0 --no-backup-if-mismatch "${patch}" &> "${T}/autepatch.$$.${patchname}.log" + ret=$? + eend ${ret} + + popd &>/dev/null + return ${ret} + else + gpatch -g0 --dry-run "${target}" "${patch}" &> "${T}/autepatch.$$.${patchname}.log" || \ + return 1 + + ebegin " Applying ${patchname} ..." + patch -g0 --no-backup-if-mismatch "${target}" "${patch}" &> "${T}/autepatch.$$.${patchname}.log" + ret=$? + eend ${ret} + + popd &>/dev/null + return ${ret} + fi + + # Should never happen + return 1 +} -- cgit v1.2.3-65-gdbad