#!/bin/bash

# The MIT License
#
# Copyright (c) 2011,2012 by Michael Prokop <mika@debian.org>
# Copyright (c) 2012-2020 by Christoph Berg <myon@debian.org>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

set -e
set -u

if [ -z "${PACKAGE:-}" ]; then
  PACKAGE="${JOB_NAME%-source*}"
fi

echo "PACKAGE=$PACKAGE"
echo "BUILD_NUMBER=${BUILD_NUMBER:-}"
echo "JOB_NAME=${JOB_NAME:-}"
echo "GIT_COMMIT=${GIT_COMMIT:-}"
echo "buildtype=${buildtype:-}"
echo "distribution=${distribution:=sid}"
echo "branch=${branch:-}"
echo "merge=${merge:-}"
echo "revision=${revision:-}"

# read pgapt config
for dir in . .. /home/jenkins/jenkins/workspace/apt.postgresql.org /home/buildd/workspace/apt.postgresql.org; do
  test -f $dir/pgapt.conf || continue
  set -x
  . $dir/pgapt.conf
  break
done
set_dist_vars $distribution

[ -n "${DEBEMAIL:-}" ] || export DEBEMAIL="$MAILING_LIST"

export PG_SUPPORTED_VERSIONS="pgdg"
# tell /usr/share/postgresql-common/supported-versions which distro/release we are targeting
export DISTRO RELEASE

# prepare 'source' directory
if [ "${GIT_COMMIT:-}" ]; then # git expects the checkout in 'source' subdir
  cd source
elif [ "${apt_suite:-}" ] ; then # apt-get source specified
  rm -rf $PACKAGE* source
  schroot -c $apt_suite -- apt-get source -d $PACKAGE/$apt_suite
  dpkg-source -x $PACKAGE*.dsc source
  cd source
else # use source tree in current directory
  :
fi

# merge with another branch
if [ "${merge:-}" ]; then
  REMOTE="https://salsa.debian.org/postgresql/postgresql.git"
  git remote add debian $REMOTE || :
  git fetch debian
  git reset --hard $branch
  git clean -xdf
  git merge --allow-unrelated-histories -m "Merge with $REMOTE ($merge)" debian/$merge
fi

# get newest version number from changelog
PREVIOUS_VERSION=$(dpkg-parsechangelog -SVersion)
BASE_VERSION=$(echo $PREVIOUS_VERSION | sed -e 's/[~.]\(pgdg\|pgapt\).*//')

# tweaks shared by several packages
TWEAK=()
if grep -q '^#dbg#' debian/rules debian/control*; then
    case ${distribution:-} in
      jessie|wheezy|squeeze|zesty|xenial|precise|trusty)
        # Revert to old-style -dbg packages
        sed -i -e 's/^#dbg#//' debian/rules debian/control*
        TWEAK+=("Using old-style -dbg packages in debian/control.")
        ;;
    esac
fi

# use older debhelper version
debhelper_compat ()
{
  local level="$1"
  if [ -f debian/compat ]; then
    pkglevel="$(cat debian/compat)"
  else
    pkglevel="$(grep -o 'debhelper-compat (= [0-9]*' debian/control | sed -e 's/.* //')"
  fi
  if [ -z "$pkglevel" ]; then
    echo "Could not determine debhelper compat level"
    exit 1
  fi
  echo "Package is using debhelper compat level $pkglevel"
  [ "$level" -ge "$pkglevel" ] && return
  sed -i -e "s/debhelper[^,]*/debhelper (>= $level)/" debian/control*
  echo "$level" > debian/compat
  TWEAK+=("Using debhelper $level.")
}

# for postgresql server packages, move packages to a separate components
# = $PG_MAIN_VERSION: main
# < $PG_MAIN_VERSION: lib packages to N.N, rest to main
# > $PG_MAIN_VERSION: all packages to N.N
set_package_component ()
{
  PKGPREFIX="$1" # empty ok
  SECTION="$2"
  echo "Setting $PKGPREFIX* packages component to '$SECTION'"
  perl -i -000 -pe "s/^Section: (?:.+\/)?(.*)/Section: $SECTION\$1/m if (/^$PKGPREFIX/m)" \
    debian/control
}
show_package_sections ()
{
  perl -000 -ne 'if (/^(Package: .*)/m) { print "$1 "; print "$1\n" if /^(Section: .*)/m; }' \
    debian/control
}
case $PACKAGE in
  postgresql-?.?|postgresql-??)
    PGVERSION=${PACKAGE#postgresql-}
    if dpkg --compare-versions $PGVERSION lt $PG_MAIN_VERSION; then
      set_package_component "Package: lib" "$PGVERSION\/"
      TWEAK+=("Moving lib packages to component $PGVERSION.")
    elif dpkg --compare-versions $PGVERSION gt $PG_MAIN_VERSION; then
      set_package_component "" "$PGVERSION\/"
      TWEAK+=("Moving binary packages to component $PGVERSION.")
    else
      set_package_component "" ""
    fi
    show_package_sections

    # enable cassert on sid
    if [ "$distribution" = "sid" ]; then
      sed -i -e 's/^#CASSERT_FLAGS/CASSERT_FLAGS/' debian/rules
      TWEAK+=("Enabling cassert.")
    fi

    case ${distribution:-} in
      jessie|wheezy|squeeze|zesty|xenial|precise|trusty)
        # Revert to old-style PIE config
        sed -i -e 's/^#PIE# //' debian/rules
        TWEAK+=("Using old-style PIE config in debian/rules.")
        ;;
    esac
    ;;
esac

# tweaks to get packages in older dists working

# PostgreSQL server tweaks
case $PACKAGE in
  postgresql-1[1-9]) # use llvm >= 5 (older versions choke on C++ exceptions, breaks PostGIS)
    case $distribution in
      bullseye|groovy) # clang-11
        ;;
      focal|eoan) # use clang-9
        sed -i -e 's/\(llvm\|llvm-config\|clang\)-[0-9]\+/\1-9/g' debian/control debian/rules
        TWEAK+=("Use clang/llvm 9 for jit support.")
        ;;
      buster|disco) # use clang-7
        sed -i -e 's/\(llvm\|llvm-config\|clang\)-[0-9]\+/\1-7/g' debian/control debian/rules
        TWEAK+=("Use clang/llvm 7 for jit support.")
        ;;
      stretch|bionic|xenial) # replace clang/llvm with 6.0
        # llvm <= 6.0.1 supports x32 only (missing r328687)
        sed -i -e 's/llvm-.*/llvm-6.0-dev [amd64 i386],/' \
               -e 's/clang-.*/clang-6.0 [amd64 i386],/' debian/control
        sed -i -e 's/\(llvm\|llvm-config\|clang\)-[0-9]\+/\1-6.0/g' debian/rules
        sed -i -e 's/\[.*amd64.*\]/[amd64 i386]/' debian/postgresql-*.install
        TWEAK+=("Use clang/llvm 6.0 for jit support on amd64/i386; disable on ppc64el.")
        ;;
    esac
    ;;
esac
case $PACKAGE in
  postgresql-[89].?|postgresql-1[01])
    case $distribution in buster|stretch|jessie|disco|bionic|xenial)
      # debian/postgresql-*.install is only relevant for 9.0
      sed -i -e 's/^#py2#//' debian/control debian/rules debian/postgresql-*.install
      TWEAK+=("Re-enable plpython2 packages.")
      ;;
    esac
    ;;
esac
case $PACKAGE in
  postgresql-8.?|postgresql-9.[01])
    case $distribution in stretch|jessie|bionic|xenial)
      sed -i -e '/ssl/ s/^#//' debian/control debian/postgresql-contrib-*.install
      sed -i -e 's/without-openssl/with-openssl/' debian/rules
      TWEAK+=("Re-enable OpenSSL support.")
      ;;
    esac
    ;;
esac
case $PACKAGE in
  postgresql-8.?|postgresql-9.?)
    case $distribution in buster)
      echo >> debian/rules
      echo "# dh_dwz is broken in buster for manual debug packages (#939164)" >> debian/rules
      echo "override_dh_dwz:" >> debian/rules
      TWEAK+=("Disable dh_dwz.")
      ;;
    esac
    ;;
esac
case $PACKAGE in
  postgresql-13)
    case $distribution in xenial)
      sed -i -e 's/^#xenial#//' debian/rules
      TWEAK+=("Disable libedit tests on xenial.")
      ;;
    esac
esac

# adjust debhelper level
case $PACKAGE in
  TODO) # debhelper with backport
    case $distribution in
      jessie) debhelper_compat 10 ;;
      stretch) debhelper_compat 12 ;;
      buster) debhelper_compat 13 ;;
      bullseye) debhelper_compat 13 ;;
      xenial) debhelper_compat 10 ;;
      bionic) debhelper_compat 12 ;;
      eoan|focal) debhelper_compat 12 ;;
      groovy) debhelper_compat 13 ;;
    esac
    ;;
  *) # debhelper without backport
    case $distribution in
      jessie|stretch) debhelper_compat 10 ;;
      buster) debhelper_compat 12 ;;
      bullseye) debhelper_compat 13 ;;
      xenial) debhelper_compat 9 ;;
      bionic) debhelper_compat 11 ;;
      eoan|focal) debhelper_compat 12 ;;
      groovy) debhelper_compat 13 ;;
    esac
    ;;
esac

# use ~ in version number for backport-style packages
case $PACKAGE in
  autopkgtest|cl-*|dh-exec|django-*|pkg-perl-tools|python-*|flask-*|sfcgal|speaklater)
    DOT='~'
    ;;
esac

# tweaks for other packages
case $PACKAGE in
  postgresql-common)
    case $distribution in buster|stretch|jessie|disco|bionic|xenial)
      sed -i -e 's/^#py2#//' debian/rules PgCommon.pm
      TWEAK+=("Re-enable plpython2 packages.")
      ;;
    esac
    ;;

  flask-security)
    case $distribution in stretch|xenial)
      sed -i -e '/python3-pytest-pep8/d' debian/control
      TWEAK+=("Remove python3-pytest-pep8 from Build-Depends.")
      ;;
    esac
    case $distribution in xenial)
      sed -i -e '/pytest-runner/d' debian/control
      sed -i -e 's/^#xenial/xenial/' debian/patches/series
      TWEAK+=("Removing pytest-runner from Build-Depends and setup.py.")
      ;;
    esac
    ;;

  libdbd-pg-perl|libpg-perl)
    DOT='~'
    case $distribution in
      buster|stretch|jessie|eoan|disco|bionic|xenial)
        sed -i -e 's/perl-xs-dev/perl/' debian/control
        TWEAK+=("Use perl in place of perl-xs-dev.")
        ;;
    esac
    ;;

  pgloader)
    case $distribution in jessie|xenial|trusty)
      sed -i -e '/html/d' debian/pgloader.docs debian/rules
      TWEAK+=("Do not build docs because Sphinx is too old.")
      ;;
      stretch|bionic)
        sed -i -e 's/#bionic/bionic/' debian/patches/series
        TWEAK+=("Remove theme options from sphinx docs.")
        ;;
    esac
    ;;

  pgadmin4)
    case $distribution in stretch|xenial)
      sed -i -e '/fonts-glewlwyd/d' -e '/fonts-open-sans/d' debian/control
      TWEAK+=("Not symlinking fonts-glewlwyd and fonts-open-sans files.")
      ;;
    esac
    case $distribution in xenial)
      sed -i -e 's/^#xenial/xenial/' debian/patches/series
      TWEAK+=("Dropping :widths: table options from rst documentation.")
      ;;
    esac
    ;;

  patroni)
    case $distribution in stretch|xenial)
      # remove consul/kubernetes modules at test time
      sed -i -e '/^python3/i rm -fv patroni/dcs/consul.py patroni/dcs/kubernetes.py tests/test_consul.py tests/test_kubernetes.py' debian/tests/test
      sed -i -e '/python3-\(consul\|kubernetes\)/d' debian/control debian/tests/control
      # Do not run the acceptance tests with consul or etcd as DCS.
      sed -i -e '/^#.consul/,/^$/d' debian/tests/control
      sed -i -e '/^#.etcd/,/^$/d' debian/tests/control
      TWEAK+=("Removing consul and kubernetes support.")
      ;;
    esac
    ;;

  pgbouncer)
    case ${distribution:-} in
      wheezy|trusty|xenial)
        TWEAK+=("Revert switch to c-ares because it is too old on $distribution.")
        sed -i -e '/libc-ares-dev/d' debian/control
        sed -i -e 's/--with-cares=yes/--with-cares=no/' debian/rules
        sed -i -e '/1.7.2-3/,/28 Jun 2017/d' debian/NEWS # remove news item about c-ares switch
        ;;
    esac
    ;;

  postgis)
    case ${distribution:-} in
      buster|stretch|focal|eoan|bionic|xenial)
        sed -i -e '/proj-7.0.1.patch/d' debian/patches/series
        TWEAK+=("Disable proj-7.0.1.patch.")
        ;;
    esac
    ;;

  postgresql-multicorn)
    case ${distribution:-} in
      jessie|stretch|trusty|xenial|zesty) # have older sqlalchemy
        sed -i -e 's/^655e4fb2b854cc004bf93db7a73a825dd49e35b5/#655e4fb2b854cc004bf93db7a73a825dd49e35b5/' debian/patches/series
        TWEAK+=("Using old sqlalchemy array api.")
        ;;
    esac
    ;;

  psycopg2)
    DOT='~'
    case ${distribution:-} in
      xenial)
        sed -i -e '/DEB_BUILD_MAINT_OPTIONS/s/^/#/' debian/rules
        TWEAK+=("Disable hardening flags.")
        ;;
    esac
    ;;

  repmgr)
    # Add libedit-dev to support building with postgres < 13
    sed -i -e 's/libreadline-dev,/libreadline-dev,\n libedit-dev,/' debian/control*
    TWEAK+=("Add libedit-dev dependency")
    ;;
esac

# for binnmu-style rebuilds, add a "revision" parameter to the source job
if [ "${revision:-}" ] ; then
  PGDG_REVISION="+${revision}"
else
  case $PREVIOUS_VERSION in
    *pgdg*|*pgapt*) PGDG_REVISION=$(echo $PREVIOUS_VERSION | sed -e 's/.*+/+/') ;;
    *) PGDG_REVISION="+1" ;;
  esac
fi

# set $UNRELEASED to force using a ~version
CL_DISTRIBUTION=$(dpkg-parsechangelog -SDistribution)
if [ "${UNRELEASED:-}" ] || echo "$CL_DISTRIBUTION" | grep -q "UNRELEASED" ; then
  case ${buildtype:-} in
  snapshot*) # create a ~ orig tarball
    TILDE='~'
    [ $buildtype = 'snapshot-dot' ] && TILDE='.'
    DATE="$(date -u +%Y%m%d.%H%M)"
    BASE_VERSION=$(echo "$BASE_VERSION" | sed -e "s/-/$TILDE$DATE-/")
    echo "1.0" > debian/source/format
    NO_ORIGTARGZ="1.0"
    test -d debian/patches && QUILT_PATCHES=debian/patches quilt push -a
    TWEAK+=("Use source format 1.0 for git snapshot build.")
    ;;
  esac
  SHORT_REVISION=$(echo ${GIT_COMMIT:-missing} | cut -c 1-7)
  SUFFIX="~${BUILD_NUMBER:-missing}.git${SHORT_REVISION}"
else
  SUFFIX=""
fi

# update changelog
# $DOT defaults to '.', but can be set to '~'
VERSION_STRING="$BASE_VERSION$SUFFIX${DOT:-.}$PGDG_DISTRIBUTION$PGDG_REVISION"
DATE=$(dpkg-parsechangelog -SDate)
cat > debian/changelog.tmp <<EOT
$PACKAGE ($VERSION_STRING) $distribution-pgdg; urgency=medium

  * Rebuild for $distribution-pgdg.
EOT
if [ "${TWEAK:-}" ]; then
  echo "  * Changes applied by generate-pgdg-source:" >> debian/changelog.tmp
  for tweak in "${TWEAK[@]}"; do
    echo "    + $tweak" >> debian/changelog.tmp
  done
else
  echo "  * No source changes." >> debian/changelog.tmp
fi
cat - debian/changelog >> debian/changelog.tmp <<EOT

 -- $MAILING_LIST  $DATE

EOT
mv debian/changelog.tmp debian/changelog
sed -ne '1,/^ --/p' debian/changelog

# remove artifacts from last build (-r because sometimes uscan leaves temp directories behind)
rm -rf ../*.*

# get orig tarball and unpack it in case it's a debian/ only checkout
[ "${NO_ORIGTARGZ:-}" ] || origtargz --tar-only --path ../result --path=$HOME/tarballs

if ! [ -f debian/control ] ; then
  make -f debian/rules debian/control
fi
if [ -f debian/control.in ]; then
  case $PACKAGE in
    postgis|postgis-2.5) debian/rules debian/control ;; # has its own update rule
    *) pg_buildext checkcontrol ;;
  esac
fi

# build source package and move it to 'result' for archiving
dpkg-buildpackage -uc -us -nc -d -sa -S -i -I --buildinfo-option=-O../buildinfo.tmp
cd ..
rm -rf result buildinfo.tmp
mkdir result
dcmd mv -v ${PACKAGE}_*.changes result

# clean up generated 'source' directory
if [ -z "${GIT_COMMIT:-}" ]; then rm -rf source; fi

# vim:foldmethod=marker ts=2 ft=sh ai expandtab sw=2
