summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Elio Pettenò <flameeyes@gentoo.org>2006-12-18 09:45:47 +0000
committerDiego Elio Pettenò <flameeyes@gentoo.org>2006-12-18 09:45:47 +0000
commitb815207e7ff9c3a380c897698891f38a57125351 (patch)
treea41468fa68d498d883cd2f5d7c9f93f288c148cf
parentAdd a patch for KDE's admindir to show that autoepatch can be used for more t... (diff)
downloadautoepatch-b815207e7ff9c3a380c897698891f38a57125351.tar.gz
autoepatch-b815207e7ff9c3a380c897698891f38a57125351.tar.bz2
autoepatch-b815207e7ff9c3a380c897698891f38a57125351.zip
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
-rwxr-xr-xautoepatch.sh63
-rw-r--r--lib/functions.sh126
2 files changed, 189 insertions, 0 deletions
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 | grep -q "Free Software Foundation" &>/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
+}