Module files

A project using EasyAnt MUST contain a file named module.ivy and an optional file named module.ant.

The module.ivy file

This file is the module descriptor of your project.
It contains several informations like your company name, the module name, dependencies, and Easyant build information.

A short example

<ivy-module version="2.0" xmlns:ea="http://www.easyant.org"> 
<info organisation="org.mycompany" module="myJavaApp" status="integration" >
<ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.2"/>
</info>
<configurations>
<conf name="default" visibility="public" description="runtime dependencies and master artifact can be used with this conf"/>
<conf name="test" visibility="private" description="this scope indicates
that the dependency is not required for normal use of the application, and is
only available for the test compilation and execution phases."/>
</configurations>
</ivy-module>
In this module descriptor, we have an application named myJavaApp created by org.mycompany.
To use easyant you must declare the easyant namespace
xmlns:ea="http://www.easyant.org"
Pay attention to the ea:build tag.
This tags define which build-type is used for your project. In this example we use build-std-java which provides all the targets necessary to compile / package a standard java application.
Note: The organisation argument in ea:build tag is optionnal. If not specified easyant will use the default one (org.apache.easyant.buildtypes).
Note: This tag support property as attribute. . If you have a few property to set it's often easier to use property as attribute. If you have lot of properties we strongly recommend you to declare it using property tag
Running easyant with this example will run the default target (package).
A few seconds later, you will have the generated jar in your_project/target/artifacts/myJavaApp.jar.

Configure the project

By default default target are defined in builtypes, but you have the hability to adapt it if necessary.

In the example bellow, we will configure myDefaultTarget as the default target.
 <ea:configure-project defaultTarget="myDefaultTarget"/>
Note: This tag support property as attribute. . If you have a few property to set it's often easier to use property as attribute. If you have lot of properties we strongly recommend your to declare it using property tag

Changing build-system properties

So now we want to change several things on this build system.
For example, we want to have the generated jar in "dist" directory instead of "targets/artifacts".
We will add additional informations inside tag.
<ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.2"/>
<ea:property name="target.artifacts" value="dist"/>
</ea:build>
Running "easyant" will generate the output jar in "dist" directory.

Adding dependencies

Dependencies are defined in the module.ivy files.
There is a section dedicated to dependencies
Let's consider that our project needs an artifact named foo provided by acme in revision 2.0
The dependencies section will look like this :
<dependencies>
<dependency org="acme" name="foo" rev="2.0" conf="default"/>
</dependencies>
If you want to have more informations on dependencies please refer to the official ivy documentation

Using additional plugins

In some cases, we want to use several features that are not included in the default build-type provided by easyant.
If your project needs to use a specific plugin, you can use the ea:plugin tag inside ea:build tag.
Example:
Suppose we want to use code coverage feature.
<ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.2"/>
<ea:property name="target.artifacts" value="dist"/>
<ea:plugin org="org.apache.easyant.plugins" module="emma" revision="0.1"/>
</ea:build>
Calling to "easyant -p" we should see the emma public target :
org.apache.easyant.plugins#emma.:emma     generate emma covera report
As you can see the target is prefixed by the project name.
Most of the time the project name is quite long so easyant allows you to define an alias for the project names. This alias can be used in place of the complete project name. You can define an alias for a plugin using as argument as below.
<ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.2"/>
<ea:property name="target.artifacts" value="dist"/>
<ea:plugin org="org.apache.easyant.plugins" module="emma" revision="0.1" as="emma"/>
</ea:build>
Calling to "easyant -p" we should see the emma public target :
emma.:emma generate emma covera report
Note: The organisation argument in ea:plugin tag is optionnal. If not specified easyant will use the default one (org.apache.easyant.plugins).
Note: This tag support property as attribute. . If you have a few property to set it's often easier to use property as attribute. If you have lot of properties we strongly recommend you to declare it using property tag

Property as attribute

The following tags allow property as attribute :
  • build
  • plugin
  • configure-project
If you have a few property to set it's often easier to use property as attribute.
Example in ea:build
  <ea:build module="build-std-java" revision="0.9" my.property="myvalue"/>
Example in plugin
  <ea:plugin module="run-java" revision="0.9" run.main.classname="org.myproject.Main"/>
Example in configure-project
  <ea:configure-project defaultTarget="myDefaultTarget" run.main.classname="org.myproject.Main"/>
If you have lot of properties we strongly recommend you to declare it using property tag.


The Optional module.ant file

Easyant also provides you a hook for injecting custom build logic into your build process. This could include any kind of custom manipulation for using easyant locally.

The module.ant file is a conventional ant script. You can retain any convenient build logic from your legacy scripts in module.ant. All targets defined in this file are available for invocation using easyant through command terminal.

Example: Consider the following module.ivy file:

<ivy-module version="2.0"> 
<info organisation="org.apache.easyant" module="standard-java-app" status="integration" >
<ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.2">
<ea:plugin organisation="org.apache.easyant.plugins" module="checkstyle" revision="0.1"/>
</ea:build>
</info>
<configurations>
<conf name="default" visibility="public" description="runtime dependencies and master artifact"/>
<conf name="test" visibility="private" description="this scope indicates this is only available for the test compilation and execution phases."/>
</configurations>
<dependencies>
<dependency org="hsqldb" name="hsqldb" rev="1.8.0.7" conf="default->default"/>
<dependency org="junit" name="junit" rev="4.4" conf="test->default" />
</dependencies>
</ivy-module>
The above code snippet is a declaration of a easyant project that uses the standard-java-app build type. The same functionality can be achieved by the following module.ant file in your project root directory:
<project name="org.apache.easyant.buildtypes#standard-java-app"
xmlns:ea="antlib:org.apache.easyant">
<ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.2"/>
<ea:plugin organisation="org.apache.easyant.plugins" module="checkstyle" revision="0.1"/>
</project>
Note: organisation are optionnal in ea:build / ea:plugin. If no organisation is set easyant will use the default one.
  • org.apache.easyant.buildtypes for buildtypes
  • org.apache.easyant.plugins for plugins
Similarly, you can provide additional functionalities using the module.ant incase, you dont find smaller things missing in your build types or plugins. For larger customizations, you may consider writing new plugins.

Mixing module.ivy and module.ant

EasyAnt offer the possibility to mix both files.
This make sense if we need to use buildtypes/plugins and additional targets specific to your project.

Let's try to add a target name hello world in the project.
The module ivy looks like this :
<ivy-module version="2.0"> 
<info organisation="org.apache.easyant" module="standard-java-app" status="integration" >
<ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.2"/>
</info>
<configurations>
<conf name="default" visibility="public" description="runtime dependencies and master artifact"/>
<conf name="test" visibility="private" description="this scope indicates this is only available for the test compilation and execution phases."/>
</configurations>
<dependencies/>
</ivy-module>
Here we're able to run any phase/target provided by the build-std-java build type.

Now we will add our helloWorld target in module.ant
<project name="org.apache.easyant.buildtypes#standard-java-app"
xmlns:ea="antlib:org.apache.easyant">
<target name="helloWorld" description="display a helloWorld message">
<echo message="Hello World!"/>
</target>
</project>
Running a easyant -p should display our new target helloWorld. This target should be available if we launch easyant helloWorld.

Considering that all the phases provided build-std-java are loaded before the module.ant, you can attach your custom target to any phase.
This complete the basic needs.

Going further : overriding target / extension-point

Let's consider the use case were you want to adapt a specific target or extension-point to your need.
We need to keep in mind that ant-based system works with a useFirst mechanism.
Which means :
  • properties are set only first time we use it
  • target / extension-point are set first time we use it
But the choregraphy is to load :
  • the module.ivy
  • the module.ant
This means that you're not able to override target/extension-point in the module.ant.

Fortunately EasyAnt provides a way to do it.
The real choregraphy is to load :
  • the override.module.ant
  • the module.ivy
  • the module.ant
The override.module.ant is a true ant script loaded before the module.ivy. It's the right place if you want to override target/extension-point provided by things defined later in module.ivy.

For example suppose we want to introduce a new phase named my-phase run before the default package phase.
<project name="org.apache.easyant.buildtypes#standard-java-app"
xmlns:ea="antlib:org.apache.easyant">
<!-- Define a new phase -->
<extension-point name="my-phase" description="foobar"/>
<!-- Override the package phase that depends on my-phase and the default package phase -->
<extension-point name="package" depends="my-phase, org.apache.easyant.plugins#phases-std.package" description="package the application"/>
</project>