#!/bin/bash
set -eo pipefail

GITUSER=${GITUSER:-git}
GITHOME="/home/$GITUSER"
SELF=`which $0`

case "$1" in

# called by sshd on each `git push`
  run) 
    export RECEIVE_USER=$2
    export RECEIVE_FINGERPRINT=$3
    # ssh provides the original requested command in $SSH_ORIGINAL_COMMAND
    SSH_ORIGINAL_COMMAND="$(echo $SSH_ORIGINAL_COMMAND | sed 's/\///g' )" # remove any '/'s
    export RECEIVE_REPO="$(echo $SSH_ORIGINAL_COMMAND | awk '{print $2}' | perl -pe 's/(?<!\\)'\''//g' | sed 's/\\'\''/'\''/g')"
    REPO_PATH="$GITHOME/$RECEIVE_REPO"
    if [ ! -d $REPO_PATH ]; then
      mkdir -p $REPO_PATH
      cd $REPO_PATH
      git init --bare > /dev/null
    fi
    cd $GITHOME
    PRERECEIVE_HOOK="$REPO_PATH/hooks/pre-receive"
    # inject the hook below
    cat > $PRERECEIVE_HOOK <<EOF
#!/bin/bash
cat | $SELF hook
EOF
    chmod +x $PRERECEIVE_HOOK
    git-shell -c "$SSH_ORIGINAL_COMMAND"
    # if we're processing a receive-pack on an existing repo, run a build
    if [[ $SSH_ORIGINAL_COMMAND == git-receive-pack* ]] && \
       [[ -e $REPO_PATH/refs/heads/master ]]; then
      # SECURITY: git user runs the builder as root (for docker access)
      sudo $GITHOME/builder $RECEIVE_USER $RECEIVE_REPO >&2
    fi
    ;;

# used internally
  hook)
    while read oldrev newrev refname
    do
      # Only run this script for the master branch. You can remove this 
      # if block if you wish to run it for others as well.
      if [[ $refname = "refs/heads/master" ]] ; then
 
        $GITHOME/receiver "$RECEIVE_REPO" "$newrev" "$RECEIVE_USER" "$RECEIVE_FINGERPRINT"  
 
        rc=$?
        if [[ $rc != 0 ]] ; then
          echo "      ERROR: failed on rev $newrev - push denied"
          exit $rc
        fi
      fi
    done
    #exit 1 # for debugging
    ;;

  *)
    echo "Usage: gitreceive <command> [options]"
    ;;
esac

