Update destination directory with new files (if modified) using ant - ant

I'm facing a problem with ant "copy". Here is my requirement:
I want to sync 2 dirs(dir1 and dir2) but i want to keep the extra files/dirs present in dir2. My aim is i want to copy dir1 contents(if modified ) to dir2 but want to keep any additional files/dirs present in dir2.
I tried ant's sync task, but it is trying to keep both dirs in sync ie., it is deleting extra contents present in dir2. I don't find any flag to disable this feature:
<sync todir="dir2" failonerror="true" verbose="true">
<fileset dir="dir1" excludes="*.svn" />
</sync>
I tried ant's copy with "modified" selector, but its also doing the same: :(
<copy todir="dir2" failonerror="true">
<fileset dir="dir1" excludes="*.svn" >
<modified/> <!-- Copies only modified files -->
</fileset>
Can any one suggest, how can i achieve my requirement with ant?

By default, the ANT copy task does not overwrite files:
<copy todir="target/dir2" verbose="true" overwrite="false">
<fileset dir="src/dir1"/>
</copy>
The copy task will also detect if the file has changed.
The copy task will not delete files, so I don't understand why your second example (using a modified selector) did not work.

Related

How to echo the file names that only copied or removed by sync task in ant?

I'm trying to copy the schema files from my workspace to a config folder as part of build.
I've achieved that by using the sync task.
These are my requirements:
1.Need to replace only the latest not every file each time.
2.Need to display in console, what are the files being changed (copied /removed)
<target name="copy-schema">
<sync todir="C:/config/schema">
<fileset dir="${schema.dir}" id="schema_dir"/>
<preserveintarget preserveemptydirs="true">
<include name="**/**" />
</preserveintarget>
</sync>
</target>
This copies the schema Files, but I'm not able to see what are the files copied.
I've tried the below,
<target name="copy-schema">
<sync todir="C:/config/schema">
<fileset dir="${schema.dir}" id="schema_dir"/>
<preserveintarget preserveemptydirs="true">
<include name="**/**" />
</preserveintarget>
</sync>
<property name="filesCopied" refid="schema_dir"/>
<echo>${fileCopied}</echo>
</target>
But it prints all the files in the directory.
Any help is appreciated.
Thanks in advance
The sync task supports a verbose attribute to log the files that are being copied.
Try adding the verbose attribute in your sync:
<sync todir="C:/config/schema" verbose="true">

Ant copy files to dir while renaming original files

I have a task that needs to copy over files to a certain location. If the files already exist in the destination, these destination files need to be renamed (appended with .bak). If the destination file doesn't exist, the file should just be put into place.
Currently I have this:
<target name="install-jsps">
<copy todir="target">
<fileset dir="source"/>
<globmapper from="*.jsp" to="*.jsp.bak"/>
</copy>
</target>
This however renames the source files while I want to rename the target files before copying over the source files. I cannot do a rename of the whole target folder because some target files are not in the source fileset.
Preferably I don't want to use an external library like ant-contrib.
You can do it in two copy tasks: one to make the backups, one to copy in the new files from the source. The extra bit you need is the present selector in the fileset used to make the backup. The selector allows you to only back up the files that are about to be superceded, i.e. the ones that are present in the source directory.
<copy todir="dest">
<fileset dir="dest" includes="*.jsp">
<present targetdir="source" />
</fileset>
<globmapper from="*" to="*.bak" />
</copy>
<copy todir="dest">
<fileset dir="source" includes="*.jsp" />
</copy>

How To copy a file in ant irrespective of its location

I want to copy a jar file from ../source,but I am not sure where it exactly is,it can be anywhere in any subdirectory but it is there. I am writing this code
<target name="CopyingFromSource" depends="clean">
<copy file="../source/org.springframework-spring-support-2.0.8.jar" todir="../result"/>
</target>
but is showing me can't find org.springframework-spring-support-2.0.8.jar Can you please tell me how to copy it?
It is present anywhere either immediately in /source or in any subdirectory.
Use copy task with nested fileset like that :
<project>
<copy todir="../result">
<fileset dir="/home/gilreb/temp" includes="**/org.springframework-spring-support-2.0.8.jar" id="foobar"/>
</copy>
</project>
see Ant manual copy task and Ant manual fileset for turther details.. i.e. if you need to copy the flat file only and not it's whole path you need to use :
<copy todir="../result" flatten="true">
...
</copy>

Relocate contents of dynamic folder

I have a zip file which has one base folder inside it with other content inside that. I don't always know what that base folder is going to be called until I unzip it.
I'd like to move that base folder, and rename it at the same time, in ant - but can't seem to find out how. I've written code to extract the contents of the zip file to ${local.sdk.dir}/temp/ but from here i can't work out how to rename/move the extracted folder
<move todir="${local.sdk.dir}/${remote.sdk.file.name}">
<fileset dir="${local.sdk.dir}/temp/<WHAT_DO_I_PUT_HERE?>"></fileset>
</move>
also tried
<move todir="${local.sdk.dir}/${remote.sdk.file.name}" includeEmptyDirs="yes" verbose="true">
<fileset dir="${local.sdk.dir}/temp/" >
<include name="**/*" />
</fileset>
</move>
and played about with this, but closest I can get without ant throwing an error is to copy the contents of the temp dir, not the base folder within temp.
You can do all this in one step - copy from the zip file and rename the files changing the dir name as you copy. The copy task accepts a nested resource collection, so you can use a zipfileset to specify the files to copy directly from the zip file.
In order to rename the files as they are copied, you can use a mapper, which the copy task also takes as a nested element. In this case, a cutsdirmapper looks like the tool for the job.
So, if I've understood what you want to do correctly, something like this should work:
<copy todir="${local.sdk.dir}/${remote.sdk.file.name}">
<zipfileset src="${your.zip.file}" />
<cutdirsmapper dirs="1" />
</copy>
cutdirsmapper is only available in Ant 1.8.2 onward, so if you're using an earlier version, you could try a regexpmapper:
<regexpmapper from="[^/]*(.*)" to="\1" />
Similar to this question
<target name="relocate_sdk_folder">
<path id="sdk_folder_name">
<dirset dir="${local.sdk.dir}/temp/">
<include name="*"/>
</dirset>
</path>
<property name="sdk_folder_name" refid="sdk_folder_name" />
<echo message="renaming ${sdk_folder_name} to ${remote.sdk.file.name}" />
<move file="${sdk_folder_name}" tofile="${local.sdk.dir}/${remote.sdk.file.name}" />
</target>

How to create directories specified by a mapper in Ant

Given a fileset
<fileset id="myFiles" dir=".">
<include name="**/*.file"/>
</fileset>
How do I create a sub-directory at each file in the set, named after the filename without the extension?
For example, given the files folderA/X.file and folderA/folderB/Y.file, I want to create the directories folderA/X and folderA/folderB/Y
The ant touch task supports creating files, parent dirs and filename mapping, so can be used to achieve this:
<target name="mkdirs">
<touch mkdirs="true">
<fileset dir="the_dir"/>
<mapper type="glob" from="*.file" to="the_dir/*/.tmp" />
</touch>
<delete>
<fileset dir="the_dir" includes="**/.tmp"/>
</delete>
</target>
This creates temporary files in target dirs (creating the dirs if the don't exist) then deletes the temporary files leaving the dirs you wanted.
You would be using for task to iterate on your file list. But I have not come across any substring type of utility in Ant which you can use to strip the extension and create the directory. Do search for this utility, if its not there then you need to implement an Ant task to do that.
Sorry to answer my own question. Unless someone knows otherwise, there appears to be no way for out-of-the-box ANT to create directories (e.g. using mkdir) relative to entries in a fileset.
Ant-Contrib contains useful for loop tasks, as Bhushan suggests, which could possibly perform this sort of task.
Had some better things to be getting on with, so in the end, I just wrote a batch file called by an ANT task (apply tasks can iterate over filesets).
<apply executable="cmd" failonerror="1">
<arg value="/c"/>
<arg line="build\tools\makeRelDir.bat"/>
<fileset dir=".">
<include name="**/*.file"/>
</fileset>
</apply>
where the batch file does this:
mkdir %~dp1%~n1
(Why is it so hard to do something some simple in ANT? Am I missing something?)

Resources