#!/bin/sh -eu
#
# Quick commandline tool for fetching and/or merging github pull requests.
#
# Steps for use:
# 
# Once per computer or user, depending on location:
#     Install the program `jq`; debian package name `jq`
#
#     Place this in the system directory shown by `git --exec-path` or in any
#     directory listed on your $PATH, typically including $HOME/bin
#
#     You can (re)name it what you like, except that the name must begin
#     "git-".  If the script name includes "pull" or "merge", invoking it will
#     do a merge.  Otherwise, it will do a "fetch", leaving the branch for you
#     to inspect at FETCH_HEAD
#
#     (you can create the second copy with e.g. `ln -s`)
#
# Once for each clone:
#     Configure the github project, e.g.,
#         git config github.project linuxcnc/linuxcnc
# 
# To merge or fetch an individual pull request, just specify it by number:
#     git merge-pr 144
#
# If you put a copy / symlink as git-fetch-pr, you can also
#     git fetch-pr 144
#
# To act on a pull request associatred with another fork of this project,
# specify the name of the fork:
#
#     git fetch-pr jepler/linuxcnc#37
#
# This script does NOT check that you are merging the pull request to the
# branch requested on github.
#
# License: CC0 https://creativecommons.org/share-your-work/public-domain/cc0/
#          Also commonly called "Public Domain"

if ! type jq 2>&1 > /dev/null; then
    echo 1>&2 "This script requires the commandline json decoder 'jq'."
    if [ -e /etc/debian_version ]; then
        echo 1>&2 "This is part of the debian package 'jq'."
    fi
    exit 100
fi

project="`git config github.project || true`"
gitdir="`git rev-parse --git-dir || true`"

if [ -z "$gitdir" ]; then
    echo 1>&2 'This command needs to be executed inside a git tree'
    exit 99
fi
gitdir="`readlink -f "$gitdir"`"

if [ $# -ne 1 ]; then
    echo 1>&2 'Specify a pull request to act on, e.g., 33 or user/repo#33'
    exit 99
fi

num="$1"; shift
case "$num" in
(*\#*)
    project="${num%%#*}"; num="${num##*#}";
esac
if [ -z "$project" ]; then
    echo 1>&2 'Either specify the fork on the commandline (user/repo#number)'
    echo 1>&2 'or configure the project (git config github.project user/repo)'
    exit 99
fi
t="$gitdir/prinfo.js"
# GET /repos/:owner/:repo/pulls/:number
curl -s -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/$project/pulls/$num > $t

cloneurl="`jq -r .head.repo.clone_url "$t"`"
if [ "$cloneurl" = "null" ]; then 
    message="`jq -r .message "$t"`"
    echo 1>&2 'Failed to retrieve pull request information.'
    if [ "$message" != "null" ]; then
        echo 1>&2 "Github says: $message"
    fi
    echo 1>&2 "The full json response may be found at $t"
    echo 1>&2 "(until the next run of this script)"
    exit 98
fi
ref="`jq -r .head.ref "$t"`"

case "$0" in
(*pull*|*merge*)
    git pull --no-ff "$cloneurl" "$ref" ;;
(*)
    git fetch "$cloneurl" "$ref"
esac
rm "$t"
