#!/bin/bash
#
# getPackages.sh
# Generates the content of the %packages section of
# a kickstart file, selecting all packages currently
# installed on system using as few lines as possible
#
# Author: Davidson Paulo <dpaulo@fedoraproject.org>
# License: GNU GPLv3 (General Public License version 3)

Output=/tmp/test.$$

getLines () {
  while read Line ; do
    echo $Line
  done < <(egrep '(<id>|<packagereq)' "$1") |
    grep -v '"optional"' |
    sed -r 's/^<id>(.*)<\/id>$/#\1$/;
            s/^<packagereq .*>(.*)<\/packagereq>$/\1/' |
    tr '\n' ' ' |
    sed 's/#/\n/g;s/\$ /\:/g;s/ /,/g' |
    grep -v ':$' |
    sed 's/,$//' |
    grep -v '^$' |
    sort
}

getPackages() {
  rpm -qa | rev | cut -d'-' -f3- | rev | sort | uniq
}

getGroupPackages() {
  echo "$1" | grep "^$2:" | cut -d':' -f2 | tr ',' '\n'
}

getIncluded() {
  GroupPackages="$1"
  Packages="$2"

  echo -e "$GroupPackages"'\n'"$Packages" | sort | uniq -d
}

getExcluded() {
  Included="$1"
  GroupPackages="$2"
  Packages="$3"

  echo -e "$Included"'\n'"$GroupPackages" | sort | uniq -u
}

countLines() {
  echo "$1" | wc -l
}

matchGroup() {
  Group=$1
  Packages="$2"
  Comps="$3"
  GroupPackages=`getGroupPackages "$Comps" $Group`
  Included=`getIncluded "$GroupPackages" "$Packages"`
  NumInc=$(countLines "$Included")

  if [ $NumInc -ne 0 ] ; then
    Excluded=`getExcluded "$Included" "$GroupPackages" "$Packages"`
    NumExc=$(countLines "$Excluded")

    if [ $NumInc -gt $NumExc ] ; then
      echo "@$Group" >> $Output.group
      echo "$Excluded" | grep -v '^$' | sed 's/^/-/' >> $Output.exc
    else
      echo "$Included" | grep -v '^$' >> $Output.inc
    fi
  fi
}

echo "Getting comps..."
Comps=`getLines comps.xml`
echo "Getting installed packages..."
Packages=`getPackages`
echo "Generating kickstart %packages section..."
while read Group ; do
  matchGroup $Group "$Packages" "$Comps"
done < <(echo "$Comps" | cut -d':' -f1)

cat $Output.group | sort | uniq
cat $Output.inc | sort | uniq
cat $Output.exc | sort | uniq

rm -f $Output.*
