#!/bin/sh

GL_PACKAGE_CONF=/etc/gitolite
# must be the same as the value for the same variable in
# $GL_PACKAGE_CONF/example.gitolite.rc.  Sorry about the catch-22 :)

# TODO need to fix for portability to ksh and so on
# TODO need to get the version in there somehow

# This program is meant to be completely non-interactive, suitable for running
# server-side from a "post RPM/DEB install" script, or manually by users.

# usage:
#   $0 [foo.pub]

# The pubkey filename must end with ".pub" and is mandatory when you first run
# this command.  Otherwise it is optional, and can be used to override a
# pubkey file if you happen to have lost all gitolite-access to the repos (but
# do have shell access via some other means)

# ----------------------------------------------------------------------
#   local functions
# ----------------------------------------------------------------------

die() { echo "$@" >&2; exit 1; }

get_rc_val() {
    `dirname $0`/gl-query-rc $1
}

# ----------------------------------------------------------------------
#   tempdir setup
# ----------------------------------------------------------------------

TEMPDIR=`perl -MFile::Temp -l -e 'print File::Temp::tempdir("tmp.XXXXXXXXXX", TMPDIR => 1);'`
export TEMPDIR
trap "/bin/rm -rf $TEMPDIR" 0

# ----------------------------------------------------------------------
#   argument handling
# ----------------------------------------------------------------------

# save arguments for use in commit message later
args="$*"

if [ "$1" = "-h" ]
then
    echo Usage:
    echo "  gl-setup [-q] [-q] [YourName.pub]       # ssh mode"
    echo "  gl-setup [-q] [-q] [YourName]           # http mode"
    echo
    echo "Please see 'appendix d' in doc/install.mkd for more.  (Online at"
    echo "  http://sitaramc.github.com/gitolite/install.html#gl-setup)"
    exit 1
fi

# quiet mode; only used to suppress popping up an editor on a new rc file
if [ "$1" = "-q" ]
then
    shift
    quiet=1
fi

# extra quiet mode (second '-q'); suppress the lint check at the end
if [ "$1" = "-q" ]
then
    shift
    nolint=1
fi

# ----------------------------------------------------------------------
#   get the admin_name and (usually) the pubkey file name
# ----------------------------------------------------------------------

if [ -n "$GITOLITE_HTTP_HOME" ]
then
    HOME=$GITOLITE_HTTP_HOME
    admin_name=$1
else
    pubkey_file=$1
    admin_name=
    if [ -n "$pubkey_file" ]
    then
        echo $pubkey_file | grep '.pub$' >/dev/null || die "$pubkey_file must end in .pub"
        [ -f $pubkey_file ] || die "cant find $pubkey_file"
        admin_name=` basename $pubkey_file .pub`
        echo $admin_name | grep '@' >/dev/null && die "please don't use '@' in the initial admin name"
    fi
fi

# ----------------------------------------------------------------------
#   report changes to rc file (for manual fixing) or setup a new rc file
# ----------------------------------------------------------------------

export GL_RC
GL_RC=`get_rc_val GL_RC 2>/dev/null`
[ -z "$GL_RC" ] && GL_RC=$HOME/.gitolite.rc

if [ -f $GL_RC ]
then
    print_rc_vars() {
        perl -ne 's/^\s+//; s/[\s=].*//; print if /^\$/;' < $1 | sort
    }
    print_rc_vars $GL_PACKAGE_CONF/example.gitolite.rc > $TEMPDIR/.newvars
    print_rc_vars $GL_RC                               > $TEMPDIR/.oldvars
    grep -f $TEMPDIR/.oldvars -v $TEMPDIR/.newvars > $TEMPDIR/.diffvars
    if [ -s $TEMPDIR/.diffvars ]
    then
        cp $GL_PACKAGE_CONF/example.gitolite.rc $HOME/.gitolite.rc.new
        echo new version of the rc file saved in $HOME/.gitolite.rc.new
        echo
        echo please update $GL_RC manually if you need features
        echo controlled by any of the following variables:
        echo ----
        sed -e 's/^/    /' < $TEMPDIR/.diffvars
        echo ----
    fi
else
    [ -n "$GITOLITE_HTTP_HOME" ] || [ -n "$pubkey_file" ] || die "looks like first run -- I need a pubkey file"
    [ -z "$GITOLITE_HTTP_HOME" ] || [ -n "$admin_name"  ] || die "looks like first run -- I need an admin name"

    cp $GL_PACKAGE_CONF/example.gitolite.rc $GL_RC
    if [ -z "$quiet" ]
    then
        printf "The default settings in the "rc" file ($GL_RC) are fine for most\n"
        printf "people but if you wish to make any changes, you can do so now.\n\nhit enter..."
        read i
        ${EDITOR:-vi} $GL_RC
    fi
fi

# ----------------------------------------------------------------------
#   setup ~/.ssh
# ----------------------------------------------------------------------

# setup ssh stuff.  We break our normal rule that we will not fiddle with
# authkeys etc., because in this case it seems appropriate
(
    cd $HOME
    mkdir -p .ssh
    chmod go-rwx .ssh
    touch .ssh/authorized_keys
    chmod go-w . .ssh .ssh/authorized_keys
)

# ----------------------------------------------------------------------
#   setup gitolite's env vars
# ----------------------------------------------------------------------

export GL_BINDIR
export REPO_BASE
export GL_ADMINDIR
GL_BINDIR=`  get_rc_val GL_BINDIR  `
REPO_BASE=`  get_rc_val REPO_BASE  `
GL_ADMINDIR=`get_rc_val GL_ADMINDIR`

# ----------------------------------------------------------------------
#   setup hooks, admindir, the admin repo
# ----------------------------------------------------------------------

gl-install -q

[ -f $GL_ADMINDIR/conf/gitolite.conf ] || {
    echo "
        repo    gitolite-admin
                RW+     =   $admin_name

        repo    testing
                RW+     =   @all
    " | cut -c9- > $GL_ADMINDIR/conf/gitolite.conf
   RERUN_GL_INSTALL=1
}
[ -n "$pubkey_file" ] && cp $pubkey_file $GL_ADMINDIR/keydir

touch $HOME/.ssh/authorized_keys
gl-compile-conf -q

# setup the admin repo
[ -n "$pubkey_file" ] || [ -n "$GITOLITE_HTTP_HOME" ] && { RERUN_GL_INSTALL=1; (
    cd $HOME; cd $REPO_BASE/gitolite-admin.git
    GIT_WORK_TREE=$GL_ADMINDIR; export GIT_WORK_TREE
    git add conf keydir
    git rm --cached conf/gitolite.conf-compiled.pm
    git config --get user.email >/dev/null || git config user.email $USER@`hostname`
    git config --get user.name  >/dev/null || git config user.name  "$USER on `hostname`"
    git diff --cached --quiet 2>/dev/null || git commit -am "gl-setup $args"
)
}

# now that the admin repo is created, you have to set the hooks properly; best
# do it by running install again
[ "$RERUN_GL_INSTALL" = 1 ] && gl-install -q

# ----------------------------------------------------------------------
#   lint check on ssh keys
# ----------------------------------------------------------------------

[ -z "$nolint" ] && {
    # the never-ending quest to help with bloody ssh issues...
    cd $GL_ADMINDIR/keydir
    [ -n "$pubkey_file" ] && $GL_BINDIR/sshkeys-lint -q -a $admin_name < $HOME/.ssh/authorized_keys
}

# ----------------------------------------------------------------------

exit 0
