Ant: renaming a group of files subject to a condition - ant

I'm using Ant 1.8.2. Given a directory, how do I add an ".html" extension to all files in the directory and its sub-directories only if those files don't already have an .html extension?

There's an example in the Ant move task docs for renaming .bak files that is similar, here it is adjusted for .html files under a directory called my_dir:
<move todir="my_dir" includeemptydirs="false">
<fileset dir="my_dir">
<exclude name="**/*.html" />
</fileset>
<mapper type="glob" from="*" to="*.html" />
</move>
The fileset excludes files that already have the target extension, the mapper defines the renaming pattern.

Related

Copying only files which have another file as a sibling [based on extension]?

I am trying to use ANT to copy some files of a C++ build into another directory.
The output of the build looks like this:
/Build
/LibA
LibA.lib
LibA.pdb
/LibB
LibB.lib
LibB.pdb
/ProjA
myexe.exe
myexe.pdb
/Foo
foo.exe
foo.pdb
/...
Now, I would like to copy all *.exe files and their *.pdb files to another directory (but not the *.pdb files of the libs).
I tried with:
<copy todir="outdir">
<fileset dir="Build">
<include name="**/*.exe" />
<include name="**/*.pdb" />
</fileset>
</copy>
However, then I will also get the *.pdb files inside the LibA, LibB, ... folders.
Is there any way I can only copy the pdb-files which have an *.exe-file in the same directory as their sibling?
Unfortunately, the folders are not named in any way that would allow using wildcards based on the folder name.
Of course, I could list each file individually, such as:
<include name="ProjA/*.pdb" />
<include name="Foo/*.pdb" />
<!-- ... -->
However, I am thinking that maybe there is an elegant way where I can specify "copy all *.exe files and all *.pdb files which have an *.exe file next to them".
You could use the <present> selector to find the "sibling" files, something like this:
<copy todir="outdir">
<fileset dir="Build" includes="**/*.pdb">
<present targetdir="Build">
<mapper type="glob" from="*.pdb" to="*.exe" />
</present>
</fileset>
<fileset dir="Build" includes="**/*.exe" />
<flattenmapper />
</copy>
This will only copy the .pdb files with matching .exe files.
To keep it simple, use a separate fileset for the exe files.
The flatten mapper is only needed if you want to copy just the files ignoring the directory structure in the source.

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>

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>

Ant Copying Empty Directories

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

Apache Ant: Selecting files with fileset?

It's really easy to select a file with a specific filename, or filetype using fileset in ANT, however I have yet not figured out how to write a fileset that remove all files with a filename beginning with a dot, such as .builtpath, and .hgignore, but excluding .htaccess;
Here's my current file:
<delete includeemptydirs="true">
<fileset dir="${temp.dir}/fromRepo">
<exclude name=".htaccess"/>
<include name="**/*" /> <!-- How to select files starting with .?!-->
</fileset>
</delete>
Suggest you try:
<delete includeemptydirs="true">
<fileset dir="${temp.dir}/fromRepo">
<exclude name="**/.htaccess"/>
</fileset>
</delete>
If you don't specify any wildcard - as in ".htaccess" then that rule will only match the exact file name, i.e., '.htaccess' in the top-level directory of the fileset. Prepending the directory wildcard ** to .htaccess will tell Ant to exclude from the delete all files called '.htaccess' found under the directory hierarchy of the fileset.
There's an implicit include of all files if you don't specify any include rule - so no need to specify the 'global' include.
One thing to watch out for - setting includeemptydirs true will remove any empty directories when using a fileset with the delete task. A directory will only be considered empty if it doesn't contain any files. In other words: directories containing a file called '.htaccess' will not be deleted, but those with a '.htaccess' file will not be deleted - hope that's what you need.

Resources