Developing Plugins

Antmod build plugins are the way to extend Antmod's standard build functionality. This can be done in two ways:

  1. By adding new build targets using build file injection
  2. By listening to plugin events

Plugin structure

Each build plugin has the following structure:

${env.ANTMOD_HOME}
  |
  +-plugins
      |
      +-pluginname
         |
         +-injectmodule.xml    Build file injection into read-only "build.xml" of modules.
         |
         +-injectrelease.xml   Build file injection into read-only "build.xml" of releases.
         |
         +-modulebuild.xml     For receiving module-level plugin events in "event-" targets
         |
         +-releasebuild.xml    For receiving release-level plugin events in "event-" targets
         |
         +-plugin.properties   Properties of this plugin which are automatically loaded
         |
         +-lib/                Optional 3rd party libraries, not loaded automatically
         |
         +-src/                Optional src tree, compiled as part of Antmod bootstrap build

Build file injection

Antmod places a "build.xml" in the release and each module of the release when the release is being checked out or updated. The build logic in those read-only "build.xml" files can be added or overridden per module in a "local.build.xml" file. This is very flexible, but not reusable.

Build plugins allow you to add (not override) build targets to the standard read-only "build.xml" files using build file injection. The process is simple: during a checkout or update Antmod:

  • adds the contents of each plugin's "injectrelease.xml" file to the "build.xml" of the release, and
  • adds the contents of each plugin's "injectmodule.xml" file to the "build.xml" of each module in the release

This means that the injection build files of a plugin are not complete Ant build files, instead they just contain a snipped of a complete build file.

A sample plugin "injectrelease.xml" would look like this if it were to add an "helloworld" build target to each release:

  <target name="helloworld" depends="@antmod.target@" description="Hello World!">
    <echo message="Release ${antmod.release} says: Hello World!"/>
  </target>

Plugin events

Antmod adds the concept of "plugin events" to Ant build files.

  • A plugin event is fired at release or module level
  • A plugin event has a name
  • Any plugin can listen to release-level events in its "releasebuild.xml" file
  • Any plugin can listen to module-level events in its "modulebuild.xml" file

For a plugin to listen to an event, it simply creates an Ant target called "event-eventname" in either "releasebuild.xml" or "modulebuild.xml". To know what events can be listened to, check the read-only "build.xml" of a release or module, and search for "pluginevent". An example is the "build-post" event which can be listened to for adding build logic after compilation has completed. For this, add the following to your plugin's "modulebuild.xml":

  <!-- after default build has compiled, this target does its work -->
  <target name="event-build-post">
    <echo message="Default javac has completed, this plugin just says hello for now."/>
  </target>

For a plugin to fire an event, it can use the Ant target that comes with Antmod for that. Interestingly, this way a plugin can listen to events from other plugins, providing an advanced inter-plugin communication mechanism. Firing an event called "helloworld-echo-post" to other plugins would be as simple as adding the following line to your Ant build file:

   <pluginevent level="module" eventname="helloworld-echo-post"/>

Build file injection recommendation

If a plugin contains 3rd party libraries or has a large amount of Ant build logic, it is advised to not use build file injection alone for that. Instead, put the actual build logic in either "modulebuild.xml" or "releasebuild.xml", and have "injectmodule.xml" or "injectrelease.xml" only inject one line that invokes the plugin's "modulebuild.xml" or "releasebuild.xml".

Keeping Ant build logic inside the plugin, and not having it injected, also has the advantage that upgrades to new versions of the plugin do not require an update of the already checked out releases for the developer using the plugin.

For example a helloworld plugin would then do the following in its "injectrelease.xml":

  <target name="helloworld" depends="@antmod.target@" description="Complex helloworld.">
    <ant
        antfile="${antmod.plugins.helloworld.home}/releasebuild.xml"
        target="helloworld"
        inheritRefs="true"/>
  </target>

In this example, the "releasebuild.xml" of the helloworld plugin would have to contain a "helloworld" Ant target of course.