Ant absolute path to single file in fileset - ant

I'm using Jenkins with Email-Ext plugin to automate PHP Unit Testing. If the tests failed I want to send a notification email to myself including the zipped test reports.
The Email-Ext plugin requires an Ant Fileset definition in the attachment field.
The zipped test report can be found here:
D:\Test_Reports\test-report-failed.zip
I can't find a working example of the use of fileset with absolute path to a single file.
I tried the following but didn't work:
<fileset file="D:\Test_Reports\test-report-failed.zip" />
Could find any example of using absolute paths but relative paths only.
This is the official help from the Email-ext plugin about the attachment field:
This is the set of attachments that will be used for the email. The format is a comma separated list of Ant include file syntax. The base directory is the workspace.

You can use <include/> tag to do this. It will look like this.
<fileset dir="D:\Test_Reports">
<include name="test-report-failed.zip" />
</fileset>
If you want to get file path in property then you can do this in that way (I've tested this and it works):
<path id="absolute.path.id">
<fileset dir="D:\Test_Reports">
<include name="test-report-failed.zip" />
</fileset>
</path>
<property name="absolute.path" value="${toString:absolute.path.id}" />
<echo>file absolute path: ${absolute.path}</echo>

Just specify the absolute path of your file in the attachment field (not the XML element).

I solved it by changing the Jenkins Job's workspace to the directory where are the test reports and other resources located. Then I was using relative addressing to the zip file like: test-report-failed.zip

Related

Ant failing with Content is not allowed in prolog

I am using subant and it is resulting into Content is not allowed in prolog problem.
<subant target="main" genericantfile="build.xml">
<fileset dir = "." />
</subant>
Error:
The following error occurred while executing this line:
pattern.py:1: Content is not allowed in prolog.
Please note I have different files in those folders for example, python files.
When I use explicit listing using the filelist, all works fine.
<subant target="main" genericantfile="build.xml">
<filelist dir="."
files = "A/build.xml,
B/build.xml"
/>
</subant>
With subant you either specify genericantfile along with a dirset (to run the same build file many times, each time with a different basedir) or you omit genericantfile but supply a fileset or other resource collection of build files to run. You are mixing the two styles, and it looks like when you provide a fileset ant is ignoring the genericantfile attribute and treating each element of that fileset as a build file, attempting to parse each of the files as XML, and failing for those that are not XML (i.e. the python files).
<subant target="main">
<fileset dir = "." includes="**/build.xml" />
</subant>
would include only the real build files in the fileset.

The archive doesn't exist error when running ant jar task

I'm running an ant build file that creates a Jar. The task looks like this:
<target name="generator-app" depends="clean,compile">
<jar jarfile="${gen.App}">
<manifest>
...
</manifest>
<fileset dir="${classes}">
<include name="com/mypackage/**" />
</fileset>
<zipfileset dir="${jars}" />
</jar>
</target>
The build file runs and creates the file as expected when I run it on Linux, but fails with this error on any other platform:
BUILD FAILED /home/user/build.xml:287: the archive doesn't exist
I tried using destfile instead of jarfile, but the same result occurs. The archive does not exist indeed, but the purpose of the task is to create it.
Is there any limitation on certain platforms or any way to correct this?
Forward slashes don't seem very windowy to me :) Maybe you should convert your slashes based on your os? Do you pass this path somewhere?
I found the problem. I tried using a newer version of ant, and now the error indicates exactly what is missing (a jar to be packaged in the jar to be created).

can you do this seemingly simple Ant copy task without using ant-contrib's foreach?

I have a source directory with a bunch of plugins. Each plugin has its own lib directory. I want the contents of each of those lib directories to be merged into a single lib directory within my build. In theory you'd do something like this:
<copy todir="build/web/lib">
<fileset dir="web/plugins/*/lib/" includes="**/*" />
</copy>
However, Ant chokes when the dir attribute includes a wildcard. Is ant-contrib the only alternative, or can you make this work with vanilla ant?
Choke message is build.xml:28: [...]/web/plugins/*/lib does not exist.
The dir= attribute of a fileset doesn't take a wildcard - hence the error you see. You need to specify a single directory, in this case web/plugins, and use a slightly different wildcard for the includes:
<copy todir="build/web/lib">
<fileset dir="web/plugins" includes="*/lib/**/*" />
</copy>
If you need to alter the paths as you copy, you can use a mapper, for example the flattenmapper will give you file names with all leading directory information stripped off.

How do I convert an Ant Path into a FileSet?

I'm writing an Ant script to package a project into a WAR file. The software consists of several projects with their own source directories, libraries, etc.
The WAR task has a nested element lib which I'm currently working on. I currently have a reference of the required libs as a Path (containing several FileSets, which I use in a classpath reference. The lib, however, wants the input to be a FileSet, and it refuses a Path.
I tried converting my Path into a FileSet, but then I didn't get it to work as a classpath elsewhere.
Is there a way to convert a Path into a FileSet? I would hate to copy-paste the directories.
<path id="compile.libs">
<fileset dir="${common.path}/lib" includes="*.jar"/>
<fileset dir="${data.path}/lib" includes="*.jar"/>
<fileset dir="${gui.path}/lib" includes="*.jar"/>
<fileset dir="${gui.path}/WebContent/WEB-INF/lib" includes="*.jar"/>
</path>
...when used with <war ..><../> <lib refid="compile.libs"/> </war> leads to:
BUILD FAILED
build.xml:173: compile.libs doesn't denote a zipfileset or a fileset
Assuming the paths are absolute, you can first convert the Path to a comma-delimited list using <pathconvert>, and then convert the list back into a Fileset:
<!-- create path -->
<path id="foo.path">
<pathelement location="/foo/bar/baz.txt"/>
<pathelement location="/qux/quux/quuux.txt"/>
</path>
<!-- convert foo.path to foo.list -->
<pathconvert
refid="foo.path"
property="foo.list"
pathsep=","
dirsep="/"
>
<!--
<fileset> will want relative paths, so we need to strip
the leading /. result: "foo/bar/baz.txt,qux/quux/quuux.txt"
-->
<map from="/" to=""/>
</pathconvert>
<!-- convert foo.list to fileset -->
<fileset id="foo.fileset" dir="/" includes="${foo.list}"/>
(Note the above assumes Unix; you may need to fiddle a bit with separators and whatnot if you're on Windows or you want to make it platform-independent.)
You may have several choices.
You may provide more than one
<lib> nested element to <war>
task. Maybe this would be enough.
You may preassemble all of your
lib files in one temporary
directory and then just reference that
directory as a fileset.
There is an ant-contrib
PathToFileSet task, but it
requires a central root directory,
and this may not be a case with your
compile.libs layout.
Since Ant 1.8.0 you can use a mappedresources. Source: Ant script: Prevent duplication of JAR in javac-classpath war-lib
I think I would try option 1.
I solved this by staging the libs like this :
<copy todir="stage/libs" flatten="true">
<path refid="classpath" />
</copy>
and then using a in the WAR task.simple.
The jars in the classpath used to compile are not the same that needs to be packaged inside the war. For example: I'm sure you need servlet-api.jar to compile your project but you don't need it inside the war because the container provides it. And some jars aren't needed at compile time but at runtime.
I know I'm not answering your question, just want you to think what you are doing.

How to include directory structure in an ant jar file?

I am a bit of an ant newbie, and I'm having trouble making a jar correctly. As an example, say I want to make a jar with my StringUtil class. Using the following ant directive, I can create the jar, but the problem is that the directory structure is lost. It simply puts StringUtil.class in the base directory of the jar. How can I correct this ant directive so that StringUtil.class is inside the com/test directory in the jar?
<jar destfile="myjar.jar" >
<fileset file="${build}/com/test/StringUtil.class"/>
</jar>
Thanks!
You need to tell Ant to build the jar from the base directory, then tell it to include only the desired file. Like so:
<jar destfile="myjar.jar" >
<fileset dir="${build}" includes="com/test/StringUtil.class"/>
</jar>
Here's the doc for <fileset> tags.

Resources