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">In this module descriptor, we have an application named myJavaApp created by org.mycompany.
<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>
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
<ea:build organisation="org.apache.easyant.buildtypes" module="build-std-java" revision="0.2"/>Running "easyant" will generate the output jar in "dist" directory.
<ea:property name="target.artifacts" value="dist"/>
</ea:build>
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>If you want to have more informations on dependencies please refer to the official ivy documentation
<dependency org="acme" name="foo" rev="2.0" conf="default"/>
</dependencies>
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"/>Calling to "easyant -p" we should see the emma public target :
<ea:property name="target.artifacts" value="dist"/>
<ea:plugin org="org.apache.easyant.plugins" module="emma" revision="0.1"/>
</ea:build>
org.apache.easyant.plugins#emma.:emma generate emma covera reportAs 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"/>Calling to "easyant -p" we should see the emma public target :
<ea:property name="target.artifacts" value="dist"/>
<ea:plugin org="org.apache.easyant.plugins" module="emma" revision="0.1" as="emma"/>
</ea:build>
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
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">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:
<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>
<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.
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.- org.apache.easyant.buildtypes for buildtypes
- org.apache.easyant.plugins for 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">Here we're able to run any phase/target provided by the build-std-java build type.
<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>
Now we will add our helloWorld target in module.ant
<project name="org.apache.easyant.buildtypes#standard-java-app"Running a easyant -p should display our new target helloWorld. This target should be available if we launch easyant helloWorld.
xmlns:ea="antlib:org.apache.easyant">
<target name="helloWorld" description="display a helloWorld message">
<echo message="Hello World!"/>
</target>
</project>
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
- the module.ivy
- 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
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>