#!/bin/bash
set +o posix

# Script : slackwarearm-current/source/x/x11/x11.r2bhelper
# Purpose: Build modular X.org packages, handling build numbers
#          and X.org section types (app/driver/util) automatically.
#          This is a helper script for the ''r2b'' Slackware ARM build system.
#
# by Stuart Winter <mozes@slackware.com>
#
# Copyright 2008-2018  Stuart Winter, Surrey, England.
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
#  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
#  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
#  EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
#  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
#  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
#  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# When dealing with an Xorg update in Slackware, the easiest way to do it (without
# running the entire X11.SlackBuild), is to:
# - Filter only the x updates from the ChangeLog entries
# - Grep "Removed" note down which exist for ARM, and paste those .t?z file names into
#   Slackware ARM's changelog.
# - Grep "Rebuilt" and add those to this script
# - Grep "Added" and add those to the "Upgraded" (since the script handles them the same)
# - Grep "Upgraded", as below:
# cat /tmp/f | grep Upgraded | sed 's?+x/??g' | cut -d: -f1 | rev | cut -d- -f4- | rev | while read updpkg ; do echo "$updpkg \\" ; done
# The first time, run this script WITHOUT updating build numbers - just to get everything
# upgraded and on the live filesystem.
# Run again, without updating version numbers to ensure everything links against each other
# For the Rebuilt packages, build those by supplying the "R" option to the "build" function
# For Upgraded packages, build those with the U option.
#######################################################################################
#
# pkg-config --libs --cflags glib-2.0
#
#
# todo:
# Filter all xorg-server update entries down to a single one, since xorg-server-xnest andso on
# are built by the single "xorg-server" package.
# This filtering can be done during the **R2B process marker stage.

source /usr/share/slackdev/buildkit.sh
export ORIGCWD=$PWD

mkdir -vpm755 $ORIGCWD/build-logs/$SLKPORTARCH/fails

# If building in /patches for a Stable Release, we drop the packages into /tmp/patches/
slack_findpkgstore_is_stablerelease && { export SLACKPATCHING=yes ;} || { export SLACKPATCHING=no ;}
echo "Building in patches? $SLACKPATCHING"

# Location of Slackware Change Log.  Since this is an r2b helper script, it's normally
# called with the change log file path explicitly defined using the '-c' operator
# to this script.
CHANGELOG=$PORTSRC/ChangeLog.txt

# Return a package name that has been stripped of the dirname portion
# and any of the valid extensions (only):
pkgbase() {
  # basename + strip extensions .tbz, .tgz, .tlz and .txz
  echo "$1" | sed 's?.*/??;s/\.t[bglx]z$//'
}

# Strip version, architecture and build from the end of the name
package_name() {
  pkgbase $1 | sed 's?-[^-]*-[^-]*-[^-]*$??'
}

display_help() {
cat << EOF
 -c, --changelog               Override the default location of the Slackware
                               ChangeLog.txt [ default: $CHANGELOG ]
 -p, --port-specific           Path of script that will handle building the
                               port specific modules.
EOF
}

function buildx11modularpkg () {

 INDIPKG=$1

 echo "*********************************"
 echo "***** Working on modular package: ${INDIPKG} *****"
 echo "*********************************"

 # Determine the section of X where we'll find the source:
 # the head -n1 is because *xcb-util* returns the 'x11/src/xvb' dir basename for all of the
 # other xcb-util-* archives.
 if [ "$SLACKPATCHING" = "no" ]; then
     dbuild $( basename $( find $SLACKSOURCE/x/x11/src -name "*$INDIPKG*z" -printf "%h\n" | head -n1 )) $INDIPKG 2>&1 | tee $ORIGCWD/build-logs/$SLKPORTARCH/$INDIPKG.log
  else
    # For /patches - we don't use distcc on stable machines:
    ./arm/build $( basename $( find $SLACKSOURCE/x/x11/src -name "*$INDIPKG*z" -printf "%h\n" | head -n1 )) $INDIPKG 2>&1 | tee $ORIGCWD/build-logs/$SLKPORTARCH/$INDIPKG.log
 fi
}

# Get script parameters:
PARAMS="$( getopt -qn "$( basename $0 )" -o c:p: -l changelog:,port-specific: -- "$@" )"
# If params are incorrect then
if [ $? -gt 0 ]; then display_help >&2 ; exit 2 ; fi
eval set -- "${PARAMS}"
for param in $* ; do
  case "$param" in

     -p|--port-specific)           PORTSPECIFIC="$2"
                                   shift 2;;

     -c|--changelog)               CHANGELOG="$2"
                                   shift 2;;
     --) shift; break;;
esac done

# Ensure that the R2B markers are present, as that indicates Sud has been run
# and that we've had a manual check through the list.
if [ "$( grep -E '^\*\*R2B|^\*\*R2B' ${CHANGELOG} | xargs )" != "**R2B **R2B" ]; then
   printf "\nERROR: r2b markers are not present within ${CHANGELOG}, or perhaps less than or more than one set?\n"
   exit 1
fi

# Now we can proceed by parsing the ChangeLog for the list of X11 modules to build.
echo "X11 r2b helper"
echo "Slackware Change Log (acting as a build list): $CHANGELOG"

# First check whether we were supplied the helper script for the port-specific stuff:
# The helper script needs to be executable.
if [ ! -z "${PORTSPECIFIC}" ]; then
   if [ -x "${PORTSPECIFIC}" ]; then
       echo "*** Running the port specific X11 modules helper script ${PORTSPECIFIC}"
      # The good thing about sourcing it is that the helper script code originally came
      # from this script, so it can refer to the variables set within this parent script.
      # We don't need to check for R2B markers because the x11 port-specific script is
      # not a build list per se, but a manually maintained shell script that performs some
      # setup, so it doesn't need checking automatically here.
      source ${PORTSPECIFIC}
      exit $?
      # Exit after completion.  If you want to build x11 modules that are also present
      # in the x86 upstream, you need to use the ChangeLog.txt list entries that are
      # copied from the x86 Change Log.
    else
      echo "*** ${PORTSPECIFIC} script supplied, but does not exist or is not executable!"
      exit 1 # probably ought to make this something else to be caught by x11.r2bhelper script.. but we can check manually for the moment.
   fi
fi

# Ensure that the R2B markers are present, as that indicates Sud has been run
# and that we've had a manual check through the list.
if [ "$( grep -E '^**R2B|^**R2B' ${CHANGELOG} | xargs )" != "**R2B **R2B" ]; then
   printf "\nERROR: r2b markers are not present within ${CHANGELOG}, or perhaps less than or more than one set?\n"
   exit 1
fi

# Don't build with DRI:
# No point. I thought it'd help with the KDE crash but it doesn't.
#sed -i 's?--with-dri-driver-path=.*?\\?g' $SLACKSOURCE/x/x11/configure/xorg-server

# We rebuild things over and over to get them all holding hands.  Obviously this doesn't
# guarantee hand holding since the build list remains static, but those who refuse can be
# cajoled into it later if need be.
#
#
# We rebuild things over and over to get them all holding hands.  Obviously this doesn't
# guarantee hand holding since the build list remains static, but those who refuse can be
# cajoled into it later if need be.
if [ ! -z "$R2BHELPERBUILDPASSES" ]; then
   buildpasses=$R2BHELPERBUILDPASSES
   echo "r2b helper build passes is set"
 else
   buildpasses=3
fi
echo "Build passes: $buildpasses"
for (( pass=1; pass <=${buildpasses} ; pass++ )); do
   echo "***********************************"
   echo "***** x11 indibuild PASS $pass    *****"
   echo "***********************************"

   # Find packages between the R2B markers, filtering out any 'Removed' packages
   # (as these are handled by 'Sud'):
   # Note that we don't filter any duplicates because we may insert duplicates
   # in order to facilitate building.
   # The build numbers are set externally so a package can rebuild as many times
   # as necessary.
   while read line ; do
       x11modpkg=$( package_name $( echo $line | awk -F: '{print $1}' ) )
    #echo "PKG: *$pkg*"
       # Is it excluded for ARM?
       if [ -z "$( egrep "^${x11modpkg}$" $PORTSRC/source/x/EXCLUDED_PKGS )" ]; then
        # Check if it's in the Slackware x86 master tree's "slackware/x/" directory:
          if [ -d $SLACKSOURCE/x/$x11modpkg ]; then
             # It's in Slackware's X series but not part of X.org:
             echo "WARNING: x/$x11modpkg is not a modular X11 package - ignoring (will be handled by r2b directly)"
           else
             # It's part of X.org - one of the modular packages.
             echo "Building X11 modular package: ${x11modpkg}"
             buildx11modularpkg ${x11modpkg}
          fi
        else
           echo "WARNING: x/${x11modpkg} is excluded on Slackware ARM - ignored"
       fi
   done< <( sed -n '/^**R2B/,/^**R2B/p' $CHANGELOG | sed -e 's?_X11MOD_ ??g' -e 's?^+??g' | grep -E "^x/.*t[bglx]z:" | grep -v "\:[[:space:]]\{2,\}Removed\.$" | cut -d/ -f2 )

# end build "pass"
done
