#!/bin/bash

# The MIT License
#
# Copyright (c) 2011,2012 by Michael Prokop <mika@debian.org>
# Copyright (c) 2012-2022 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 "PG_SUPPORTED_VERSIONS=${PG_SUPPORTED_VERSIONS:=pgdg}"
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
# 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\).*//')

# 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
    ;;
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
      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],/' \
               -e '/postgresql-.*-jit-llvm/d' \
               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.?|prometheus-sql-exporter)
    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

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

# remove unsupported autopkgtest restrictions
case $distribution in bionic)
  if test -f debian/tests/control && grep needs-internet debian/tests/control; then
    sed -i -e 's/\(, \)\?needs-internet//' debian/tests/control
    TWEAK+=("Remove needs-internet from debian/tests/control.")
  fi
  ;;
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
    ;;

  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
      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
    ;;

  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
    ;;

  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
    case ${distribution:-} in
      stretch|bionic)
        sed -i -e 's/, skippable//' -e 's/exit 77/exit 0/' debian/tests/*
        TWEAK+=("Remove skippable flag from autopkgtest.")
        ;;
    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
