#!/bin/sh
######################################################################
# Generic Cygwin shell script that 
#
#  1) identifies the package by finding the DESCRIPTION file, then
#  2) installs the package locally, 
#  3) checks the package.
#  4) builds the source and binary distributions, and
#
# This is done by first copying necessary files (not garbage files 
# such as Emacs backup files) to a temporary directory. 
#
# Usage:
#  1) The current directory must be such that the ${pkg}/DESCRIPTION
#     file exists if ${pkg} is to be installed.
#  2) sh buildPackage.sh
#
# Requirements:
#  1) It require that Rtools are used (and not standard Cygwin!).
#     For this I have myself a MSDOS startup script RCMDprompt.bat.
#  2) The Rd.sty must be in the texmf path of LaTeX.  Simply copy 
#     the ${R_HOME}/share/texmf/ directory to your local texmf, e.g.
#     to C:\localtexmf\R\ and rehash TeX (I MikTeX, this is done in
#     'MikTeX Options'.
#
# Reference:
#  [1] Duncan Murdoch, Using MiKTeX with R for Windows, 2005.
#      http://www.murdoch-sutherland.com/Rtools/miktex.html 
#
# Henrik Bengtsson, hb@biostat.ucsf.edu
######################################################################

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Assert that Rd.sty is in the LaTeX search path, or try to fix it.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
if test -z "`findtexmf Rd.sty`"; then
  # If not, try to add it via TEXINPUTS, which might not always
  # work with MikTeX depending on its setup, cf. [1].
  TEXINPUTS=${R_PATH}/shared/texmf/
  echo "Added ${R_PATH}/shared/texmf/ to TEXINPUTS"
  # Check if Rd.sty is in the LaTeX search path
  if test -z "`findtexmf Rd.sty`"; then
    echo "ERROR: Rd.sty is not available, which will make R CMD check to fail when it checks the LaTeX manual of the package. Please make sure ${R_HOME}/shared/texmf/ is in the local texmf path and the refresh your texmf database.  If you are using MikTeX, please see instructions at http://www.murdoch-sutherland.com/Rtools/miktex.html."
    exit
  fi
fi


if test -d ${R_HOME}/library/00LOCK; then
  echo "ERROR: Lock found: ${R_HOME}/library/00LOCK"
  exit -1;
fi

pkg=`grep -h -w Package: */DESCRIPTION | head -1 | cut -c10-`;
if test -z ${pkg}; then
  echo "ERROR: Found DESCRIPTION, but it is not for a package."
fi
#if ! test -d ../${pkg},*; then
#  echo "ERROR: Identified package, but directory ${pkg}/ is missing!"
#  exit
#fi


# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Identifying package and R versions
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
version=`grep -w Version: ${pkg}/DESCRIPTION | cut -c10-`;
echo "Preparing to build ${pkg} version ${version}..."

# Get the R version
Rterm --version 2> "${TMP}\tmp.txt"
Rversion=`grep "^R [12][.][0-9]*[.][0-9]" "${TMP}\tmp.txt" | cut -c3-7`

if test -z ${Rversion}; then
  Rversion=`grep "^Version [12][.][0-9]*[.][0-9]" "${TMP}\tmp.txt" | cut -c9-13`
  if test -z ${Rversion}; then
    Rversion=`grep "^R version [12][.][0-9]*[.][0-9]" "${TMP}\tmp.txt" | cut -d' ' -f3`
    if test -z ${Rversion}; then
      Rversion=devel
    fi
  fi
fi
echo Rversion=${Rversion}
if test -z ${Rversion}; then
  echo "ERROR: Could not identify the R version for 'Rterm --version'"
  exit
fi
rm -f "${TMP}\tmp.txt"
echo "Building package using R 'v${Rversion}'"


# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Identifying work directory
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
opwd=`pwd`
echo "Return directory is ${opwd}"

mkdir -p "${opwd}/R${Rversion}/"

if test -z ${buildDir}; then
#  buildDir="${TMP}/R${Rversion}";
  buildDir="${opwd}/R${Rversion}";
fi

if ! test -d ${buildDir}; then
  mkdir -p "${buildDir}"
fi


# TEMPDIR must be set anyway. The R CMD scripts will check it.
dest=${buildDir}/${pkg}
echo $dest
rm -rf "${dest}/"
mkdir "${dest}/"
echo "Tempory working directory for package ${pkg} is ${dest}"
  
# From "Checking and building packages" in [1]:
# "To exclude files from being put into the package, one can specify
#  a list of exclude patterns in file .Rbuildignore in the top-level
#  source directory. These patterns should be Perl regexps, one per
#  line, to be matched against the file names relative to the 
#  top-level source directory. In addition, files called CVS or 
#  GNUMakefile, or with base names starting with .#, or starting and
#  ending with #, or ending in ~ or .bak or .swp, are excluded by 
#  default."

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# 2) Copying...
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
echo "Copying files from package ${pkg}..."

# 2a) The DESCRIPTION file
if test -e ${pkg}/DESCRIPTION; then
  cp ${pkg}/DESCRIPTION "${dest}/"
elif test -e ${pkg}/DESCRIPTION.in; then
  echo "  Using DESCRIPTION.in as DESCRIPTION"
  cp ${pkg}/DESCRIPTION.in "${dest}/DESCRIPTION"
else
  echo "  ERROR: Neither DESCRIPTION nor DESCRIPTION.in was found"
  exit
fi

# 2a) The NAMESPACE file
if test -e ${pkg}/NAMESPACE; then
  cp ${pkg}/NAMESPACE "${dest}/"
fi

# 2a) The NAMESPACE file
if test -e ${pkg}/Makefile; then
  cp ${pkg}/Makefile "${dest}/"
fi

# 2a) The LICEN[CS]E file
if test -e ${pkg}/LICEN?E; then
  cp ${pkg}/LICEN?E "${dest}/"
fi

# 2b) The man/ directory
dir="man"
echo "  ${dir} (*.Rd files only)"
mkdir "${dest}/${dir}/"
if test -d ${pkg}/${dir}/; then
  cp -fpr ${pkg}/${dir}/*.Rd "${dest}/${dir}/"
  cp -fpr ${pkg}/${dir}/.*.Rd "${dest}/${dir}/"
else
  mkdir "${pkg}/${dir}/"
  echo "  WARNING: Created missing ${dir}/ in package ${pkg}."
fi

# 2c) The R/ directory
dir="R"
echo "  ${dir} (*.R and *.Rex files only)"
if test -d ${pkg}/${dir}/; then
  mkdir "${dest}/${dir}/"
  cp -fpr ${pkg}/${dir}/*.r   "${dest}/${dir}/"
  cp -fpr ${pkg}/${dir}/*.R   "${dest}/${dir}/"
fi

# 2d) The src/ directory
dir="src"
echo "  ${dir} (recursively)"
if test -d ${pkg}/${dir}/; then
  mkdir "${dest}/${dir}/"
  cp -fpr ${pkg}/${dir} "${dest}/"
fi

# 2e) The data/, inst/, and tests/ directories
for dir in data inst tests vignettes; do
  echo "  ${dir}"
  if test -d ${pkg}/${dir}/; then
    cp -fpr ${pkg}/${dir}/ "${dest}/${dir}/"
    # Remove garbage files
    rm -f "${dest}/${dir}/*~"
    rm -f "${dest}/${dir}/*/*~"
    rm -f "${dest}/${dir}/*/*/*~"
  fi
done

# 2f) The incl/ directory
for dir in incl; do
  echo "  ${dir}"
  if test -d ${pkg}/${dir}/; then
    cp -fpr ${pkg}/${dir}/ "${dest}/${dir}/"
    # Remove garbage files
    rm -f "${dest}/${dir}/*~"
    rm -f "${dest}/${dir}/*/*~"
    rm -f "${dest}/${dir}/*/*/*~"
  fi
done



cd "${buildDir}"
echo "Temporary working directory is ${buildDir}"

echo "Directory structure:"
ls -alR ${dest}/

# From "Checking and building packages" in [1]:
# "Run-time checks whether the package works correctly should 
#  be performed using R CMD check prior to invoking the build
#  procedure."


# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# 5a) Building source distribution
#
# Note that you have to build this file first, otherwise *subdirectories*
# of src/ will contain *.o files etc.  This is because --clean does not
# clean subdirectories of src/.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
buildOpts=""
# buildOpts="--no-vignettes"
mkdir -p "${opwd}/R${Rversion}/"
echo "Building source code distribution of package ${pkg}..."
R --no-init-file CMD build --force ${buildOpts} ${pkg}
#mv "${pkg}_${version}.tar.gz" "${opwd}/R${Rversion}/"


# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# 4) Building binary distribution
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#echo "Installing package ${pkg} on this machine and building binary (Windows) distribution of package ${pkg}..."
## RCMD build --force --binary ${buildOpts} ${pkg}
R --no-init-file CMD INSTALL --build --merge-multiarch ${pkg}_${version}.tar.gz

mv "${pkg}_${version}.tar.gz" "${opwd}/R${Rversion}/"
mv "${pkg}_${version}.zip" "${opwd}/R${Rversion}/"


# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# 3) Installing
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#echo "Installing package ${pkg} on this machine..."
#RCMD INSTALL --clean ${pkg}

if test "$1" = "--install-only"; then
  exit;
fi
if test "$1" = "-io"; then
  exit;
fi



# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# 5) Checking package
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
rm -rf "${opwd}/R${Rversion}/${pkg}.Rcheck/"

echo "Checking package ${pkg}..."
export _R_CHECK_TIMINGS_=1
export _R_CHECK_FULL_=1
R --no-init-file CMD check --as-cran --timings ${pkg}_${version}.tar.gz
## RCMD check ${pkg}

# 5b) Moving Rcheck files back home
# mv "${dest}.Rcheck/" "${opwd}/R${Rversion}"


cd "${opwd}"

# 6) Removing temporary files
rm -rf "${dest}"


######################################################################
# HISTORY:
# 2012-02-23
# o Now using 'R --no-init-file CMD <cmd>' instead or 'RCMD <cmd>'.
# 2012-01-10
# o Now Rcmd check also reports on timing statistics.
# 2011-07-14
# o BUG FIX: R --version no longer includes a version for R-devel.
# 2010-12-05
# o BUG FIX: The windows binaries were not building both i386 and
#   x64.  Added --merge-multiarch to fix this.
# 2010-09-28
# o BUG FIX: The tests for Rd.sty existence assumed that there were
#   to whitespaces in the path to Rd.sty.
######################################################################

