Ant concat exclude directory - ant

My application folder structure looks like this...
-js
-libs
-jquery.js
-jquery-ui.js
-app.js
-ui.js
I wish to concatenate the .js files that are in the /js directory but not those in the /js/libs directory. I am using the following code, but it is ignoring the exclude statement:
<concat destfile="${build.dir}/js/foot-${build.major}-${build.minor}.concat.js">
<fileset dir="${build.dir}/js">
<exclude name="**/libs/**" />
</fileset>
</concat>

The <fileset> should specify both include and exclude patterns. In addition, it may be good to specify a destination directory for <concat> separate from the <fileset> input directory.
<target name="concat-test">
<concat destfile="${basedir}/concat.js" fixlastline="yes">
<fileset dir="${basedir}/js">
<include name="**/*.js" />
<exclude name="**/libs/**" />
</fileset>
</concat>
</target>

Related

Ant fileset matching only files but excluding all sub directories

How do I copy only files immediately under the directory and not its subdirectories? I don't know a priori the names of the files or the subdirectories. I've tried the following to no avail:
<include name="*"> # includes all files and subdirs
===
<include name="*">
<exclude name="*/**> # or "*/" or "**"
Any help would be appreciated.
UPDATE:
I ended up just adding a delete task to delete the copied subdirectories:
<delete includeemptydirs="true">
<fileset dir="${targetdir}">
<type type="dir"/>
</fileset>
</delete>
<?xml version="1.0" encoding="UTF-8"?>
<project default="copy-top-most-files-only" name="My Project">
<property name="to.dir" value="/path/to/dest/folder/" />
<property name="from.dir" value="/path/to/source/folder/" />
<target name="copy-top-most-files-only">
<copy todir="${to.dir}" includeEmptyDirs="false" >
<fileset dir="${from.dir}">
<exclude name="*/**/*" />
</fileset>
</copy>
</target>
</project>
One way to do this is to specify a <depth> selector, for example:
<copy todir="dest">
<fileset dir="src">
<depth max="0" />
</fileset>
</copy>
That will prevent subdirectories from being copied.
You can combine selectors with include/exclude rules if needed.

Ant to delete subdirectories and files in subdirectories but not any file from the directory itself

My requirement is to delete all subdirectories from a specified directory, but NOT delete files in the specified directory.
I have fussed around with fileset and dirset and I could not get a single collection to do the job. What works is this:
<delete includeemptydirs="true" verbose="true" >
<fileset dir="release/reports" >
<exclude name="*.*" />
</fileset>
<dirset dir="release/reports" includes="**/*" />
</delete>
Isn't there a way to do this with one collection (either fileset or dirset)?
It should work like that :
<delete includeEmptyDirs="true">
<fileset dir="C:/yourdir" includes="**/*" excludes="*.*"/>
</delete>

How to preserve file order in Ant concat?

How to preserve file order in Ant concat?
Simple concat with fileset & includesfile produces rather "random" order, as order is not guaranteed:
<concat destfile="C:/targetdir/concatenated.file">
<fileset dir="C:/sourcedir/">
<includesfile name="C:/targetdir/includes.file" />
</fileset>
</concat>
What I need is concatenation in specific order that the files are listed in the includes file.
So far I've found resourcelist, which should preserve order, but I can't seem to be able to produce any concatenated file with it. :/
<concat destfile="C:/targetdir/concatenated.file">
<resourcelist>
<file file="C:/targetdir/includes.file"/>
<filterchain>
<striplinecomments>
<comment value="#"/>
</striplinecomments>
<prefixlines prefix="C:/sourcedir/"/>
</filterchain>
</resourcelist>
</concat>
Plus, the resourcelist can't seem to handle rows like
LibraryX/A/Stuff/Morestuff/*
Instead the row just produces a ".../Morestuff/* does not exist." -error
Includes file has list of relative paths:
LibraryX/A/Stuff/FileA.txt
LibraryX/A/Stuff/FileB.txt
LibraryX/A/Stuff/FileC.txt
LibraryX/A/Stuff/FileY.txt
I was able to get a filelist working pretty easily:
<concat destfile="C:/targetdir/concatenated.file">
<filelist dir="C:/sourcedir/">
<file name="i.txt" />
<file name="n.txt" />
<file name="o.txt" />
<file name="r.txt" />
<file name="d.txt" />
<file name="e.txt" />
<file name="r.txt" />
</filelist>
</concat>
Hope that helps!
If you are using Ant 1.7+, you can use the sort command
<concat destfile="C:/targetdir/concatenated.file">
<sort>
<fileset dir="C:/sourcedir/">
<include name="C:/targetdir/*.file" />
</fileset>
</sort>
</concat>
You can find the documentation of sort here
[On Ant 1.8.2+] You can also pass the fileset via a sort, and sort on filename, like below:
<concat destfile="./${dir.publish}/${dir.js}/b.main-${build.number}.debug.js">
<sort xmlns:rcmp="antlib:org.apache.tools.ant.types.resources.comparators">
<fileset dir="./${dir.publish}/">
<include name="**/${dir.js.main}/**/*.js"/>
<exclude name="**/${dir.js.main}/**/*.min.js"/>
</fileset>
<rcmp:name />
</sort>
</concat>
Couple of things to watch out for:
Directories are sorted before files
Capitals come before lowercase
UPDATE: Another alternative if you need to manually specify order:
<!-- create a ordered list of all the build files so that CIAPI & CIAPI.widget are built first
(can't find a smarter way to do this, since ant filesets are unordered) -->
<fileset id="a" dir="."><include name="CIAPI/build.project.xml"/></fileset>
<fileset id="b" dir="."><include name="CIAPI.widget/build.project.xml"/></fileset>
<fileset id="c" dir=".">
<include name="**/build.project.xml"/>
<exclude name="CIAPI/build.project.xml" />
<exclude name="CIAPI.widget/build.project.xml" />
</fileset>
<union id="all_build_files">
<fileset refid="a"/>
<fileset refid="b"/>
<fileset refid="c"/>
</union>
Ugly, but, erm, this is ant?
try this, put in alphabetical order
<project name="concatPath" default="full">
<target name="full">
<fileset id="fs" dir="./files" />
<pathconvert refid="fs" property="concatList" pathsep=";" targetos="unix"/>
<echo>${concatList}</echo>
</target>
</project>
this can be used with hierarchical structure of directories, and the order will be the exposed by David.
Remember that XML is not order-dependent, by definition.
To concatenate files in a sorted order, consider using <replace> instead.
Create an order file that defines the order. Then, in your build file:
Copy the order file to the destination file with <copy>
Concatenate your files together into a temporary file with <concat>
Load the files into properties with <loadfile>
Insert the text from those files into the destination file with <replace>
Example order file order_file.txt:
FILE_A_HERE
CONCAT_FILES_HERE
Example ant build file build.xml:
<copy file="order_file.txt" tofile="destination.txt" overwrite="yes">
<concat destfile="tempfile.txt">
<fileset dir="includes/">
<include name="*.txt">
<exclude name="fileA.txt">
</fileset>
</concat>
<loadfile property="fileA" srcFile="includes/fileA.txt" />
<loadfile property="concatFile" srcFile="tempfile.txt" />
<replace file="destination.txt" token="FILE_A_HERE" value="fileA" />
<replace file="destination.txt" token="CONCAT_FILES_HERE" value="concatFile" />

How can I exclude files from a reference path in Ant?

In a project we have several source paths, so we defined a reference path for them:
<path id="de.his.path.srcpath">
<pathelement path="${de.his.dir.src.qis.java}"/>
<pathelement path="${de.his.dir.src.h1.java}"/>
...
</path>
Using the reference works fine in the <javac> tag:
<src refid="de.his.path.srcpath" />
In the next step, we have to copy non-java files to the classpath folder:
<copy todir="${de.his.dir.bin.classes}" overwrite="true">
<fileset refid="de.his.path.srcpath">
<exclude name="**/*.java" />
</fileset>
</copy>
Unfortunately, this does not work because "refid" and nested elements may not be mixed.
Is there a way I can get a set of all non-java files in my source path without copying the list of source paths into individual filesets?
Here's an option. First, use the pathconvert task to make a pattern suitable for generating a fileset:
<pathconvert pathsep="/**/*,"
refid="de.his.path.srcpath"
property="my_fileset_pattern">
<filtermapper>
<replacestring from="${basedir}/" to="" />
</filtermapper>
</pathconvert>
Next make the fileset from all the files in the paths, except the java sources. Note the trailing wildcard /**/* needed as pathconvert only does the wildcards within the list, not the one needed at the end:
<fileset dir="." id="my_fileset" includes="${my_fileset_pattern}/**/*" >
<exclude name="**/*.java" />
</fileset>
Then your copy task would be:
<copy todir="${de.his.dir.bin.classes}" overwrite="true" >
<fileset refid="my_fileset" />
</copy>
For portability, instead of hard-coding the unix wildcard /**/* you might consider using something like:
<property name="wildcard" value="${file.separator}**${file.separator}*" />

Ant - copy only file not directory

I need to copy all files in a folder except directory in that folder using Ant script.
Im using below script to do that.
<copy todir="targetsir">
<fileset dir="srcdir">
<include name="**/*.*"/>
</fileset>
</copy>
But it copies all files and directory in that folder.
how to restrict/filter directory in that folder?
thanks,
I think there is an easier way.
flatten="true" - Ignore directory structure of source directory, copy all files into a single directory, specified by the todir attribute. The default is false.
Do you mean that srcdir conatins sub-directories, and you you don't want to copy them, you just want to copy the files one level beneath srcdir?
<copy todir="targetsir">
<fileset dir="srcdir">
<include name="*"/>
<type type="file"/>
</fileset>
</copy>
That should work. The "**/*.*" in your question means "every file under every sub directory". Just using "*" will just match the files under srcdir, not subdirectories.
Edited to exclude creation of empty subdirectories.
I do not have enough reputation to comment, so I'm writing new post here. Both solutions to include name="*" or name="*.*" work fine in general, but none of them is exactly what you might expect.
The first creates empty directories that are present in the source directory, since * matches the directory name as well. *.* works mostly because a convention that files have extension and directories not, but if you name your directory my.dir, this wildcard will create an empty directory with this name as well.
To do it properly, you can leverage the <type /> selector that <fileset /> accepts:
<copy todir="targetsir">
<fileset dir="srcdir">
<include name="*"/>
<type type="file"/>
</fileset>
</copy>
Can you try
<copy todir="targetsir">
<fileset dir="srcdir">
<include name="*.*"/>
</fileset>
</copy>
** is used to match a directory structure.
<copy todir="targetsir" includeEmptyDirs="false">
<fileset dir="srcdir">
<include name="*"/>
</fileset>
</copy>
If your folder has many subdirectories and you don't want them to be copied (if you want only files) try this..
<target name="copy">
<copy todir="out" flatten="true">
<fileset dir="tn">
<filename name="**/cit.txt" />
</fileset>
</copy>
</target>
The secret is to use not fileset but dirset instead.

Resources