I'm having a problem when I try to call another ant build file and copying its result to a directory :
<!-- Copying PatientStation -->
<ant dir="../SubProject" antfile="build.xml" />
<copy todir="D:/Export">
<fileset dir="../SubProject/${fullVersionName}/jar" />
</copy>
After the ant call, I'm not positioned in the remote directory instead of the current one.
BUILD FAILED
D:\myWorkspace\Build\build1.xml:64: D:\myWorkspace\SubProject\D:\Export does not exist.
I dont' have a PC in front of me, so I can't say definitely what will work, but normally in Ant, if a directory doesn't begin with a slash, it is assumed to be a sub-directory of the current ${basedir}.
Try one of the following:
<!-- You're in the "D" drive, so don't specify the drive letter -->
<!-- This specifies the current drive you're on -->
<copy todir="/Export"/>
Or
<!-- If that doesn't work, try this -->
<!-- Windows uses backslash as separators -->
<copy todir="D:\\Export"/>
Or
<!-- Add a slash in front of the drive letter -->
<copy todir="/D:/Export"/>
One of these will work.
You can do it by set your destination folder location in variable.
Try this one:
<property name="tgtpath" location="D:/Export" />
<copy todir="${tgtpath}">
<fileset dir="../SubProject/${fullVersionName}/jar" />
</copy>
Related
I have the following ant targets defined. The idea is to do the heavy work only, if some contents of a folder have changed.
<target name="checksumAssets">
<echo message="verify checksums" />
<checksum todir="${bin.loc}/../checksums" verifyproperty="checksum.isUpToDate.test">
<fileset dir="${bin.loc}/assets/" id="filelist">
<include name="somefolder/" />
<exclude name="somefolder/result.swf"/>
</fileset>
</checksum>
<echo message="${toString:filelist}"/>
<echoproperties regex="checksum.isUpToDate.test"/>
</target>
<target name="createAsset" depends="checksumAssets" unless="${checksum.isUpToDate.test}">
<!-- do create the assets and other magic -->
<echo message="create checksum files" />
<checksum todir="${bin.loc}/../checksums" >
<fileset refid="filelist" />
</checksum>
</target>
somefolder contains images which will be processed and result in a swf file containing these assets.
i want this heavy processing only to take place if something in the asset folder changes.
this works as espected in two cases:
i add a new file to somefolder
i change an existing file in somefolder
my problem is:
it does not work when i delete a file from this folder.
this means, the createAsset Target is not called on ant createAsset if i remove a file from the folder in question. it is called in the two aforementioned cases and if there are no checksum files present in the checksums folder.
is there something i missed?
ant version is 1.8.2
i've found a workaround.
since <checksum> only saves the checksum of single files, it cannot know if a file is missing from a previous run. for this it would need to save the checksum of a complete filelist on disk.
this is what i accomplished:
<target name="checksumAssets">
<echo message="verify checksums" />
<!-- generate filelist.txt with actual content of somefolder -->
<fileset dir="${bin.loc}/assets/somefolder/" id="filelist">
<exclude name="result.swf"/>
<exclude name="filelist.txt"/>
</fileset>
<concat destfile="${bin.loc}/assets/somefolder/filelist.txt" fixlastline="true">${toString:filelist}</concat>
<!-- checksum folder including the filelist.txt -->
<checksum todir="${bin.loc}/../checksums" verifyproperty="checksum.isUpToDate.test">
<fileset dir="${bin.loc}/assets/" id="checkedlist">
<include name="somefolder/" />
<exclude name="somefolder/result.swf"/>
</fileset>
</checksum>
</target>
<target name="createAsset" depends="checksumAssets" unless="${checksum.isUpToDate.test}">
<!-- do create the assets and other magic -->
<echo message="create checksum files" />
<checksum todir="${bin.loc}/../checksums" >
<fileset refid="checkedlist" />
</checksum>
</target>
first i generate a filelist.txt with the content of the current folder.
then i generate checksums of all files in this folder, including the filelist.txt
on every an run, filelist.txt will be generated and checked against the filelist.txt from the last successful run of createAsset.
now the createAsset target is run if a content file changes or if the content of this folder changes.
mission accomplished ;)
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
I am still very new to ant and, although I know coldfusion, I don't know very much about java conventions, but I know that ant is built using java conventions. That being said I am working on an ant process to copy a project to a temp folder, change some code in the project, and then push the temp directory up to an FTP. I am trying to exclude all of my git, eclipse, and ant files from the copy so that my testing platform doesn't get cluttered. I setup a target to do the copy, but it seems that Ant not only is ignoring my excludes (which I am sure I wrote wrong), but it is only copying top level directories and files. No recursive copy. My current target is:
<target name="moveToTemp" depends="init">
<delete dir="./.ant/temp" />
<mkdir dir="./.ant/temp" />
<copy todir="./.ant/temp">
<fileset dir=".">
<include name="*" />
<exclude name=".*/**" />
<exclude name=".*" />
<exclude name="build.xml" />
<exclude name="settings.xml" />
<exclude name="WEB-INF/**" />
</fileset>
<filterset>
<filter token="set(environment='design')" value="set(environment='testing')" />
</filterset>
</copy>
</target>
I know that I am not doing my excludes right, but I don't know what I am doing wrong with them. I see double asterisks (**) used all the time in Ant but I can't figure out
By default an Ant fileset will (recursively) include all files under the specified directory, equivalent to:
<include name="**/*" />
That's the implicit include. If you supply an include, it overrides the implicit one.
Your include
<include name="*" />
Says 'match any file in the fileset directory', but that excludes traversal of subdirectories, hence your issue. Only files and the top-level directories are being copied.
See Patterns in the Ant docs for directory-based tasks: ** matches any directory tree (zero or more directories).
For your case you should be able to simply remove the 'include', so that the implicit 'include all' applies.
Suggest you also investigate the defaultexcludes task, which lets you set up this sort of thing once for the whole project.
Responding to the title of the question. You can include copy of empty directories as follows. (includeemptydirs attribute)
Example:
<copy includeemptydirs="true" todir="${directory}${file.separator}sentinel_files">
<fileset dir="${basedir}${file.separator}sentinel_files"/>
</copy>
Use the documentation provided in:
https://ant.apache.org/manual/Tasks/copy.html
I am trying to get ant4eclipse to work and I have used ant a bit, but not much above a simple scripting language. We have multiple source folders in our Eclipse projects so the example in the ant4eclipse documentation needs adapting:
Currently I have the following:
<target name="build">
<!-- resolve the eclipse output location -->
<getOutputpath property="classes.dir" workspace="${workspace}" projectName="${project.name}" />
<!-- init output location -->
<delete dir="${classes.dir}" />
<mkdir dir="${classes.dir}" />
<!-- resolve the eclipse source location -->
<getSourcepath pathId="source.path" project="." allowMultipleFolders='true'/>
<!-- read the eclipse classpath -->
<getEclipseClasspath pathId="build.classpath"
workspace="${workspace}" projectName="${project.name}" />
<!-- compile -->
<javac destdir="${classes.dir}" classpathref="build.classpath" verbose="false" encoding="iso-8859-1">
<src refid="source.path" />
</javac>
<!-- copy resources from src to bin -->
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset refid="source.path">
<include name="**/*"/>
<!--
patternset refid="not.java.files"/>
-->
</fileset>
</copy>
</target>
The task runs successfully, but I cannot get the to work - it is supposed to copy all non-java files over too to emulate the behaviour of eclipse.
So, I have a pathId named source.path which contains multiple directories, which I somehow needs to massage into something the copy-task like. I have tried nesting which is not valid, and some other wild guesses.
How can I do this - thanks in advance.
You might consider using pathconvert to build a pattern that fileset includes can work with.
<pathconvert pathsep="/**/*," refid="source.path" property="my_fileset_pattern">
<filtermapper>
<replacestring from="${basedir}/" to="" />
</filtermapper>
</pathconvert>
That will populate ${my_fileset_pattern} with a string like:
1/**/*,2/**/*,3
if source.path consisted of the three directories 1, 2, and 3 under the basedir. We're using the pathsep to insert wildcards that will expand to the full set of files later.
The property can now be used to generate a fileset of all the files. Note that an extra trailing /**/* is needed to expand out the last directory in the set. Exclusion can be applied at this point.
<fileset dir="." id="my_fileset" includes="${my_fileset_pattern}/**/*">
<exclude name="**/*.java" />
</fileset>
The copy of all the non-java files then becomes:
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset refid="my_fileset" />
</copy>
That will copy the source files over retaining the source directory structure under todir. If needed, the flatten attribute of the copy task can be set to instead make all the source files copy directly to todir.
Note that the pathconvert example here is for a unix fileseystem, rather than windows. If something portable is needed, then the file.separator property should be used to build up the pattern:
<property name="wildcard" value="${file.separator}**${file.separator}*" />
<pathconvert pathsep="${wildcard}," refid="source.path" property="my_fileset">
...
You could use the foreach task from the ant-contrib library:
<target name="build">
...
<!-- copy resources from src to bin -->
<foreach target="copy.resources" param="resource.dir">
<path refid="source.path"/>
</foreach>
</target>
<target name="copy.resources">
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset dir="${resource.dir}" exclude="**/*.java">
</copy>
</target>
If your source.path contains file paths as well then you could the if task (also from ant-contrib) to prevent attempting to copy files for a file path, e.g.
<target name="copy.resources">
<if>
<available file="${classes.dir}" type="dir"/>
<then>
<copy todir="${classes.dir}" preservelastmodified="true">
<fileset dir="${resource.dir}" exclude="**/*.java">
</copy>
</then>
</if>
</target>
I am trying to replace placeholders in source files with values defined in a .properties file using the copy task with **
My build.xml contains
<target name="configure">
<echo message="Creating DB configuration" />
<copy todir="${dir.out}" overwrite="true">
<fileset dir="${dir.in}" />
<filterchain>
<expandproperties/>
<replacetokens begintoken="<" endtoken=">" propertiesResource="conf.properties" />
</filterchain>
</copy>
</target>
A sample from the conf.properties:
tbs.base_directory = d:/oracle/oradata/my_app
tbs.data_file = ${tbs.base_directory}/data01.dbf
I want to refer from within the .properties file to variables, in this case I would like to substitute tbs.base_directory in tbs.data_file.
Unfortunately it is not substituted. Any ideas?
Thanks
Problem is that expandproperties applies to copied file not to the property resource you are using to define your tokens. A possible solution is to first load conf.properties to force properties expansion and dump it into a temporary file that is used for token substitution. Something like the following should work:
<target name="configure">
<echo message="Creating DB configuration" />
<!-- force expanding properties in tokens property file -->
<loadproperties srcfile="conf.properties" />
<!-- dump expanded properties in a temp file -->
<echoproperties prefix="tbs" destfile="conf.expanded.properties"/>
<copy todir="${dst.out}" overwrite="true">
<fileset dir="${dir.in}" />
<filterchain>
<expandproperties/>
<!-- use temporary file for token substitution -->
<replacetokens begintoken="<" endtoken=">" propertiesResource="conf.expanded.properties" />
</filterchain>
</copy>
<!-- delete temp file (optinal)-->
<delete file="conf.expanded.properties"/>
</target>
Drawback of this solution is that it only works as long as you can select the properties to write in the temporary file (i.e all properties in the conf.properties file starts with the same prefix).