I have an Ant target that executes 2 steps in sequence:
<target name="release">
<antcall target="-compile"/>
<antcall target="-post-compile"/>
</target>
With the above script, it quits immediately if the "-compile" target fails. "-post-compile" does not get a chance to run. Is there a way to make sure the second step (-post-compile) is executed even if the 1st one (-compile) fails?
If you are using ant-contrib (which is very common), you could make use of the try-catch task and put your post-compile call into its finally element.
Also, if you are not using ant-contrib, then you might use the subant task to call your compile target. subant has a failonerror attribute, which you can use to individually ignore failed targets. Lots of usage examples on the task description page.
I think you are looking for
-keep-going (-k)
This will tell Ant to continue building all targets which do not depend on the failed target.
Related
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.
I'm extremely new to ant script and i want to find out if my build is successful or not. my main target has two antcalls and i don't know how to check if they were successful or not, in order to evaluate the main target.
run all is my main target
<target name="run all">
<antcall target="Run basic configuration" />
<antcall target="Run custom configuration"/>
i want to add a fail condition for the "run all" target.
Each target does check individually if they are successful, but I want to know if the target that calls the ant is unsuccessful in case those two fail.
Also, if one fails does the other one get called?
To determine if an antcall is successful requires a more careful definition of what success is. It can mean:
The code executed without throwing an exception.
The code did what you wanted it to do.
In the first case, you can wrap the execution of your antcall with a trycatch block to catch exceptions. The trycatch task is part of ant-contrib, but that is frequently used in Ant coding. You'd do:
<trycatch property="exception.message" reference="exception.object">
<try>
<antcall target="targetName"/>
</try>
<catch>
<!-- handle exception logic here -->
</catch>
<finally>
<!-- do any final cleanup -->
</finally>
</trycatch>
In the second case, you need to pass back to the caller some state that indicates that the code did what you wanted it to do.
Note that the antcall task reloads the ant file (e.g., build.xml), so it can be an expensive operation. There are alternatives to using the antcall task:
Use the antcallback task (ant-contrib). The antcallback task specifically addresses the need to pass back data.
Use the depends attribute when defining a target to call dependent tasks.
Use the runtarget task (ant-contrib). With runtarget, all of your properties are passed and any properties you set in your target are available to the caller.
Use the macrodef task. It avoids reparsing of the ant file, can be passed attributes with default values, can be passed nested elements, and more. As such, this is the preferred solution in most cases.
In each of the cases above, just set return properties that you can inspect in the calling target to determine whether the called or dependent targets did what you expected them to do.
I want to have a 'master' ant target which depends on multiple "worker targets", (each of which does "one thing well")
However, I want to conditionally execute the "master" target, i.e. and not execute the "worker' subtargets if the condition is not met
(specficially, the master target creates and populates the database. The subtarget creates schema, populates tables, etc. The final step in the master target leaves a marker file to indicate "database created once." On subsequent runs, the process should not try to create the database.
The question
How can I implement this in a manner both "antish" (i.e. without "antcall) and DRY (dont' repeat yourself).
Example
<target name="check-db-created">
<available file="db.created.marker.txt" property="db.already.created"/>
</target>
<target name="create-new-db"
unless="db.already.created"
depends="check-db-created,create-db-mssql,create-tables,compile-sp,disable-constraints.....">
</target>
<target name="create-db-mssql" >
..do stufff
</target>
Comments
The issue is that the 'sub-targets' ('create-db-mssql', create-tables', etc) execute even though the "master" target does not need to run. Ant documentation clearly discusses this.
Important: the if and unless attributes only enable or disable the
target to which they are attached. They do not control whether or not
targets that a conditional target depends upon get executed. In fact,
they do not even get evaluated until the target is about to be
executed, and all its predecessors have already run.
I can code around the rpoblem by adding "unless" clauses to all the 'worker targets', but would like to avoid repeating.
Additionally, I use antcall as follows, but would prefer to avoid the "GOTO" of the ant world.
<target name="create-new-db" depends="check-db-created"
unless="db.already.created">
<antcall target="create-new-db-internal"/>
</target>
<target name="create-new-db-internal"
depends="create-db,create-tables,compile-sp,disable-constraints,insert-base-data,insert-installer-generated-sql,insert-kb-data"
>
</target>
thanks
For various reasons that I won't go into (I promise it's necessary to do this with the current code base; I know it's goofy), I want to execute a target twice in the same build task.
For example, I want to execute the target foo, then bar, then foo again. This is a simplified version of what I already tried:
<target name="foo">
...
</target>
<target name="bar" depends="foo">
...
</target>
<target name="project" depends="foo,bar">
...
</target>
In this case when executing the project target, foo only ran once. I also tried getting rid of the depends attribute on the bar target and making the project's depends attribute "foo,bar,foo", but still the same result.
Is there a way to force a task to execute, even if it's already successfully completed? Or is there a better way to go about this?
The antcall task allows you to explicitly call a target.
I think that's a better solution than using the depends mechanism. As you've identified, this determines what has already run. Antcall instructs the target to run regardless of whether it's run before.
You can parameterise the call to customise what it does on each invocation.
I'm currently working with some developers who like to set up Ant tasks that define environment specific variables rather than using properties files. It seems they prefer to do this because it's easier to type:
ant <environment task> dist
Than it is to type:
ant -propertyfile <environment property file> dist
So for example:
<project name="whatever" default="dist">
<target name="local">
<property name="webXml" value="WebContent/WEB-INF/web-local.xml"/>
</target>
<target name="remote">
<property name="webXml" value="WebContent/WEB-INF/web-remote.xml"/>
</target>
<target name="build">
<!-- build tasks here --->
</target>
<target name="dist" depends="build">
<war destfile="/dist/foo.war" webxml="${webXml}">
<!-- rest of war tasks here -->
</war>
</target>
I am finding it hard to convince them that properties files are they right way to go. I believe properties files are better because:
They provides more flexibility - if you need a new environment just add a new properties file
It's clearer what's going on - You have to know about this little "trick" to realize what they're accomplishing
Doesn't provide default values and the ability to use overrides - if they used property files they could provide defaults at the top of the project but have the ability to override them with a file
Script won't break if an environment task isn't supplied on command line
Of course all they hear is that they need to change their Ant script and have to type more on the command line.
Can you provide any additional arguments in favor of properties files over "property tasks"?
Properties tasks tightly couple the build file to environments. If your fellow developers are arguing that they "have to change their ant script" with your suggestions, why aren't they arguing about changing it every time they have to deploy to a new environment? :)
Perhaps you can convince them to allow both properties file and command-line configuration. I set up my Ant builds so that if a build.properties exists in the same directory as the build.xml, it reads it in. Otherwise it uses a set of default properties hard-coded into the build. This is very flexible.
<project name="example">
<property file="build.properties"/>
<property name="foo.property" value="foo"/>
<property name="bar.property" value="bar"/>
...
</project>
I don't provide a build.properties with the project (i.e. build.properties is not versioned in SCM). This way developers aren't forced to use the property file. I do provide a build.properties.example file that developers can reference.
Since Ant properties, once set, are immutable, the build file will use properties defined in this order:
Properties provided with -D or -propertyfile via the command line
Properties loaded from build.properties
Default properties within build.xml
Advantages of this approach:
The build file is smaller and therefore more maintainable, less bug-prone
Developers that just can't get away from setting properties at the command line can still use them.
Properties files can be used, but aren't required
The arguments you have are already pretty compelling. If those arguments haven't worked, then arguing isn't going to solve the problem. In fact, nothing is going to solve the problem. Don't assume that people are rational and will do the most practical thing. Their egos are involved.
Stop arguing. Even if you win, the resentment and irritation you create will not be worth it. Winning an argument can be worse than losing.
Make your case, then let it go. It's possible that after a while they will decide to switch to your way (because it actually is better). If that happens, they will act like it was their own idea. There will be no mention of your having proposed it.
On the other hand, they may never switch.
The only solution is to work towards a position of authority, where you can say how things are to be done.
The problem with the first solution (using ant property) is basically hardcoding.
It can be convenient when you start a project for yourself but quickly you have to remove that bad habit.
I'm using a property file close to what said robhruska except that I have committed the build.properties file directly. This way you have a default one.
In other hand, I understand I could add those default values in the build.xml. (I will probably try that in the next hours/days ;-) ).
Anyway, I really don't like the first approach and I would force those guys to follow the second one ...