# actions.sh
# -----------------------------------------------------------------------------
#
# mingw-pkg module implementing the action hooks for all core activities.
#
# -----------------------------------------------------------------------------
#
# $Id: actions.sh,v 84c632a2bf6d 2020/08/23 13:41:42 keith $
#
# Written by Keith Marshall <keithmarshall@users.sourceforge.net>
# Copyright (C) 2011-2018, 2020, MinGW.org Project
#
# 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.
#
# -----------------------------------------------------------------------------
#
  require module defn

# phase() and step() helper functions; these facilitate progress reporting
# during action processing.
#
  phase() {
    test "x$active_phase" = "x$1" || {
      active_phase="$1"; test $# -gt 1 && shift
      echo; echo "$bold>>> $*$unbold"; echo
    }
  }
  step() { echo ">>> $*"; }

# Action "initialize" (a.k.a. "initialise"): initialize the package tree
# for management by "mingw-pkg"; add the "arch/mingw32" directory, in which
# mingw32 specific configuration files and patches will be collected.
#
  defn initialize
  defn_set_hook initialize end request_initialize_mkarchdir
  request_initialize_mkarchdir() {
    mkdir -p ${PACKAGE_SRCDIR-"."}/arch/${ARCH="mingw32"}
  }

# Action "import": this should unpack the upstream package tarball,
# optionally downloading it if necessary, into a working tree which has
# been initialized with only "arch/mingw32/*.pkgspec", (or optionally,
# such a tree instantiated "on-the-fly", from a mingw-port tarball,
# which may itself need to be downloaded from MinGW.org's online
# mingw-ports repository, to complete the operation).
#
  defn import
  defn_set_hook import default request_import
  request_import() { require module import; }

# Action "mkspec": add a "*.pkgspec" template to the "arch/mingw32" working
# directory; user should then edit this, to apply any specific customisation
# which may be appropriate for the associated package.
#
  defn mkspec
  defn_set_hook mkspec default request_mkspec
  request_mkspec() { require module mkspec; }

# Action "patch": apply a specified $PATCHFILE, or a series of patches
# from a specified $PATCHDIR, (default "arch/mingw32/*.patch"), to the
# working package tree.
#
  defn patch
  defn_set_hook patch default request_apply_patches
  request_apply_patches() { phase patch "apply patches"
    ( cd "$PACKAGE_ABS_SRCDIR"
      if test "x$PATCHFILE" = x
      then
	for PATCHFILE in ${PATCHDIR="arch/${ARCH="mingw32"}"}/*.patch
	  do request_apply_patches; done
	phase "done."
      elif test -f $PATCHFILE
      then
	step "applying patch: $PATCHFILE"
	patch ${PATCHFLAGS-"-p1"} < $PATCHFILE
	test "x$PATCHDIR" = x && phase "done."
      fi
    )
  }

# Action "compile": compile the package codebase, as determined by the
# current state of the working package directory tree; assumes that the
# GNU "configure && make" paradigm applies, running "configure" if the
# "config.status" file does not yet exist, then runs "make"; supports
# "out-of-tree" builds, when either $PACKAGE_SRCDIR or $SRCDIR is
# defined appropriately, to locate the top source directory.
#
  defn compile
  defn_set_hook compile default request_compile
  request_compile() { phase compile "compile codebase"
    test -f config.status || invoke_action_hooks require_configure
    eval default_compile $compile_options || die "application build failed"
    phase "done."
  }
  default_compile() { local make_cmd="make $make_options"
    eval 'PACKAGE_SRCDIR="${PACKAGE_SRCDIR-"${SRCDIR-"."}"}" $make_cmd "$@"'
  }

# Action "configure": explicitly run the configure script; may be used to
# force reconfiguration, prior to "compile",  when "config.status" already
# exists, and the "makefile" neglects to track configuration changes.
#
  defn configure
  defn_set_hook configure default request_configure
  defn_set_hook require_configure default require_configure
  require_configure() { test -f ${PACKAGE_SRCDIR="${SRCDIR-"."}"}/configure \
    && invoke_action_hooks configure
  }
  request_configure() {
    test "x$active_phase" = "xcompile" \
      || phase configure "configure for build"
    test -r "$PACKAGE_SRCDIR/arch/$ARCH/$PACKAGE-$VERSION-$ARCH.xconfig" &&
      . "$PACKAGE_SRCDIR/arch/$ARCH/$PACKAGE-$VERSION-$ARCH.xconfig"
    ${xtool_mode-false} || configure_options=`eval $xhost_configure_options`
    eval ${PACKAGE_SRCDIR="${SRCDIR-"."}"}/configure $configure_options \
      || die "package configuration failed"
    test "x$active_phase" = "xconfigure" && phase "done."
  }

# Action "install": install the application into the target directory
# specified at configuration time, or a staging directory specified by
# $INSTALLDIR, at installation time.
#
  defn install
  defn_set_hook install default request_install
  request_install() {
    test -f Makefile || invoke_action_hooks request_compile
    ${is_staged-"false"} && option make prefix=${INSTALLDIR="`pwd`/dist/staged"}
    make $make_options ${install_options-"install-strip"}
  }

# Action "distribute": create either a mingw-port, or a full package
# distribution, comprising the original upstream source, bundled with
# the MinGW-specific source files, to create a composite source package,
# plus additional binary packages, as specified by the MinGW package
# specification.
#
  defn distribute
  defn_set_hook distribute default request_distribute
  request_distribute() {
    if ${MINGW_PORT_DISTRIBUTION-false}
    then
      SRCTAG=port SRCDIST=mingw-port TAGGED_VERSION=$VERSION
      STAGED_PKGDIR=${STAGED_PKGDIR-"`pwd`/port"} COMPRESS_CMD=xz PKGEXT=".tar.xz"
      invoke_action_hooks srcdist
      rm -rf $STAGED_SRCDIR
    else
      for hooked in srcdist pkgdist; do invoke_action_hooks $hooked; done
    fi
  }

  srcdist_include() {
    test -d "$1" && { archdir="$1"; shift; } || archdir="arch/${ARCH-"mingw32"}"
    for argv
      do test -f "$archdir/$argv" && cp "$archdir/$argv" "$STAGED_SRCDIR/$archdir"
      done
  }

  defn_set_hook srcdist default request_prepare_srcdist
  request_prepare_srcdist() {
    phase srcdir "prepare ${SRCDIST-source} distribution"
    for hooked in stage_srcdist package_srcdist
      do invoke_action_hooks $hooked; done
    phase "done."
  }

  defn_set_hook package_srcdist default request_package_srcdist
  request_package_srcdist() {
    ( package=$PACKAGE-$TAGGED_VERSION-$ARCH-${SRCTAG-"src"}${PKGEXT-".tar"}
      srcdist_include `test -d ${archdir="arch/${ARCH-"mingw32"}"} && {
	cd $archdir; echo README*; }` pkgbuild.sh $PACKAGE-$VERSION-$ARCH.$pkgspec
      echo; step "storing package '$package'"
      cd ${STAGED_PKGDIR="`pwd`/dist"}
      if test "x${COMPRESS_CMD-"none"}" = xnone
      then ${ARCHIVE_CMD-"tar"} cPhf $package --hard-dereference $PACKAGE-$VERSION
      else ${ARCHIVE_CMD-"tar"} cPhf - --hard-dereference $PACKAGE-$VERSION \
	| $COMPRESS_CMD -c > $package
      fi
    )
  }

  defn_set_hook pkgdist default request_create_distribution
  request_create_distribution() {
    phase dist "prepare package archives for distribution"
    ( ${is_pre_staged-"false"} || prepare_staged_distribution
      cd $STAGED_PKGDIR/staged; rm -rf $PACKAGE-$VERSION; mv ../$PACKAGE-$VERSION .
      package_staged_distribution $COMPONENTS
    )
    ${keep_staged_image-"false"} || rm -rf $STAGED_PKGDIR/staged
    phase "done."
  }

  prepare_staged_distribution() {
    rm -rf ${STAGED_PKGDIR="`pwd`/dist"}/staged
    is_staged=true INSTALLDIR=$STAGED_PKGDIR/staged action_install
  }

  package_staged_distribution() {
    for component
    do  packing_list=`sanitized_name $component`_package_content
	case $component in
	  *:*) package="`IFS=:; set -- $component; echo $1`"
	       component="`IFS=:; set -- $component; echo $2`" ;;
	  *)   package=$PACKAGE ;;
	esac
	package="$package-$TAGGED_VERSION-$ARCH-$component${PKGEXT-".tar"}"
	step "storing package '$package'"
	if test "x${COMPRESS_CMD-"none"}" = xnone
	then eval ${ARCHIVE_CMD-"tar"}' cPhf ../$package --hard-dereference $'$packing_list
	else eval ${ARCHIVE_CMD-"tar"}' cPhf - --hard-dereference $'$packing_list \
	  | $COMPRESS_CMD -c > ../$package
	fi
    done
  }

  defn clean
  defn_set_hook clean default request_make_clean
  request_make_clean() { make $make_options clean; }

  defn mkxml
  defn_set_hook mkxml default request_mkxml
  request_mkxml() { load module mkxml; }
#
# -----------------------------------------------------------------------------
# $RCSfile: actions.sh,v $: end of file
