#!/bin/sh

# Copyright (C) 2007  International Business Machines.
# All Rights Reserved.
# This file is distributed under the Common Public License.
# It is part of the BuildTools project in COIN-OR (www.coin-or.org)
#
## $Id: prepare_new_release 1024 2008-06-20 14:14:32Z ladanyi $
#
# Author: Andreas Waechter     IBM      2007-06-21

#set -x -v

set -e
echo ''

if test "$#" -eq 0; then
  cat <<EOF
Usage: prepare_new_release stable_repos

stable_repos is the URL for the stable branch of your project, for which
you want to create a new release.  You can specify the entire URL, or you
just enter what comes after "https://projects.coin-or.org/svn".  A typical
example is

  prepare_new_release Ipopt/stable/3.3

You can use this script to prepare a new release based on the specified
stable branch.

This script will do the following:

- automatically determine the next release number
- check out a clean copy of the stable version specified
- update the externals to point to the latest releases in the dependencies
  (for the same stable branch as specified in the Externals script)
- update the version number in your configure.ac files
- receive the code for the externals
- use the "get.*" scripts to download ThirdParty code (if there are any)
- rerun the autotools
- check if all dependencies are using the same version of the BuildTools
- run the configure script and compile the code
- run the unit test

If there is any error during these tasks the script will stop and you should
examine the output.

If the script terminates successfully, you could have a look at the output,
particularly at the output of the unit test ('make test') and the
chosen Externals.

So far, no changes will have been made to the repository.  If you want to
commit the new release, run the "commit_new_release" script, as described
at the end of the output.

EOF
  exit 0
fi

stable_url=$1
if (echo $stable_url | grep -E 'stable/' >/dev/null); then :; else
  echo ''
  echo 'This URL is not for a stable release. Exiting.'
  echo ''
  exit -2
fi

case $stable_url in
  http*) ;;
  *)
    stable_url=https://projects.coin-or.org/svn/$stable_url
    ;;
esac

base_url=`echo $stable_url | sed -e 's|/stable/[0-9\.]*||'`
echo "Base URL..........: $base_url"
echo "Stable URL........: $stable_url"
stable_branch=`echo $stable_url | sed -e 's|.*/stable/]*||'`
echo "Stable branch.....: $stable_branch"

# finding out which releases already exist for that stable branch
echo ''
echo '===> Checking for current releases for this branch...'
tmp=`svn list $base_url/releases/`
release_vers=
for i in $tmp; do
  i=`echo $i | sed -e 's|/||g'`
  case $i in
    $stable_branch.*) release_vers="$release_vers $i";;
  esac;
done

# Determine latest release number
new_rel=-10000
for i in $release_vers; do
  echo "     $i"
  rel=`echo $i | sed -e "s|^$stable_branch.||"`
  if test $rel -gt $new_rel; then
    new_rel=$rel
  fi
done

if test $new_rel = -10000; then
  new_rel=0
elif test $new_rel = 0; then
  new_rel=1
else
  new_rel=`(expr $new_rel + 1)`
fi
new_ver="$stable_branch.$new_rel"

echo ''
echo "New release.......: $new_ver"

echo ''
echo "===> Checking out stable release $stable_branch without externals..."
echo ''

case $base_url in
  *ThirdParty/* )
    is_thirdparty=yes
    is_data=no
    ;;
  *Data )
    is_thirdparty=no
    is_data=yes
    ;;
  *)
    is_thirdparty=no
    is_data=no
    ;;
esac

if test $is_thirdparty = yes || test $is_data = yes; then
  buildtoolsurl=$2
  if test "$buildtoolsurl" == ""; then
    echo ''
    echo 'For a ThirdParty project you need to provide a URL for BuildTools'
    echo 'as second argument.  Exiting.'
    echo ''
    exit -3
  fi
  case $buildtoolsurl in
    http*) ;;
    *)
      buildtoolsurl=https://projects.coin-or.org/svn/$buildtoolsurl
      ;;
  esac
fi

tmpbas=tmp_checkout
if test $is_thirdparty = yes; then
  tmpcodir=$tmpbas/a/b
elif test $is_data = yes; then
  tmpcodir=$tmpbas/a
else
  tmpcodir=$tmpbas
fi

rm -rf $tmpbas
cmd="svn co --ignore-externals $stable_url $tmpcodir"
echo $cmd
eval $cmd

if test $is_thirdparty = yes || test $is_data = yes; then
  echo ''
  echo '===> Checking out BuildTools for ThirdParty project...'
  echo ''
  cmd="svn co $buildtoolsurl $tmpbas/BuildTools"
  echo $cmd
  eval $cmd
fi

tmpcodir=`cd $tmpcodir; pwd`
tmpbas=`cd $tmpbas; pwd`

cd $tmpcodir

echo ''
conf_ac_files=`find . -name 'configure.ac' | grep -v -E 'ThirdParty/.*/.*/configure.ac'`
echo "===> Creating backup (.bak) for configure.ac files..."
for i in $conf_ac_files; do
  cp $i $i.bak
done

echo ''
echo "===> Updating version number ($new_ver) in configure.ac files"
for i in $conf_ac_files; do
  sed -e "s|AC_INIT\(.*\)\[[0-9A-Za-z\.]*\],\(.*\)|AC_INIT\1[$new_ver],\2|" $i > bla
  mv bla $i
  svn di $i
done

if test -r Externals; then

  echo ''
  echo '===> Creating new Externals file with pointers to releases...'
  echo ''

  rm -f Externals.releases
  ext_name=
  ext_url=
  for i in `cat Externals`; do
    if test "$ext_name" = ""; then
      ext_name="$i"
    else
      ext_url=$i
      if (echo $ext_url | grep -E 'stable/' >/dev/null); then :; else
        echo ''
        echo "The external URL $ext_url is not for a stable branch. Exiting."
        echo ''
        exit -2
      fi
    
      ext_base_front=`echo $ext_url | sed -e 's|/stable/.*||'`
      ext_base_end=`echo $ext_url | sed -e 's|.*/stable/[0-9\.]*||'`
      ext_stable_branch=`echo $ext_url | sed -e 's|.*/stable/]*||' -e s"|$ext_base_end||"`

      echo "Determining release replacement for $ext_name:"
      tmp=`svn list $ext_base_front/releases/`
      ext_release_vers=
      for i in $tmp; do
        i=`echo $i | sed -e 's|/||g'`
        case $i in
          $ext_stable_branch.*) ext_release_vers="$ext_release_vers $i";;
        esac;
      done
      # Determine latest release number
      ext_latest=-10000
      for i in $ext_release_vers; do
        rel=`echo $i | sed -e "s|^$ext_stable_branch.||"`
        if test $rel -gt $ext_latest; then
          ext_latest=$rel
        fi
      done
      if test $ext_latest = -10000; then
        echo ''
        echo "Error: No release for $ext_name for its stable defined in External"
        echo ''
        exit -5
      fi

      if test "$ext_base_end" = ""; then
        ext_rel_url=$ext_base_front/releases/$ext_stable_branch.$ext_latest
      else
        ext_rel_url=$ext_base_front/releases/$ext_stable_branch.$ext_latest$ext_base_end
      fi

      echo "  $ext_rel_url"
      echo "$ext_name  $ext_rel_url" >> Externals.releases
      ext_name=
    fi
  done

  echo '===> Creating backup (.bak) for Externals'
  mv Externals Externals.bak
  mv Externals.releases Externals

  echo ''
  echo '===> Updating svn:externals properties, and checking out externals...'
  echo ''

  svn pset svn:externals -F Externals .

  svn update

  echo ''
  echo '===> If there are ThirdParty externals, run the download scripts...'
  echo ''

  ext_name=
  ext_url=
  for i in `cat Externals`; do
    if test "$ext_name" = ""; then
      ext_name="$i"
    else
      ext_url=$i

      case $ext_name in
        ThirdParty/*)
          pkg=`echo $ext_name | sed -e 's|ThirdParty/||' -e 's|/||g'`
          getfile=get.$pkg
          if test -r $ext_name/$getfile; then
	    curdir=`pwd`
            cd $ext_name
            echo "Running $getfile -patch in `pwd`"
#	    mv $getfile $getfile.orig
#	    sed -e 's+ftp://+http://+g' $getfile.orig > $getfile
#	    chmod +x $getfile
            eval ./$getfile -patch
#	    mv $getfile.orig $getfile
            cd "$curdir"
          fi
          ;;
      esac
      ext_name=
    fi
  done
fi # if test -r Externals

if test $is_thirdparty = yes; then
  pkg=`echo $base_url | sed -e 's|.*/||g'`
  if test -r get.$pkg; then
    echo ''
    echo '===> Download third party code...'
    echo ''
    ./get.$pkg
  fi
fi

echo ''
echo '===> Running the autotools...'
echo ''

if test $is_thirdparty = yes; then
  curdir=`pwd`
  cd ../..
  BuildTools/run_autotools
  cd "$curdir"
elif test $is_data = yes; then
  curdir=`pwd`
  cd ..
  BuildTools/run_autotools
  cd "$curdir"
else
  BuildTools/run_autotools
fi

if test -r Externals; then

  echo '===> Verifying consistency of the BuildTools versions...'
  echo ''

  ext_name=
  ext_url=
  rm -f problems.ext
  for i in `cat Externals`; do
    if test "$ext_name" = ""; then
      ext_name="$i"
    else
      ext_url=$i

      echo "  checking $ext_name"

      num_M=`svn status $ext_name | grep -E '^M' | wc -l`

      if test $num_M -ne 0; then
        echo $ext_name >>problems.ext
        echo '    ... BuildTools not consistent!'
      else
        echo '    ... Ok'
      fi
      ext_name=
    fi
  done

  if test -r problems.ext; then
    echo ''
    echo 'PROBLEM DURING CONSITENCY CHECK:'
    echo ''
    echo 'Please contact the project manager(s) for the following project(s).'
    echo 'A new release needs to be made with your stable branch of BuildTools.'
    echo ''
    cat problems.ext
    echo ''
    rm -f problems.ext
    exit -2
  fi
  rm -f problems.ext
fi # if test -r Externals

if test $is_thirdparty != yes && test $is_data != yes; then
  (set -e
   echo ''
   echo '===> Creating build directory and running the configuration script...'
   echo ''
   mkdir build
   cd build
   cmd="$tmpcodir/configure -C --enable-maintainer-mode"
   echo $cmd
   eval $cmd
   echo ''
   echo '===> Compiling code...'
   echo ''
   cmd='make install'
   echo $cmd
   eval $cmd
   echo ''
   echo '===> Running the unit test...'
   echo ''
   echo '*******************************************************************************'
   echo '***                                                                         ***'
   echo '***                       BEGIN OUTPUT OF MAKE TEST                         ***'
   echo '***                                                                         ***'
   echo '*******************************************************************************'
   echo ''
   cmd='make test'
   echo $cmd
   eval $cmd
   echo ''
   echo '*******************************************************************************'
   echo '***                                                                         ***'
   echo '***                        END OUTPUT OF MAKE TEST                          ***'
   echo '***                                                                         ***'
   echo '*******************************************************************************'
  )
  if test $? != 0; then
    echo ''
    echo 'Error during build or test'
    echo ''
    exit -3
  fi
fi

echo ''
echo '===> ALL TESTS PASSED'
if test $is_thirdparty != yes && test $is_data != yes; then
  echo ''
  echo 'Please review the output above, particularly the one of make test'
fi
if test -r Externals; then
  echo ''
  echo 'Also, please check the Externals:'
  cat Externals
fi

echo ''
echo 'After reviewing the output above, you can create a new release by going into'
echo 'the directory'
echo ''
echo "          $tmpcodir"
echo ''
echo "and run the commit_new_release script"

cat >.new_release_data <<EOF
tmpcodir=$tmpcodir
tmpbas=$tmpbas
base_url=$base_url
stable_url=$stable_url
new_ver=$new_ver
stable_branch=$stable_branch
EOF
