pull-request.sh

Sun, 06 Jul 2014 20:46:36 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sun, 06 Jul 2014 20:46:36 +0300
changeset 9
7e8ccf76a84d
parent 7
7dbc04a61376
permissions
-rwxr-xr-x

- added various safeguards to pullreq

#!/bin/bash
hg log -r tip >/dev/null || exit 1

if [ -z "$(which curl)" ]
then
	echo "no curl installed" >/dev/stderr
	exit 1
fi

# Get path to this script
pushd $(dirname $0) >/dev/null
	selfpath=$(dirname $(readlink $0))
popd >/dev/null

# What's the upstream?
# TODO: can this be dynamically retrieved from bitbucket?
upstream=$(hg paths upstream |rev |cut -d '/' -f 1,2 |rev)

if [ -z "$upstream" ]
then
	echo "cannot find upstream! Please set the 'upstream' path in .hg/hgrc" >/dev/stderr
	exit 1
fi

echo "upstream is $upstream"

# Get all heads and filter merges out since we don't generally want to post
# pull requests for those.
# allheads=$(hg heads --template '{node}@{parents}\n' |sed 's@ @#@g')
heads=$(hg heads --template '{node}\n')
i=0

#for head in $allheads
#do
#	if [ "$(echo $head |sed 's@#@ @g' |wc -w)" -le "1" ]
#	then
#		heads="${heads}$(echo $head |cut -f 1 -d '@') "
#	fi
#done

#if [ -z "$allheads" ]
#then
#	echo "No non-merge heads. Nothing to do."
#	exit 0
#fi

numheads=$(echo $heads |wc -w)

# Ask the user which head to request pull of. We do this even if there is just
# one head, to give the user a chance to review exactly what is being submitted.
echo "There are $numheads heads:"

for head in $heads
do
	let i+=1
	bookmarksblurb=""
	tmpfile=$(tempfile)
	hg log -r $head --template '{bookmarks}\n{desc}\n' >$tmpfile
	bookmarks=$(head -n1 $tmpfile)
	title=$(tail -n1 $tmpfile)
	rm $tmpfile

	if [ -n "$bookmarks" ]
	then
		bookmarksblurb=" [${bookmarks}]"
	fi

	echo "[${i}] $(echo $head |head -c 8)${bookmarksblurb}: $title"
done

head_index=-1
while [ "$head_index" -le "0" -o "$head_index" -gt "$numheads" ]
do
	echo -n "Which head? "
	read head_index
done

# Data for the pull request
head=$(echo $heads |cut -d ' ' -f $head_index)
title=$(hg log -r ${head} -r tip --template '{desc}')
source_repo=$(hg paths default |rev |cut -d '/' -f 1,2 |rev)

titlefile=$(tempfile)
echo "$title" >$titlefile
vim $titlefile
title=$(cat $titlefile)

if [ -z "$title" ]
then
	echo "no title given"
	exit 1
fi

# Ensure history is compressed..
upstream_tip=$(hg log -r upstream_tip --template '{node}\n')
parents=$(hg log -r $head --debug --template '{parents}\n')
p1=$(hg log -r $(echo $parents |cut -f 1 -d ' ') --template '{node}\n')
p2=$(hg log -r $(echo $parents |cut -f 2 -d ' ') --template '{node}\n')

if [ "$p1" != "$upstream_tip" -a "$p2" != "$upstream_tip" ]
then
	echo -n "history isn't compressed! compress now? [y/n] "
	read answer
	if [ "$answer" = "y" ]
	then
		bookmarks=$(hg log -r $head --template '{bookmarks}')
		oldhead=$head
		hg up -r upstream_tip &&
			hg revert --all -r $head &&
			hg commit -m "$title" || exit 1
		head=$(hg id -i)
		hg bookmarks -f $bookmarks
		hg up -r $oldhead && hg commit -m "- closed head $oldhead" --close-branch && hg up -r $head
	fi
fi

# Ensure the head is pushed!
if [ -n $( hg outgoing --template '{node}\n' 2>/dev/null |grep $head ) ]
then
	echo -en "$head is not pushed!\npush now? [y/n] "
	read answer
	if [ "$answer" != "y" ]
	then
		echo "abort: head is not pushed"
		exit 1
	fi

	hg push -r $head -f
fi

echo "Requesting pull of $head"

# Get the JSON template and fill in the values
json=$(cat $selfpath/pullrequest_template.json \
	|sed "s@{{TITLE}}@${title}@" \
	|sed "s@{{SOURCE_REPO}}@${source_repo}@" \
	|sed "s@{{HEAD}}@${head}@")

# Get bitbucket credentials
echo -n "username: "
read username
echo -n "password: "
read -s password
echo

response=$(tempfile)

# Post the pull request.
curl \
	-X POST \
	-H "Content-Type: application/json" \
	-u "${username}:${password}" \
	-d "$json" \
	-o "$response" \
	"https://api.bitbucket.org/2.0/repositories/${upstream}/pullrequests" \
	>/dev/stdout 2>&1

mercurial