PR: 19220 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276425 13f79535-47bb-0310-9956-ffa450edef68master
@@ -34,6 +34,8 @@ Other changes: | |||
* <loadproperties> supports loading from a resource. | |||
* <fail> accepts nested conditions. | |||
Changes from Ant 1.6.1 to current Ant 1.6 CVS version | |||
============================================= | |||
@@ -37,6 +37,16 @@ or character data nested into the element.</p> | |||
<td align="center" valign="top">No</td> | |||
</tr> | |||
</table> | |||
<h3>Parameters specified as nested elements</h3> | |||
<p>As an alternative to the <i>if</i>/<i>unless</i> 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 <a href="conditions.html">here</a>.<br /> | |||
<b>Since Ant 1.6.2</b> | |||
</p> | |||
<h3>Examples</h3> | |||
<pre> <fail/></pre> | |||
<p>will exit the current build with no further information given.</p> | |||
@@ -47,8 +57,9 @@ build.xml:4: No message | |||
</pre> | |||
<pre> <fail message="Something wrong here."/></pre> | |||
<p>will exit the current build and print something like the following to wherever | |||
your output goes:</p> | |||
<p>will exit the current build and print something | |||
like the following to wherever your output goes: | |||
</p> | |||
<pre> | |||
BUILD FAILED | |||
@@ -58,6 +69,32 @@ build.xml:4: Something wrong here. | |||
<pre> <fail>Something wrong here.</fail></pre> | |||
<p>will give the same result as above.</p> | |||
<pre> <fail unless="thisdoesnotexist"/></pre> | |||
<p>will exit the current build and print something | |||
like the following to wherever your output goes: | |||
</p> | |||
<pre> | |||
BUILD FAILED | |||
build.xml:2: unless=thisdoesnotexist | |||
</pre> | |||
A simple example using conditions to achieve the same effect: | |||
<pre> | |||
<fail> | |||
<not> | |||
<isset property="thisdoesnotexist"/> | |||
</not> | |||
</fail> | |||
</pre> | |||
<p>Output:</p> | |||
<pre> | |||
BUILD FAILED | |||
build.xml:2: condition satisfied | |||
</pre> | |||
<hr> | |||
<p align="center">Copyright © 2000-2001,2004 The Apache Software Foundation. All rights | |||
Reserved.</p> | |||
@@ -25,5 +25,57 @@ | |||
<target name="testIfAndUnless"> | |||
<fail unless="unless" if="if"/> | |||
</target> | |||
<target name="testNested1" description="should fail with default message"> | |||
<fail> | |||
<and /> | |||
</fail> | |||
</target> | |||
<target name="testNested2" description="should pass"> | |||
<fail> | |||
<or /> | |||
</fail> | |||
</target> | |||
<target name="testNested3" description="should fail"> | |||
<fail message="testNested3"> | |||
<and /> | |||
</fail> | |||
</target> | |||
<target name="testNested4a" description="should error"> | |||
<fail if="if"> | |||
<and /> | |||
</fail> | |||
</target> | |||
<target name="testNested4b" description="should error"> | |||
<fail unless="unless"> | |||
<and /> | |||
</fail> | |||
</target> | |||
<target name="testNested4c" description="should error"> | |||
<fail if="if" unless="unless"> | |||
<and /> | |||
</fail> | |||
</target> | |||
<target name="testNested5" description="should error"> | |||
<fail> | |||
<and /> | |||
<or /> | |||
</fail> | |||
</target> | |||
<target name="testNested6" description="should fail with message"> | |||
<fail> | |||
<and /> | |||
testNested6 | |||
testNested6 | |||
testNested6 | |||
</fail> | |||
</target> | |||
</project> |
@@ -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. | |||
* <pre>fail := defined(ifProperty) && !defined(unlessProperty)</pre> | |||
* | |||
* A single nested<CODE><condition></CODE> element can be specified | |||
* instead of using <CODE>if</CODE>/<CODE>unless</CODE> (a combined | |||
* effect can be achieved using <CODE>isset</CODE> 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 <CODE>BuildException</CODE> to exit (fail) the build. | |||
* If specified, evaluate conditions: | |||
* A single nested condition is accepted, but requires that the | |||
* <CODE>if</CODE>/<code>unless</code> 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); | |||
} | |||
} |
@@ -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"); | |||
} | |||
} |