#!/bin/bash
usage="Roll a minor release or release candidate
usage: $0 STEP... [OPTION...] VERSION [REVISION]

  STEP:
    build-env  download and set up prerequisites, into 'prefix/'
    roll       roll the tarballs, writing into 'deploy/'
    sign       sign the tarballs;
    test       (tell how to) run my tests
                 copy to dist-dev WC, ready for my testing
  * tag        create a tag
  * post       post the tarballs to dist-dev;
                 show an 'up for testing/signing' email
  * publish    move the tarballs to the dist-release area;
    announce   print release announcements (email and web content)
  * clean-dist clean all old releases from the dist-release area

  * This step commits a modification to the svn project resources.

  OPTION:
    --base-dir=DIR  directory for all files and 'deploy/', 'prefix/', 'tempdir/'
                    also passed to release.py [default: the CWD]
    --security      enable 'security release' options
    --patches=DIR   specify the directory where security patches are found
    --branch=PATH   specify the branch, relative to ^/subversion
                    [default: branches/VER.x]

  VERSION: a full version identifier (such as 1.1.0-rc1)

  REVISION: the branch revision number [default: from file 'subversion-VERSION.rev']
"

set -e

BASE_DIR="$PWD"  # e.g. /opt/svnrm
RELEASE_PY="$HOME/src/subversion-g/tools/dist/release.py"
DIST_DEV_WC="$HOME/install/subversion-dist/dev/subversion"
DIST_RELEASE_WC="$HOME/install/subversion-dist/release/subversion"
SITE_WC="$HOME/src/svn/site/publish"
PATCHES_DIR=
SECURITY_MODE=
BRANCH_PATH=

DO_BUILD_ENV=
DO_ROLL=
DO_SIGN=
DO_TEST=
DO_TAG=
DO_POST=
DO_PUBLISH=
DO_ANNOUNCE=
DO_CLEAN_DIST=
while [ "$#" -gt 0 ]; do
  case "$1" in
    build-env) DO_BUILD_ENV=1; shift;;
    roll) DO_ROLL=1; shift;;
    sign) DO_SIGN=1; shift;;
    test) DO_TEST=1; shift;;
    tag) DO_TAG=1; shift;;
    post) DO_POST=1; shift;;
    publish) DO_PUBLISH=1; shift;;
    announce) DO_ANNOUNCE=1; shift;;
    clean-dist) DO_CLEAN_DIST=1; shift;;
    --base-dir) BASE_DIR=$2; shift; shift;;
    --base-dir=*) BASE_DIR=${ARG#--base-dir=}; shift;;
    --security) SECURITY_MODE=1; shift;;
    --patches=*) PATCHES_DIR=${ARG#--patches=}; shift;;
    --branch=*) BRANCH_PATH=${ARG#--branch=}; shift;;
    -*) echo "$usage"; exit 1;;
    *) break;;
  esac
done

cd "$BASE_DIR"

# read VERSION and REVISION arguments
VERSION="$1"                # e.g. "1.10.0-rc1"
BASE_VER="${VERSION%-*}"    # e.g. "1.10.0"
BRANCH_VER="${VERSION%.*}"  # e.g. "1.10"
if test -z "$VERSION"; then
  echo "VERSION is required"
  exit 1
fi
if [ "$VERSION" = "$BASE_VER" ]; then
  IS_STABLE_RELEASE=1
else
  IS_STABLE_RELEASE=
fi

REVISION=
if [ $# -ge 2 ]; then
  REVISION="${2#r}"
fi

# read REVISION from a file if not given
REVISION_FILE="subversion-$VERSION.rev"
RF=
if [ -f "$REVISION_FILE" ]; then
  RF="$(< $REVISION_FILE)"
fi
if [ "$REVISION" ] && [ "$RF" ]; then
  if [ "$RF" != "$REVISION" ]; then
    echo >&2 "revision number given ($REVISION) != revision number in file '$REVISION_FILE' ($RF)"
    exit 1
  fi
elif [ "$RF" ]; then
  REVISION="$RF"
fi

if test -z "$REVISION"; then
  echo "REVISION is required (and not found in file '$REVISION_FILE')"
  exit 1
fi

RELEASE_PY="$RELEASE_PY --base-dir=$BASE_DIR"

function run() {
  echo >> svn-roll.log "starting: $@"
  (set -x; "$@") || exit
  echo >> svn-roll.log "    done: $@"
}


if test "$DO_BUILD_ENV"; then
  run rm -rf prefix tempdir

  run $RELEASE_PY build-env $VERSION
fi


if test "$DO_ROLL"; then
  run rm -rf deploy
  run rm -f $DIST_DEV_WC/*$VERSION*

  ROLL_OPTS=
  if [ "$PATCHES_DIR" ]; then
    ROLL_OPTS=--patches="$PATCHES_DIR"
  fi
  if [ "$BRANCH_PATH" = "" ]; then
    BRANCH_PATH=branches/$BRANCH_VER.x
  fi
  run $RELEASE_PY roll $ROLL_OPTS --branch "$BRANCH_PATH" $VERSION $REVISION
fi


if test "$DO_SIGN"; then
  # Signing
  run $RELEASE_PY sign-candidates --target deploy $VERSION
fi


if test "$DO_TEST"; then
  # Prepare for Testing
  run cp -aiv deploy/* $DIST_DEV_WC/

  echo "please run tests manually for now:"
  echo "(cd $DIST_DEV_WC/ && svn-dist-check $VERSION)"
  echo "(cd ~/src/ && svn-dist-unpack $VERSION && svn-dist-test $VERSION)"
fi


# The following parts make permanent changes to resources.
#
if test "$DO_TAG"; then
  # Tagging
  run $RELEASE_PY create-tag $VERSION $REVISION
fi


if test "$DO_POST"; then
  # Commit
  run $RELEASE_PY post-candidates $VERSION

  echo
  echo "please email dev@:"
  EMAIL_SUBJECT="Subversion $VERSION up for testing/signing"
  EMAIL_BODY="The $VERSION release artifacts are now available for testing/signing.
Please get the tarballs from
  https://dist.apache.org/repos/dist/dev/subversion
and add your signatures there.

Thanks!"
  echo "Subject: $EMAIL_SUBJECT"
  echo "[[["
  echo "$EMAIL_BODY"
  echo "]]]"

  echo
  echo "Please adjust the topic on #svn-dev to mention \"$VERSION is up for testing/signing\""
fi


if test "$DO_PUBLISH"; then
  run $RELEASE_PY move-to-dist $VERSION
fi


if test "$DO_ANNOUNCE"; then
  # Get the latest signatures, for 'write-announcement' to use
  run svn up --set-depth infinity "$DIST_RELEASE_WC"

  ANNOUNCEMENT_OPTS=
  if [ "$SECURITY_MODE" ]; then
    ANNOUNCEMENT_OPTS=--security
  fi
  ANNOUNCEMENT_EMAIL=$(run $RELEASE_PY write-announcement --target "$DIST_RELEASE_WC" $ANNOUNCEMENT_OPTS $VERSION)
  DOWNLOADS_SECTION=$(run $RELEASE_PY write-downloads --target deploy $VERSION)
  echo

  echo "Please send this announcement email:"
  echo "[[["
  echo "$ANNOUNCEMENT_EMAIL"
  echo "]]]"
  echo

  if false; then
  echo "Please update in ^/subversion/site/publish/download.html a line like"
  echo "    [define version]$VERSION[end]"
  echo "    [define supported]$VERSION[end]"
  echo
  echo "Please insert in ^/subversion/site/publish/download.html"
  echo "[[["
  echo "$DOWNLOADS_SECTION"
  echo "]]]"
  echo
  fi
  # Replace the EZT '[define ...]VER[end]' and the downloads section
  # This assumes we're updating to a newer patch release on $BRANCH_VER
  DOWNLOAD_HTML_FILE="$SITE_WC/download.html"
  DOWNLOADS_SECTION_FILE="downloads-section-$VERSION.txt"
  echo "$DOWNLOADS_SECTION" > "$DOWNLOADS_SECTION_FILE"
  if [ "$IS_STABLE_VERSION" ]; then
  DEFINE_MATCH_RE="^\[\(define \(version\|supported\)\)\]$BRANCH_VER.[0-9]\+\[\(end\)\]"
  DEFINE_REPLACEMENT="[\\1]$VERSION[\\3]"
  DOWNLOADS_SECTION_START_RE="<p.*Apache Subversion $BRANCH_VER"
  DOWNLOADS_SECTION_END_RE="<\/table>"
  run sed -i.orig \
          -e "s/$DEFINE_MATCH_RE/$DEFINE_REPLACEMENT/" \
          -e "/$DOWNLOADS_SECTION_START_RE/r $DOWNLOADS_SECTION_FILE" \
          -e "/$DOWNLOADS_SECTION_START_RE/,/$DOWNLOADS_SECTION_END_RE/d" \
          "$DOWNLOAD_HTML_FILE"
  fi
  if ! [ "$IS_STABLE_VERSION" ]; then
  # insert in pre-releases section
  PRE_RELEASE_INSERT_POINT_RE="<\/div>.*#\<pre-releases\>"
  run sed -i.orig \
          -e "/$PRE_RELEASE_INSERT_POINT_RE/!b" \
          -e "h" \
          -e "r $DOWNLOADS_SECTION_FILE" \
          -e "p" \
          -e "g" \
          "$DOWNLOAD_HTML_FILE"
  fi
  rm "$DOWNLOADS_SECTION_FILE"
  echo
  #run svn diff -x -U1 "$DOWNLOAD_HTML_FILE"
  echo

  NEWS_HTML_FILE="$SITE_WC/news.html"
  INDEX_HTML_FILE="$SITE_WC/index.html"
  ANNOUNCEMENT_EMAIL_URL="https://lists.apache.org/list.html?announce@subversion.apache.org"
  run $RELEASE_PY write-news $VERSION --announcement-url="$ANNOUNCEMENT_EMAIL_URL" --edit-html-file="$NEWS_HTML_FILE"
  run $RELEASE_PY write-news $VERSION --announcement-url="$ANNOUNCEMENT_EMAIL_URL" --edit-html-file="$INDEX_HTML_FILE"

  echo "The following changes are scheduled already:"
  run svn status "$SITE_WC"
  echo
  echo "'download', 'news', 'index' should have been updated; please double-check."
  echo
  echo "Please remove old news items from:"
  echo "  index.html"
  echo
  if [ "$IS_STABLE_RELEASE" ]; then
  echo "Please update:"
  echo "  docs/release-notes/release-history.html"
  echo "  doap.rdf"
  echo
  fi
  echo "Please commit:"
  echo "  svn ci -m 'Announce Subversion $VERSION' publish/"
  echo

  if [ "$IS_STABLE_RELEASE" ]; then
  echo "Please submit the version number '$VERSION' and date of the new release on:"
  echo "  https://reporter.apache.org/addrelease.html?subversion"
  echo
  fi

  echo "Please adjust the topic on #svn and #svn-dev to mention \"$VERSION released\""
  echo

fi


if test "$DO_CLEAN_DIST"; then
  run $RELEASE_PY clean-dist
fi

