summaryrefslogtreecommitdiff
path: root/git-pull-request.sh
blob: b3eb9dff00361fee016856090c0be9f333fa6d25 (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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/bin/bash
# Note, yes, this is a bash script, don't expect it to work with dash or zsh

SUBDIRECTORY_OK=Yes
OPTIONS_KEEPDASHDASH=Yes
OPTIONS_SPEC="\
git pull-request [options] <cmd> [args]

Available sub-commands are:

list       List pull requests along with their status
create     Create a new pull request
merge      Merge a given pull request into your current branch
needs-work Indicate a pull request needs additional work before merging
reject     Reject a pull request
archive    Archive a pull request

--
 General Options
q,quiet     Be less verbose
g,git       Show the git commands being run behind the curtain

 List Options
H,heads     Show the non-archived pull requests
A,archive   Show the archived pull requests
p,pattern=  Specify a regexp to match for which pull requests to show
"

. git-sh-setup

# Cmdline options
# GIT_QUIET defined in git-sh-setup and is for 'say'
# GIT_SHOWCMD if 1 will show any sub-executed git commands
GIT_SHOWCMD=0

while test $# != 0
do
        case "$1" in
	-q)     GIT_QUIET=1 ;;
	-g)     GIT_SHOWCMD=1 ;;
	-H)     SHOW_HEADS=1 ;;
        -A)     SHOW_ARCHIVE=1 ;;
        -p)     SHOW_PATTERN="$2"; shift ;;
        --) shift; break;;
        *)      usage ;;
        esac
        shift
done

SUBCMD="$1"
shift

if test "x$SUBCMD" = "x"; then
  SUBCMD="list"
fi

#############################################################################
##  Utility functions  ######################################################
#############################################################################

rgit ()
{
    test "x$GIT_SHOWCMD" = "x1" && echo >&2 "+ git $*"
    git "$@"
}

find_requests ()
{
    local SUB
    SUB="$1"
    test "x$SUB" = "x" && SUB="heads"
    rgit show-ref | sane_grep "refs/pull-requests/${SUB}/.*__meta\$" | \
	sed -e 's!.* refs/pull-requests/'"${SUB}"'/!!' | sed -e 's/__meta$//'
}


load_meta_from ()
{
    local SHA
    SHA="$1"
    
    unset -v METADATA
    declare -g -A METADATA
    METADATA[META_SHA]="$SHA"
    
    local METATEXT
    METATEXT=$(rgit cat-file -p "$SHA":pull-request.meta | \
	sed -e's/=/ /')

    if test "x$METATEXT" = "x"; then
	echo >&2 Unable to read metadata from "$SHA":pull-request.meta
	exit 128
    fi

    while read KEY VALUE; do
	METADATA["${KEY}"]="${VALUE}"
    done <<<"${METATEXT}"

    local BAD
    for REQ in STATE COMMIT ONTOP LANDINTO; do
	if test "x${METADATA[${REQ}]}" = "x"; then
	    echo >&2 "Reading ${SHA}:pull-request.meta: Metadata lacks $REQ"
	    BAD=1
	fi
    done
    test "x$BAD" = "x" || exit 1
}

first_commit_on ()
{
    rgit rev-list --reverse "$1" | head -n 1
}

summarise_meta_at ()
{
    local PR SHA BRANCH
    PR="$1"
    SHA="$2"
    BRANCH="$3"
    
    load_meta_from "$SHA"

    echo -ne "${PR}\t${METADATA[STATE]}\t"
    echo $(rgit log --pretty="format:%s" $(first_commit_on "$SHA"))
}

summarise_meta ()
{
    local COMMIT BRANCH
    while read COMMIT BRANCH; do
	summarise_meta_at "$1" "$COMMIT" "$BRANCH"
    done <<<$(rgit show-ref "$1"__meta)
}

#############################################################################
##  Command implementations  ################################################
#############################################################################

cmd_list () {
    test "x$SHOW_HEADS$SHOW_ARCHIVE" = "x" && SHOW_HEADS=1
    local GREP
    test "x$SHOW_PATTERN" = "x" || GREP="| sane_grep '$SHOW_PATTERN'"
    local META_HEADS META_ARCHIVE
    test "x$SHOW_HEADS" = "x1" && META_HEADS=$(find_requests heads ${GREP})
    test "x$SHOW_ARCHIVE" = "x1" && META_ARCHIVE=$(find_requests archive ${GREP})

    METAS="${META_HEADS} ${META_ARCHIVE}"
    if test "x$METAS" = "x "; then
	say "No pull requests found"
	exit 1
    else
	for META in ${METAS}; do
	    summarise_meta $META
	done
    fi
}

#############################################################################
##  Command invocation  #####################################################
#############################################################################

if declare -F "cmd_${SUBCMD}" >/dev/null 2>/dev/null; then
    "cmd_${SUBCMD}"
else
    echo >&2 $0: Unknown sub-command: $SUBCMD
    usage
fi

exit 0