diff --git a/WHATSNEW b/WHATSNEW index 0afb78ee4..ebffb7cb2 100644 --- a/WHATSNEW +++ b/WHATSNEW @@ -34,6 +34,8 @@ Other changes: * supports loading from a resource. +* accepts nested conditions. + Changes from Ant 1.6.1 to current Ant 1.6 CVS version ============================================= diff --git a/docs/manual/CoreTasks/fail.html b/docs/manual/CoreTasks/fail.html index 1d5563af9..125bc2075 100644 --- a/docs/manual/CoreTasks/fail.html +++ b/docs/manual/CoreTasks/fail.html @@ -37,6 +37,16 @@ or character data nested into the element.

No + +

Parameters specified as nested elements

+ +

As an alternative to the if/unless attributes, + conditional failure can be achieved using a single nested condition. + For a complete list of core conditions, as well as information + about custom conditions, see here.
+ Since Ant 1.6.2 +

+

Examples

  <fail/>

will exit the current build with no further information given.

@@ -47,8 +57,9 @@ build.xml:4: No message
  <fail message="Something wrong here."/>
-

will exit the current build and print something like the following to wherever -your output goes:

+

will exit the current build and print something + like the following to wherever your output goes: +

 BUILD FAILED
 
@@ -58,6 +69,32 @@ build.xml:4: Something wrong here.
 
  <fail>Something wrong here.</fail>

will give the same result as above.

+
  <fail unless="thisdoesnotexist"/>
+

will exit the current build and print something + like the following to wherever your output goes: +

+
+BUILD FAILED
+
+build.xml:2: unless=thisdoesnotexist
+
+ +A simple example using conditions to achieve the same effect: +
+  <fail>
+     <not>
+       <isset property="thisdoesnotexist"/>
+     </not>
+   </fail>
+
+ +

Output:

+
+BUILD FAILED
+
+build.xml:2: condition satisfied
+
+

Copyright © 2000-2001,2004 The Apache Software Foundation. All rights Reserved.

diff --git a/src/etc/testcases/taskdefs/fail.xml b/src/etc/testcases/taskdefs/fail.xml index 6d0150cee..b7b7f3037 100644 --- a/src/etc/testcases/taskdefs/fail.xml +++ b/src/etc/testcases/taskdefs/fail.xml @@ -25,5 +25,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +testNested6 +testNested6 +testNested6 + + diff --git a/src/main/org/apache/tools/ant/taskdefs/Exit.java b/src/main/org/apache/tools/ant/taskdefs/Exit.java index 13a086323..f3fbfc792 100644 --- a/src/main/org/apache/tools/ant/taskdefs/Exit.java +++ b/src/main/org/apache/tools/ant/taskdefs/Exit.java @@ -18,8 +18,8 @@ package org.apache.tools.ant.taskdefs; import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Task; - +import org.apache.tools.ant.taskdefs.condition.Condition; +import org.apache.tools.ant.taskdefs.condition.ConditionBase; /** * Exits the active build, giving an additional message @@ -34,11 +34,15 @@ import org.apache.tools.ant.Task; * are true. i.e. *
fail := defined(ifProperty) && !defined(unlessProperty)
* + * A single nested<condition> element can be specified + * instead of using if/unless (a combined + * effect can be achieved using isset conditions). + * * @since Ant 1.2 * * @ant.task name="fail" category="control" */ -public class Exit extends Task { +public class Exit extends ConditionBase { private String message; private String ifCondition, unlessCondition; @@ -69,31 +73,40 @@ public class Exit extends Task { } /** - * evaluate both if and unless conditions, and if - * ifCondition is true or unlessCondition is false, throw a - * build exception to exit the build. - * The error message is constructed from the text fields, or from + * Throw a BuildException to exit (fail) the build. + * If specified, evaluate conditions: + * A single nested condition is accepted, but requires that the + * if/unless attributes be omitted. + * If the nested condition evaluates to true, or the + * ifCondition is true or unlessCondition is false, the build will exit. + * The error message is constructed from the text fields, from + * the nested condition (if specified), or finally from * the if and unless parameters (if present). * @throws BuildException */ public void execute() throws BuildException { - if (testIfCondition() && testUnlessCondition()) { + boolean fail = (nestedConditionPresent()) ? testNestedCondition() + : (testIfCondition() && testUnlessCondition()); + if (fail) { String text = null; - if (message != null && message.length() > 0) { - text = message; + if (message != null && message.trim().length() > 0) { + text = message.trim(); } else { - - if (getProject().getProperty(ifCondition) != null) { + if (ifCondition != null && ifCondition.length() > 0 + && getProject().getProperty(ifCondition) != null) { text = "if=" + ifCondition; } if (unlessCondition != null && unlessCondition.length() > 0 - && getProject().getProperty(unlessCondition) == null) { + && getProject().getProperty(unlessCondition) == null) { if (text == null) { text = ""; } else { text += " and "; } text += "unless=" + unlessCondition; + } + if (nestedConditionPresent()) { + text = "condition satisfied"; } else { if (text == null) { text = "No message"; @@ -138,4 +151,26 @@ public class Exit extends Task { return getProject().getProperty(unlessCondition) == null; } + /** + * test the nested condition + * @return true if there is none, or it evaluates to true + */ + private boolean testNestedCondition() { + if (ifCondition != null || unlessCondition != null) { + throw new BuildException("Nested conditions " + + "not permitted in conjunction with if/unless attributes"); + } + + int count = countConditions(); + if (count > 1) { + throw new BuildException("Too many conditions: " + count); + } + + return (count == 0) ? true + : (((Condition)(getConditions().nextElement())).eval()); + } + + private boolean nestedConditionPresent() { + return (countConditions() > 0); + } } diff --git a/src/testcases/org/apache/tools/ant/taskdefs/FailTest.java b/src/testcases/org/apache/tools/ant/taskdefs/FailTest.java index c83e214ab..f5df9932d 100644 --- a/src/testcases/org/apache/tools/ant/taskdefs/FailTest.java +++ b/src/testcases/org/apache/tools/ant/taskdefs/FailTest.java @@ -101,4 +101,50 @@ public class FailTest extends BuildFileTest { } } -} + public void testNested1() { + expectSpecificBuildException("testNested1", + "it is required to fail :-)", + "condition satisfied"); + } + + public void testNested2() { + try { + executeTarget("testNested2"); + } catch (BuildException be) { + fail("condition not satisfied; testNested2 must not fail"); + } + } + + public void testNested3() { + expectSpecificBuildException("testNested3", + "it is required to fail :-)", + "testNested3"); + } + + public void testNested4() { + String specificMessage = "Nested conditions " + + "not permitted in conjunction with if/unless attributes"; + + char[] c = {'a', 'b', 'c'}; + StringBuffer target = new StringBuffer("testNested4x"); + + for (int i = 0; i < c.length; i++) { + target.setCharAt(target.length() - 1, c[i]); + expectSpecificBuildException(target.toString(), + "it is required to fail :-)", specificMessage); + } + } + + public void testNested5() { + expectSpecificBuildException("testNested5", + "it is required to fail :-)", + "Too many conditions: 2"); + } + + public void testNested6() { + expectSpecificBuildException("testNested6", + "it is required to fail :-)", + "testNested6\ntestNested6\ntestNested6"); + } + + }