#!/usr/bin/env bash
# create software release
# =======================
PURPOSE="install iops utilities & dependencies on a linux system";
VERSION="2016-10-16-1476570292"
 AUTHOR="fidy@andrianaivo.org";


# SCRIPT HEADER
# =============

# -- auto: path variables
scriptSelf=$0;
if [[ "$scriptSelf" = "bash" ]];then INSTALLMODE=1
else
  INSTALLMODE=0
  scriptName=${scriptSelf##*/}; scriptCallDir=${scriptSelf%/*};
  cd $scriptCallDir; scriptFullDir=$PWD; scriptFullPath=$scriptFullDir/$scriptName;
  scriptTopDir=${scriptFullDir%/*}
fi
# -- /auto: path variables


# -- check: script requirements
# executables
scriptRequiredBinaries="awk date grep sed"
for bin in $scriptRequiredBinaries;
do
if ! ([[ -x "$bin" ]] 2>/dev/null || [[ -x "$(which $bin 2>/dev/null)" ]]);then
  echo -e "\033[31mERROR: the binary [$bin] is required but not found. Aborting...\033[0m"
  exit 99
fi
done
# -- /check: script requirements


# -- vars: runtime values
# - directory structure
tmpDir=${scriptTopDir}/temp.d/releases
[[ -d ${tmpDir} ]] || mkdir -p ${tmpDir}
# - log & tmp files
logFile=${tmpDir}/${scriptName}.log
outFile=${tmpDir}/${scriptName}.out
# - usage options & commands
usageOpts=$(grep ") *#OPTS#" $scriptFullPath | sed "s/).*OPTS#/	/")
usageCmds=$(grep ") *#CMDS#" $scriptFullPath | sed "s/).*CMDS#/	/")
# - verbosity
DEBUG=0;	function isDebug  { [[ $DEBUG  -ge ${1:-1} ]]; }
QUIET=0;	function isQuiet  { [[ $QUIET  -gt 0 ]]; }
FORCE=0;	function isForce  { [[ $FORCE  -gt 0 ]]; }
DRYRUN=0;	function isDryrun { [[ $DRYRUN -gt 0 ]]; }
#-- /vars: runtime values



# SCRIPT HELPERS
# ==============

# -- script usage
function printUsage   {
read -d '' USAGE <<daer
# $scriptName version $VERSION  (INSTALL-MODE:$INSTALLMODE)
# $PURPOSE

  Usage: $scriptName [OPTIONS] <COMMANDS>

AVAILABLE OPTIONS:
$usageOpts

AVAILABLE COMMANDS:
$usageCmds

daer
echo -e "\033[1m$USAGE\033[0m\n";
[[ -n "$1" ]] && exit ${1};
}
# -- /script usage


# -- /helper functions
# - default output functions
function printVersion { echo -e "\033[1m# $scriptName version $VERSION\033[0m\n"; [[ -n "$1" ]] && exit ${1}; }
function printOutput  { [[ -e $outFile ]] && out=$(cat $outFile); [[ -n "$out" ]] && echo -e "$out" || echo -e "NO OUTPUT"; }
function printTitle   { echo; msg="$*";linesno=$(( ${#msg} + 4 ));msglines=$(for i in `seq $linesno`;do echo -n "=";done);echo -e "$msglines\n# $msg #\n$msglines"; }
function printOut     { echo -en "$@"; }
function printOk      { echo -en "\033[32m$*\033[0m"; }
function printInfo    { echo -en "\033[34m$*\033[0m"; }
function printError   { echo -en "\033[31m$*\033[0m"; }
# - default exit functions
function exitError    { echo -e "\n\033[31m[$HOSTNAME] ERROR: ${1:-"Unknown Error"}. Exiting...\033[0m" 1>&2; exit ${2:-1}; }
function exitInfo     { echo -e "\n\033[34m[$HOSTNAME] INFO: ${1:-"Thank you for using $scriptName"}.\033[0m" 1>&2; exit ${2:-1}; }
# - custom minicheck functions
function isInternet    { curl -sI  --connect-timeout 5 http://64.15.113.150 >>$logFile; }
function isInstallmode { [[ $INSTALLMODE -eq 1 ]]; }
# - run command wrapper
function runCommand {
  txt="$1"; shift; cmd="$*";
  echo -en "=> $txt ... ";
  if isDryrun;then printInfo "\n--\n${cmd}\n--\n"; return; fi
  ${cmd} >$outFile 2>&1; rc=$?;
  if [[ $rc -eq 0 ]];then
    echo -e "[\033[32mdone\033[0m]"
  else
    echo -e "[\033[31merror\033[0m]\n--\n"
    printOutput
    return 1
  fi
}
# tasks to be executed on script interruption
function exitCleanUp  {
  printOut "* Script was interrupted by [${1:-"UNKNOWN"}]. Running cleanup tasks...\n";
  #[[ -f $scriptTmpFile ]] && rm -rf $scriptTmpFile;
}
# cross-unix file modification date
function getModTime { stat -c %Y $1 2>/dev/null || stat -f %m $1 2>/dev/null; }
# -- /helper functions




# SCRIPT MAIN
# ===========
# -- run cleanup function on interruption
trap "exitCleanup SIGHUP"  SIGHUP
trap "exitCleanUp SIGINT"  SIGINT
trap "exitCleanUp SIGTERM" SIGTERM


# print usage if no parameters provided (normal mode only)
[[ -z "$1" ]] && printUsage 0


# -- OPTIONS PARSING
options=""
 params=""
while [[ -n "$1" ]]
do
  case "$1" in
    -v|--version|version)#OPTS#
      options+="$1 "
      printVersion 0
      ;;
    -h|--help|help)#OPTS#
      options+="$1 "
      printUsage 0
      ;;
    -d|--debug)#OPTS#
      options+="$1 "
      DEBUG=1
      ;;
    -q|--quiet)#OPTS#
      options+="$1 "
      QUIET=1
      ;;
    -f|--force)#OPTS#
      options+="$1 "
      FORCE=1
      ;;
    -n|--dryrun)#OPTS#
      options+="$1 "
      DRYRUN=1
      ;;
    *)
      params+="$1 "
      ;;
  esac
  shift
done
scriptParameters="${options} ${params}"
scriptParameters="${scriptParameters%* }"

# beginn installation immediately
isInstallmode && echo "INSTALL MODE"

# print debug infos
isDebug && printInfo "# PARAMS: $scriptParameters\n"
isDebug && printInfo "$startMessages\n"


# -- ACTION PARSING
set -- $params
  case "$1" in

    show.output|out)#CMDS#
      printOk "VIEW LAST COMMAND OUTPUT ... \n"
      printOutput | less
      ;;

    self.show|show)#CMDS#[dirpath] show a tree view (default is topDir)
      dir=$scriptTopDir
      level="-L 1"
      if [[ -n "$2" && -d $scriptTopDir/$2 ]];then
        dir=$scriptTopDir/$2
        level=
      fi
      if which tree >/dev/null 2>&1;then
        tree $level $dir
      else
        find $dir -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
      fi
      ;;

    self.edit|edit)#CMDS#edit this script
      isQuiet || printOk "EDIT FILE: ${scriptFullPath} ...\n"
      cmd="vim ${scriptFullPath}"
      isDryrun && { printInfo "EDIT CMDS: ${cmd}\n"; shift; exit; }
      ${cmd}
      # check for modifications
      printOut "FILE CHANGE CHECK ... "
      sleep 1
      lastChangedDiff="$(date +%s) - $(getModTime ${scriptFullPath})"
      lastChanged=$(expr $lastChangedDiff)
      printOut "(last changed ${lastChanged}s ago) "
      if [[ $lastChanged -lt 5 ]];then
        printInfo "[CHANGED]\n"
        printOut "BASH SYNTAX CHECK ... "
        bash -n ${scriptFullPath} && printOk "[OK]\n"
        # autoupdate version
        NEWVERSION="$(date +'VERSION=\"%Y-%m-%d-%s\"')"
        sed -i.bak "s/^ *VERSION=.*/$NEWVERSION/" ${scriptFullPath} && printOk "FILE VERSION UPDATED\n"
      else
        printOut "[UNCHANGED]\n"
      fi
      ;;

    archive) #CMDS#	create archive release.tgz only
      # goto topdir
      pushd $scriptTopDir >/dev/null
      RELEASE_NAME=$(git remote -v|sed "s/.*\/\(.*\)\.git.*/\1/"|tail -1)
      RELEASE_VERSION=$(git log --oneline -n1| awk '{print $1}')
      RELEASE_FILEPATH="$tmpDir/${productId:-release}-${RELEASE_NAME}_${RELEASE_VERSION}.tgz"
      printInfo "CREATING ARCHIVE RELEASE ($RELEASE_FILEPATH)\n--\n"
      git archive -v --prefix "${RELEASE_NAME}_${RELEASE_VERSION}/" -9 -o $RELEASE_FILEPATH $RELEASE_VERSION
      printInfo "--\n"
      popd >/dev/null
      ;;

    *)
      exitInfo "Invalid parameters: $params"
      ;;
  esac



# print exit message
[[ -n ""$exitMessages ]] && printInfo "\n\n- EXIT NOTES -----\n$exitMessages"


exit 0
# - end of file (but not of life)
     <Fsx@HKlpugp~m
:Ig!$s=vo~9t̴X𵽽?O孭-+onmT=
INx^t}/ymU`̍Vy`ەRNe91%Vz1Jf<6/e󰳳ucsd/ّc];߼m˥o+_o[kc`ڑ0#/!`ڑ\gC괫b(|]`az]^Ẁ!"GlxV׵30C86A]{x۹F9f`ZO^pA,; TWN!.)CfzGas6tw<af)>. cslB^(&cQa03bK@hIS\+fa#.yGi|?`7+ Pe|/omoe$3fx&@QteI+sptx6=?Id;Lg3bѲ3hxZ-#p*ʛ;[;ʋ
Q]簮lӵtM+x'=l]<\$ IU7s4 wF.sFuT#8>M7kPأi-:g.G5sBRl9&{wa{vxZ\p=A?%pau=STbzTҼ-XU\+9^T%2O;`Iɉ̆(C`]ºf^]Erv%2n,We,2>& *ZB`:Ս=<KiL$;qQ7;U}dpLN&L"pk1=Bє䅲v/^S-ewpOV!nLq ?G3I28bogE<Y~*f'(P7|F\CN/u6yb>/#?M;a㞄)SAځPxQXs\.<uz5Ô/s7E-/p쎭4{ aÀ^zhytd{l09!A9 Ѹ(\52:j5{#5YFr AIy9m.yCp_ڋ$(?DFRt ur*E3=O]F3hP,l<Kxc	d 9ORU=]itiv2x\c	=Lw	cKv1$*dEyEC5)sP(gR8'Y<gPG̉uμ37H|Nw#ˑ'phFqG~[5R@wpӖgّå`5}]cBùsH9lB>_di~'_k'G*Ztv6'Qa8q k'nܨE=
 5uePǵܑzAX50.)\V+)sc]k77OAZW*#\õY+mFYDB5 P|X5fjVMGM;7&<5	)8*H=44Sycۮ*aˍXH(RSaո1\MA lybq{P*QWtiS'{>(4>RK&A[
LvʾԪN =s{`8!;M.
eCSG8sQM1<37j&#Ѣ^Yau{J#穬x,7;dS_-qЄς\(RL|"ȃ/Pm`ombGI88۝gQmr|?H펔d~BMc0>aĵ?t0J=QϗrƢ#CxE\txS
*#rH7Z7"q}Zx޾;:@~Y8vO@{M}͔.a$RAjB.m3zt^J['L5X>[ʨS%Ǹƙ;#,9idc(ZM<GSz{(24*QYr? p>!Oz? p1È`N"VC!|y,!|"G >s#fJŶ뀐(vft:ebp3i<M& ۤ͏	[D6
Fxߍ9MW)g!	ǧK'>=!el+nx]>ŏ(.	ݞm2')!(|lh)Ɏ1Pl)'Lͮ <4JN,J$a̩k>U°rUQшF~Cz%emWGSL"q?aOa:Gq]$10M{6,k>jgF_5βtMM2PXϣe~ta*ܟp0&)|
ʙidȞ
_>tRMpA4AF-}4w|P1h3f٣jO=s	aiymhާ1. ĀY晗'Qý(	>w-9Fti?`:eAP$c
SO|Cu:͟lbsVhO14<Ѳ9R~(GXWc
E}C,9:k{sSGsΧ2#N΃8sȫ٬n"
oWEC\C|A{%4}
)[hS.v`ax	 NEm6p&Rr&()P;{#^esw"ZDxd!903$Y0#.썐f6Zjf41 Hq6)~/-(S0<Xc"a)N/93Z˽4JUe旽pT:OөUyI\0h5"ap%3]HW9u=b׿kW7꿶ۥ߿tC{8(vwl
)<\3yƋGYH9}oi(v67*}7_ױ!]cDV:RY74#ֳ7zz+l0}jQ~G?L ~Iic[J )ǓӓTˍd_

3οb#QxR?1~PeMq8w6WN'=D(NsϢ^+5yIUa0yA!ņW!6X(pfs77&Rnb
bzK=t98Z~6m(=?9D#-hY]yV׃oբ8Y6[-S2LM^@\QNݤc&{͗?kkRƓIAT}_5Jbpڛ ʢCo
RW`-UQS#sba,HU,OLQo
rBKֳE՘exb]L7ѹ=sbS& ; C!TT+U9wIdu"0ЎptF汎eQFB1,Oo2󼮭AAW ƨ~7?@bb$& %wJ~`<8DU23	 1:xSv7eOwIRYRϸPE(ThWȡz厚	u![ߨ%U='џP#㳼G/////_ջ<E/7o}ܸ͝7('\Q*#F|wۦ@]+ ?xg^&$3q6ܔ{srqQ,|+0'>6hލ9]O7MrBPQ)͕SSvMzV'L̅3_fR3qT۟;)XYT?.I cOK	0z8r{"	L*+BP^'deR(a.I`^=3qm	,B.bwe*r.Z^ݤvk 4rHbMa+%ɉ3R"}ԝ"jToxDc$kdͩ`B,v x6uzj;5gjLS\R	U_ ./,ϱI1V͂&e]\Fbp6gHտiRB2&H]B	>t>ci4	M3T £P¹N08l( ~(<rqî4xL^16^BfPt<r\4)uǂS|5/7A$Rnf_ܤƩIBeϝv}ELP
"Ae.92Q"jě]I2`bwi*#~=6yV-?Y|5XԳS0h~^X5"~B:::شWiYsdxs/sɣ>>9"?ӄkaK:NjuZMNW`:;o;G=@[D8&^y3kB	 Z&b菔FwF,^WڿIu-U_yiRzHbU*X?&Xקּ]UƢ-
Vz \CM~\8!uc7]*6]]t\kkkx*R^,jwUXEY*?0?\-F5%9^昨A))a%=rd}"@GҌ)2_*>#xLotX?eqOŢRzz
jMs4AnB߱^ժZ&\?k>QT1M$I)iE=*}jNOkJ~E=Mڕ=a$[0R)I.&>upkuz"E%ݰdB!dzWtS~H5eBз|@5Soi:?7B+o(-aiI,*(%	K@5*~vsXxpɔ-H30.;*.mP,oJ i/!W|i?-k.#]la~lZm?el_U7_ז      sZ x  