Stop ant script without failing build
Asked Answered
C

3

9

In my ant script I want to exit (stop executing build) without failing when a condition is met. I have tried to use:

<if>
    <equals arg1="${variable1}" arg2="${variable2}" />
  <then>
    <fail status="0" message="No change, exit" />
  </then>
</if>

Ant script is stopped on condition but build is failed. I want to the build to be stopped but with no errors. I'm using "Invoke Ant" step in Jenkins.

Thanks.

Concession answered 2/1, 2013 at 22:33 Comment(1)
Why would a task called fail do anything other than fail?Brevet
F
12

I would suggest to refactor your ant script by reconsidering your approach. If you approach your problem with "execution of a build when a certain condition is met" instead of "failing the build if another condition is met" it is easier to implement:

<!-- add on top of your build file -->
<if>
    <equals arg1="${variable1}" arg2="${variable2}" />
  <then>
    <property name="runBuild" value="true"/>
  </then>
  <else>
    <property name="runBuild" value="false"/>
  </else>
</if>


<!-- add to the target that shall be executed conditionally -->
<target name="myTarget" if="${runBuild}">
...

<!-- exit message as separate target -->
<target name="exitTarget" unless="${runBuild}">
  <echo message="No Change, exit" />
</target>
Farce answered 3/1, 2013 at 14:46 Comment(0)
P
12

Use builtin (since JDK 6) javascript engine, no additional libraries (antcontrib .. etc.) needed !

1. Java System.exit()

<script language="javascript">
 self.log("Ending intentionally \n...\n..\n.");
 java.lang.System.exit(0);
</script> 

you may get a BUILD FAILED when running in Eclipse : BUILD FAILED javax.script.ScriptException: sun.org.mozilla.javascript.internal.WrappedException: Wrapped org.eclipse.ant.internal.launching.remote.AntSecurityException => then use Ant api instead

2. Ant api

<script language="javascript">
 self.log("Ending intentionally \n...\n..\n.");
 project.fireBuildFinished(null);
</script>

Output Eclipse, no BUILD SUCCESSFUL is printed :

   [script] Ending intentionally 
   [script] ...
   [script] ..
   [script] .
Total time: 410 milliseconds

Output Console, BUILD SUCCESSFUL is printed 2 times :

   [script] Ending intentionally
   [script] ...
   [script] ..
   [script] .

BUILD SUCCESSFUL
Total time: 0 seconds

BUILD SUCCESSFUL
Total time: 0 seconds

Wrap in a macrodef for reuse, f.e. :

<macrodef name="stopbuild">
 <attribute name="condition"/>
 <attribute name="paramtype" default="math"/>
 <attribute name="param1"/>
 <attribute name="param2"/>
 <attribute name="when" default="true"/>
 <sequential>
 <script language="javascript">
 falsecondition = false;
 switch ("@{condition}")
 {
  case "lt" :
   b = "@{paramtype}" == "math" ? parseInt("@{param1}") &lt; parseInt("@{param2}") : "@{param1}" &lt; "@{param2}";
   break;
  case "gt" :
   b = "@{paramtype}" == "math" ? parseInt("@{param1}") &gt; parseInt("@{param2}") : "@{param1}" &gt; "@{param2}";
   break;
  case "eq" :
   b = "@{paramtype}" == "math" ? parseInt("@{param1}") == parseInt("@{param2}") : "@{param1}" == "@{param2}";
   break;
  default:
   self.log("Wrong condition : @{condition}, supported: lt, gt, eq");
   falsecondition = true;
 }
 if(!falsecondition &amp;&amp; b == java.lang.Boolean.valueOf("@{when}")) {
   self.log("Stopping Build because @{param1} @{condition} @{param2} is @{when} !!");
   java.lang.System.exit(0);
   // alternatively use
   //project.fireBuildFinished(null);
 }
 </script>
 </sequential>
</macrodef>

Examples

 <!-- compare int, default paramtype=math and when=true -->
 <stopbuild param1="10" param2="11" condition="lt"/>

output :

[script] Stopping Build because 10 lt 11 is true !!


 <!-- compare strings, default when=true -->
 <stopbuild param1="abc" param2="abcd" paramtype="foo" condition="lt"/>

output :

[script] Stopping Build because abc lt abcd is true !!
Pignus answered 13/12, 2013 at 15:54 Comment(4)
IMO, it's an interesting solution but far more complicated than the accepted answer.Barbiebarbieri
<script language="javascript">java.lang.System.exit(0);</script> ain't complicated, in fact it's the most simple.You don't need to put in a macrodef - that was just for demonstration. And after all it needs no external libs, simply using the builtin javascript engine.Pignus
There is a drawback to this approach that is higlighted. This is the 2nd approach is proposed. This one is quite heavy.Barbiebarbieri
@Barbiebarbieri "Far more complicated" is a big, big stretch my friend. There is absolutely nothing "heavy" about this, simple facts.Adamek
D
0

Internally <fail> throws a BuildException to fail the build process, so, as long as you are using this task, you will get the ant build exit with errors.

Personally I don't know if there is any other task to "normally" exit the build, but writing one by yourself is not hard at all.

Writing a task which executes the following code should work...

public void execute() {
    // do something as you like
    System.exit(0);
}
Digenesis answered 3/1, 2013 at 12:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.