#!/bin/bash
#
# autoe version 0.0.1
# 
# A tool to build E17 Debian packages from CVS
#
# Author: Falko Schmidt <kaethorn@stud.uni-stuttgart.de>
# 
# Features:
#  * Menudriven
#  * Only build the components which got updated
#  * Manage build order (add, remove, reorder)
#  * Error handling
#  * Resetting of date-stamps

# TODO:
#  * Finetune e_replace to reset only updated components
#  * Function for checking if necessary variables are set or given as params
#  * Batchrun command line flag

# some helpful environmental variables
export MAKE="make -j3"


#########################
# Configuration options #
#########################

# Define the working directory. This is used for storing the CVS tree
# and packages (if $AUTOMOVE=0).

WORKDIR=/usr/src/e


# Flag to automatically install packages after building them. This
# might be necessary to fulfill build requirements for later 
# packages.

AUTOINSTALL=1


# Flag to automatically move packages to $MOVEDIR after installation.

AUTOMOVE=1


# Flag to reset date after checkout
# This is recommended if your debian/changelog files have a date stamp of 
# form 'date +%Y%m%d' (can be specified below).

DATERESET=1


# Format of the date string used in debian/changelog files

#DATE="$(date +%Y%m%d)"


# Directory to move packages to, optionally every time a package builds 
# successfully - see $AUTOMOVE.

MOVEDIR="/var/lib/debarchiver/incoming/unstable/"


# List of scripts that can be executed from the menu

#CUSTSCRIPTS="/usr/bin/debarchiver /usr/local/bin/eunison-local.sh"


# Maintainer string for entry in debian/changelog

#MAINTAINERADDRESS="Falko Schmidt <kaethorn@stud.uni-stuttgart.de>"


# define the dpkg-buildpackage command line

DBUILDPACKAGE="dpkg-buildpackage -b"


# Flag to control whether to replace the Maintainer string in debian/control.
# This doesn't need to be touched usually.
REPLACE_CONTROL_MAINTAINER=0


# Packages which don't build (yet)
DONTBUILDLIST="e17/apps/euphoria e17/proto/exorcist"


# List of scripts that will be run after BatchRun finished creating
# debs.

#BATCHCOMMANDS="/usr/bin/debarchiver /usr/local/bin/eunison-local.sh"


# Comment this once line once all necessary variables are set
NOTCONFIGURED="1"



################################
# Don't edit beyond this point #
################################

# The build list
ULIST=""

# List of addable items
ALIST=""

#-------------------------------------------------------------------#
# function which prints the help                                    #
#-------------------------------------------------------------------#
function e_printhelp {
   echo ""
   echo "   BatchRun     - This option runs of the following commands:"
   echo "                    * Update"
   echo "                    * CheckUpdates"
   echo "                    * Build"
   echo "                    * user defined commands (see \$BATCHCOMMANDS)"
   echo "   Update       - Checks out the CVS repository."
   echo "   CheckUpdates - Scan for items which have been updated"
   echo "                  during the checkout. Overrides the previous"
   echo "                  build list."
   echo "   ViewList     - Display the current build list."
   echo "   ReorderList  - Reorder items on the build list."
   echo "   RemoveItem   - Remove items from the build list."
   echo "   AddItem      - Manually add items to the build list."
   echo "   Build        - Build the items on the build list."
   echo "   Help         - Print this help text."
   echo "   Install      - Installs all Debian packages found."
   echo "   Move         - Moves .deb, .dsc, .changes and .tar.gz"
   echo "                  files (the latter only if applicable)"
   echo "                  to "$MOVEDIR
   echo "   Custom       - Prompt for running external scripts which"
   echo "                  can be specified with the \$CUSTSCRIPTS"
   echo "                  variable."
   echo "   Quit         - Quit autoe. The original build list can be "
   echo "                  recovered by choosing 'CheckUpdates' the"
   echo "                  next time you run autoe."
   echo ""

}

#-------------------------------------------------------------------#
# function which prints the list of remaining build jobs            #
#-------------------------------------------------------------------#
function e_printlist {
   
  echo ""
  echo "   Current build jobs:"
  echo ""
  
  if [[ $ULIST = "" ]]
  then
     echo "   No items found. Make sure to check for updates first."
     echo ""
     return
  fi

  COUNTER=1
  for e in $ULIST
  do
     echo "   "$COUNTER")" $e
     let COUNTER=$COUNTER+1
  done
  
  echo ""

}

#-------------------------------------------------------------------#
# function to replace date stamps and adjust maintainer entries     #
#-------------------------------------------------------------------#
function e_replace {

   cd $1

   for file in $(find -name 'changelog*')
   do 
      # add cvs+date stamp
      sed -e 's/(\([0-9]\(\.[0-9]\+\)\+\)\-1)/(\1\-0cvs'$DATE')/g' $file > 58239
      cat 58239 > $file
      sed -e 's/(\(\@VERSION\@\)\-1)/(\1\-0cvs'$DATE')/g' $file > 58239
      cat 58239 > $file
      sed -e 's/(\([0-9]\(\.[0-9]\+\)\+\))/(\1\-0cvs'$DATE')/g' $file > 58239
      cat 58239 > $file
      sed -e 's/(\(\@VERSION\@\))/(\1\-0cvs'$DATE')/g' $file > 58239
      cat 58239 > $file

      # adjust date
      sed -e 's/cvs[0-9]*/cvs'$DATE'/g' $file > 58239
      cat 58239 > $file

      if [ $REPLACE_CONTROL_MAINTAINER = "1" ]
      then
         # adjust maintainer
         sed -e 's/\-\-\ .*/\-\-\ Falko Schmidt \<kaethorn\@stud\.uni\-stuttgart\.de\>\ \ Tue\,\ 7\ Mar\ 2006\ 13\:30\:15\ \+0000/g' $file > 58239
         cat 58239 > $file
      fi

   done


   if [ $REPLACE_CONTROL_MAINTAINER = "1" ]
   then
      for file in $(find -name 'control')
      do

         sed -e 's/Maintainer.*/Maintainer\: Falko Schmidt \<kaethorn\@stud\.uni\-stuttgart\.de\>/g' $file > 58239
         cat 58239 > $file
  
      done
   fi

   rm -f 58239
   cd ..

}

#-------------------------------------------------------------------#
# function which checks out the E17 CVS repository                  #
#-------------------------------------------------------------------#
function e_checkout {
	
   echo ""
   echo "   Checking out the CVS sources ..."
   cvs -z3 -d :pserver:anonymous@anoncvs.enlightenment.org:/var/cvs/e checkout -P e17 misc e_modules devs &> e17-log-co
   #cvs -z3 -d kaethorn@cvs.enlightenment.org:/cvs/e co -P e17 misc e_modules devs &> e17-log-co
   #cvs -d :pserver:anonymous@thinktux.net/root co e17 misc &> e17-log-co
   echo "   ...done"

   echo ""
   
   if [ "$DATERESET" = "1" ]
   then
      echo "   Resetting the date for e17/ ..."
      e_replace e17
      echo "   ...done"
   
      echo ""

      echo "   Resetting the date for misc/ ..."
      e_replace misc
      echo "   ...done"
   fi

   echo ""
}

#-------------------------------------------------------------------#
# function which generates a list of updates elements so that       #
# only those are being built later                                  #
#-------------------------------------------------------------------#
function e_checkupdates {
   
   # Libs
   LILIST="$(grep -e U\ e17\/libs\/ e17-log-co | sed -e 's/U\ e17\/libs\///g' | sed -e 's/\/.*//g' | uniq | sed -e 's/.*/e17\/libs\/&/g')"
   # Apps
   APLIST="$(grep -e U\ e17\/apps\/ e17-log-co | sed -e 's/U\ e17\/apps\///g' | sed -e 's/\/.*//g' | uniq | sed -e 's/.*/e17\/apps\/&/g')"
   # Proto
   PRLIST="$(grep -e U\ e17\/proto\/ e17-log-co | sed -e 's/U\ e17\/proto\///g' | sed -e 's/\/.*//g' | uniq | sed -e 's/.*/e17\/proto\/&/g')"
   # Misc
   MILIST="$(grep -e U\ misc\/ e17-log-co | sed -e 's/U\ misc\///g' | sed -e 's/\/.*//g' | uniq | sed -e 's/.*/misc\/&/g')"
   # e-modules
   MOLIST="$(grep -e U\ e_modules\/ e17-log-co | sed -e 's/U\ //g' | sed -e 's/\/.*//g' | uniq)"
   
   ULIST="$LILIST $APLIST $PRLIST $MILIST $MOLIST"
   echo ""
   if [[ $ULIST = "" ]]
   then
   	echo "   No updates found or CVS error."
   else
   	echo "   Found updates for the following components:"
   	echo ""
   	COUNTER=1
	for e in $ULIST
   	do
   	   echo "   "$COUNTER") "$e
	   let COUNTER=$COUNTER+1
   	done
   fi
   echo ""
}

#-------------------------------------------------------------------#
# function which build selected elements of the source tree         #
#-------------------------------------------------------------------#

function e_build {
   
   echo ""
   
   if [[ $ULIST = "" ]]
   then
      echo "   No updates found. Make sure you chose check for updates first."
      echo ""
      return
   fi
   
   # remember the parent dir
   PD=$(pwd)
   
   for e in $ULIST
   do
       echo ""
       echo ""
       echo "######################################"
       echo "# Building "$e" ..."
       echo "######################################"
       echo ""
       cd $e

       # run autogen.sh and configure
       
       # exception for ecore:
       if [ "$e" = "e17/libs/ecore" ]
       then
          ./autogen.sh --prefix=/usr --disable-ecore-evas-dfb \
	  			     --disable-ecore-dfb  
	  RC=$?
       # skip packages which don't build (yet)
       elif [[ $( echo $DONTBUILDLIST | grep $e" " | wc -c ) > 0 ]]
       then
          echo ""
	  echo "   Not configuring "$e"!"
	  echo ""
	  RC=$?
       else
          ./autogen.sh --prefix=/usr 
	  RC=$?
       fi
       
       # check the return code
       if [ "$RC" -ne 0 ]
       then
          echo ""
	  echo ""
	  echo " * something went wrong while configuring "$e"!"
	  echo ""
	  cd $PD
	  return
       fi
       
       # build the package
       if [[ $( echo $DONTBUILDLIST | grep $e" " | wc -c ) > 0 ]]
       then
          echo ""
	  echo "   Not building "$e"!"
	  echo ""
	  let RC=$?
       else
          $DBUILDPACKAGE -m"$MAINTAINERADDRESS" -e"$MAINTAINERADDRESS"
          RC=$?
       fi
       
       # check the return code
       if [ "$RC" -ne 0 ]
       then
          echo ""
	  echo ""
	  echo " * something went wrong while building "$e"!"
	  echo ""
	  cd $PD
	  return
       fi

       echo ""
       echo ""
       echo "######################################"
       echo "# finished building "$e" ..."
       echo "######################################"
       echo ""
       
       # remove the successfully built item from the list
       ULIST="${ULIST/$e/}"
       
       # install packages if wanted by user
       if [[ $AUTOINSTALL = 1 ]]
       then
       if [[ $( echo $DONTBUILDLIST | grep $e" " | wc -c ) = 0 ]]
       then
          cd ..
	  dpkg -i *.deb
	  RC=$?
	  if [ $RC -ne 0 ]
	  then
	     echo ""
	     echo "   Something went wrong while installing "$e"!"
	     echo ""
	     return
	  fi
	  echo ""
	  echo "   Successfully installed "$e"."
	  echo ""
	  
	  # move packages if wanted by user
	  if [[ $AUTOMOVE = 1 ]]
	  then
	     # check whether we build source files tarballs
             if [[ $( echo $DBUILDPACKAGE | grep '\-b' | wc -c) > 0 ]]
	     then
	        mv *.deb *.changes $MOVEDIR
             else   
	        mv *.deb *.tar.gz *.changes *.dsc $MOVEDIR
	     fi
	  fi
       fi
       fi

       # return to parent dir
       cd $PD
       
   done
}

#-------------------------------------------------------------------#
# function which places an build list item in front of another      #
#-------------------------------------------------------------------#
function e_place {
   
   echo ""
   echo " * Where shall "$1" be placed in front of?"
   echo ""
   OPTIONS="$ULIST Cancel"
   select opt in $OPTIONS; do
   if [ "$opt" = "Cancel" ]; then
	return
   elif [ "$opt" = "$1" ]; then
	echo "   Can't place an item in front of itself."
   elif [ "$opt" = "" ]; then
	echo "   bad option"
   elif [ "$(echo $ULIST | grep "$opt" | wc -c)" > 0 ]; then
   	ULIST="${ULIST/$1/}"
	SUBSTR=$1" "$opt
	ULIST="${ULIST/$opt/$SUBSTR}"
   	echo "   ...done"
	return
   else
	echo "   bad option"
   fi
   done
   echo ""
}

#-------------------------------------------------------------------#
# function which adds an item to the list of build jobs             #
#-------------------------------------------------------------------#
function e_add {

   if [[ $ALIST = "" ]]
   then
   # Libs
   LILIST="$(find e17/libs | sed -e 's/e17\/libs\///g' | sed -e 's/\/.*//g' | uniq | sed -e 's/.*/e17\/libs\/&/g')"
   # Apps
   APLIST="$(find e17/apps | sed -e 's/e17\/apps\///g' | sed -e 's/\/.*//g' | uniq | sed -e 's/.*/e17\/apps\/&/g')"
   # Proto
   PRLIST="$(find e17/proto | sed -e 's/e17\/proto\///g' | sed -e 's/\/.*//g' | uniq | sed -e 's/.*/e17\/proto\/&/g')"
   # Misc
   MILIST="$(find misc | sed -e 's/misc\///g' | sed -e 's/\/.*//g' | uniq | sed -e 's/.*/misc\/&/g')"
   # e-modules
   MOLIST="$(find e_modules | sed -e 's/\/.*//g' | uniq)"
		        
   ALIST="$LILIST $APLIST $PRLIST $MILIST $MOLIST"
   fi
   
   echo "   Choose the item which needs to be added."
   echo ""
   OPTIONS="$ALIST Ready"
   select opt in $OPTIONS; do
   if [ "$opt" = "Ready" ]; then
	echo "   done"
	return
   elif [ "$opt" = "" ]; then
	echo "   bad option"
   elif [ "$(echo $ALIST | grep "$opt" | wc -c)" > 0 ]; then
   	ALIST="${ALIST/$opt/}"
	ULIST=$ULIST" "$opt
	e_printlist
	return
   else
	echo "   bad option"
   fi
   done
   echo ""
   
}

#-------------------------------------------------------------------#
# function which removes items from the list of build jobs          #
#-------------------------------------------------------------------#
function e_remove {

   echo ""
   if [[ $ULIST = "" ]]
   then
   	echo "   Nothing to remove."
	return
   fi
   
   echo "   Choose the item which needs to be removed."
   echo ""
   OPTIONS="$ULIST Ready"
   select opt in $OPTIONS; do
   if [ "$opt" = "Ready" ]; then
	echo "   done"
	return
   elif [ "$opt" = "" ]; then
	echo "   bad option"
   elif [ "$(echo $ULIST | grep "$opt" | wc -c)" > 0 ]; then
   	ULIST="${ULIST/$opt/}"
	e_printlist
	return
   else
	echo "   bad option"
   fi
   done
   echo ""
   
}

#-------------------------------------------------------------------#
# function which manages shuffling items in the build list          #
#-------------------------------------------------------------------#
function e_reorder {
   
   echo ""
   if [[ $ULIST = "" ]]
   then
   	echo "   Nothing to reorder."
	return
   fi
   
   echo "   Choose item which needs to be reordered."
   echo ""
   OPTIONS="$ULIST Ready"
   select opt in $OPTIONS; do
   if [ "$opt" = "Ready" ]; then
	echo "   done"
	return
   elif [ "$opt" = "" ]; then
	echo "   bad option"
   elif [ "$(echo $ULIST | grep "$opt" | wc -c)" > 0 ]; then
	e_place "$opt"
	e_printlist
	return
   else
	echo "   bad option"
   fi
   done
   echo ""

}

#-------------------------------------------------------------------#
# function which calls scripts defined by the user                  #
#-------------------------------------------------------------------#
function e_custom {
   
   echo ""
   
   OPTIONS="$CUSTSCRIPTS Ready"
   select opt in $OPTIONS; do
   if [ "$opt" = "Ready" ]; then
	echo "   done"
	return
   elif [ "$opt" = "" ]; then
	echo "   bad option"
   elif [ "$(echo $CUSTSCRIPTS| grep "$opt" | wc -c)" > 0 ]; then
	echo "   Running script "$opt "..."
	sh "$opt"
	echo "   ... done."
   else
	echo "   bad option"
   fi
   done
   
}

#-------------------------------------------------------------------#
# function which installs all packages in e17/, misc/ & e_modules   #
#-------------------------------------------------------------------#
function e_install {
   
   echo ""
   echo "   Installing packages ..."
   echo ""
   find e17 misc e_modules -name '*.deb' -exec dpkg -i {} \; -print
   echo ""
   echo "   ... done"
   echo ""
   
}

#-------------------------------------------------------------------#
# function which moves all repository relevant files to $MOVEDIR    #
#-------------------------------------------------------------------#
function e_move {
   
   echo ""
   echo "   Moving files ..."
   echo ""
   echo "      *.deb ..."
   find e17 misc e_modules -name '*.deb' -exec mv {} $MOVEDIR \; -print
   echo "       ... done"
   echo ""
   echo "      *.changes ..."
   find e17 misc e_modules -name '*.changes' -exec mv {} $MOVEDIR \; -print  
   echo "       ... done"
   echo ""
   # check whether we build source files tarballs
   if [[ $( echo $DBUILDPACKAGE | grep '\-b' | wc -c) = 0 ]]
   then
      echo "      *.tar.gz ..."
      find e17 misc e_modules -name '*.tar.gz' -exec mv {} $MOVEDIR \; -print
      echo "       ... done"
      echo ""
      echo "      *.dsc ..."
      find e17 misc e_modules -name '*.dsc' -exec mv {} $MOVEDIR \; -print
      echo "       ... done"
      echo ""
   fi
   echo "   ... done"
   echo ""
   
}

#-------------------------------------------------------------------#
# function which calls scripts after BatchRun has finished          #
#-------------------------------------------------------------------#
function e_runbatchcommands {
   
   if [[ $e = "" ]]
   then
      echo ""
      echo "   No additional commands to exectue."
      echo ""
      return
   fi
   
   for e in $BATCHCOMMANDS
   do
      echo ""
      echo "   Executing "$e
      echo ""
      sh $e
      echo ""
      echo "   ...done"
   done

}

#-------------------------------------------------------------------#
# function which checks whether variables are set correctly         #
#-------------------------------------------------------------------#
function e_checkenv {

   if [[ $NOTCONFIGURED = "1" ]]
   then
      echo ""
      echo "   autoe is not configured properly. Please edit this script"
      echo "   and adjust the necessary options."
      echo ""
      exit 1
   fi
   
   if [[ $1 = "--batch" ]] | [[ $1 = "-b" ]]
   then
      e_checkout
      e_checkupdates
      e_build
      e_runbatchcommands
      exit 0
   fi
      
   for e in $CUSTSCRIPTS
   do
      if [ ! -e $e ] | [ ! -x $e ]
      then
         echo ""
	 echo "   Warning! The script "$e "was specified"
	 echo "   in \$CUSTSCRIPTS but doesn't exist or is not executable."
	 echo ""
      fi
   done

   for e in $BATCHCOMMANDS
   do
      if [ ! -e $e ] | [ ! -x $e ]
      then
         echo ""
	 echo "   Warning! The script "$e "was specified"
	 echo "   in \$BATCHCOMMANDS but doesn't exist or is not executable."
	 echo ""
      fi
   done


   if [ ! -d $MOVEDIR ] && [ "$AUTOINSTALL" = "1" ]
   then
      echo ""
      echo "   Warning! Directory "$e "doesn't exist"
      echo "   (or is a file). Please provide a directory where"
      echo "   packages can be moved to by setting the \$MOVEDIR"
      echo "   variable."
      echo ""
      exit 1
   fi

   if [ ! -d $WORKDIR ]
   then
      echo ""
      echo "   Warning! Directory "$e "doesn't exist"
      echo "   (or is a file). Please provide a directory where"
      echo "   this script should be operating in."
      echo ""
      exit 1
   fi


}

#-------------------------------------------------------------------#
# main                                                              #
#-------------------------------------------------------------------#

# check the settings manage command line options
e_checkenv

echo "#-------------------------------------------------------#"
echo "|                  Welcome to autoe                     |"
echo "|                                                       |"
echo "|    This script aids in the repetitive process of      |"
echo "|    checking out the E17 CVS repository followed       |"
echo "|      by building a selected list of relevant          |"
echo "|             libraries and applications.               |"
echo "|                                                       |"
echo "#-------------------------------------------------------#"

cd $WORKDIR


OPTIONS="BatchRun Update CheckUpdates ViewList ReorderList AddItem RemoveItem Build Install Move Custom Help Quit"
select opt in $OPTIONS; do
if [ "$opt" = "Quit" ]; then
	echo " * done"
	exit
elif [ "$opt" = "BatchRun" ]; then
	e_checkout
	e_checkupdates
	e_build
	e_runbatchcommands
elif [ "$opt" = "Update" ]; then
	e_checkout
elif [ "$opt" = "Build" ]; then
	e_build
elif [ "$opt" = "CheckUpdates" ]; then
	e_checkupdates
elif [ "$opt" = "ReorderList" ]; then
	e_reorder
elif [ "$opt" = "ViewList" ]; then
	e_printlist
elif [ "$opt" = "AddItem" ]; then
	e_add
elif [ "$opt" = "RemoveItem" ]; then
	e_remove
elif [ "$opt" = "Help" ]; then
	e_printhelp
elif [ "$opt" = "Install" ]; then
	e_install
elif [ "$opt" = "Move" ]; then
	e_move
elif [ "$opt" = "Custom" ]; then
	e_custom
else
	echo "   bad option"
fi
done

