Alias/synonym for ant target - ant

I have an ant target called "unittest" which I find clunky and I would like to use "test" instead. I need to keep the name "unittest" around though because other people also use the ant build file.
Is there a way that I could add aliases or synonyms for particular targets?
I tried using a comma separated list as possible in other attributes such as depends but that this not work. I get Target "test" does not exist in the project ...
<target name="test,unittest">
I know that I could simulate this using depends but I want to avoid the extra unnecessary output this produces.
<target name="test" depends="unittest">
Is there any way to achieve this? I will be fine with accepting the depends approach if there really is no better way.

Move the contents of the unittest target into a macrodef and replace the contents of the unittest target with a call to the macro. Create a test target calling the same macro. Job done.

Related

How do I find a particular sub directory using Ant and then use it to create a symlink?

I need to create a symlink to a sub-directory using Ant. The issue is that I don't know where the target sub-directory is.
To create a symlink with ant I do this:
<symlink link="${parent.dir}/FOO/linkname" resource="${parent.dir}/BAR/target"/>
But I don't know what BAR is called in advance so I need to do a search for "target" under parent.dir and then pass the one result into the resource.
Is this possible using fileset? Or another way?
It might be possible to use a fileset but that might give you several symlinks or none.
A much better approach is to define the path to BAR in a property. If there is a dynamic part in this path, change the code so that Ant evaluates the dynamic part and everyone else uses Ant's value.
The typical example here is that the path contains a version or timestamp. Define those in your build file so you can use them everywhere. If a Java process needs the values, pass them to the process as a system property (-D...).

Dynamic basedir for Ant in Eclipse

The title might not be the best so let me explain what I am trying to do.
I have made an Ant buildfile that will help me with Maven goals. It's so much easier having to scope to Ant view and choose what I want to do. The biggest benefit with this is that I can use it in almost any project. Whether I deploy to tomcat or jboss or sakai(:deploy) or I handle mutiple instaces of the same server or skip tests... worst case I just change some path properties.
The drawback right now is that I have to keep a copy of this buildfile in every project.
What I am trying to do is have only 1 buildfile, in the workspace, and dinamicaly optain, from eclipse, the current project that I am working on. Be it module or parent I can refine that later.
So basically change the basedir for ant tasks based on the selected project in eclipse.
I have tried Ant Runtime Properties but for some reason properties like
${project_path}
fail to give me what their description say. I get this:
Variable references empty selection: ${project_path}
I hope it is clear what I am trying to do. So my question, I know it's possible, I'm just missing something and I hope some of you can help me with this.
I believe the trouble is in the Ant Runtime properties. I'm not 100% sure how I should use those.
Thank you!
EDIT after comment and further investigation..
Make the projectdir available as basedir property for ant like that :
Window > Preferences > Ant > Runtime > Properties
and create a property named basedir with value either :
${project_loc}
or
${workspace_loc}/${project_name}
and
<project basedir="${basedir}">
<echo>$${basedir} = ${basedir}</echo>
</project>
will work as expected, means echoing eclipse/yourworkspace/projectdir
Maybe there are other ways, i.e. via Ant Addon Ant4Eclipse, which aims to make Eclipse settings available for ant, never used it.

Is it possible to display the call "graph" of an ant extension-point?

I have an extension-point defined in ant :
<extension-point name="foo"/>
A lot of tasks contribute to this point in several imported ant files :
<bindtargets targets="bar" extensionPoint="foo" />
However I'm kinda lost as to exactly which tasks are contributing. Is there a way to have ant report the tasks that would be triggered by a given extension point ? More generaly, is there a way to display the "call-graph" (or simply the list of dependencies) of an ant task ?
I tried using verbose options for ant (-v and such), with no luck.
Thanks
First of all, you can try to debug the ANT process in your IDE using remote debugging by adding some parameters to ANT_OPTS (mine is set in ~/.profile):
http://blog.dahanne.net/2010/06/03/debugging-any-java-application/
And profiling may help. I found project Antro on ANT Wiki...
http://sourceforge.net/projects/antro
Maybe you can try it out. The project is said to be designed for ANT, which looks promising in solving your problem.
Also you can use Yourkit Java Profiler to do a CPU profiling. YJP can show the call graph of a java application, but I'm not sure if one can find out which are ANT targets.
The following document shows how to start a java application with YJP agent.
http://www.yourkit.com/docs/95/help/agent.jsp
I know of 2 ways to get this information:
You can get the effective target/extension-point invocation sequence from Ant's console logger. To do this, place Ant's logging facility into verbose mode by passing -verbose on the command line to Ant. There are two lines, one after the other, that dump to the console immediately before most targets as they are invoked in your build script:
A line that shows a summary of the targets in the call sequence starting with the text, Build sequence for target(s) 'artifact' is [...].
A line showing the detailed call sequence (nested targets and antcalls included). This line starts with the text, Complete build sequence is [...]. This listing considers, as much as reasonably possible, the evaluation of any if and unless attributes of each target listed at the point the line is logged to the console.
Simply invoke your Ant build as you would normally with the -verbose option and your console should have the information you're looking for.
You can get a pictorial representation of the call sequence using a tool called Grand. However, it hasn't been updated for quite some time and thus doesn't support extension-points (which is what you're concerned with here). It will interpret antcall's, ant, and depend'encies. It doesn't evaluate the if and unless attributes but simply identifies potential execution sequence - more of a dependency hierarchy than an actual call graph. The project is on Github so an update to support extension-points may not be too difficult.
The graphic is rendered using Graphviz.
For an actual call sequence, use option 1.
This is pretty sloppy, but it works. Ant is actually pretty easily scripted, and if you are using at least Java 6 (or it might be Java 7), javascript support is built in and thus can be used right out of the box. This defines a task that will echo the dependencies of any target in call order:
<scriptdef name="listdepends" language="javascript">
<attribute name="target"/>
<![CDATA[
var done = [];
var echo = project.createTask("echo")
function listdepend(t) {
done.push(t.getName());
var depends = t.getDependencies();
while (depends.hasMoreElements()) {
var t2 = depends.nextElement();
if (done.indexOf(t2)==-1) listdepend(project.getTargets().get(t2));
}
echo.setMessage(t.getName());
echo.perform();
}
var t = attributes.get("target");
if (t!=null) {
var targ = project.getTargets().get(t);
listdepend(targ);
}
]]>
</scriptdef>
In your case, you can create a new target (or not) and call it like so:
<target name="listfoo">
<listdepends target="foo"/>
</target>
As I said, this is somewhat sloppy. It probably isn't very fast (although unless your target triggers thousands of others, it probably isn't noticeably slow). It won't handle antcall tasks (although it could be modified to do so easily) or respond to if and unless attributes. If dependencies nest too far, it may hit a recursion depth limit (but I doubt any project nest them deep enough).
The array is used to make sure that each dependency is listed once (ant would only run them once).

Setting an item metadata using a property

I have been trying to make a task in my TFS builds more generic, and one of the things I am trying to do is copy some files to different directories depending on the build using the task. I toyed with the idea of using properties, but I couldn't think of a way to do that cleanly, so I tried to go with using item metadata, as I've been able to do so in another place in the same target file I'm working on, only this time, I'd like to use properties.
Here's what I want to do:
<ItemGroup>
<DestinationParent Include="$(DeploymentPath)">
<DestinationParentPath>$(DeploymentPath)</QuartzParentPath>
</DestinationParent>
</ItemGroup>
And later in the build, I tried to copy some files to the destination folder by referencing the item metadata:
<Copy SourceFiles="#(FilesToCopy)" DestinationFiles="#(FilesToCopy->'%(DestinationParentPath)\Destination\%(RecursiveDir)%(Filename)%(Extension)')" ContinueOnError="false" ></Copy>
Unfortunately, after the build runs, my BuildLog shows the following:
Copying file from "$(BinariesRoot)\%(ConfigurationToBuild.FlavorToBuild)\<File being copied>" to "\Destination\<File being copied>".
%(DestinationParentPath) had expanded to an empty string, for whatever reason. Using %(DestinationParent.DestinationParentPath) produced an error, telling me that I should simply be using %(DestinationParentPath). $(DeploymentPath) is expanded to the correct string as expected in several other places in the build.
Another source of confusion is that using %(ConfigurationToBuild.FlavorToBuild) yielded the correct value, i.e. Test, as can be seen in the following:
EDIT: this is defined under the root node Project, whereas the ItemGroup with DestinationParentPath is defined under a Target node. Does this also make a difference?
<ItemGroup>
<ConfigurationToBuild Include="Test|Any CPU">
<FlavorToBuild>Test</FlavorToBuild>
<PlatformToBuild>Any CPU</PlatformToBuild>
</ConfigurationToBuild>
</ItemGroup>
It does not seem as though the Include attribute is relevant when you're only interested in the string in the item's metadata since I'm pretty sure "Test|Any CPU" does not reference any actual file.
So once again, why is %(DestinationParentPath) expanding to an empty string?
EDIT: I forgot to mention that I also tried hard-coding the actual path for DestinationParentPath, but this still resulted in %(DestinationParentPath) expanding to an empty string.
EDIT: this is defined under the root node Project, whereas the ItemGroup with DestinationParentPath is defined under a Target node. Does this also make a difference?
Yes, it makes a difference. The ability to define an ItemGroup inside a Target is new to msbuild 3.5. Despite looking declarative, it's actually executed at runtime just as if you'd called the old style CreateItem / CreateProperty tasks. That alone leads to potential issues: you need to consider when the containing task is (first) called. Order of operations is not always obvious to the naked eye. May be wise to make the task where you use %(DestinationParentPath) dependent on the task where it's created, even if there's no "logical" dependency.
In addition, there are the age-old msbuild scoping quirks/bugs. Dynamically created properties & items are not visible to "sibling" tasks. Also, items updated in nested builds aren't always bubbled up.
Check out the workarounds in the links, you should be able to find something that works for you even if it's icky.

How can I post-process files compiled using the Ant javac task?

I need the list of files that were compiled during this run. I want to feed this list to a subsequent post-processing step.
I have found an option to list (see listfiles option) the files compiled during this run, but it seems only good for displaying the list on console.
Any idea?
Edit: I am talking about incremental compiles, so taking a fileset of the build folder is not an option.
Edit: One idea seems to be custom logger but I am still looking for something simpler
Edit: Another idea is to use depend selector with FileSet before javac and somehow keep the list in memory, to be used after javac has executed
You simply can form a fileset about all class-files in the target-directory of the javac.
Edit: After the clarification I have to adjust my answer. I didn't such thing yet, but I would try my luck with selectors. The modified-selector looks like the one you want - a fileset of all class-files in a directory, that have changed since the last run. Here is a code-snippet:
<fileset dir="${build}">
<filename name="**/*.class"/>
<modified/>
</fileset>
It does not directly post-process the output of the javac-task, but should solve your problem.

Resources