#!/bin/bash

#
# Slurp - add everything, slurp into a WIP commit and push
#

warn() {
    echo "$@" >&2
}

die() {
    warn "$@"
    exit 2
}

usage() {
    die "usage: git slurp [--force-slurp] [--force-push] [pathspec]..."
}

allowed_slurp() {
    #
    # Is slurp allowed in this repo?
    #
    test -f "$ok_file"
}

allowed_push() {
    #
    # Is push allowed in this repo?
    #
    grep -qxF PUSH "$ok_file" 2>/dev/null
}

git_relative() {
    #
    # Convert pathspec $1 to git-root-based pathspec
    #
    # Also try to clean up path a bit; i.e. remove double slashes
    # or unnecessary trailing dot.
    #
    local path="$1"
    test -n "$GIT_PREFIX" && path="$GIT_PREFIX/$path"
    local full=$(readlink -m "$path")
    test "$full" = "$git_root" && echo . && return
    printf %s "${full#$git_root/}"
}

slurp1() {
    #
    # Slurp pathspec $1
    #
    local rel_pathspec      # relative to git root
    rel_pathspec=$(git_relative "$1")
    git add "$rel_pathspec"                         || die
    git commit -m "WIP slurp, $date: $rel_pathspec" || die
}

go_slurp() {
    #
    # Do the slurp for pathspecs $@
    #
    $force_slurp || allowed_slurp || die "you don't want this."
    local date=$(date -Isec)
    local pathspec
    for pathspec in "$@";
    do
        slurp1 "$pathspec"
    done
}

go_push() {
    #
    # Do the push (if allowed)
    #
    if $force_push || allowed_push;
    then
        git push
    fi
}

main() {
    local git_root
    local ok_file
    local force_slurp=false
    local force_push=false
    while true; do case $1 in
        --force-slurp)  force_slurp=true; shift ;;
        --force-push)   force_push=true;  shift ;;
        --)             shift; break ;;
        -*)             usage ;;
        *)              break ;;
    esac done
    test -n "$1" || set -- .
    git_root="$(git rev-parse --show-toplevel)" || die
    ok_file="$git_root/.git-slurp-ok"
    go_slurp "$@"
    go_push
}

main "$@"