#!/bin/sh
#(c) Copyright 2014 Barry Kauler.
#141213 first version.
#150924 fix for path of db file in woofQ.
#170515 converted (trom T2) to OE.
#170516 ignore pkgs named packagegroup-*
#170517 strip the files.
#170601 tmp-glibc/work/${ACAT}-oe-linux in buildQ, -oe-linux-gnueabi in buildPi. 170602
#171019 allow stripping for WOOF_TARGETARCH='amd64x32' WOOF_HOSTARCH='amd64'
#171021 fix path.
#180608 some tests.
#180701 path depth cutting was wrong.
#180715 find dependencies.
#180723 support cross-build strip.
#180724 calc size of a package after stripping.
#181121 quirky/woof-distro now easyos/easy-distro
#200927 fix for oe dunfell. 201007 fix stripping. 20201014 fix stripping. /tmp/0pre-oe-add

export LANG=C #faster.
. ./DISTRO_SPECS
if [ "$DISTRO_BINARY_COMPAT" != "oe" ];then #200927
 echo "ERROR: DISTRO_BINARY_COMPAT has value '${DISTRO_BINARY_COMPAT}'"
 echo "It is required to be 'oe'. Aborting."
fi
[ ! "$DISTRO_DB_SUBNAME" ] && DISTRO_DB_SUBNAME="$DISTRO_COMPAT_VERSION" #121102 fallback if DISTRO_DB_SUBNAME not defined in file DISTRO_SPECS.
. ./DISTRO_COMPAT_REPOS-oe-${DISTRO_COMPAT_VERSION} #has PKG_DOCS_DISTRO_COMPAT
. ./DISTRO_PKGS_SPECS-oe-${DISTRO_COMPAT_VERSION}
ONE_PKGLISTS_COMPAT="`echo "$PKG_DOCS_DISTRO_COMPAT" | tr ' ' '\n' | cut -f 3 -d '|' | head -n 1`"
#...ex: Packages-oe-${DISTRO_COMPAT_VERSION}-official, which is Packages-oe-pyro-official
FIND_CAT="./support/find_cat"

PKGLISTS_COMPAT="`echo "$PKG_DOCS_DISTRO_COMPAT" | tr ' ' '\n' | cut -f 3 -d '|' | head -n 1`" #see file DISTRO_PKGS_SPECS-oe-pyro
#...ex: Packages-${DISTRO_BINARY_COMPAT}-${DISTRO_COMPAT_VERSION}-official, which is Packages-oe-pyro-official

if [ ! -f WOOFMERGEVARS ];then
 echo
 echo "ERROR: file WOOFMERGEVARS is created by merge2out. not there"
 exit
fi
. ./WOOFMERGEVARS #has WOOF_TARGETARCH

#200927
if [ ! -s PROJECTPATH ];then
 echo "ERROR: file PROJECTPATH is created by merge2out. not there"
 exit
fi
. ./PROJECTPATH
if [ -d ${PROJECTPATH}/easy-code ];then
 WOOFNAME='easy'
else
 if [ -d ${PROJECTPATH}/woof-code ];then #older woof project
  WOOFNAME='woof'
 else
  echo "ERROR: file ${PROJECTPATH}/merge2out does not exist. need path to woof project."
  exit
 fi
fi

echo
echo "Script '0pre-oe' has to run beforehand, once."
echo "Script '0pre-oe-add' is for extracting one (or more) binary package(s) from OE"
echo "and add it/them to woofQ. A db-entry will be created for the new package."
echo "The scenario is where you have compiled an extra package in OE, after"
echo "the main compile, and want to add that package to woofQ target build."
echo "This script will also detect, and offer to delete, old packages."

if [ ! -f status/OE_SUPPORT ];then
 echo
 echo "A previous run of '0pre-oe' will have created status/OE_SUPPORT"
 echo "This does not exist, aborting."
 exit
fi

. ./status/OE_SUPPORT #OEPATH, OEPROFILE
OEOK=0
[ ! "$OEPATH" ] && OEOK=1
[ ! "$OEPROFILE" ] && OEOK=1
[ ! -d ${OEPATH}/${OEPROFILE} ] && OEOK=1
if [ $OEOK -eq 1 ];then
 echo
 echo "ERROR: OE path wrong."
 exit
fi
BUILDFOLDER="$OEPROFILE"

PATHOK=yes
[ ! -d $OEPATH ] && PATHOK="$OEPATH"
if [ -d ${OEPATH}/${BUILDFOLDER}/tmp-glibc ];then #200922
 TMPFOLDER='tmp-glibc' #pyro and thud
else
 if [ -d ${OEPATH}/${BUILDFOLDER}/tmp-musl ];then
  TMPFOLDER='tmp-musl' #pyro and thud
 else
  TMPFOLDER='tmp' #dunfell
 fi
fi
[ ! -d ${OEPATH}/${BUILDFOLDER}/${TMPFOLDER}/deploy/deb ] && PATHOK="$OEPATH/${BUILDFOLDER}/${TMPFOLDER}/deploy/deb"
if [ "$PATHOK" != "yes" ];then
 echo
 rm -f status/OE_SUPPORT
 echo "ERROR: OE path '${PATHOK}' is wrong"
 exit
fi

#200922
#180723 find the cross-build strip executable in oe... (for aarch64 build it will be aarch64-oe-linux-strip)
CROSS_STRIP_FND="$(find ${OEPATH}/${OEPROFILE}/${TMPFOLDER}/sysroots-components -type f -name '*-strip' | grep '/binutils\-cross\-' | head -n 1)"
if [ "$CROSS_STRIP_FND" ];then
 CROSSSTRIP="$(basename $CROSS_STRIP_FND)"
 if [ ! -e support/${CROSSSTRIP} ];then
  cp -a -f ${CROSS_STRIP_FND} support/
 fi
else
 echo "ERROR: unable to find the cross-strip executable in OE, aborting"
 exit 2
fi

yPWD="`pwd`"
#20201014...
[ -d /tmp/0pre-oe-add ] && rm -rf /tmp/0pre-oe-add
mkdir /tmp/0pre-oe-add


#get list of all binary pkgs already in woofQ target:
CURRBINS="$(find packages-oe-${DISTRO_COMPAT_VERSION}/ -mindepth 1 -maxdepth 1 -type f -name '*.xz' | rev | cut -f 1 -d '/' | rev | sort)"
echo "$CURRBINS" > /tmp/0pre-oe-add/0pre-add1-currbins

#get list of binary pkgs in oe:
echo 'please wait, scanning...'
echo -n '' > /tmp/0pre-oe-add/0pre-oe-add-nameverarch
echo -n '' > /tmp/0pre-oe-add/0pre-oe-add-fullpkgs
OEIMAGES="$(find ${OEPATH}/${OEPROFILE}/${TMPFOLDER}/work/*-*-linux*/*/*/ -mindepth 1 -maxdepth 1 -type d -name image)"
#ex:  /mnt/sda2/oe/oe-quirky/buildQ/${TMPFOLDER}/work/pcx86_64-oe-linux/xserver-xf86-config/0.1-r33/image
#ex: /mnt/sdb1/projects/oe/oe-quirky/buildPC/${TMPFOLDER}/work/nocona-64-oe-linux/zlib/1.2.11-r0/image

#180701 fix cutting depth...
DEPTHoe=`echo -n "${OEPATH}/${OEPROFILE}/" | sed -e 's%[^/]%%g' | wc -m` #8
DEPTHarch=$((DEPTHoe+3))
DEPTHname=$(($DEPTHoe+4))
DEPTHver=$(($DEPTHoe+5))

for AIMAGE in $OEIMAGES
do
 [ ! "$AIMAGE" ] && continue
 #180701...
 ANAME="$(echo -n "$AIMAGE" | cut -f ${DEPTHname} -d '/')"
 [ "$(echo -n "$ANAME" | cut -f 1 -d '-')" == "packagegroup" ] && continue #170516 ignore pkgs named packagegroup-*
 AVER="$(echo -n "$AIMAGE" | cut -f ${DEPTHver} -d '/')"
 AARCH="$(echo -n "$AIMAGE" | cut -f ${DEPTHarch} -d '/' | sed -e 's%\-oe\-linux.*%%' | sed -e 's%\-poky\-linux.*%%')" #20200927
 [[ $ANAME == *-native ]] && continue
 [[ $ANAME == *-cross ]] && continue
 echo "${ANAME}-${AVER}-${AARCH}.tar.xz ${ANAME} ${AVER} ${AARCH}" >> /tmp/0pre-oe-add/0pre-oe-add-nameverarch
 echo "${ANAME}-${AVER}-${AARCH}.tar.xz" >> /tmp/0pre-oe-add/0pre-oe-add-fullpkgs
done
OEBINS="$(sort /tmp/0pre-oe-add/0pre-oe-add-fullpkgs)"

echo "$OEBINS" > /tmp/0pre-oe-add/0pre-add1-oebins

OECOMPARE="$(diff /tmp/0pre-oe-add/0pre-add1-currbins /tmp/0pre-oe-add/0pre-add1-oebins)"

OEDUMPED="$(echo "$OECOMPARE" | grep '^< ' | cut -f 2 -d ' ')"
OENEW="$(echo "$OECOMPARE" | grep '^> ' | cut -f 2 -d ' ')"

if [ "$OEDUMPED" ];then
 echo
 echo "These local binary packages, in folder packages-oe-${DISTRO_COMPAT_VERSION}"
 echo "are no longer in the OE build:"
 echo "$OEDUMPED"
 echo
 echo "Suggest they be deleted."
 echo -n "Press ENTER only to delete them, any other key to keep:"
 read oldoekeep
 if [ "$oldoekeep" = "" ];then
  for aoldoe in `echo "$OEDUMPED" | tr '\n' ' '`
  do
   echo "Removing ${aoldoe}"
   rm -f packages-oe-${DISTRO_COMPAT_VERSION}/${aoldoe}
   aPTN="|${aoldoe}|"
   grep -v "$aPTN" ${ONE_PKGLISTS_COMPAT} > /tmp/0pre-oe-add/0pre-add1-dbrem #ex: remove entry from Packages-oe-pyro-official
   mv -f /tmp/0pre-oe-add/0pre-add1-dbrem ${ONE_PKGLISTS_COMPAT}
  done
  
  if [ -d ${PROJECTPATH}/${WOOFNAME}-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}/${WOOF_COMPATVERSION} ];then
   echo
   echo "Suggest also copy pkg-db to the master woofQ (Quirky build system):"
   echo "${PROJECTPATH}/${WOOFNAME}-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}/${WOOF_COMPATVERSION}/${PKGLISTS_COMPAT}"
   #ex: ...easy-distro/amd64/oe/pyro/Packages-oe-pyro-official
   echo -n "Press ENTER only to copy this file:"
   read t2update
   [ "$t2update" == "" ] && cp -a -f ${PKGLISTS_COMPAT} ${PROJECTPATH}/${WOOFNAME}-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}/${WOOF_COMPATVERSION}/
  fi
  
 fi
fi

if [ "$OENEW" ];then
 echo
 echo "These OE packages are not in local folder packages-oe-${DISTRO_COMPAT_VERSION}:"
 echo "$OENEW"
 echo
 echo "Suggest they be added."
 echo -n "Press ENTER only to add them, any other key to not:"
 read oldoekeep
 if [ "$oldoekeep" = "" ];then
  for aoldoe in `echo "$OENEW" | tr '\n' ' '`
  do
   echo "Adding ${aoldoe}" #ex: aoldoe=cairo-1.14.8-r0-core2-64.tar.xz
   ANAME="$(grep "^${aoldoe} " /tmp/0pre-oe-add/0pre-oe-add-nameverarch | cut -f 2 -d ' ')"
   AVER="$(grep "^${aoldoe} " /tmp/0pre-oe-add/0pre-oe-add-nameverarch | cut -f 3 -d ' ')"
   AARCH="$(grep "^${aoldoe} " /tmp/0pre-oe-add/0pre-oe-add-nameverarch | cut -f 4 -d ' ')"
   AIMG="$(find ${OEPATH}/${OEPROFILE}/${TMPFOLDER}/work/${AARCH}-*-linux*/${ANAME}/${AVER}/ -mindepth 1 -maxdepth 1 -type d -name image)" #170601
   [ ! "$AIMG" ] && continue #precaution
   echo "Found path: ${AIMG}" #180608
   #have full path to the 'image' folder. now create db-entry, then tarball...
   
   DB_pkgname="${ANAME}-${AVER}"
   DB_nameonly="${ANAME}"
   DB_version="${AVER}"
   DB_fullfilename="${ANAME}-${AVER}-${AARCH}.tar.xz"
   DB_path="${DISTRO_COMPAT_VERSION}"
   
   #can find description by looking in the recipe...
   #ARECIPE="$(grep '^"'"${DB_nameonly}"'" \[label="' ${OEPATH}/${OEPROFILE}/recipe-depends.dot | grep -o "${OEPATH}/.*" | cut -f 1 -d '"')"
   if [ -f ${OEPATH}/${OEPROFILE}/recipe-depends.dot ];then #20200927
    RDPREFIX='recipe' #pyro, thud
    ARECIPE="$(grep "^\"${DB_nameonly}\".*label=" ${OEPATH}/${OEPROFILE}/${RDPREFIX}-depends.dot  | grep -o "${OEPATH}/.*" | cut -f 1 -d '"')" #180608
   else
    RDPREFIX='task' #dunfell
    ARECIPE="$(grep "^\"${DB_nameonly}\.do_install.*label=" ${OEPATH}/${OEPROFILE}/${RDPREFIX}-depends.dot  | grep -o "${OEPATH}/.*" | cut -f 1 -d '"' | head -n 1)"
   fi
   if [ ! "$ARECIPE" ];then #180608
    #continue #precaution
    echo "Error: the .bb recipe file was not found."
    echo "Most likely did a build in OE with drivename different from now."
    echo "Looked in this file:
  ${OEPATH}/${OEPROFILE}/${RDPREFIX}-depends.dot"
    echo "Aborting"
    exit
   fi
   echo "Found recipe: ${ARECIPE}"
   DB_description="$(grep "^SUMMARY = " $ARECIPE | cut -f 2 -d '"' | sed -e 's%[^a-zA-Z0-9_. -]%%g')"
   
   #180715 find dependencies... 200927 fix...
   DB_dependencies=''; DEPENDS0=''
   if [ -f ${OEPATH}/${OEPROFILE}/recipe-depends.dot ];then #pyro, thud
    PTNdot='^"'"${DB_nameonly}"'" -'
    DEPENDSx="$(grep "${PTNdot}" ${OEPATH}/${OEPROFILE}/recipe-depends.dot | cut -f 4 -d '"' | grep -v '\-native$' | grep -v '\-cross' | grep -v 'packagegroup\-')"
   else #dunfell
    DEPENDSx="$(grep "^\"${DB_nameonly}\.do_prepare_recipe_sysroot" ${OEPATH}/${OEPROFILE}/task-depends.dot | cut -f 4 -d '"' | cut -f 1 -d '.' | grep -vE "^${DB_nameonly}$|^${DB_nameonly} |\-native|\-cross|packagegroup" | sort -u)"
   fi
   if [ "$DEPENDSx" ];then
    DEPENDS0="$(echo "$DEPENDSx" | tr '\n' ' ' | sed -e 's% $%%')"
   else
    #echo "ERROR: You forgot to regenerate ${OEPATH}/${OEPROFILE}/recipe-depends.dot"
    #echo "       It does not have entry for '${DB_nameonly}'"
    #echo "       Go back to OE and run 'bitbake -g <buildname>'"
    DEPENDS0="" #20200927
   fi
   
   [ "$DEPENDS0" ] && DB_dependencies="$(echo -n "$DEPENDS0" | sed -e 's%^%+%' -e 's% %,+%g' -e 's%,$%%' | sed -e 's% %%g' -e 's%,$%%' -e 's%+$%%')"
   
   xDB_description="$DB_description"
   [ "$DB_description" = "" ] && xDB_description="nothing"
   DB_category="$(${FIND_CAT} $DB_nameonly "$xDB_description")" #see updated find_cat

   DB_homepage="$(grep "^HOMEPAGE = " $ARECIPE | cut -f 2 -d '"')"
   [ "$DB_homepage" ] && echo "${DB_nameonly} ${DB_homepage}" >> PKGS_HOMEPAGES
   
   #170517 strip the files... 180723 now support cross-build strip...
   echo "Stripping files..."
   [ -d ${AIMG}XXX ] && rm -rf ${AIMG}XXX
   cp -a ${AIMG} ${AIMG}XXX
   
   #201007 need to cast the net wider...
   find ${AIMG}XXX -mindepth 2 -type f 2>/dev/null |
   while read ONEFILE
   do
    [ "$ONEFILE" == "" ] && continue
    ONENOT="$(echo "${ONEFILE/*imageXXX/}" | grep -E 'firmware|/share/|/doc/|/include/|/man/|/var/|/root/|/dev/|/font/')" #20201014
    [ "$ONENOT" ] && continue
    ONEBASE="`basename "$ONEFILE"`"
    [ "$ONEBASE" == "e3" ] && continue #cannot be stripped.
    [ "$ONEBASE" == "QtWeb" ] && continue #cannot be stripped.
    if [ "$(file "$ONEFILE" | grep 'ELF' | grep -E 'executable|shared')" != "" ];then
     echo -n " ${ONEBASE}"
     ${yPWD}/support/${CROSSSTRIP} --strip-unneeded "$ONEFILE"
    fi
   done
   sync
   
#   ##171019 allow WOOF_TARGETARCH='amd64x32' WOOF_HOSTARCH='amd64' ...
#   #if [[ ${WOOF_TARGETARCH} == ${WOOF_HOSTARCH}* ]] ;then #strip will not work for cross-build.
#    find ${AIMG}XXX/bin ${AIMG}XXX/sbin ${AIMG}XXX/usr/bin ${AIMG}/sbin -type f 2>/dev/null |
#    while read ONEFILE
#    do
#     [ "$ONEFILE" == "" ] && continue
#     ONEBASE="`basename "$ONEFILE"`"
#     [ "$ONEBASE" == "e3" ] && continue #cannot be stripped.
#     [ "$ONEBASE" == "QtWeb" ] && continue #cannot be stripped.
#     if [ "`file "$ONEFILE" | grep 'ELF' | grep -E 'executable|shared'`" != "" ];then #201007 fix.
#      echo -n "."
#      ${yPWD}/support/${CROSSSTRIP} --strip-unneeded "$ONEFILE" #180723
#     fi
#    done
#    echo
#    find ${AIMG}XXX/lib ${AIMG}XXX/usr/lib -type f -name \*.so* 2>/dev/null |
#    while read ONEFILE
#    do
#     [ "$ONEFILE" == "" ] && continue
#     ONEBASE="`basename "$ONEFILE"`"
#     if [ "`file "$ONEFILE" | grep 'ELF' | grep 'shared object'`" != "" ];then
#      echo -n "."
#      ${yPWD}/support/${CROSSSTRIP} --strip-unneeded "$ONEFILE" #180723
#     fi
#    done
#   #fi
   
   #180724 this has to be done after stripping...
   DB_size="$(du -s -k ${AIMG}XXX | cut -f 1)K"
   DBENTRY="$DB_pkgname|$DB_nameonly|$DB_version|$DB_pkgrelease|$DB_category|${DB_size}|$DB_path|$DB_fullfilename|$DB_dependencies|$DB_description|$DISTRO_BINARY_COMPAT|$DISTRO_COMPAT_VERSION||"
   echo "$DBENTRY" >> $PKGLISTS_COMPAT
  
   sync
   echo ; echo '...done'
  
   #import the package...
   echo "${DBENTRY}${AARCH}|${DB_homepage}|" > ${AIMG}XXX/pkg.specs #maybe useful to have in the pkg.
   cd ${AIMG}XXX
   tar -c -f  ${yPWD}/packages-${DISTRO_BINARY_COMPAT}-${DISTRO_COMPAT_VERSION}/${DB_pkgname}-${AARCH}.tar *
   cd "$yPWD"
   cd packages-${DISTRO_BINARY_COMPAT}-${DISTRO_COMPAT_VERSION}
   xz ${DB_pkgname}-${AARCH}.tar
   cd ..
   sync
   rm -f ${AIMG}/pkg.specs
   
  done
  #sort db entries...
  sort --key=1,1 --field-separator='|' $PKGLISTS_COMPAT > /tmp/0pre-oe-add/0pre-$PKGLISTS_COMPAT
  mv -f /tmp/0pre-oe-add/0pre-$PKGLISTS_COMPAT $PKGLISTS_COMPAT
  
  if [ -d ${PROJECTPATH}/${WOOFNAME}-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}/${WOOF_COMPATVERSION} ];then
   echo
   echo "Suggest also copy pkg-db to the master woofQ (Quirky build system):"
   echo "${PROJECTPATH}/${WOOFNAME}-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}/${WOOF_COMPATVERSION}/${PKGLISTS_COMPAT}"
   #ex: ...easy-distro/amd64/oe/pyro/Packages-oe-pyro-official
   echo -n "Press ENTER only to copy this file:"
   read t2update
   [ "$t2update" == "" ] && cp -a -f ${PKGLISTS_COMPAT} ${PROJECTPATH}/${WOOFNAME}-distro/${WOOF_TARGETARCH}/${WOOF_COMPATDISTRO}/${WOOF_COMPATVERSION}/
  fi
 fi
fi

echo
echo '...finished'
