Created
January 28, 2014 22:00
-
-
Save beekhof/8677396 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 [email protected]:pacemaker/rhel $upstream | |
$git remote add upstream [email protected]: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