#! /usr/bin/env bash

# Use fpm to package up files into an RPM.

# Usage:
#   mk_rpm_fpmdir PACKAGENAME MANIFEST1 MANIFEST2 ...

# Example:
#   Make a package foopkg manifest.txt
# Where "manifest.txt" contains:
#   exec /usr/bin/stack_makefqdn  misc/stack_makefqdn.py
#   exec /usr/bin/bar             bar/bar.sh
#   read /usr/man/man1/bar.1      bar/bar.1.man
#   0444 /etc/foo.conf            bar/foo.conf

set -e

# Parameters for this RPM:
PACKAGENAME=${1?"First arg must be the package name."}
shift

# What is my name?
CMDNAME=$(basename $0)

# Defaults that can be overridden:
# Packages are 1.0 unless otherwise specifed:
: ${PKGVERSION:=1.0} ;
# If there is no iteration set, default to use the number of commits in the repository:
if [[ -z "${PKGRELEASE}" ]]; then
  PKGRELEASE=$(git rev-list HEAD --count)
  if [[ $? != 0 ]]; then
    # We're not in a git repo, fall back to 1 so we cope with being built from
    # a tarball
    PKGRELEASE=1
  fi
fi

# If there is no epoch, assume 0
: ${PKGEPOCH:=0}

# If no arch defined, assume any. Other good values include "native".
: ${PKGARCH:=all}
# NOTE: If we later compile code, we set this to "native", which
# FPM will translate to the correct value for local conditions.

# Allow us to set a different OUTPUTDIR if we're building in CI/CD
if [[ -z "${OUTPUTDIR}" ]]; then
  # The RPM is output here: (should be a place that can be wiped)
  OUTPUTDIR="${HOME}/rpmbuild-${PACKAGENAME}"
else
  echo "Using ${OUTPUTDIR} for OUTPUTDIR instead of ${HOME}/rpmbuild-${PACKAGENAME}"
fi
INSTALLROOT="$OUTPUTDIR/installroot"

# StackOverflow's TeamCity templates expect to find the list of artifacts here:
RPM_BIN_LIST="${OUTPUTDIR}/bin-packages.txt"

# -- Now the real work can be done.

# Clean the output dir.
rm -rf "$OUTPUTDIR"
mkdir -p "$INSTALLROOT"

# If there is a build script, execute it.
BUILDSCRIPTNAME="./build.${PACKAGENAME}.sh"
if [[ -x $BUILDSCRIPTNAME ]]; then
  echo "========== $BUILDSCRIPTNAME FOUND. Running."
  if [[ $PKGARCH == "all" ]]; then
    echo 'WARNING: PKGARCH=all (which may not what you want)'
    # If you are using a build.*.sh script, you probably want to
    # set PKGARCH to "native" before you run mk_rpm_fpmdir.
  fi
  $BUILDSCRIPTNAME "$INSTALLROOT" "${PKGVERSION}"
  # If we used the build build.*.sh script, it must do all compilation.
  # Therefore, we disable the automagic GO build feature.
  GO_COMPILE=false
else
  GO_COMPILE=true
fi

# If there are additional args for fpm, read them into a variable.  There is
# a chdir later, therefore we can't rely on the file path working at that time.
FPM_OPTIONS_FILE="./fpm_opts.${PACKAGENAME}.sh"
if [[ -f $FPM_OPTIONS_FILE ]]; then
  echo "========== $FPM_OPTIONS_FILE FOUND. Loading."
  FPM_OPTIONS=$(<$FPM_OPTIONS_FILE)
fi
# Warning: The contents of the file are evaluated therefore
# quotes and special chars must be quoted.

# Copy any static files into place:
set -o pipefail  # Error out if any manifest is not found.
cat "$@" | while read -a arr ; do
  PERM="${arr[0]}"
  case $PERM in
    \#*)  continue ;;   # Skip comments.
    exec) PERM=0755 ;;
    read) PERM=0744 ;;
    *) ;;
  esac
  DST="$INSTALLROOT/${arr[1]}"
  SRC="${arr[2]}"
  if [[ ${#arr[@]} != 3 ]] ; then
    echo "ERROR: Line must contain 3 items."
    echo "DEBUG NUM=${#arr[@]} PERM=$PERM DST=$DST SRC=$SRC"
    exit 1
  fi
  if $GO_COMPILE && [[ $SRC == "cmd/"* || $SRC == *"/cmd/"* ]]; then
    echo "========== BUILD&COPY $SRC"
    ( cd $(dirname "$SRC" ) && go get -d && go build ) 
    PKGARCH=native
  else
    echo "==========       COPY $SRC"
  fi
  if [[ ! -f "$SRC" ]]; then
    echo "${CMDNAME}: ERROR: File not found: $SRC"
    exit 1
  fi
  install -D -T -b -m "$PERM" -T "$SRC" "$DST"
done

set -x
# Build the RPM out of what is found in $INSTALLROOT:
cd "$OUTPUTDIR" && fpm -s dir -t rpm \
  -a "${PKGARCH}" \
  -n "${PACKAGENAME}" \
  --epoch "${PKGEPOCH}" \
  --version "${PKGVERSION}" \
  --iteration "${PKGRELEASE}" \
  ${PKGDESCRIPTION:+ --description="${PKGDESCRIPTION}"} \
  ${PKGVENDOR:+ --vendor="${PKGVENDOR}"} \
  ${FPM_OPTIONS:+ $FPM_OPTIONS} \
  -C "$INSTALLROOT" \
  .

# TeamCity templates for RPMS expect to find
# the list of all packages created in bin-packages.txt.
# Generate that list:
find "$OUTPUTDIR" -maxdepth 1 -name '*.rpm' >"$RPM_BIN_LIST"
# Output it for debugging purposes:
cat "$RPM_BIN_LIST"
