## Invoking external programs

Besides the commands for cleaning the package build dir (`cleaner`) and building the package (`builder`), you can also invoke hooks during the package build: immediately before a build (`prebuild`), after a successful build (`postbuild`), and after creating a tag (`posttag`). Typical applications are running lintian™ or pushing changes into a remote repository.

### Running lintian

gbp buildpackage exports several variables into the `posttag`'s environment (for details see the gbp-buildpackage(1) manual page). To invoke lintian™, we need to tell it where to find the changes file:

    gbp buildpackage --git-postbuild='lintian $GBP_CHANGES_FILE'

To call lintian™ automatically after each successful build, add:

    postbuild=lintian $GBP_CHANGES_FILE

to your `.gbp.conf`.

### Pushing into a remote repository

If you want to push your changes automatically after a successful build and tag, you can use gbp buildpackage's posttag hook. A very simple invocation would look like this:

    gbp buildpackage --git-tag --git-posttag="git push && git push --tags"

This assumes you have set up a remote repository to push to in `.git/config`.

Usually, you want to make sure you don't push out any unrelated changes into the remote repository. This is handled by the following hook which only pushes out the created tag to where you pulled from and also forwards the corresponding remote branch to that position:

    #!/bin/sh -e
    #
    # gbp-posttag-push: post tag hook to push out the newly created tag and to
    # forward the remote branch to that position

    if ! REMOTE=$(git config --get branch."${GBP_BRANCH}".remote); then
        REMOTE=origin
    fi

    if [ "$GBP_TAG" ]; then
         echo "Pushing $GBP_TAG to $REMOTE"
         git push "$REMOTE" "$GBP_TAG"
    else
         echo "GBP_TAG not set."
         exit 1
    fi

    if [ "$GBP_SHA1" ] && [ "$GBP_BRANCH" ]; then
        git push "$REMOTE" "$GBP_SHA1":"$GBP_BRANCH"
    else
        echo "GBP_SHA1 or GBP_BRANCH not set."
        exit 1
    fi
    echo "done."

`GBP_TAG`, `GBP_SHA1` and `GBP_BRANCH` are passed to the hook via the environment. To call this hook automatically upon tag creation, add:

    posttag="gbp-posttag-push"

to your `.gbp.conf` and make sure `gbp-push` is somewhere in your `$PATH`. On Debian™ systems, a more complete example can be found in `/usr/share/doc/examples/git-buildpackage/examples/gbp-posttag-push`.

### Running postexport hook

gbp buildpackage exports several variables into the `postexport`'s environment (for details see the gbp-buildpackage(1) manual page). The motivation for the postexport action is to allow further adjustment of the sources prior to building the package. A typical use case scenario is to allow creating multiple source and binary packages from one Debian™ branch, e.g. the bootstrap gcc and in the next stage the full gcc.

The postexport action postpones the creation of the upstream tarball, so that the metadata for creating it is already present in the exported source tree. The example postexport script below (`crosstoolchain-expand.sh`) expands changelog, lintian override files, rules and control files according to an environment variable `PKG_FLAVOR`.

Sample `gbp.conf` - enables source tree export by specifying the export directory:

    [buildpackage]
    # use a build area relative to the git repository
    export-dir = ../build-area
    # disable the since the sources are being exported first
    cleaner =
    # post export script that handles expansion of Debian™ specific files
    postexport = crosstoolchain-expand.sh

Sample postexport script: `crosstoolchain-expand.sh`

    #!/bin/sh
    #
    # Purpose: this script is intended for creating multiple source and
    # binary Debian packages from one source tree. It can be used in
    # conjunction with git-buildpackage that support a postexport hook
    #
    # A typical use is preparing a bootstrap gcc package that is needed
    # for building newlib and then preparing a full gcc package from the
    # same source tree. The user may specify the package flavor via
    # PKG_FLAVOR environmental variable.
    #
    #
    # The script expands/processes the following files:
    #
    # - changelog.tmpl is converted to standard Debian changelog
    #
    #
    # - all binary package lintian override template files are expanded
    #   and renamed to the requested package flavor
    #
    # - source package lintian override template file is expanded and
    #   renamed
    #
    # - rules.$PKG_FLAVOR and control.$PKG_FLAVOR are renamed to rules and
    #   control resp.

    # the template string has been carefully chosen, so that
    # e.g. changelogs that refer to the source package can still be
    # processed by dch/git-dch resp.
    TMPL_STR=-XXXXXX

    # by default replace string for the template is empty
    REPLACE_STR=

    if [ -n "$PKG_FLAVOR" ]; then
        REPLACE_STR=-$PKG_FLAVOR
    fi

    REPLACE_EXPR="s/$TMPL_STR/$REPLACE_STR/g"

    # actual processing of relevant files
    cd debian

    # expand the template changelog
    # remove the symlinked version
    rm changelog
    chglog_tmpl=changelog.tmpl
    [ -f "$chglog_tmpl" ] || {
        echo "Missing changelog template (debian/$chglog_tmpl)"
        exit 1
    }
    cat changelog.tmpl | sed -e "$REPLACE_EXPR" > changelog
    rm changelog.tmpl

    # process binary package lintian overrides - each override must match
    # its package name
    for f in *.lintian-overrides.tmpl; do
        outfile=${f%.tmpl}
        [ -f "$f" ] || {
    	echo "Missing lintian override files for binary packages"
    	exit 1
        }
        cat $f | sed -e "$REPLACE_EXPR" > ${outfile/$TMPL_STR/$REPLACE_STR}
        rm $f
    done

    # process the only source package lintian override
    source_lintian=source/lintian-overrides.tmpl
    cat $source_lintian | sed -e "$REPLACE_EXPR" > ${source_lintian%.tmpl}
    rm $source_lintian

    # rules and control file are package flavor specific
    [ -f rules.$PKG_FLAVOR ] && mv rules.$PKG_FLAVOR rules
    [ -f control.$PKG_FLAVOR ] && mv control.$PKG_FLAVOR control
    rm -f rules.* control.*

    exit 0

### Running preexport hook

gbp buildpackage exports several variables into the `preexport`'s environment (for details see the gbp-buildpackage(1) manual page). The motivation for the preexport action is to allow further actions before preparing and exporting the orig tarballs to the build directory. A usecase could be having the orig tarballs in a separate repository due to very large binary assets, that need to be checked out to the correct branch before creating the tarballs.