summaryrefslogtreecommitdiff
path: root/git/gerrit-add-reviewers
blob: a9d6347f3d740678ab18c2f09bf1c99f7adc8c9b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/bin/bash
# Finds commits with a review tag ("R=foo@example.com") and adds them as
# gerrit reviewer.
#
# Author: Peter Wu <lekensteyn@gmail.com>
# 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 <revlist>" >&2
        echo "To review changes on this branch since master: $0 master.." >&2
        exit 1
    fi
    ;;
esac