ant target to run only based on condition [duplicate] - ant

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Ant task to check if a file exists?
<target name="buildjunit">
<mkdir dir="${BUILD_TEST_DIR}" />
<ant antfile="build.xml" dir="${app}\dcs" target="compile-junit" inheritAll="false">
<property name="BUILD" value="${COMP_BUILD}" />
<property name="VER" value="${PREVIOUS_VERSION}" />
<property name="build.local" value="true" />
<property name="CONFIG" value="${CONFIG_HOME}/ESW/ESWCONFIG/ITT" />
</ant>
</target>
I want to build ant target compile-junit only if some of the jar doesnt exist in perticulary directory, how can i do it? ie compile-junit target inside buidljunit should run only when there is no jar file exist in the directory project/jarlocation/dcs.

Slight variation to the question I commented as similar. To run when it doesn't exist replace 'if' with 'unless':
<target name="check-abc">
<available file="abc.txt" property="abc.present"/>
</target>
<target name="do-unless-abc" depends="check-abc" unless="abc.present">
...
</target>

Related

how to ignore a failure ant task?

I have this ant script that is reading from a parameter a list of components and running other ant tasks (build.xml's):
<for list="${components.locations}" param="component" failonany="false">
<sequential>
<property name="#{component}" value="true"/>
<if>
<and>
<available file="${repository.location}/#{component}"/>
<available file="${repository.location}/${jars.location}"/>
</and>
<then>
<ant inheritAll="false" antfile="${repository.location}/#{component}/build.xml">
<!-- failonerror="false" -->
<property name="copy.libs" value="${copy.libs}"/>
<property name="repository.location" value="${repository.location}"/>
<property name="jars.location" value="${repository.location}/${jars.location}"/>
</ant>
</then>
</if>
</sequential>
</for>
The problem is if one component is failing, the script doesn't continue to next one.
I tried running with -k (-keep-going) argument but it doesn't help.
I found this property failonerror="false" but it's valid for "exec" tasks and couldn't integrate it with "ant" tasks or inside a "target".
Other direction was "failonany" property of the "for" but I didn't manage setting it up explicitly.
Can you please advice...
Thanks.
First of all, I would suggest deleting ant-contrib.jar and never looking back. Believe me, you will be doing yourself a favor.
You can use the subant task to iterate Ant builds on a set of directories or files. Simply define a dirset and pass any extra properties you need.
Instead of using ant-contrib's <if> block, use the standard target's if attribute to switch the entire target on or off. This is much safer and better practice.
<property name="repository.location" location="repository_location" />
<property name="jars.location" location="${repository.location}/jars" />
<property name="components" value="dir1,dir2,dir3" />
<target name="init">
<condition property="jars.available">
<available file="${jars.location}" />
</condition>
</target>
<target name="default" depends="init" if="jars.available">
<subant inheritall="false" failonerror="false">
<dirset id="components.dirs" dir="${repository.location}" includes="${components}" />
<property name="copy.libs" value="${copy.libs}" />
<property name="repository.location" value="${repository.location}" />
<property name="jars.location" value="${jars.location}" />
</subant>
</target>

Available tag in ant is always true if a file is unavailable also

This code is always returning a true value even if file at given path does not exists
<available file="${x}/schema/#{componentname}-schema.sql" type="file" property="schema.file" />
<if>
<equals arg1="true" arg2="${schema.file}" />
<then>
<debug message="****schemafile is ${schema.file} ******" />
</then>
</if>
Output is always :-
*schemafile is true***
even if file is not available at that path.
Please help me to find the error.
I've refactored your example, in order to use standard ANT tasks:
<project name="demo" default="run" xmlns:if="ant:if">
<property name="src.dir" location="src"/>
<target name="run">
<available file="${src.dir}/schema/schema.sql" type="file" property="schema.file" />
<echo message="****schemafile is ${schema.file} ******" if:set="schema.file"/>
</target>
</project>
Notes:
I don't recognise the "debug" task so use the standard "echo" task instead
I recommend not using the ant-contrib "if" task. ANT 1.9.1 introduced an if attribute which can be used instead.
The following alternative variant will work with older versions of ANT. It uses an "if" target attribute to perform conditional execution:
<project name="demo" default="run">
<property name="src.dir" location="src"/>
<available file="${src.dir}/schema/schema.sql" type="file" property="schema.file" />
<target name="run" if="schema.file">
<echo message="****schemafile is ${schema.file} ******"/>
</target>
</project>
problem was i was iterating above code in for loop, and since property is immutable, it is always set to true if set at-least once. Thats why after 1 iteration even if the file was not found, it echoes schemafile is true** .
i have added below code to set property to false after that code
<var name="schema.file" unset="true"/>
<property name="schema.file" value="false"/>

get property from different ant project

Is it possible to read properties from another ant project ?
I could do it with:
<ant antfile="child/build.xml" target="echoproperties">
<property name="echoproperties.file" value="${tmp}/child.properties" />
</ant>
<property prefix="child" file="${tmp}/child.properties" />
<delete file="${tmp}/child.properties" />
While in child/build.xml:
<target name="echoproperties">
<echoproperties destfile="${echoproperties.file}" />
</target>
But I would like to avoid creating temporary files.
I've found that Ant-Contrib has antfetch task although it's functionality is not that great (no prefix, no propertysets).

Ant not creating tar files

I have a little ant script which should create 3 tar files.
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." >
<property name="dcc-shell.dir" value="${basedir}"/>
<property name="dcc-mdp.dir" value="${dcc-shell.dir}/eq-mo-drop-copy-converter-mdp"/>
<property name="mdp-code.dir" value="${dcc-mdp.dir}/src/main/*"/>
<property name="dcc-srv.dir" value="${dcc-shell.dir}/eq-mo-drop-copy-converter-server"/>
<property name="srv-code.dir" value="${dcc-srv.dir}/src/main/*"/>
<property name="dcc-trans.dir" value="${dcc-shell.dir}/eq-mo-drop-copy-converter-transformer"/>
<property name="trans-code.dir" value="${dcc-trans.dir}/src/main/*"/>
<target name="create MDP Tar">
<tar destfile="${dcc-shell.dir}/mdp.tar"
basedir="${dcc-mdp.dir}/**"
excludes="${dcc-mdp.dir}/target/*"
/>
</target>
<target name="create Trans Tar">
<tar destfile="${dcc-shell.dir}/trans.tar"
basedir="${dcc-trans.dir}/**"
excludes="${dcc-trans.dir}/target/*"
/>
</target>
<target name="create SRV Tar">
<tar destfile="${dcc-shell.dir}/srv.tar"
basedir="${dcc-srv.dir}/**"
excludes="${dcc-srv.dir}/target/*"
/>
</target>
</project>
The script runs fine:
Buildfile: C:\eq-Drop-Copy\eq-mo-drop-copy-converter-shell\build.xml
BUILD SUCCESSFUL
Total time: 94 milliseconds
However no tar files are created within the project. Somewhat of a mystery to myself
EDIT
I have been getting the following error!
<target name="create MDP.Tar">
<tar destfile="C:/eq-Drop-Copy/eq-mo-drop-copy-converter-shell/mdp.tar"
basedir="C:/eq-Drop-Copy/eq-mo-drop-copy-converter-shell/eq-mo-drop-copy-converter-mdp/*"
excludes="C:/eq-Drop-Copy/eq-mo-drop-copy-converter-shell/eq-mo-drop-copy-converter-mdp/target/*"
/>
</target>
I have changed the xml to the absoulet paths:
<target name="create MDP.Tar">
<tar destfile="C:/eq-Drop-Copy/eq-mo-drop-copy-converter-shell/mdp.tar"
basedir="C:/eq-Drop-Copy/eq-mo-drop-copy-converter-shell/eq-mo-drop-copy-converter-mdp/*"
excludes="C:/eq-Drop-Copy/eq-mo-drop-copy-converter-shell/eq-mo-drop-copy-converter-mdp/target/*"
/>
</target>
However still the same error how can the basedir not exist the build file is contained within it. The basedir within the MDP target is pointing to an absoulet path and tar all the files within that. why would this be giving an error?
Most likely you called it without giving a target. Your printout does not show any tar targets executed.
Try calling it with target name as argument to ant. Then you will also find out that using spaces in target names may not be such a good idea.
I corrected several issues:
basedir attribute shouldn't have "*" in it. It'll automatically do the whole tree.
Targets can't contain spaces
You probably didn't specify targets. Therefore, I simply added a default target "create_all_tars", and used <antcall> to call the needed targets.
<project basedir="." default="create_all_tars" >
<property name="dcc-shell.dir"
value="${basedir}"/>
<property name="dcc-mdp.dir"
value="${dcc-shell.dir}/eq-mo-drop-copy-converter-mdp"/>
<property name="mdp-code.dir"
value="${dcc-mdp.dir}/src/main/*"/>
<property name="dcc-srv.dir"
value="${dcc-shell.dir}/eq-mo-drop-copy-converter-server"/>
<property name="srv-code.dir"
value="${dcc-srv.dir}/src/main/*"/>
<property name="dcc-trans.dir"
value="${dcc-shell.dir}/eq-mo-drop-copy-converter-transformer"/>
<property name="trans-code.dir"
value="${dcc-trans.dir}/src/main/*"/>
<target name="create_all_tars">
<antcall target="create_MDP_Tar"/>
<antcall target="create_Trans_Tar"/>
<antcall target="create_SRV_tar"/>
</target>
<target name="create_MDP_Tar">
<tar destfile="${dcc-shell.dir}/mdp.tar"
basedir="${dcc-mdp.dir}"
excludes="${dcc-mdp.dir}/target/**"/>
</target>
<target name="create_Trans_Tar">
<tar destfile="${dcc-shell.dir}/trans.tar"
basedir="${dcc-trans.dir}"
excludes="${dcc-trans.dir}/target/**"/>
</target>
<target name="create_SRV_Tar">
<tar destfile="${dcc-shell.dir}/srv.tar"
basedir="${dcc-srv.dir}"
excludes="${dcc-srv.dir}/target/**"/>
</target>
Does this help?

ant large project. How to enforce common output directory structure - include,import and inhertAll=false?

I have a toplevel ant project and many subprojects under it.
./build.xml
./datamodel_src/src/build.xml
./datamodel_src/src/module1/build.xml
./datamodel_src/src/module2/build.xml
./infrastructure_src/src/build.xml
./interfaces_src/src/build.xml
Each of the subproject, I want to enforce a common output directory structure. Project will have a work area and each sub project will have its own work area under it. Each subproject should create its artifacts (lib, docs, classes etc) under a work area for the subproject.
So the output would be some thing like
c:/sandbox/mainprojectworkarea/subprojectworkarea/lib
c:/sandbox/mainprojectworkarea/subprojectworkarea/docs
c:/sandbox/mainprojectworkarea/subprojectworkarea/classes
Currently I do this as follows.
The toplevel build.xml is like below
<project name="toplevelproject" default="compile" basedir=".">
<target name="compile">
<ant dir="infrastructure_src/src" />
<ant dir="interfaces_src/src " /> <!--does not work-->
<ant dir="datamodel_src/src inhertAll=false" /> <!--works-->
</target>
</project>
common.xml is like below
<property environment="env" />
<property name="project.sandbox" value="${env.BUILD_HOME}/sandbox" />
<property name="sandbox" value="${project.sandbox}" />
<property name="pwa" value="${sandbox}/pwa" />
<property name="wa" value="${pwa}/${ant.project.name}" />
<property name="build" value="${wa}/build" />
<property name="lib" value="${wa}/lib" />
<property name="docs" value="${wa}/docs" />
<property name="exports" value="${wa}/exports" />
This is "included" into all projects. For example "datamodel_src/src/build.xml" is like below
<!DOCTYPE project [
<!ENTITY common SYSTEM "../../common.xml">
]>
<project name="dmodel" default="compile" basedir=".">
&common;
<target name="compile">
<echo message="will create lib in ${lib}"/>
<echo message="will create docs in ${docs}"/>
<ant dir="module1" inheritAll="false"/> <!--works fine-->
<ant dir="module2" /> <!--does not work -->
</target>
</project>
This works when I set inhertiAll=false for ant calls.
Is there a better and correct way to?
Expanding answer from Kevin to this question.
Using import the common.xml becomes a real project like below
<project name="toplevelproject" default="compile" basedir=".">
<property name="toplevel" value="settotrue"/>
<target name="compile">
<ant dir="infrastructure_src/src" />
<ant dir="interfaces_src/src" />
<ant dir="datamodel_src/src" />
</target>
</project>
The "datamodel_src/src/build.xml" is now some think like below.
<project name="dmodel" default="compile" basedir=".">
<import file="../../common.xml" />
<target name="compile">
<echo message="will create classes in ${build}"/>
<echo message="will create lib in ${lib}"/>
<ant dir="module1" inheritAll="false"/> <!--works fine-->
<ant dir="module2" /> <!--does not work -->
</target>
</project>
The import gives option to have common targets etc, hence I would go with it.
I'm doing something similar using imports rather than includes. All my common targets and properties are defined in a common build file and each subproject just imports the common file. When you import a file, the properties defined in that file become relative to the importing file.
So I would try doing the following:
Move your compile target from your subproject build files into your common.xml.
Import your common.xml into each subproject build.xml.

Resources