#!/bin/sh

# Main dependencies: aptly, grep, awk, sed, date
# Debug dependencies: time

# This shell script was written in order to help you to update your mirrors
# every day via crontab. All you need is to name your mirrors in the appropriate
# format: '$release/$component';

# For example, do this:
# % aptly mirror create sid/main http://mirror.yandex.ru/debian/ sid main
# % aptly mirror create sid/contrib http://mirror.yandex.ru/debian/ sid contrib

# When you run this script it does:
# 1) update all your mirrors
# 2) *drop* *all* your publications and snapshots
# 3) create new snapshots and publish them

# It's originally written by Dmitrii Kashin <freehck@freehck.ru>, and is
# distributed under GNU GPLv2[1]. Fell free to improve it.

set -e

usage () {
    cat <<EOF
repo-update.sh [-d] [-g <gpg-key-passphrase>] [-l <log-file>]
  
-d	Activates debug mode.
-g	Set a passphrase for your gpg key (it can be useful if you run script
        with cron.
-l	File to store log. Type '-' for output to screen.
EOF
}

# Defaults:
SCRIPT="$0"
LOGFILE="$HOME/.aptly/repo-update.log"
SHELL=/bin/sh
PROMPT="%"
DATE=`date +%F`
SUFFIX="$DATE"
GPG_PASSWD=""

while getopts hdg:l: option
do
    case "$option" in
        d) DEBUG=1;;
        g) GPG_PASSWD="$OPTARG";;
	l) LOGFILE="$OPTARG";;
	h) usage; exit 0;;
	*) usage; exit 1;;
    esac
done

if [ "x$LOGFILE" = "x-" ]
then
    TO_LOGFILE=""
else 
    TO_LOGFILE=">>$LOGFILE"
fi

if [ $DEBUG -eq 1 ]
then
    WITH_TIMER=time
else
    WITH_TIMER=
fi

# Additional functions

logger () {
    STR=$1
    CMD=$(echo "echo \"$STR\" $TO_LOGFILE" | sed 's/\$/\\\$/g' | sed "s/$GPG_PASSWD/\*\*\*/g")
    echo $CMD | $SHELL
}

# update all mirrors
cmd_update_mirrors () {
    CMD_MIRRORS_UPDATE="for mirror in \$(aptly mirror list -raw); do aptly mirror update \$mirror $TO_LOGFILE; done"
    #CMD_MIRRORS_UPDATE="aptly mirror list -raw | xargs -n 1 -r aptly mirror update $TO_LOGFILE"
    logger "$PROMPT $CMD_MIRRORS_UPDATE"
    echo "$CMD_MIRRORS_UPDATE" | $WITH_TIMER $SHELL; echo
}

# Create snapshots for each mirror with the same name and a new SUFFIX
cmd_snapshots_create () {
    CMD_SNAPSHOTS_CREATE="for mirror in \$(aptly mirror list -raw); do aptly snapshot create \$mirror-$DATE from mirror \$mirror $TO_LOGFILE; done"
    #CMD_SNAPSHOTS_CREATE="aptly mirror list -raw | xargs -n 1 -I{} aptly snapshot create {}-\"$SUFFIX\" from mirror {} $TO_LOGFILE"
    logger "$PROMPT $CMD_SNAPSHOTS_CREATE"
    echo "$CMD_SNAPSHOTS_CREATE" | $WITH_TIMER $SHELL; echo
}

# Drop all publications made previous time
cmd_publications_drop () {
    # TODO: learn with author whether it's normal with the dot in the first field; I suppose it's a bug
    CMD_PUBLICATIONS_DROP="for publication in \$(aptly publish list -raw | awk '{print \$2}'); do aptly publish drop \$publication $TO_LOGFILE; done"
    #CMD_PUBLICATIONS_DROP="aptly publish list -raw | awk '{print \$2}' | xargs -n 1 -r aptly publish drop $TO_LOGFILE"
    logger "$PROMPT $CMD_PUBLICATIONS_DROP"
    echo "$CMD_PUBLICATIONS_DROP" | $WITH_TIMER $SHELL; echo
}

# Drop all snapshots made previous time
cmd_snapshots_drop () {
    CMD_SNAPSHOTS_DROP="for snapshot in \$(aptly snapshot list -raw); do aptly snapshot drop \$snapshot $TO_LOGFILE; done"
    #CMD_SNAPSHOTS_DROP="aptly snapshot list -raw | xargs -n 1 -r aptly snapshot drop $TO_LOGFILE"
    logger "$PROMPT $CMD_SNAPSHOTS_DROP"
    echo "$CMD_SNAPSHOTS_DROP" | $WITH_TIMER $SHELL; echo
}

# Publish & sign all the mirrors
cmd_publish () {
    # Run berserk, spreading fear and pain!
    CMD_PUBLISH=$(aptly mirror list -raw | awk -F/ "{targets[\$1]=targets[\$1]\" \"\$2;} END{for (tar in targets) print tar, targets[tar];}" | awk "{release=\$1; comp=snapshots=\"\"; for(i=2; i<=NF; i++) {(comp!=\"\") ? comp=comp\",\"\$i : comp=\$i; snapshots=snapshots\" \"release\"/\"\$i\"-$SUFFIX\"}; print \"aptly publish snapshot -distribution=\"release\" -component=\"comp\" -passphrase=$GPG_PASSWD \"snapshots\" $TO_LOGFILE\"; }")
    logger "$PROMPT $CMD_PUBLISH"
    echo "$CMD_PUBLISH" | $WITH_TIMER $SHELL; echo
}


logger "Script $SCRIPT's started at $(LANG=C date)"
cmd_update_mirrors
cmd_publications_drop
cmd_snapshots_drop
cmd_snapshots_create
cmd_publish

exit 0;

# [1] http://www.gnu.org/licenses/gpl-2.0.html