Apache Ant - Select All Symlinks - ant

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.

Related

Ignore full path for specific files when running 'tar' task in ant

I have my proj structure like this
myproj
-bin/myproj-run
-bin/myproj-cli
-lib/x.jar
-target/myproj.jar
I want to create a tar.gz that looks like
myproj
-bin/myproj-run
-bin/myproj-cli
-lib/x.jar
-myproj.jar
How do I do it using ant tar task ?
This one should work (I've tested this on my computer and it works):
<project name="tar.test" default="tartest">
<dirname property="basedir" file="${ant.file.tar.test}" />
<target name="tartest">
<tar destfile="${basedir}/files.tar">
<tarfileset dir="${basedir}/myproj">
<exclude name="target/**" />
</tarfileset>
<tarfileset dir="${basedir}/myproj/target"/>
</tar>
</target>
</project>
BTW, you should read tar manual on apache page, you will find there few examples which shoud help you.
I would first <copy> the files to some other directory (e.g., one called 'package') with the folder structure that you want. Then, run <tar> and <gzip>:
<tar destfile="myTar.tar" basedir="package" />
<gzip src="myTar.tar" destfile="myTar.tar.gz"/>

ant script to compare directories

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.

Get immediate subdirectory of a root directory containing a subdirectory

I have a following directory structure
root_dir
fixed_dir
random_dir
subdir1
subdir2
subdir2.1
subdir3
subdir3.1
subdir3.2
In the ANT build file I know the root_dir, fixed_dir, and one directory that is either random_dir or a subdirectory below random_dir (subdirX). I need to determine the path of random_dir given some subdirX. Is it possible to find this directory in ANT and if so, how?
Here is a tested solution for finding the immediate subdirectory of a root directory that contains some subdirectory subdirX at any level of nesting given the file structure provided in the question.
<property name="root.dir" location="${basedir}/root_dir" />
<property name="subdirX" value="subdir2.1" />
<target name="find-immediate-subdir-of-root-containing-subdirX">
<dirset dir="${root.dir}" includes="**/${subdirX}" id="mydirset" />
<pathconvert property="random_dir" pathsep="${line.separator}" refid="mydirset">
<mapper type="regexp"
from="^(${root.dir}${file.separator}[^${file.separator}]+).*"
to="\1"/>
</pathconvert>
<echo message="${random_dir}" />
</target>
Output
find-immediate-subdir-of-root-containing-subdirX:
[echo] /ant/project/basedir/root_dir/random_dir
BUILD SUCCESSFUL
Total time: 1 second
With Ant addon Flaka you'll get the parent as property of a file object (see Flaka Manual, section 3.7.2, i.e.
<project xmlns:fl="antlib:it.haefelinger.flaka">
<!-- let standard ant tasks, i.e. echo
understand EL expresssions -->
<fl:install-property-handler />
<echo>#{file('${basedir}').parent}</echo>
<!-- or without fl:install-property-handler use fl:echo-->
<fl:echo>#{file('${basedir}').parent}</fl:echo>
</project>
so you would use :
#{file('${yoursubdir}').parent

Intermodule dependency in ant

I am using Ant 1.8
I have multiple modules in intelliJ IDEA. Each module has a build.xml and currently i need to browse till build.xml of that file and run ant for every module.
e.g. module B's build success depends on whether module A's build was successful.
Now, i want to update this process. It will be great if an option exists wherein i can write a single build process which will first build distribution for module A and then while building distribution for B, it will be checked if build for module A is successful.
Is there any way using current Ant mechanism. i could see something similar in ivy but i cant use it in my project.
Please suggest an approach using basic Ant features.
The subant task in ANT is the most flexible way to invoke a multi-module build, for example:
<project name="parent" default="build">
<target name="build">
<subant>
<filelist dir=".">
<file name="moduleA/build.xml"/>
<file name="moduleB/build.xml"/>
</filelist>
<target name="clean"/>
<target name="build"/>
</subant>
</target>
</project>
Project structure
|-- build.xml
|-- moduleA
| `-- build.xml
`-- moduleB
`-- build.xml
Note:
In my opinion the most powerful way to use this task is to combine it with the buildlist task from Apache ivy. Let the ivy inter-module dependency declarations automatically determine the module build order.
Thanks Mark!!
Your answer helped me a lot.
In addition to above answer I would like to add details, if properties are being loaded from properties file.
Project Structure:
|-- build.xml
|-- ProjectOne
-- build.xml
-- antbuilds.properties
|-- ProjectTwo
-- build.xml
-- antbuilds.properties
Common ANT build file:
<project name="Parent" default="all">
<target name="ProjectOne">
<subant>
<property file="ProjectOne/antbuilds.properties"/>
<filelist dir=".">
<file name="ProjectOne/build.xml"/>
</filelist>
<target name="deploy"/>
</subant>
</target>
<target name="ProjectTwo">
<subant>
<property file="ProjectTwo/antbuilds.properties"/>
<filelist dir=".">
<file name="ProjectTwo/build.xml"/>
</filelist>
<target name="deploy"/>
</subant>
</target>
<target name="all" depends="ProjectOne, ProjectTwo">
</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 ?

Resources