How to find substring in apache ant property value? - ant

I have multiple files under a directory. All these files have similar names e.g. com.xyz.projname1.xml, com.xyz.projname2.xml, etc.
When I try to get the filename in a for loop, it returns the absolute path of com.xyz.projname1.xml.
I just want to check if the absolute path contains 'projname1'.
<target name="update-proj-version-and-name">
<for param="file" >
<path>
<fileset dir="${project.dir.target}/artifact/" casesensitive="no">
<include name="*.xml"/>
</fileset>
</path>
<sequential>
<property name="proj.file.name" value="#{file}"/>
<echo>proj name - ${proj.file.name}</echo>
<!-- Here I need to check if ${proj.file.name} contains 'projname1' then invoke one of our macrodef -->
</sequential>
</for>
</target>
Can you please help?
Thanks,
Ranjeet

Related

Ant task: add a file to an archive with a parameter

everyone!
I'm currently struggling with an Ant task for a DITA plugin. It would consist in adding a file (whatever the extension is) to an archive via the command line. The idea is to set a parameter like this :
dita -f mymap.ditamap -transtype htmlCustom -Dadd-file=fileOfMyChoice.txt
The part that interests me is the last one: -Dadd-file=fileOfMyChoice.txt
So far, I've tried to include two choices into my target.
The user sets a add-file parameter and its value is added into the fileset with the base set of generated files.
Or, nothing is passed via this parameter and the base set of generated files is included in the fileset.
The part that is still challenging to me if the one that identifies if a parameter add-file is passed and how its value is transmitted in a fileset.
If you have any pointers for me, that would be awesome.
<target name="map2exportmap">
<dirname property="dita.temp.dir.fullpath" file="${dita.temp.dir}${file.separator}dummy.file"/>
<xslt in="${dita.temp.dir.fullpath}${file.separator}.job.xml"
out="${dita.temp.dir.fullpath}${file.separator}allResources.out"
style="${dita.plugin.com.myplugin.dir}/xsl/generateAllResources.xsl"
force="true"/>
<mkdir dir="${dita.map.output.dir}/temp"/>
<fileset id="global" dir="${user.input.dir}/" includesfile="${dita.temp.dir.fullpath}${file.separator}allResources.out" />
<union id="globalAddendum">
<fileset id="ditaGeneration" dir="${user.input.dir}/" includesfile="${dita.temp.dir.fullpath}${file.separator}allResources.out"/>
<fileset id="additionalFile" dir="${user.input.dir}/" includesfile="${add-File}"/>
</union>
<condition property="withAddedFile" refid="globalAddendum" else="global">
<isset property="add-file"/>
</condition>
<copy todir="${dita.map.output.dir}/temp">
<fileset dir="${user.input.dir}/" includesfile="${withAddedFile}"/>
</copy>
<zip destfile="${dita.map.output.dir}/${dita.map.filename.root}.zip">
<fileset dir="${dita.map.output.dir}/temp"/>
</zip>
<delete dir="${dita.map.output.dir}/temp"/>
</target>
everyone!
I found the solution!
Here is the code if it can help anyone.
<target name="map2exportmap">
<dirname property="dita.temp.dir.fullpath" file="${dita.temp.dir}${file.separator}dummy.file"/>
<xslt in="${dita.temp.dir.fullpath}${file.separator}.job.xml"
out="${dita.temp.dir.fullpath}${file.separator}allResources.out"
style="${dita.plugin.com.xxxxx.xxxxxxx.dir}/xsl/generateAllResources.xsl"
force="true"/>
<mkdir dir="${dita.map.output.dir}/temp"/>
<!-- Create two filesets depending on the argument `add-file` sent in the command line -->
<fileset id="base" dir="${user.input.dir}/" includesfile="${dita.temp.dir.fullpath}${file.separator}allResources.out" />
<fileset id="addedFile" file="${add-file}"/>
<!-- this is the core of the condition. It tests if there was an argument for `add-file, then ii sets the property `with.or.without.added.file`-->
<condition property="with.or.without.added.file" value="addedFile" else="base">
<isset property="add-file"/>
</condition>
<echo>${with.or.without.added.file}</echo>
<echo>${add-file}</echo>
<!-- Process the copy of content in the tempoerary folder-->
<copy todir="${dita.map.output.dir}/temp">
<fileset refid="${with.or.without.added.file}"/>
<fileset id="base" dir="${user.input.dir}/" includesfile="${dita.temp.dir.fullpath}${file.separator}allResources.out" />
</copy>
<!-- Execute the zip packaging -->
<zip destfile="${dita.map.output.dir}/${dita.map.filename.root}.zip">
<fileset dir="${dita.map.output.dir}/temp"/>
</zip>
<delete dir="${dita.map.output.dir}/temp"/>

antcall in foreach is not executing loop

I want to build couple of projects based on no of .composites by using ant scripts.
i added all the taskref tags,lib path every thing in my build.xml file.
i wrote the following piece of code for the same and i am getting the error
foreach doesn't support the nested "antcall" element.
<target name="createApplicationDAA">
<foreach param="program">
<path>
<fileset dir="${soaProjectName}/Composites" includes="**/*.composite"/>
</path>
<antcall target="createDAA"/>
</foreach>
</target>
<target name="createDAA">
..........
....
</target>
clearly,
my requirement is to create all DAAs by building all the composites by using foreach or for loop in ant script.
can anybody please let me know,where am i doing wrong?
foreach doesn't use nested elements to determine what to run, it takes a target attribute:
<target name="createApplicationDAA">
<foreach param="program" target="createDAA">
<path>
<fileset dir="${soaProjectName}/Composites" includes="**/*.composite"/>
</path>
</foreach>
</target>
<target name="createDAA">
<echo>${program}</echo>
</target>
Alternatively, use <for>, which takes a nested <sequential>
<target name="createApplicationDAA">
<for param="program">
<path>
<fileset dir="${soaProjectName}/Composites" includes="**/*.composite"/>
</path>
<sequential>
<echo>#{program}</echo>
</sequential>
</for>
</target>

copy a file from inside of a directory in a filelist

I have a filelist that contains a list of directories. I need to iterate through that filelist and get a file from each directory and copy it to another location.
I was attempting to use filelist in combination with foreach, but foreach does not support filelist. Is there any other way of doing this in ANT?
My attempt with for.
This fails at the <copy> task saying that it cannot find a directory. The directory it is looking for is ${basedir}/bin/ instead of the directory that is first listed in the filelist it is given. I am assuming it is because it is not reading my filelist correctly. My foreach version gives the same error.
<for
list="devBuild"
delimiter=","
param="dirName"
trim="true">
<sequential>
<copy
todir="./apks/"
failonerror="true"
verbose="true">
<fileset dir="#{dirName}/../bin/">
<include name="*/*.apk"/>
</fileset>
</copy>
</sequential>
</for>
Partially Working
Right now, the for loop is working... kinda. The way i want it to work is shown directly below. However, this fails saying the devBuild reference can not be found. However, that filelist is created earlier in a different target and is created with that reference. Why can i not use that reference ID in a different target?
<for
delimiter=","
param="dirName"
trim="true">
<path>
<filelist
refid="devBuild"></filelist>
</path>
<sequential>
<echo>#{dirName}</echo>
<copy
todir="./apks/"
failonerror="true"
verbose="true">
<fileset dir="#{dirName}/../bin/">
<include name="*/*.apk"/>
</fileset>
</copy>
</sequential>
</for>
The following way does work, but i would like to use the reference ID instead of creating the filelist again.
<for
delimiter=","
param="dirName"
trim="true">
<path>
<filelist
id="devBuild"
dir="${basedir}"
files="${build1},${build2},${build3},${build4}"
/>
</path>
<sequential>
<echo>#{dirName}</echo>
<copy
todir="./apks/"
failonerror="true"
verbose="true">
<fileset dir="#{dirName}/../bin/">
<include name="*/*.apk"/>
</fileset>
</copy>
</sequential>
</for>
I figured out the problem. When i am making my call to this other target i was not setting the flag for inheritrefs. This needs to be true so the other target will get the references.

Update fileset using ant dynamically

I would like to create a jar file dynamically depending on selected java modules
Here is the part of the ant script which does that.
<property name="modules.selected" value="A,C,F" />
<for list="${modules.selected}" param="module">
<sequential>
<echo>Module chosen ${basedir}/#{module}/src</echo>
<copy todir="${build.dir.src}" overwrite="true">
<fileset dir="${basedir}/#{module}/src">
<include name="**/*.${src.valid.exts}" />
</fileset>
</copy>
</sequential>
</for>
In the above script I am selecting a module and then constructing a directory and copying all the modules present in the directory to a location (build/src).
But I really dont like the logic mentioned above would like to change to include all the required modules in a fileset and use the populated fileset to copy.
Here is the logic I am looking for
<fileset id="required-modules" dir="${basedir}/#{module}/src">
<for list="${modules.selected}" param="module">
<sequential>
<echo>Module chosen ${basedir}/#{module}/src</echo>
<include name="**/*.${src.valid.exts}" />
</sequential>
</for>
</fileset>
<copy todir="${build.dir.src}" overwrite="true">
<fileset refid="required-modules" />
</copy>
Could anyone update the above script to make it work.

How can I process only files that have changed?

At the moment I'm doing this:
<delete dir="${RSA.dir}/file1" />
<copy todir="${RSA.dir}/file1" >
<fileset dir="${CLEARCASE.dir}/file1" />
</copy>
and repeating the same thing for other files - but it takes a long time.
I only want to delete and copy files that have been updated, with their modified date in clearcase later than that in RSA.
How can I do that?
Look into the sync task.
If you want to do it based on file contents, and ignore the timestamp, I think this macro will do that:
<macrodef name="mirror" description="Copy files only if different; remove files that do not exist in dir. This works similiar to robocopy /MIR." >
<attribute name="dir"/>
<attribute name="todir"/>
<sequential>
<copy overwrite="true" todir="#{todir}">
<fileset dir="#{dir}">
<different targetdir="${todir}"/>
</fileset>
</copy>
<delete includeemptydirs="true">
<fileset dir="#todir}">
<present targetdir="${dir}" present="srconly"/>
</fileset>
</delete>
</sequential>
</macrodef>
You need to use a selector on a FileSet. Something like this:
<fileset dir="${your.working.dir}/src/main" includes="**/*.java">
<different targetdir="${clean.clearcase.checkout}/src/main"
ignoreFileTimes="false"
ignoreContents="true" />
</fileset>
That compares your working dir to a clean checkout you have elsewhere, and returns the files whose last modified times have changed. You can use the fileset as the argument for a <delete> or a <copy>.

Resources