I have a file that looks something like this:
// run script Y
#include ./relativePath/to/script.y
// run script Z
#include ./relativePath/to/script/z.z
// etc.
What I would like ANT to do, is take this file and replace all the includes with the actual content of the files that are pointed to by the #include 'directive', relative to the file itself. I am searching around replaceregexp but not getting much joy.
Can anyone point me in the direction to look in?
TIA
I didn't find a perfect way to do this. I did however come up with a solution that matched my needs.
Instead of starting with the single source file and trying to figure out the files to replace, I looped over the files that I knew might be included, replacing 'included' instances of them with their file content.
Something like:
<target name="fubar">
...
<foreach target="injectFile" inheritall="true" param="include.file">
<fileset dir="${src.dir}" casesensitive="yes" />
</foreach>
</target>
<target name="injectFile">
... code that works out relative path of include file here ...
<loadfile property="include.file.content" srcFile="${include.file}" />
<replace file = "${build.file}"
token = "#include ${include.file.relative.path}"
value = "${include.file.content}" />
</target>
your syntax is very close to the C preprocessor. Is it a solution to put the filenames in quotes, e.g.:
#include "./relativePath/to/script.y"
an to feed you file in the cpp:
cpp -o output inputfile
Related
I tried to use ants loadproperties with expandproperties:
This works for simple text properties but i get weird results when a property contains a windows path.
<property name="myAntFile" value="${ant.file}" />
<loadproperties srcFile="my.properties">
<filterchain>
<expandproperties />
</filterchain>
</loadproperties>
<echo message="$${external} = ${external}" />
the properties file looks like this:
external=${myAntFile}
the result is:
Buildfile: C:\projects\trunk\build.xml
...
[echo] ${external} = C:projects\trunkbuild.xml
I know that for properties files there are escape rules for backslashes and special whitespace characters. However i dont see how i can translate the buildscripts properties to that special meaning.
Anyone has a idea how to solve that or is this a ant bug (maybe the expandproperties chain should get a additional property for escaping when used in property file contexts?)?
With ant you can use a forward slash / as the path separator when defining paths, even on Windows: C:/projects/trunk/build.xml
If ${ant.file} returns the path using backslashes, convert this path first before you load the properties file.
Unfortunately I haven't yet found the definitive way to convert paths from C:\a\path to C:/a/path and back. Supposedly pathconvert can do the trick...
<pathconvert targetos="unix" property="myAntFile.withForwardSlashes">
<path location="${myAntFile}"/>
</pathconvert>
... but it confuses relative and absolute paths and I couldn't make it work while testing this on my OS X machine.
What would be the best way to do this using an Ant task:
Start with a bunch of text files with names like this:
Filename_With_Underscores.txt
Another_Filename_With_Underscores.txt
Yet_Another_Filename_With_Underscores.txt
and turn them into this:
Filename+With+Underscores.txt
Another+Filename+With+Underscores.txt
Yet+Another+Filename+With+Underscores.txt
I actually need to change the identically-named folder that each text file is contained in also, that is, to start with this folder/file structure:
Filename_With_Underscores/Filename_With_Underscores.txt
and turn it into this:
Filename+With+Underscores/Filename+With+Underscores.txt
but I can handle that if I know how to rewrite the text file names.
I would know how to replace all underscores with plus signs in the contents of a file, using replaceregexp, but how do I do this to the folder and file names themselves?
I've used a mapper to rewrite folder and file names in the past, for example:
<target name="dita_wrap" description="Wraps each file in a folder with the same name as the file, copies all to new location">
<copy todir="output" verbose="true">
<fileset dir="source"
includes="*/*.dita" />
<regexpmapper handledirsep="true" from="^(.*)/([^/]*)\.dita$"
to="\1/\2/\2.dita" />
</copy>
</target>
However getting something like that to capture and replace each underscore in a filename, no matter how many underscores there might be, is eluding me. Any advice?
You need a <filtermapper>, for example:
<copy todir="output" verbose="true">
<fileset dir="source" includes="*/*.txt" />
<filtermapper>
<replacestring from="_" to="+"/>
</filtermapper>
</copy>
Works for me:
$> find . -type f
./build.xml
./source/Filename_With_Underscores/Filename_With_Underscores.txt
./output/Filename+With+Underscores/Filename+With+Underscores.txt
I've looked all over the net as to how I can load a list of files that contain spaces and don't yet exist with an Ant task.
I have a file that contains one file path per line, like so:
dir1/dir2/dir with spaces/file1.js
dir1/dir2/dir with spaces/dir3/file2.js
dir1/file1.js
Since the paths have spaces I cannot use:
<filelist files="..." />
The files also don't exist yet, so it seems like I can't use
<fileset>
<includesfile name="..." />
</fileset>
Any ideas would be greatly appreaciated.
You can use a resourcelist for this. For example, if your list of files are in a file called 'files.txt':
<resourcelist id="files">
<file file="files.txt"/>
</resourcelist>
<touch mkdirs="true">
<resources refid="files" />
</touch>
For me this yields:
[touch] Creating .../filelist/dir1/dir2/dir with spaces/file1.js
[touch] Creating .../filelist/dir1/dir2/dir with spaces/dir3/file2.js
[touch] Creating .../filelist/dir1/file1.js
The reason this works is that a <resourcelist> treats each line in the file read as a separate resource, so line separators rather than commas or spaces divide the items.
My problem is, I have to read the source path for a copy job from an xml file and then copy all files in that dir read from the xml file to another dir.
Since code is more than words:
<xmltask source="${projectfile}">
<copy path="Project/RecentResultsInfo/ResultsDirectoryOfRecentLoadTest/text()" property="recentdir" attrValue="true"/>
</xmltask>
<copy todir="${targetdirectory}">
<fileset dir="${recentdir}"/>
</copy>
The output when running this target is:
C:\develop\build.xml:44: Warning: Could not find resource file "C:\develop\C:\Programme\tool\test_90\" to copy.
It seems in fileset it does not recognize, that recentdir holds a full path inside. The written xml from the application has a newline before and after the path in the xml file that is read with the path. So ant does not recognize the path since theres a newline in front of it.
Is there anything like trim for ant?
Can anybody help me getting ant to accept that path?
Done it now by using Ant-Contrib, but that is used in this project anyway.
<xmltask source="${projectfile}">
<copy path="Project/RecentResultsInfo/ResultsDirectoryOfRecentLoadTest/text()" property="recentdirraw" attrValue="true"/>
</xmltask>
<!-- replace newlines and whitespace from read path -->
<propertyregex property="recentdir" input="${recentdirraw}" regexp="^[ \t\n]+|[ \t\n]+$" replace="" casesensitive="false" />
<copy todir="${targetdirectory}">
<fileset dir="${recentdir}"/>
</copy>
Simply modifying the property with a regex trimming the text by striping of whitespace and newlines.
As far as I can see, the copy element in xmltask provides a trim attribute.
trims leading/trailing spaces when writing to properties
Does that work?
Given an ant fileset, I need to perform some sed-like manipulations on it, condense it to a multi-line string (with effectively one line per file), and output the result to a text file.
What ant task am I looking for?
The Ant script task allows you to implement a task in a scripting language. If you have JDK 1.6 installed, Ant can execute JavaScript without needing any additional dependent libraries. The JavaScript code can read a fileset, transform the file names, and write them to a file.
<fileset id="jars" dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
<target name="init">
<script language="javascript"><![CDATA[
var out = new java.io.PrintWriter(new java.io.FileWriter('jars.txt'));
var iJar = project.getReference('jars').iterator();
while (iJar.hasNext()) {
var jar = new String(iJar.next());
out.println(jar);
}
out.close();
]]></script>
</target>
Try the ReplaceRegExp optional task.
ReplaceRegExp is a directory based task for replacing the occurrence of a given regular expression with a substitution pattern in a selected file or set of files.
There are a few examples near the bottom of the page to get you started.
Looks like you need a conbination of tasks:
This strips the '\r' and '\n' characters of a file and load it to a propertie:
<loadfile srcfile="${src.file}" property="${src.file.contents}">
<filterchain>
<filterreader classname="org.apache.tools.ant.filters.StripLineBreaks"/>
</filterchain>
</loadfile>
After loading the files concatenate them to another one:
<concat destfile="final.txt">
...
</concat>
Inside concat use a propertyset to reference the files content:
<propertyset id="properties-starting-with-bar">
<propertyref prefix="src.file"/>
</propertyset>
rodrigoap's answer is enough to build a pure ant solution, but it's not clean enough for me and would be some very complicated ant code, so I used a different method: I subclassed ant's echo task to make an echofileset task, which takes a fileset and a mapper. Subclassing echo buys me the ability to output to a file. A regexmapper performs the transformation on filenames that I need. I hardcoded it to print out each file on a separate line, but if I needed more flexibility I could add an optional separator attribute. I also thought about providing the ability to output to a property, too, but it turned out I didn't need it since I echo'ed straight to a file.