ant script to compare directories - ant

I have a javascript project with the following structure:
root -
/docs
/dist
/source
/resources
/plugins
Code is in source directory and an ant script is executed to generate compressed files in dist directory. All the files are in source control.
I want to run a directory diff before running the ant script to make sure the list of files in source and dist directories are same. If not, stop execution and tell the user to checkin the needed files before running the build.
I am new to ant and am unable to find any documentation to list differences in files list between 2 directories. Appreciate any inputs.

You could try the following. Prints a list of the files to be checked in before failing:
<project name="demo" default="build">
<target name="check">
<apply executable="echo" failonerror="false" resultproperty="files.found">
<arg line="missing file:"/>
<srcfile/>
<fileset id="srcfiles" dir="source" includes="*.txt">
<present present="srconly" targetdir="dist"/>
</fileset>
</apply>
<fail message="Files need to be checked in" if="files.found"/>
</target>
<target name="build" depends="check">
..
..
..
</target>
</project>
Note:
Tested on Linux. Probably won't work on windows.

Related

How to compile each jasper file to its own directory?

I'm trying to create a ant script to compile my jasper files, but I have many "srcdir" and "destdir":
<target name="all">
<jrc
srcdir="many..."
destdir="many..."
tempdir="any"
xmlvalidation="true">
<classpath refid="classpath"/>
<include name="**/*.jrxml"/>
</jrc>
</target>
...and I would like it to compile each file to it's own dir. For every ".jrxml" file.
Is there a way?
You can use ant-contrib foreach task to loop over each jrxml file and call the jrc task for each of those. If you don't have it, you'll need to install ant-contrib by copying its JAR file to the lib directory of your Ant installation (if you're using Eclipse, you can add it by going to "Window > Preferences > Ant > Runtime" and adding the JAR into "Ant Home Entries").
The following defines a target "all" that will select all the jrxml files under the current directory. For each of those file, the "jrc" target will be called and the corresponding file will be referenced by the property jrxml.file.
Inside this task, the directory where the jrxml file is located is retrieved with the dirname task and the name of the jrxml file is retrieved with the basename task. The built .jasper file will be created under a folder having the same name as the jrxml file. (It needs to be created first with the mkdir task).
<taskdef resource="net/sf/antcontrib/antcontrib.properties" />
<target name="all">
<foreach target="jrc" param="jrxml.file">
<path>
<fileset dir=".">
<include name="**/*.jrxml"/>
</fileset>
</path>
</foreach>
</target>
<target name="jrc">
<dirname property="jrxml.dir" file="${jrxml.file}"/>
<basename property="jrxml.filename" file="${jrxml.file}" suffix="jrxml"/>
<mkdir dir="${jrxml.dir}/${jrxml.filename}"/>
<jrc srcdir="${jrxml.dir}"
destdir="${jrxml.dir}/${jrxml.filename}"
tempdir="${jrxml.dir}/${jrxml.filename}"
xmlvalidation="true">
<classpath refid="classpath"/>
<include name="${jrxml.filename}.jrxml"/>
</jrc>
</target>
As an example, if you have a structure:
+folder
+--jrxml
+----Example1.jrxml
+----Example2.jrxml
the result will be
+folder
+--jrxml
+----Example1.jrxml
+----Example1
+------Example1.jasper
+----Example2.jrxml
+----Example2
+------Example2.jasper

How to copy file to a directory which has partial fixed name and other half changes with integer values. using ant script

I want to use ant script to copy a file to directory which is not path is fixed but last folder name is not fixed.
Path D:\Home\Config\plugins\1780.
The last folder name (1780) it changes randomly and is not fixed.
I want to copy a war file in to that folder.
How can I do it.
Thanks,
Prashant
You should iterate (once) over plugins subdirectories and copy to the (only?) entry.
<target name="run">
<foreach target="loop" param="loop.param">
<dirset dir="D:\Home\Config\plugins" />
</foreach>
</target>
<target name="loop">
<copy todir="$loop.param">
...
</copy>
</target>

Copy entire directory before creating an ear file

I am trying to build an ear file from an ant script. There are several targets that create .jar and .war (to be contained within the ear) files using different projects and these are building without issue so I will not include them.
Imagine this directory structure:-
Project1/
build/
lib/
META-INF/
build.xml
So when the ant script is called the build directory is deleted and remade, all fairly standard stuff. Then I create the jar's and war's from external projects and store them in build/ - everything is fine.
But I also want to include the directories lib/ and META-INF/ in the ear file. So I try to copy them to the build directory using this target.
<target name="file_cleanup">
<copy todir="${build}">
<fileset dir="lib/"/>
<fileset dir="META-INF/"/>
</copy>
</target>
This file_cleanup target is a dependant of the default build target which creates the ear - shown below:
<target name="ear" depends="initialise, file_cleanup, other targets...">
<ear destfile="My.ear" appxml="META-INF/application.xml">
<fileset dir="${build}" includes="*.jar,*.war"/>
</ear>
</target>
What I want to see when I extract the ear is:
target1.jar
target2.war
lib/
META-INF/
But what I actually get is:
target1.jar
target2.war
and all of the contents of both the lib and META-INF directories...
I was able to resolve this issue by creating additional properties and directories and copying the directory structures to the new directories:
<target name="initialise">
<delete dir="${build}"/>
<mkdir dir="${build}"/>
<mkdir dir="${build}/${lib}"/>
<mkdir dir="${build}/${meta-inf}"/>
</target>
<target name="file_cleanup">
<copy todir="${build}/${lib}">
<fileset dir="lib"/>
</copy>
<copy todir="${build}/${meta-inf}">
<fileset dir="META-INF"/>
</copy>
</target>

running specific target in different ant scripts in different directories

We have a large amount of apps. They all have a build.xml file located in the projects base directory. I am trying to create an ant script that will go through and call a specific target on each of the build.xml files in all the projects.
Here are the issues:
Some of the projects are in deeper directories than others.
Only some of the projects need to be built at a time.
I was trying to use subant + antfile and defining a CSV of file paths in a properties file, but this did not work. Below is what i have and the error i am getting.
If there is a better way to do this or you know what my problem is, please let me know! Thanks!
This is the property defined in a property file. I am wanting the person running the script to add the file paths in here that are relative to the current location of the script they are running.
projects.to.build=
This is the subant task i am trying to use in the main build script.
<filelist
id="projectNames"
dir="${basedir}"
files="${projects.to.build}"
/>
<target name="debugAll" description="Builds all the projects listed in the projectNames.properties file.">
<subant target="debug" antfile="${projects.to.build}">
</subant>
</target>
Here is the error i get when i try to run the build script when there are projects defined in the properties file. I am using the relative path. For example: ..\Apps\AnApp1\build.xml,..\Apps\AnApp2\build.xml,..\OtherApps\foo\AnotherApp1\build.xml
"No Build Path Specified" (at my subant task)
You specified the antfile attribute, so ANT was expecting to a single build.xml file.
The subant documentation describes how you can use a fileset as child parameter.
Here's an example:
<project name="Subant demo" default="run-debug-target">
<target name="run-debug-target">
<subant target="debug">
<fileset dir="." includes="**/build.xml" excludes="build.xml"/>
</subant>
</target>
</project>
Update
Alternatively a filelist could be used:
<project name="Dry run" default="run">
<target name="run">
<subant target="test">
<filelist dir="projects" files="one/build.xml,two/build.xml,three/build.xml,four/build.xml"/>
</subant>
</target>
</project>
Processing the following build files:
projects/one/build.xml
projects/two/build.xml
projects/three/build.xml
projects/four/build.xml
Is it possible to run the target in the all the build files concurrently ?
E.g.
<project name="Dry run" default="run">
<target name="run">
<subant target="test">
<filelist dir="projects" files="one/build.xml,two/build.xml,three/build.xml,four/build.xml"/>
</subant>
</target>
</project>
In this example, is there any way to run target "test" present in all the build files (one/build.xml,two/build.xml,three/build.xml,four/build.xml) concurrently ?

Apache Ant - Select All Symlinks

I need a symbolic link selector in Apache Ant.
The following selectors are available to the Core.
Can anyone advise me on writing a <scriptselector> for selecting only the symbolic linked files under a directory? Or any other way?
The reason:
folder
|-- file-0.0.1
|-- file-0.0.2
|-- file-0.0.3
`-- file --> file-0.0.3
I just want to get the file that is symbolically linked by file. In this case file-0.0.3, but the symbolic link can change and I don't want all the other files to be in the Ant <fileset>
Please take a look at :
http://ant.apache.org/manual/Tasks/symlink.html
I don't have a linux machine to test now but I guess that with the something like this :
<symlink action="record" linkfilename="my.links">
<fileset dir="${my.folder}" includes="*"/>
</symlink>
You should be able to record your symlinks into a file and then processing the files as you wish. For example you could then create a list only with the "symlinked" files and iterate over it to do what you want.
EDIT :
For this solution you will need to install the ant-contrib. Just unpack the ant-contrib-1.0b3.jar to your ant/lib directory. Then use the following build.xml file :
<project name="test" default="build">
<!--Needed for antcontrib-->
<taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
<target name="build">
<property name="my.dir" value="/home/stefanos"/>
<exec executable="bash" outputproperty="symlinks" dir="${my.dir}">
<arg value="-c"/>
<arg value="\ls -1 | xargs -l readlink"/>
</exec>
<foreach list="${symlinks}" delimiter="${line.separator}" param="link" target="process.link"/>
</target>
<target name="process.link">
<!--Do whatever you want with the file targeted by the symlink-->
<echo message="Processing link : ${link}"/>
</target>
</project>
The trick is the linux command which returns all the targeted files from the symlinks. Then you just iterate through them with the foreach task and you call a target in which you can do whatever you need with the files.

Resources