#!/bin/bash
# Desc: Creates git bundles from git repos in current working directory,
#   saving them to $outDir.
# Usage: bkBundleDir.sh
# Output: .bundle files in ./archive/ directory.

#==BEGIN Define functions==
yell() { echo "$0: $*" >&2; } # Yell, Die, Try Three-Fingered Claw technique; # Ref/Attrib: https://stackoverflow.com/a/25515370
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }
dateTimeShort(){
    # Desc: Timestamp without separators (YYYYmmddTHHMMSS+zzzz)
    # Usage: dateTimeShort ([str date])
    # Version 1.1.1
    # Input: arg1: 'date'-parsable timestamp string (optional)
    # Output: stdout: timestamp (ISO-8601, no separators)
    # Depends: yell
    local argTime timeCurrent timeInput timeCurrentShort

    argTime="$1";
    # Get Current Time
    timeCurrent="$(date --iso-8601=seconds)" ; # Produce `date`-parsable current timestamp with resolution of 1 second.
    # Decide to parse current or supplied date
    ## Check if time argument empty
    if [[ -z "$argTime" ]]; then
	## T: Time argument empty, use current time
	timeInput="$timeCurrent";
    else
	## F: Time argument exists, validate time
	if date --date="$argTime" 1>/dev/null 2>&1; then
	    ### T: Time argument is valid; use it
	    timeInput="$argTime";
	else
	    ### F: Time argument not valid; exit
	    yell "ERROR:Invalid time argument supplied. Exiting."; exit 1;
	fi
    fi
    # Construct and deliver separator-les date string
    timeCurrentShort="$(date -d "$timeInput" +%Y%m%dT%H%M%S%z)";
    echo "$timeCurrentShort";
} # Get YYYYmmddTHHMMSS±zzzz
#==END Define functions==


#==BEGIN Define static vars==
scriptStartDir="$(pwd)"; # Note current working directory (where git repos should be located)
outDir="$scriptStartDir/archive/"; # Specify where .bundle files should be written
#==END Define static vars==


#==BEGIN Create Git Bundles==
#===BEGIN Create output dir if necessary===
if [ ! -d "$outDir" ]; then
    mkdir -p "$outDir";
    yell "STATUS:Created output directory for bundles:$outDir";
fi;
#===END Create output dir if necessary===


#===BEGIN Loop through dirs===
for dir in ./*/ ; do  # cycle through dirs
    (
	pushd "$dir" 1>/dev/null 2>&1; # Enter dir
	if [ -d ./.git ]; # Check if git repo by seeing if `.git` subdir exists.
	then
	    yell "DEBUG:========================";
	    yell "DEBUG:dir:$dir";
	    dirName="$(basename "$dir")";
	    yell "DEBUG:dirName:$dirName";
	    #git status -s;
	    outFileName="$(dateTimeShort)".."$dirName".bundle;
	    yell "DEBUG:outFileName:$outFileName";
	    outFilePath="$outDir""$outFileName";
	    yell "DEBUG:outFileName:$outFilePath";
	    git bundle create "$outFilePath" --all;
	    if [ $? -eq 0 ]; then yell "STATUS:git bundle created at:$outFilePath"; fi;
	else
	    yell "ERR:No .git dir: "$(pwd)
	fi;
	popd 1>/dev/null 2>&1;
    );
done
#===END Loop through dirs===
#==END Create Git Bundles==
