|
FlakaExamples
Snippets, Flaka in the wild, Ant problems and solutions
Featured This is work in progress ... Flaka provides some very innovative features and syntactic sugar. This page will show how to tackle common ant problems with Flaka. Examples are taken from 'real-life' => production code, questions from stackoverflow.com, the Ant user list .. etc. CategoriesPropertiesOne of the most common question is how to overwrite or edit existing properties in ant. Question : How do i overwrite an existing property ? Properties once set are immutable in ant by design. <!-- set a new property --> <fl:let>foo := 'bar'</fl:let> <!-- overwrite an existing property or userproperty
(those properties defined on the commandline via -Dfoo=bar ..) -->
<fl:let>foo ::= 'baz'</fl:let>notice the double '::' in foo ::= 'baz' Question : How do i extract a specific part from a csv separated property ? <project xmlns:fl="antlib:it.haefelinger.flaka">
<property name="module.list" value="mod1,mod2,mod3,mod4,mod5"/>
<target name="main">
<!-- simple echo -->
<fl:echo>xtractedvalue => #{split('${module.list}',',')[0]}</fl:echo>
<!-- create property for further processing.. -->
<fl:let>
xtractedvalue := split('${module.list}',',')[0]
</fl:let>
<echo>$${xtractedvalue} => ${xtractedvalue}</echo>
</target>
</project>output : [fl:echo] xtractedvalue => mod1
[echo] ${xtractedvalue} => mod1a similar one : Question : Given is an ant property which has value of the type 1.0.0.123 <project xmlns:fl="antlib:it.haefelinger.flaka">
<property name="foobar" value="1.0.0.123"/>
<target name="main">
<!-- simple echo -->
<fl:echo>xtractedvalue => #{split('${foobar}','\.')[3]}</fl:echo>
<!-- create property for further processing.. -->
<fl:let>
xtractedvalue := split('${foobar}','\.')[3]
</fl:let>
<echo>$${xtractedvalue} => ${xtractedvalue}</echo>
</target>
</project>output : [fl:echo] xtractedvalue => 123
[echo] ${xtractedvalue} => 123Question : For some reason i need to strip of the drive name of some property <project xmlns:fl="antlib:it.haefelinger.flaka" name="World">
<!-- simple echo -->
<fl:echo>#{replace('${basedir}', '$1' , '.:\\\\(.+)' )}</fl:echo>
<!-- set property -->
<fl:let>cwd := replace('${basedir}', '$1' , '.:\\\\(.+)' )</fl:let>
</project>Files / DirectoriesQuestion : After compiling my java sources how to run the corresponding classes ? This example shows also how to iterate over a fileset with the ant builtin ${toString:filesetid} property. <project xmlns:fl="antlib:it.haefelinger.flaka">
<property name="srcroot" value="path/to/srcrootdir"/>
<property name="classroot" value="path/to/classrootdir"/>
<!-- seek all classes with main method -->
<fileset dir="${srcroot}" includes="**/*.java" id="mainclasses">
<contains text="public static void main"/>
</fileset>
<!-- iterate over classes with main method and call
corresponding classfile -->
<fl:for var="file" in="split('${toString:mainclasses}', ';')">
<fl:let>
; strip the '.java' extension
file = replace(file, '', '.java')
; replace fileseparator with '.'
; when running on windows you have to use :
; replace(file, '\.', '${file.separator}${file.separator}')
file = replace(file, '\.', '${file.separator}')
</fl:let>
<fl:echo>
starting => #{file} in ${classroot}..
</fl:echo>
<java classname="#{file}">
<classpath>
<!--
when using a fileset you'll get a
java.util.zip.ZipException because you're
referencing not jarfiles but classfiles
therefore you've to use pathelement location
-->
<pathelement location="${classroot}"/>
</classpath>
</java>
</fl:for>
</project>Question : In ant, how can i check if a set of files (comma-separated list of paths) exists or not? a) when with combined file function calls <project xmlns:fl="antlib:it.haefelinger.flaka">
<!-- when you have a cvs property use split function
to get your list to iterate over -->
<property name="checkpath" value="/foo/bar,/foo/baz,/foo/bazz"/>
<fl:for var="file" in="split('${checkpath}', ',')">
<fl:fail message="#{file} does not exist !!" test="!file.tofile.exists"/>
</fl:for>
<!-- creating the list inline -->
<fl:for var="file" in="list('/foo/bar','/foo/baz', '/foo/bazz')">
<fl:fail message="#{file} does not exist !!" test="!file.tofile.exists"/
</fl:for>
<!-- using some if then else construct with choose -->
<fl:choose>
<fl:when test="file('/foo/bar').exists and file('/foo/baz' and file('/foo/bazz').exists">
<!-- create property based on existence -->
<fl:let>pathExist := true</fl:let>
<!-- .. other nested tasks .. -->
</fl:when>
<fl:otherwise>
<fl:let>pathExist := false</fl:let>
<!-- .. other nested tasks .. -->
</fl:otherwise>
</fl:choose>
<echo>${pathExist}</echo>
</project>ConditionsQuestion : I would like to do something like this <target name="clean" description="clean">
<if>
<available file="${build}" type="dir" />
<then>
<delete dir="${build}" />
</then>
</if>
</target>Solution : The standard way in vanilla ant would be something like <target name="check">
<condition property="delbuild">
<available file="${build}" type="dir"/>
</condition>
</target>
<target name="clean" depends="check" if="delbuild">
<delete dir="${build}"/>
<!-- .. -->
</target>with Flaka its straightforward <fl:when test=" '${build}'.isdir ">
<delete dir="${build}"/>
</fl:when>Question : Is there any if then else construct in ant ? <project xmlns:fl="antlib:it.haefelinger.flaka">
<!-- some if/then/else construct -->
<fl:choose>
<!-- if -->
<when test=" '${buildtype}' eq 'prod' ">
<!-- then -->
<echo>..starting ProductionBuild</echo>
</when>
<when test=" '${buildtype}' eq 'test' ">
<!-- then -->
<echo>..starting TestBuild</echo>
</when>
<!-- else -->
<otherwise>
<fl:unless test="has.property.dummybuild">
<fail message="No valid buildtype !, found => '${buildtype}'"/>
</fl:unless>
<echo>.. is DummyBuild</echo>
</otherwise>
</fl:choose>
</project>output with ant -f build.xml -Dbuildtype=prod or [echo] ..starting ProductionBuild output with typo => ant - build.xml -Dbuildtype=testt BUILD FAILED /home/rosebud/workspace/AntTest/build.xml:21: No valid buildtype !, found => 'testt' output with ant -f build.xml -Ddummybuild=whatever [echo] .. is DummyBuild |