apatch/apatch

121 lines
2.7 KiB
Bash
Executable file

#!/bin/sh
# output functions from abuild/functions.sh
NORMAL="\033[1;0m"
STRONG="\033[1;1m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
_prefix="${BLUE}${STRONG}apatch${NORMAL}:"
msg() {
local prompt="$GREEN>>> ${_prefix}"
printf "${prompt} %s\n" "$1" >&2
}
warning() {
local prompt="${YELLOW}>>> WARNING: ${_prefix}"
printf "${prompt} %s\n" "$1" >&2
}
error() {
local prompt="${RED}>>> ERROR: ${_prefix}"
printf "${prompt} %s\n" "$1" >&2
}
if [ ! -f APKBUILD ]; then
error "please run this in a package directory"
exit 1
fi
if [ "$1" == "" ]; then
echo "usage: apatch <patch name>"
exit 1
fi
set -e
msg "running abuild"
abuild clean fetch unpack default_prepare
# obtain builddir
startdir="$PWD"
srcdir="$startdir/src"
. APKBUILD
unset -f grep cut head git rm mv
[ -n "$builddir" ] || builddir="$srcdir/$pkgname-$pkgver"
patchpath="$startdir/$1"
for patch in $source; do
if [ "$patch" = "$1" ]; then
# if the patch was in source, it was already applied in prepare() above,
# but we want the original src to not have it, so we can get a full diff of
# its original changes + our new ones
(
msg "reversing $patch"
cd "$builddir"
patch -R -p1 < "$patchpath"
)
break
fi
done
header=""
if [ -f "$patchpath" ]; then
msg "patch exists, trying to extract existing message"
# try to extract the original header from the patch
patch_start=$(grep -En '^(diff --git|--- )' "$patchpath" | cut -d: -f1 | head -n 1)
header_file="/tmp/$(mktemp -u apatch.XXXXXX)"
head -n $(( patch_start - 1 )) "$patchpath" > "$header_file"
fi
(
cd "$builddir"
git init
git add .
git commit -m "$pkgver" >/dev/null
# if file exists, try to apply
if [ -e "$patchpath" ]; then
git apply --reject --whitespace=fix "$patchpath" || {
rejects="$(git status --porcelain | grep -F '??' | grep -F '.rej' | cut -c4-)"
if [ -n "$rejects" ]; then
warning "$1 partially applied with rejects"
for reject in $rejects; do
target="${reject%.rej}"
msg "trying to wiggle $target"
wiggle --merge --replace "$target" "$reject" || {
warning "could not merge $target, fix manually"
}
rm "$reject"
rm "$target.porig" # left by wiggle
done
else
warning "$1 failed to apply"
fi
}
fi
msg "you can edit now!"
$SHELL || true
git add .
msg "saving patch $1"
echo -n > "$patchpath" # empty the file first
if [ -n "$header_file" ]; then
mv "$header_file" "$patchpath"
fi
git diff --cached >> "$patchpath"
if [ ! -s "$patchpath" ]; then
msg "patch is empty, removing"
rm "$patchpath"
fi
rm -rf .git
)