Skip to content

Instantly share code, notes, and snippets.

@beekhof
Created January 28, 2014 22:00
Show Gist options
  • Save beekhof/8677396 to your computer and use it in GitHub Desktop.
Save beekhof/8677396 to your computer and use it in GitHub Desktop.
#!/bin/bash
fix=0
command=""
patches=""
while true ; do
case "$1" in
-\?) echo "$help"; exit 0; shift;;
-x) set -x; shift;;
out|log|push|pull|init|show|save|commit|report) command=$1; shift;;
patch|pick) command=patch; patches="$patches $2"; shift; shift;;
patch-list) command=patch; shift; patches="$patches $*"; break;;
fix) command=report; fix=1; shift;;
--help)
echo "$0 - A tool for working with rhel repos"
echo "init - create a git repo from the existing tarball and patch set"
echo "show - display pending patches"
echo "stash - save pending patches to file(s)"
echo "pick {hash} - import a patch from upstream"
echo "patch-list {hash} ... {hash} - import a list of patches from upstream"
echo "commit - correctly name and include pending patches into the build"
echo "report - check that all patches are commits in the git repo"
echo "fix - like report, but fix any problems"
echo "push - sync changes in RHEL branches to clusterlabs.org"
echo "pull - sync changes in RHEL branches from clusterlabs.org"
echo "log - show recent changes in RHEL branches"
exit 0;;
--) shift ; break ;;
"") break;;
*) echo "Unsupported option: $1"; exit 1;;
esac
done
spec=`ls -1tr *.spec | head -n 1`
branch=`git branch | grep '*' | awk '{print $2}'`
upstream=`dirname $PWD`/rhel-branches
git="git --git-dir=$upstream/.git"
start="$git merge-base origin/$branch HEAD"
verrel=`rhpkg verrel 2>&1`
while [ $? != 0 ]; do
if [ $PWD = "/" ]; then
echo "Cannot find the correct directory for rhpkg to operate on"
exit 1
fi
cd ..
verrel=`rhpkg verrel 2>&1`
done
function apply_patch() {
BUG=$1; shift
HASH=$1; shift
DESC=$1; shift
if [ $HASH = HEAD ]; then
HASH=`$git show --pretty="format:%h" | head -n 1`
fi
PATCH=`grep Patch $spec | grep -v Patch9[89]: | sed -e s/:.*// -e s/Patch// | awk '{print 1+$1}' | tail -n 1`
LAST_PATCH=`grep Patch $spec | grep -v Patch9[89]: | sed -e s/:.*// -e s/Patch// | awk '{print $1}' | tail -n 1`
name=`$git show --pretty=format:'%s' --quiet --abbrev-commit ${HASH}`
name=$(echo $name | tr ",;:/.\ _\-()\&\$'\"\*=" "___________________")
fin=1
while [ $fin -ne 0 ]; do
name=$(echo $name | sed -e 's/_\+/_/g' | tr 'A-Z' 'a-z')
name=$(echo $name | sed -e 's/_$//')
short=$(echo $name | sed -e 's/^[^_]*_//')
echo "$SUBJECT_LINE"
echo " [l]ong : $name"
echo " [s]hort: $short"
echo " [c]hop another word off"
echo " [e]dit"
echo
read -n1 -p "Use long or short name [l/s/c/e]? " foo
echo
if [ "$foo" = "s" ]; then
name=$short
elif [ "$foo" = "l" ]; then
:
elif [ "$foo" = "c" ]; then
name=$short
continue
elif [ "$foo" = "e" ]; then
read -p "Enter a new name: "
name=$REPLY
continue
else
continue
fi
fin=0
done
name="pcmk-${name}.patch"
if [ $BUG != $HASH ]; then
name="bz${BUG}-${name}"
fi
if [ -f "$name" ]; then
echo "$name exists!"
echo -n "Overwrite [y/N]? "
read -n1
echo
if [ "$REPLY" != "y" ]; then
echo "Giving up"
exit 1
fi
fi
$git show ${HASH} > ${name}
git add ${name}
if [ x$LAST_PATCH != x ]; then
after_source=`grep Patch${LAST_PATCH} $spec | head -n 1`
after_prep=`grep %patch${LAST_PATCH} $spec | head -n 1`
else
PATCH=1
after_source=`grep Source0 $spec | head -n 1`
after_prep=`grep %setup $spec | head -n 1`
fi
sed -i.sed "s@$after_source@$after_source\nPatch${PATCH}: ${name}@" $spec
sed -i.sed "s@$after_prep@$after_prep\n%patch${PATCH} -p1@" $spec
}
function commits_in_build()
{
do_fix=$1; shift
quiet=$1; shift
changes=""
fixed=0
echo -e "\n\n### Checking for unbuilt commits"
patches=`$git log --reverse --pretty=format:'%h' master..$branch`
for p in $patches; do
stop=0
if [ $stop = 0 ]; then
grep -q $p *.patch
if [ $? = 0 ]; then
for file in `grep -l $p *.patch`; do
grep -q $file $spec
if [ $? = 0 ]; then
test $quiet = 0 && echo "Found $p in $file"
stop=1
else
echo "Not built: Commit $p is found in $file but is not part of any builds"
fi
done
fi
fi
if [ $stop = 0 ]; then
h=`$git show $p | grep "cherry picked from commit" | tail -n 1 | sed s/.*commit// | sed s/\)//`
grep -q $h *.patch
if [ $? = 0 ]; then
for file in `grep -l $h *.patch`; do
grep -q $file $spec
if [ $? = 0 ]; then
test $quiet = 0 && echo "Found $p cherry-picked from $h in $file"
stop=1
else
echo "Not built: Commit $p cherry-picked from $h is found in $file but is not part of any builds"
fi
done
fi
fi
if [ $stop = 0 ]; then
if [ $do_fix = 0 ]; then
$git show --quiet --pretty=format:"Commit not in build: %h - %s" $p
else
fixed=1
log="`$git show --pretty=format:'%s' --date=relative --quiet --abbrev-commit ${p} | sed -e s/PE:/pengine:/`"
changes="$changes
- $log"
resolves=$(echo $log | grep -E "(Resolves:|bz[# \t]*[0-9]+)")
if [ -n "$resolves" ]; then
last_bug=$(echo $resolves | sed -e 's/.*[# \t]\+\([0-9]\+\).*/\1/g' )
fi
echo
while : ; do
echo -n "Bugzilla(s) for `$git show --pretty=format:'%s' --date=relative --quiet ${p}`"
if [ -n "$last_bug" ]; then
echo -n " [$last_bug]"
fi
read -p ": "
case $REPLY in
*[!0-9]*) echo "Invalid bug number: $REPLY";;
"") BUG=$last_bug; break;;
*) BUG=$REPLY; last_bug=$REPLY; break;;
esac
done
if [ -n "$BUG" ]; then
changes="${changes}
Resolves: rhbz#${BUG}"
else
BUG=$p
fi
apply_patch $BUG $p "$p"
fi
fi
done
if [ $fixed = 1 ]; then
COUNT=`grep "global specversion" $spec | awk '{print 1+$3}'`
sed -i.sed "s@global specversion.*@global specversion ${COUNT}@" $spec
if [ "x$changes" = x ]; then
changes="unknown changelog"
fi
rpmdev-bumpspec -c "$changes" -u "`git config --get user.name` <`whoami`@redhat.com>" -s $$ $spec
# Fix the versions
sed -i.sed "s@.$$1@@" $spec
sed -i 's/- $//' $spec
fi
}
if [ $command = init ]; then
if [ ! -e $upstream ]; then
git clone git@oss.clusterlabs.org:pacemaker/rhel $upstream
$git remote add upstream git@github.com:ClusterLabs/pacemaker.git
fi
fi
otherbranch=`$git branch | grep '*' | awk '{print $2}'`
if [ $branch != $otherbranch ]; then
$git branch -r | grep -q $branch
if [ $? != 0 ]; then
read -p "What version/hash should $branch start with? "
(cd $upstream && git checkout -b $branch $REPLY)
(cd $upstream && git push --set-upstream origin $branch )
else
(cd $upstream && git checkout $branch)
if [ $? != 0 ]; then
echo "Couldn't switch to upstream branch '$branch'"
exit 1
else
echo "Switched to upstream branch '$branch'"
fi
fi
fi
if [ $command = init ]; then
$git pull --rebase
elif [ $command = show ]; then
commits_in_build 0 1
elif [ $command = log ]; then
$git $command --pretty=format:'+ %an (%ar) %Cred%h%Creset: %s %C(bold blue)%d%Creset' --date=relative --abbrev-commit -M
elif [ $command = push ]; then
$git $command
elif [ $command = out ]; then
$git $command
elif [ $command = pull ]; then
( cd $upstream && git $command --rebase )
elif [ $command = stash ]; then
$git format-patch `$start`..
elif [ $command = patch ]; then
# Fetch to get patches for cherry picking
# Pull to pick up any queued patches
$git fetch --all
( cd $upstream && git pull --rebase )
for p in $patches; do
echo "Cherry picking $p"
( cd $upstream && git cherry-pick -x $p )
rc=$?
echo "Result $rc"
if [ $rc != 0 ]; then
read -p "Resolve and continue"
fi
done
commits_in_build 0 1
elif [ $command = commit ]; then
$git push
if [ $? != 0 ]; then
echo -e "\n\nThe are other pending patches, try a '`basename $0` pull' first\n"
exit 1
fi
commits_in_build 1 1
elif [ $command = report ]; then
echo -e "\n\n### Checking for patches not in Git"
patches=`grep Patch $spec | sed s/.*://`
for p in $patches; do
stop=0
known=1
if [ ! -e $p ]; then
echo "Patch not found: $p"
continue
fi
if [ $stop = 0 ]; then
c=`grep -e "^From " -e "^commit" $p | awk '{print $2}'`
if [ $? != 0 -o x"$c" = x ]; then
echo "Unsync'd patch: $p"
known=0
fi
fi
if [ $known = 1 ]; then
$git show --quiet --oneline $c >/dev/null 2>&1
if [ $? != 0 ]; then
echo "Unknown patch: $p $c"
known=0
stop=1
fi
fi
if [ $stop = 0 -a $known = 1 ]; then
$git log --pretty=format:"Found %H for $p" master..$branch | grep $c
if [ $? = 0 ]; then
stop=1
fi
fi
if [ $stop = 0 -a $known = 1 ]; then
$git log --grep $c --pretty=format:"Found %h cherry-picked from $c for $p" master..$branch | grep $c
if [ $? = 0 ]; then
stop=1
fi
fi
if [ $stop = 0 ]; then
if [ $fix = 1 ]; then
rc=0
echo "Importing $p into git (cherry picked from $c)"
if [ $known = 1 ]; then
( cd $upstream && git cherry-pick -x $c )
rc=$?
else
msg=$(grep Subject: $p | sed -e 's/Subject://' -e 's/PATCH.*] //')
if [ -z "$msg" ]; then
msg=$(echo $p | sed -e 's/.*pcmk-//' -e 's/.*pacemaker-//' -e 's/.patch//' -e 's/_/ /g')
fullp=$PWD/$p
( cd $upstream && patch -p1 < $fullp )
( cd $upstream && git commit -a -m "Import: $msg" )
$git show > $p
fi
fi
if [ $rc != 0 ]; then
fix=0
fi
fi
fi
done
commits_in_build 0 0
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment