I have the antcontrib.jar in my lib folder of Ant. I set my ant home as "C/Prog Files/apache-ant".
But still when I run my build.xml, i get the warning "could not load antlib.xml and antcontrib.prop".
Because of this, I am not able to do any "regex" operations.
I properly loaded the antcontrib.jar in the lib folder of the ant.
Where I am wrong here?
Provide resource and classpath in your taskdef correctly as follows
<typedef resource="net/sf/antcontrib/antlib.xml" classpath="<path to ant-contrib.jar>"/>
Here's an example of an Ant script that uses Ant-Contrib's <propertyregex> task:
build.xml
<project name="ant-propregex-simple" default="run">
<taskdef resource="net/sf/antcontrib/antlib.xml" />
<target name="run">
<property name="line.to.test" value="First Second" />
<property name="the.regex" value="^([^ ]*) ([^ ]*)$" />
<propertyregex
input="${line.to.test}"
regexp="${the.regex}"
select="\2"
property="the.match"
/>
<echo>${the.match}</echo>
</target>
</project>
The key is the <taskdef ...> line.
Output
run:
[echo] Second
BUILD SUCCESSFUL
Related
Is it possible to access "as" prefix inside the included ant file
(i.e. to access "as" attribute value specified in include task)
file including.xml:
<project name="myproject">
<include file="included.xml" as="nested" />
</project>
file included.xml:
<project>
<echo message="I am included into ${ant.project.name} as ${SomePropertyIAskAbout}" />
</project>
Desired output: "I am included into myproject as nested"
<include> executes an included buildfile as if were in the including buildfile. Having both files reference a custom property will do the trick.
including.xml
<project name="myproject">
<property name="including-as-attribute" value="nested" />
<include file="included.xml" as="${including-as-attribute}" />
</project>
included.xml
<project>
<fail unless="including-as-attribute"/>
<echo message="I am included into ${ant.project.name} as ${including-as-attribute}" />
</project>
Output of ant -f including.xml
[echo] I am included into myproject as nested
User passes a list of files in an XML file, below will be the sample:
<property-bundle name = "abc">
<action>clean</action>
<target-location>/vst/property/pog/</target-location>
<file-name>test1.props</file-name>
<file-name>test2.props</file-name>
<file-name>test3.props</file-name>
</property-bundle>
Now based on that action remove, I have to incorporate logic in build.xml to delete the files in the directory , but for that I want to perform a validation only if the file exists then remove or else throw the build failure error. I was able to read the values from the user input XML and takes those files into a file list property
<property name="file.list" value="test1.props,test2.props,test3.props"/>
<target name = "clean">
<delete>
<fileset dir="${target.location}" includes = "${file.list}"/>
</delete>
</target>
but with the clean target it only validates if the directory exists since it is fileset but does not do the validation if file exists , I read that filelist does validation for file exists but filelist can work with delete.
Since we are using Ant 1.6.5 in our environment I can not use antcontrib , It takes whole lot of process and approvals to upgrade Ant now , Can you please guide me on how it can be achieved with the pure Ant.
You should be able to just use delete's #failonerror attribute which throws an error if the file cannot be deleted.
<target name = "clean">
<delete failonerror="true">
<fileset dir="${target.location}" includes="${file.list}"/>
</delete>
</target>
The above will delete files and then error when it doesn't find a file, leaving you in a partially deleted state. If you want to avoid partial deletions, you can run another task to check first
<target name="failIfMissing">
<copy failonerror="true" todir="${temp.directory}">
<fileset dir="${target.location}" includes="${file.list}"/>
</copy>
</target>
by attempting to copy to a temporary directory, failing if some of the target files did not exist.
It is possible to loop over files with Ant-Contrib Tasks and then it will look something like this:
<target name="clean">
<foreach target="delete.if.exists" param="fileName">
<fileset dir="${target.location}" includes="${file.list}"/>
</foreach>
</target>
<target name="delete.if.exists">
<delete failonerror="true" file="$fileName"/>
</target>
Folks,
Thank you all for your outstanding help & contributions , I have finally achieved this with below
<target name="validate.file" depends="defineAntContribTasks,validate.dir">
<echo message=" The value of the filelist is ::::::::::::: ${file.list} :::::::::::::::::: "/>
<for param="file" list="${file.list}">
<sequential>
<if>
<available file="${target.location}/#{file}"/>
<then>
<echo message = "File::: #{file} ::::is valid , Found in :::${target.location}::: "/>
</then>
<else>
<fail message=" File::: #{file} ::::is not valid ,it is not found in :::${target.location}::: ,plesae recheck and submit again"/>
</else>
</if>
</sequential>
</for>
</target>
Thanks again for all of your valuable time and guidance.
<target name="removeUnwantedFiles" description="delete the build destination tree to ensure that it will contain ONLY what is explicitly needed for a build and ONLY what is intended to be release.">
<delete>
<fileset dir="${project-home}">
<includesfile name="${scripts}/excludeJavaFilesForV1.txt"/>
</fileset>
</delete>
</target>
This works for me.. hope this helps..
Ant is not a programming language and therefore has no native looping mechanism. In the absence of external plugins a trick that can used is an XSL transformation. Process the input XML file into a Ant script which implements the desired operation on each file.
Example
├── build.xml
├── files-process.xsl
├── files.xml <-- Input listed above
├── test1.props
├── test2.props
└── test3.props
Run the build and the files listed in "files.xml" are deleted:
build:
[delete] Deleting: /home/mark/tmp/test1.props
[delete] Deleting: /home/mark/tmp/test2.props
[delete] Deleting: /home/mark/tmp/test3.props
Run the build a second time and an error is generated:
BUILD FAILED
/home/mark/tmp/build.xml:6: The following error occurred while executing this line:
/home/mark/tmp/build-tmp.xml:4: file not found: test1.props
build.xml
Use the xslt task to generate a temporary Ant script containing the desired file deletion logic:
<project name="demo" default="process-files">
<target name="process-files">
<xslt style="files-process.xsl" in="files.xml" out="build-tmp.xml"/>
<ant antfile="build-tmp.xml"/>
</target>
<target name="clean">
<delete file="build-tmp.xml"/>
</target>
</project>
files-process.xsl
The following stylesheet generates an Ant script:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<project name="genbuild" default="build">
<target name="build">
<xsl:apply-templates select="property-bundle/file-name"/>
</target>
</project>
</xsl:template>
<xsl:template match="file-name">
<available file="{.}" property="{generate-id()}.exists"/>
<fail message="file not found: {.}" unless="{generate-id()}.exists"/>
<delete file="{.}" verbose="true"/>
</xsl:template>
</xsl:stylesheet>
build-tmp.xml
To aid readability I have formatted the generated Ant script:
<project name="genbuild" default="build">
<target name="build">
<available file="test1.props" property="N65547.exists"/>
<fail message="file not found: test1.props" unless="N65547.exists"/>
<delete file="test1.props" verbose="true"/>
<available file="test2.props" property="N65550.exists"/>
<fail message="file not found: test2.props" unless="N65550.exists"/>
<delete file="test2.props" verbose="true"/>
<available file="test3.props" property="N65553.exists"/>
<fail message="file not found: test3.props" unless="N65553.exists"/>
<delete file="test3.props" verbose="true"/>
</target>
</project>
Note:
Properties in Ant are immutable, so I used the XSL generate-id() function to create a unique property name.
Software used
This example was tested with the following software versions:
$ ant -version
Apache Ant version 1.6.5 compiled on June 2 2005
$ java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
I have installed Ant in my centos 6.3 , installed location are
/opt/ant and also ANT_HOME env are same
I have created build.xml to test by deleting testdir. This directory exist in the /opt/ant/testdir like this.
build.xml
<?xml version="1.0"?>
<project name="testdir" default="all" basedir=".">
<property name="src" value="src"/>
<property name="build" value="build"/>
<property name="lib" value="lib"/>
<target name="all" depends="clean, compile" description="Builds the whole project">
<echo>Doing all</echo>
</target>
<target name="clean">
<echo message="Deleting bin/java ..." />
<delete dir="testdir/test" />
</target>
</project>
Using Command :-
ant -buildfile build.xml Clean
getting error:-
BUILD FAILED
Target "Clean" does not exist in the project "testdir".
Any suggestion to make it work?
You mis-spelt the target name ? 'Clean' as against 'clean' ??
I have found solution. I missed target="compile" block in build.xml.
<target name="compile">
<echo message="Compiling source code"/>
</target>
Run command :-
ant clean
I have two property files [one.properties and two.properties]. I want to dynamically load the property files into my Ant project from the command line.
My build file name is build.xml.
Command line:
> ant build [How do I pass the property file names here?]
Loading property files from the command line
ant -propertyfile one.properties -propertyfile two.properties
Individual properties may be defined on the command line with the -D flag:
ant -Dmy.property=42
Loading property files from within an Ant project
LoadProperties Ant task
<loadproperties srcfile="one.properties" />
<loadproperties srcfile="two.properties" />
Property Ant task
<property file="one.properties" />
<property file="two.properties" />
Match property files using a pattern
JB Nizet's solution combines concat with fileset:
<target name="init" description="Initialize the project.">
<mkdir dir="temp" />
<concat destfile="temp/combined.properties" fixlastline="true">
<fileset dir="." includes="*.properties" />
</concat>
<property file="temp/combined.properties" />
</target>
Making a build condition such that if Required System parameters are provided for build then only allowing for the next target else build gets fail.
Pass CMD: ant -DclientName=Name1 -Dtarget.profile.evn=dev
Fail CMD: ant
<project name="MyProject" default="myTarget" basedir=".">
<target name="checkParams">
<condition property="isReqParamsProvided">
<and>
<isset property="clientName" /> <!-- if provide read latest else read form property tag -->
<length string="${clientName}" when="greater" length="0" />
<isset property="target.profile.evn" /> <!-- mvn clean install -Pdev -->
<length string="${target.profile.evn}" when="greater" length="0" />
</and>
</condition>
<echo>Runtime Sytem Properties:</echo>
<echo>client = ${clientName}</echo>
<echo>target.profile.evn = ${target.profile.evn}</echo>
<echo>isReqParamsProvided = ${isReqParamsProvided}</echo>
<echo>Java/JVM version: ${ant.java.version}</echo>
</target>
<target name="failOn_InSufficentParams" depends="checkParams" unless="isReqParamsProvided">
<fail>Invalid params for provided for Build.</fail>
</target>
<target name="myTarget" depends="failOn_InSufficentParams">
<echo>Build Success.</echo>
</target>
</project>
#see also: Replace all tokens form file
I have the following Ant buildfile:
<?xml version="1.0"?>
<!-- the value of the default attr must be one of the targets. -->
<project name="Money" default="build-source" basedir=".">
<description>The Money project build file.</description>
<property name="src" location="."/>
<property name="build" location="build"/>
<property name="junit" location="lib/junit-4.9b3.jar"/>
<path id="_classpath">
<pathelement path="${junit}"/>
<pathelement path="${build}"/>
</path>
<target name="prepare">
<mkdir dir="${build}"/>
</target>
<target name="build-source" depends="prepare"
description="compile the source ">
<javac srcdir="${src}" destdir="${build}">
<classpath refid="_classpath"/>
</javac>
</target>
<target name="run" depends="build-source">
<junit printsummary="on" showoutput="on">
<test name="money.MoneyTest"/>
<classpath refid="_classpath"/>
</junit>
</target>
</project>
It's pretty basic - I'm just trying to get this thing to run properly. What I don't get is: 1) Why does it output the compiled files to a /build/money directory? I want the output directory to be just /build, given this directory structure for my files:
build/
build.xml
lib/
src/
test/
2) When there are tests that don't pass, it says "Test money.MoneyTest FAILED". I'd like it to output info about the failure, expected / actual values, line number, etc.
I can't figure this out by staring at the buildfile above. Any advice?
It outputs the compiled files under build, creating a directory structure that corresponds to the layout of your packages.
Since you put your classes in the money package, the output will be under build/money. If you put your classes under a org.example.foo package, your output would be in the build/org/example/foo directory.
To have your .class files in build, you would have to use the default package.
Edit
I assume your source files have a package money; declaration, as in:
package money;
public class MoneyTest {
...
}
If you add a <formatter> element, detailed reports about test failures will be written to an output file (by default, named TEST-name). See also the Ant Junit Task Documentation.
<junit printsummary="withOutAndErr" showoutput="on">
<formatter type="plain"/>
<test name="money.MoneyTest"/>
<classpath refid="_classpath"/>
</junit>
I have not found a way to directly print the failed tests reports to standard output.