How to get the user temp directory in ant - ant

I can use %tmp% to get the user temp directory in batch file. How can I get the user temp directory in ant?

As a followup to a previous answer, you can access the user's environment variables and use the value from TMP or TEMP:
<project name="test" default="showtemp">
<property environment="env"/>
<target name="showtemp">
<echo message="TMP=${env.TMP}"/>
</target>
</project>
Perhaps a better method would be to use the java system property java.io.tmpdir
<project name="test" default="showtemp">
<target name="showtemp">
<echo message="java.io.tmpdir=${java.io.tmpdir}"/>
</target>
</project>

The tempfile task can be used to create temporary files and directories.
Don't forget ANT is a Java program to access to the windows temporary directory would be platform specific. You could try access it using the environment variables:
<propety environment="env"/>
<echo message="windows tmpdir=${env.tmp}"/>

Related

Change baseDir attribute while using import tag

Let me first provide the background of the problem I'm facing.
I have a directory structure as below.
c:\myDirectory
c:\myDirectory\Project1
c:\myDirectory\Scripts
Under the c:\myDirectory\Scripts there is a script that download the source code (from svn) and creates the c:\myDirectory\Project1 directory.
I have another ant scripts ( c:\myDirectory\Scripts**compile-source.xml ) that compiles the Project1
from an ant script build.xml that is downloaded to c:\myDirectory\Project1
Snippet for c:\myDirectory\Scripts\compile-source.xml
<project name="compile" default="buildAll" basedir=".">
<property file=".\build.properties">
</property>
.......
<import file="${project.home.path}/${project.name}/build.xml"/>
<target name="buildAll">
<antcall target="jar-pack"/>
</target>
</project>
Snippet for c:\myDirectory\Project1\build.xml.
<project name="CommonFeatures" default="jar-pack" basedir=".">
<description>
A build file for the Common Features project
</description>
....
</project>
Note that the basedir for the project is set as "." for both the above ant scripts.
When I execute the script c:\myDirectory\Scripts\compile-source.xml from the c:\myDirectory\Scripts directory the target "jar-pack" present in the c:\myDirectory\Project1\build.xml gets executed.
However, the problem is that basedir attribude in build.xml ( basedir="." ) is the current working directory and in this case its c:\myDirectory\Scripts. Hence the script build.xml errors out since the basedir for build.xml is expected to be c:\myDirectory\Project1. The build.xml script would have worked, if basedir="." were set to "c:\myDirectory\Project1", but unfortunately build.xml file comes from the source code that is downloaded and I'm unable to edit.
So here's my question, Is it possible to do any of the following.
Override the value of the attribude basedir="." in build.xml when the is done in c:\myDirectory\Scripts\compile-source.xml ?
Is it possible to change the basedir in build.xml by any other mechanism so that the script c:\myDirectory\Project1\build.xml is executed under directory c:\myDirectory\Project1 ?
Any other way to resolve this issue?
Any help from Ant experts to overcome this issue is highly appreciated.
You can update basedir using subant task. Check this answer
Create the following build.xml file (assuming it is in Z:/any/folder):
<?xml version="1.0" encoding="UTF-8"?>
<project name="project">
<target name="mytarget">
<subant target="debug">
<property name="basedir" value="X:/any/dir/with/project"/>
<fileset dir="Y:/any/folder/with" includes="build.xml"/>
</subant>
</target>
</project>
The you can execute ant mytarget from Z:/any/folder
You can specifically reference the location of your build file, which is described in this stack overflow thread. This would allow you to get and use the directory your build file resides in as a reference point.
For your case the usage of the subant or ant tasks may be better suited, but nevertheless...
You can (but you should know/consider the side-effects!) extend ant with the common ant-contrib task definitions and use the var task which is able to override properties. Make sure to use the latest version (> 1.0b3).
<!-- adjust to your path and include it somewhere at the beginning of your project file -->
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="lib/ant-contrib-1.0b3.jar" />
<!-- works e.g. for basedir = /foo/bar to update it to /foo/bar/.. ~ /foo -->
<var name="basedir" value="${basedir}/.." />
update: but one has to be careful, because this does not change . (current working directory) (so <property name="x" location="tmp" /> would be relative to . and not to basedir anymore ; update: setting basedir outside of ant or via <project basedir= also sets . to basedir!). Here is some test target proving the effect on both:
<target name="tst.dummy.basedir-override">
<!-- example output:
tst.dummy.basedir-override:
[echo] basedir before: basedir=D:\tst, '.'=D:\tst\.
[echo] updating it via 'var' to '..'
[echo] basedir now: basedir=D:\tst/.., '.'=D:\tst\.
-->
<property name="cur" location="." /> <!-- makes the relative path absolute -->
<echo message="basedir before: basedir=${basedir}, '.'=${cur}" />
<echo message="updating it via 'var' to '..'" />
<var name="basedir" value="${basedir}/.." />
<property name="cur2" location="." /> <!-- makes the relative path absolute -->
<echo message="basedir now: basedir=${basedir}, '.'=${cur2}" />
</target>

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

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 ?

How to create a Java file dynamically into certain package using Ant concat task?

I have an Ant script file in which I use concat task to create a Java cource file in the specified package which is defined in a properties file.
For example, I define the package name:
ma.package=com.my.package
In Ant script, I call:
<concat destfile="./${prject.root}/${ma.package}/MyClass.java">
However, MyClass.java was created in a subfolder com.my.package, instead of folder structure com\my\package. How to fix it?
I use Eclipse Helios under Windows XP.
You can use a PathConvert with a nested UnpackageMapper to convert the package name to a path. For example:
<project default="test">
<property name="ma.package" value="com.my.package"/>
<target name="test">
<pathconvert property="ma.package.dir">
<path path="${ma.package}"/>
<unpackagemapper from="*" to="*"/>
</pathconvert>
<echo message="ma.package : ${ma.package}"/>
<echo message="ma.package.dir : ${ma.package.dir}"/>
</target>
</project>
The output is:
Buildfile: C:\tmp\ant\build.xml
test:
[echo] ma.package : com.my.package
[echo] ma.package.dir : C:\tmp\ant\com\my\package
So you could use the converted property value in your concat:
<concat destfile="${ma.package.dir}/MyClass.java">

How to turn directories to .jar files with Ant

How to turn a list of directories into a list of .jar files ?
It seems that using Copy Task and Mappers is the right way to do this but I did not find any nested element creating a jar file from a directory.
Of course, the list of directories would be computed and not hard coded in the ant script.
For instance, a foo directory contains bar1, bar2 and bar3 directories. The script would create bar1.jar from the bar1 dir, bar2.jar from bar2 dir and bar3.jar from bar3 dir
The script would create a bar4.jar from a newly added bar4 directory without any change in the script (no hardcoded list).
Thanks ahead for your help
You can use the subant task to do this. For example:
<project name="jars" default="jar" basedir=".">
<property name="dir.build" value="${basedir}/build"/>
<property name="dir.root" value="${basedir}/foo"/>
<target name="init">
<tstamp/>
<mkdir dir="${dir.build}"/>
</target>
<target name="jar" depends="init">
<!-- ${ant.file} is the name of the current build file -->
<subant genericantfile="${ant.file}" target="do-jar">
<!-- Pass the needed properties to the subant call. You could also use
the inheritall attribute on the subant element above to pass all
properties. -->
<propertyset>
<propertyref name="dir.build"/>
</propertyset>
<!-- subant will call the "do-jar" target for every directory in the
${dir.root} directory, making the subdirectory the basedir. -->
<dirset dir="${dir.root}" includes="*"/>
</subant>
</target>
<target name="do-jar">
<!-- Get the basename of the basedir (bar1, bar2, etc.) -->
<basename file="${basedir}" property="jarname"/>
<jar jarfile="${dir.build}/${jarname}.jar" basedir="${basedir}"/>
</target>
</project>
You could use the appropriate Jar task, along with the foreach ant-contrib extension task.
A sample:
<foreach list="${hmProjectsList}" delimiter="/,"
target="cvsCheckOut" param="hmProjectDir" inheritall="true" />

Resources