From ea3c2837b880e624d698c1c7687f227eb4da1078 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sat, 5 Jul 2014 13:54:00 +0200 Subject: gerrit-add-reviewers: helper to add reviewers for commits Originally I wanted it to be a git-review post-review hook, but there seems to be no way to get the most recently pushed commits. --- git/gerrit-add-reviewers | 131 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100755 git/gerrit-add-reviewers diff --git a/git/gerrit-add-reviewers b/git/gerrit-add-reviewers new file mode 100755 index 0000000..a9d6347 --- /dev/null +++ b/git/gerrit-add-reviewers @@ -0,0 +1,131 @@ +#!/bin/bash +# Finds commits with a review tag ("R=foo@example.com") and adds them as +# gerrit reviewer. +# +# Author: Peter Wu +# http://stackoverflow.com/q/24576855/427545 +# +# Requirements: git, awk, ssh, bash + +cd "$(git rev-parse --show-toplevel)" + +user= +host= +port=29418 +project= + +# Load host from gitreview file if any +[ ! -f .gitreview ] || +eval $(awk -F= ' +$1 == "host" && $2 ~ /^[a-zA-Z0-9][a-zA-Z0-9.-]*$/ { print "host=" $2 } +$1 == "port" && $2 ~ /^[0-9]{1,5}$/ { print "port=" $2 } +$1 == "project" && $2 ~ /^[a-zA-Z0-9._][a-zA-Z0-9._-]*$/ { print "project=" $2 } +' .gitreview) + +# Load settings from git config +eval $(git remote -v show -n | +awk -vorighost=$host '/fetch\)$/ && $2 ~ /^ssh:/ { + split($2, url, /[/:@]+/); + + # Apply settings on first result, or if the host matches + if (!got_one || orighost == url[3]) { + if (url[2] ~ /^[a-zA-Z0-9][a-zA-Z0-9.-]*$/) + print "user=" url[2]; + if (url[3] ~ /^[a-zA-Z0-9][a-zA-Z0-9.-]*$/) + print "host=" url[3]; + if (url[4] ~ /^[0-9]{1,5}$/) + print "port=" url[4]; + got_one = 1; + } +}') + +find_reviewers() { + local commit=$1 + + git show --no-patch --format=%b "$commit" | + awk -F= '/^R=[a-zA-Z0-9@._+-]+$/ { print $2 }' +} + +set_reviewer() { + local cmd reviewer + local commit=$1 # Commit or Change-Id + shift # Remaining arguments: reviewers + + # https://review.openstack.org/Documentation/cmd-set-reviewers.html + cmd='gerrit set-reviewers' + [ -z "$project" ] || cmd="$cmd --project $project" + for reviewer; do + cmd="$cmd -a $reviewer" + done + cmd="$cmd -- $commit" + + echo "$cmd" >&2 + ssh -p $port "$user@$host" "$cmd" +} + +check_commits() { + local revlist=$1 commits count=0 retval=0 + + # One is not going to push that many commits/reviews at a time... + commits="$(git rev-list --reverse --max-count=100 $revlist --)" || return 1 + + if [ -z "$commits" ]; then + echo "No commits found" >&2 + return 1 + fi + + for commit in $commits; do + reviewers=$(find_reviewers $commit) + if [ -n "$reviewers" ]; then + echo "Adding reviewers for $commit..." >&2 + if ! set_reviewer $commit $reviewers; then + echo >&2 + echo "Run 'git review' if you get a 'no such change' error" >&2 + retval=1 + break + fi + ((count++)) + fi + done + + printf 'Touched %d commits' $count >&2 + if [ $retval -eq 0 ]; then + echo . >&2 + else + echo ", but stopped due to an error" >&2 + fi + + return $retval +} + +if [ -z "$user" ] || [ -z "$host" ]; then + echo "Warning: gerrit is not configured" >&2 + exit 1 +fi + +case ${0##*/} in +post-review) + # TODO + # maybe read https://review.openstack.org/Documentation/cmd-query.html + # if pre: + # create temp file with possibly unprocessed commits + echo "$0: Not implemented" >&2 + ;; +pre-review) + # TODO + # elif post: + # read temp file + # for each reviewer in temp file: + # ssh user@host -p port 'gerrit command to set reviewer' + echo "$0: Not implemented" >&2 + ;; +*) + if [[ $1 == *..* ]]; then + check_commits "$1" + else + echo "Usage: $0 " >&2 + echo "To review changes on this branch since master: $0 master.." >&2 + exit 1 + fi + ;; +esac -- cgit v1.2.1