diff --git a/docs/faq.html b/docs/faq.html index 3f9757cd6..d7392fbac 100644 --- a/docs/faq.html +++ b/docs/faq.html @@ -182,6 +182,23 @@ sourcesafe control files (CVS files, editor backup files), but it doesn't seem to work. The files never get deleted. What's wrong? + +
  • + I want to execute a particular target only if + multiple conditions are true. +
  • +
  • + I have a target I want to skip if a variable is set, + so I have unless="variable" as an attribute + of the target. The trouble is that all of the targets that this target + depends on are still executed. Why? +
  • +
  • + In my fileset, I've put in an + <exclude> of all files followed by an + <include> of just the files I want, but it + isn't giving me anything at all. What's wrong? +
  • @@ -226,6 +243,10 @@
  • How do I send an email with the result of my build process? +
  • +
  • + How do I get at the properties that Ant was running + with from inside BuildListener?
  • @@ -294,10 +315,12 @@

    The page you are looking it is generated from this - document. If you want to add a new question, please submit - a patch against this document, the structure is hoped to be - self-explaining.

    + a patch against this document to one of Ant's mailing lists, + the structure is hoped to be self-explaining.

    +

    If you don't know how to create a patch, see the patches + section of this + page.

    @@ -852,6 +875,233 @@ shell-prompt> cat < foo + + + + + +
    + + + I want to execute a particular target only if + multiple conditions are true. + + +
    +
    +

    There are actually several answers to this question.

    +

    If you have only one set and one unset property to test, + you can put both an if and an unless + attribute into the target. The target will act as if they + are "anded" together.

    +

    If you are using a version of Ant 1.3 or earlier, the + way to work with all other cases is to chain targets together + to determine the specific state you wish to test for.

    +

    To see how this works, assume you have three properties, + prop1, prop2, and prop3. + You want to test that prop1 and prop2 + are set, but that prop3 is not. If the condition + holds true you want to echo "yes".

    +

    Here is the implementation in Ant 1.3 and earlier:

    +
    + + + + + + + + + + + + + + + + +
    +<target name="cond" depends="cond-if"/>
    +
    +<target name="cond-if" if="prop1">
    +  <antcall target="cond-if-2"/>
    +</target>
    +
    +<target name="cond-if-2" if="prop2">
    +  <antcall target="cond-if-3"/>
    +</target>
    +
    +<target name="cond-if-3" unless="prop3">
    +  <echo message="yes"/>
    +</target>
    +
    +
    +

    Note that <antcall> tasks do not pass + property changes back up to the environment they were called + from.

    +

    Starting with Ant 1.4, you can use the + <condition> task.

    +
    + + + + + + + + + + + + + + + + +
    +<target name="cond" depends="cond-if,cond-else"/>
    +
    +<target name="check-cond">
    +  <condition property="cond-is-true">
    +    <and>
    +      <not>
    +        <equals arg1="${prop1}" arg2="$${prop1}" />
    +      </not>
    +      <not>
    +        <equals arg1="${prop2}" arg2="$${prop2}" />
    +      </not>
    +      <equals arg1="${prop3}" arg2="$${prop3}" />
    +    </and>
    +  </condition>
    +</target>
    +
    +<target name="cond-if" depends="check-cond" if="cond-is-true">
    +  <echo message="yes"/>
    +</target>
    +
    +<target name="cond-else" depends="check-cond" unless="cond-is-true">
    +  <echo message="no"/>
    +</target>
    +
    +
    +

    This version takes advantage of two things:

    +
      +
    • If a property a has not been set, + ${a} will evaluate to ${a}.
    • + +
    • To get a literal $ in Ant, you have to + escape it with another $ - this will also break + the special treatment of the sequence ${.
    • +
    +

    This is neither readable, nor easy to understand, therefore + post-1.4.1 Ant introduces the <isset> element + to the <condition> task.

    +

    Here is the previous example done using + <isset>:

    +
    + + + + + + + + + + + + + + + + +
    +<target name="check-cond">
    +  <condition property="cond-is-true">
    +    <and>
    +      <isset property="prop1"/>
    +      <isset property="prop2"/>
    +      <not>
    +        <isset property="prop3"/>
    +      </not>
    +    </and>
    +  </condition>
    +</target>
    +
    +
    +

    The last option is to use a scripting language to set the + properties. This can be particularly handy when you need much + better control than the simple conditions shown here, but of + course comes with the overhead of adding JAR files to support + the language, to say nothing of the added maintenance in requiring + two languages to implement a single system.

    +
    +
    +
    + + + + +
    + + + I have a target I want to skip if a variable is set, + so I have unless="variable" as an attribute + of the target. The trouble is that all of the targets that this target + depends on are still executed. Why? + + +
    +
    +

    The list of dependencies is generated by Ant before any of the + targets are run. This allows dependent targets such as an + init target to set properties that can control the + execution of the targets higher in the dependency graph. This + is a good thing.

    +

    When your dependencies actually break down the higher level task + into several simpler steps, though, this behaviour becomes + counterintuitive. There are a couple of solutions available: +

    +
      +
    1. Put the same condition on each of the dependent targets.
    2. + +
    3. Execute the steps using <antcall> + instead of specifying them inside the depends + attribute.
    4. +
    +
    +
    +
    + + + + +
    + + + In my fileset, I've put in an + <exclude> of all files followed by an + <include> of just the files I want, but it + isn't giving me anything at all. What's wrong? + + + +
    +
    +

    The order of the <include> and + <exclude> tags within a fileset is ignored + when the fileset is created. Instead, all of the + <include> elements are processed together, + followed by all of the <exclude> + elements. This means that the <exclude> + elements only apply to the file list produced by the + <include> elements.

    +

    To get the files you want, focus on just the + <include> patterns that would be necessary + to get them. If you need to trim the list that the includes + would produce, use excludes.

    +
    +
    @@ -1297,6 +1547,54 @@ ant -listener BuildMonitor
    +
    + + + + +
    + + + How do I get at the properties that Ant was running + with from inside BuildListener? + + +
    +
    +

    You can get at a hashtable with all the properties that Ant + has been using through the BuildEvent parameter. For + example:

    +
    + + + + + + + + + + + + + + + + +
    +public void buildFinished(BuildEvent e) {
    +    Hashtable table = e.getProject().getProperties();
    +    String buildpath = (String)table.get("build.path");
    +    ...
    +}
    +
    +
    +

    This is more accurate than just reading the same property + files that your project does, since it will give the correct + results for properties that are specified on the command line + when running Ant.

    +
    +
    diff --git a/xdocs/faq.xml b/xdocs/faq.xml index e09a2f77e..4dd6eac08 100644 --- a/xdocs/faq.xml +++ b/xdocs/faq.xml @@ -21,10 +21,13 @@

    The page you are looking it is generated from this - document. If you want to add a new question, please submit - a patch against this document, the structure is hoped to be - self-explaining.

    + a patch against this document to one of Ant's mailing lists, + the structure is hoped to be self-explaining.

    + +

    If you don't know how to create a patch, see the patches + section of this + page.

    @@ -316,6 +319,174 @@ shell-prompt> cat < foo + + + I want to execute a particular target only if + multiple conditions are true. + + +

    There are actually several answers to this question.

    + +

    If you have only one set and one unset property to test, + you can put both an if and an unless + attribute into the target. The target will act as if they + are "anded" together.

    + +

    If you are using a version of Ant 1.3 or earlier, the + way to work with all other cases is to chain targets together + to determine the specific state you wish to test for.

    + +

    To see how this works, assume you have three properties, + prop1, prop2, and prop3. + You want to test that prop1 and prop2 + are set, but that prop3 is not. If the condition + holds true you want to echo "yes".

    + +

    Here is the implementation in Ant 1.3 and earlier:

    + + + + + + + + + + + + + + +]]> + +

    Note that <antcall> tasks do not pass + property changes back up to the environment they were called + from.

    + +

    Starting with Ant 1.4, you can use the + <condition> task.

    + + + + + + + + + + + + + + + + + + + + + + + + +]]> + +

    This version takes advantage of two things:

    + +
      +
    • If a property a has not been set, + ${a} will evaluate to ${a}.
    • + +
    • To get a literal $ in Ant, you have to + escape it with another $ - this will also break + the special treatment of the sequence ${.
    • +
    + +

    This is neither readable, nor easy to understand, therefore + post-1.4.1 Ant introduces the <isset> element + to the <condition> task.

    + +

    Here is the previous example done using + <isset>:

    + + + + + + + + + + + + +]]> + +

    The last option is to use a scripting language to set the + properties. This can be particularly handy when you need much + better control than the simple conditions shown here, but of + course comes with the overhead of adding JAR files to support + the language, to say nothing of the added maintenance in requiring + two languages to implement a single system.

    +
    +
    + + + I have a target I want to skip if a variable is set, + so I have unless="variable" as an attribute + of the target. The trouble is that all of the targets that this target + depends on are still executed. Why? + + +

    The list of dependencies is generated by Ant before any of the + targets are run. This allows dependent targets such as an + init target to set properties that can control the + execution of the targets higher in the dependency graph. This + is a good thing.

    + +

    When your dependencies actually break down the higher level task + into several simpler steps, though, this behaviour becomes + counterintuitive. There are a couple of solutions available: +

    + +
      +
    1. Put the same condition on each of the dependent targets.
    2. + +
    3. Execute the steps using <antcall> + instead of specifying them inside the depends + attribute.
    4. +
    + +
    +
    + + + In my fileset, I've put in an + <exclude> of all files followed by an + <include> of just the files I want, but it + isn't giving me anything at all. What's wrong? + + + +

    The order of the <include> and + <exclude> tags within a fileset is ignored + when the fileset is created. Instead, all of the + <include> elements are processed together, + followed by all of the <exclude> + elements. This means that the <exclude> + elements only apply to the file list produced by the + <include> elements.

    + +

    To get the files you want, focus on just the + <include> patterns that would be necessary + to get them. If you need to trim the list that the includes + would produce, use excludes.

    +
    +
    + @@ -617,6 +788,30 @@ ant -listener BuildMonitor + + How do I get at the properties that Ant was running + with from inside BuildListener? + + +

    You can get at a hashtable with all the properties that Ant + has been using through the BuildEvent parameter. For + example:

    + + + +

    This is more accurate than just reading the same property + files that your project does, since it will give the correct + results for properties that are specified on the command line + when running Ant.

    +
    +
    +