<!--
  ~ Copyright 2009 the original author or authors.
  ~
  ~ Licensed under the Apache License, Version 2.0 (the "License");
  ~ you may not use this file except in compliance with the License.
  ~ You may obtain a copy of the License at
  ~
  ~      http://www.apache.org/licenses/LICENSE-2.0
  ~
  ~ Unless required by applicable law or agreed to in writing, software
  ~ distributed under the License is distributed on an "AS IS" BASIS,
  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License.
  -->
<chapter id="ant">
    <title>Using Ant from Gradle</title>

    <para>Gradle provides excellent integration with Ant. You can use individual Ant tasks or entire Ant builds in your
        Gradle builds. In fact, you will find that it's far easier and more powerful using Ant tasks in a Gradle build
        script, than it is to use Ant's XML format. You could even use Gradle simply as a powerful Ant task scripting
        tool.
    </para>

    <para>Ant can be divided into two layers. The first layer is the Ant language. It provides the syntax for the
        <filename>build.xml</filename> file, the handling of the targets, special constructs like macrodefs, and so on.
        In other words, everything except the Ant tasks and types. Gradle understands this language, and allows you to
        import your Ant <filename>build.xml</filename> directly into a Gradle project. You can then use the targets of
        your Ant build as if they were Gradle tasks.
    </para>

    <para>The second layer of Ant is its wealth of Ant tasks and types, like <literal>javac</literal>,
        <literal>copy</literal> or <literal>jar</literal>. For this layer Gradle provides integration
        simply by relying on Groovy, and the fantastic <literal>AntBuilder</literal>.
    </para>

    <para>Finally, since build scripts are Groovy scripts, you can always execute an Ant build as an external process.
        Your build script may contain statements like: <literal>"ant clean compile".execute()</literal>.
        <footnote>
            <para>In Groovy you can execute Strings. To learn more about executing external processes with Groovy have a
                look in 'Groovy in Action' 9.3.2 or at the Groovy wiki
            </para>
        </footnote>
    </para>

    <para>You can use Gradle's Ant integration as a path for migrating your build from Ant to Gradle. For example, you
        could start by importing your existing Ant build. Then you could move your dependency declarations from the Ant
        script to your build file. Finally, you could move your tasks across to your build file, or replace them with
        some of Gradle's plugins. This process can be done in parts over time, and you can have a working Gradle build
        during the entire process.
    </para>

    <section id="sec:using_ant_tasks">
        <title>Using Ant tasks and types in your build</title>

        <para>In your build script, a property called <literal>ant</literal> is provided by Gradle. This is a reference
            to an <apilink class="org.gradle.api.AntBuilder"/> instance. This <literal>AntBuilder</literal> is used to
            access Ant tasks, types and properties from your build script. There is a very simple mapping from Ant's
            <filename>build.xml</filename> format to Groovy, which is explained below.
        </para>

        <para>You execute an Ant task by calling a method on the <literal>AntBuilder</literal> instance. You use the task
            name as the method name. For example, you execute the Ant <literal>echo</literal> task by calling the
            <literal>ant.echo()</literal> method. The attributes of the Ant task are passed as Map parameters to the
            method. Below is an example of the <literal>echo</literal> task. Notice that we can also mix
            Groovy code and the Ant task markup. This can be extremely powerful.</para>
        <sample id="useAntTask" dir="userguide/ant/useAntTask" title="Using an Ant task">
            <sourcefile file="build.gradle"/>
            <output args="hello"/>
        </sample>

        <para>
            You pass nested text to an Ant task by passing it as a parameter of the task method call. In this example, we
            pass the message for the <literal>echo</literal> task as nested text:
        </para>
        <sample id="taskWithNestedText" dir="userguide/ant/taskWithNestedText" title="Passing nested text to an Ant task">
            <sourcefile file="build.gradle"/>
            <output args="hello"/>
        </sample>

        <para>You pass nested elements to an Ant task inside a closure. Nested elements are defined in the same way
            as tasks, by calling a method with the same name as the element we want to define.</para>
        <sample id="taskWithNestedElements" dir="userguide/ant/taskWithNestedElements" title="Passing nested elements to an Ant task">
            <sourcefile file="build.gradle"/>
            <test args="zip"/>
        </sample>

        <para>You can access Ant types in the same way that you access tasks, using the name of the type as the
            method name. The method call returns the Ant data type, which you can then use directly in your build script. In the
            following example, we create an Ant <literal>path</literal> object, then iterate over the contents of it.</para>
        <sample id="useAntType" dir="userguide/ant/useAntType" title="Using an Ant type">
            <sourcefile file="build.gradle"/>
            <test args="list"/>
        </sample>

        <para>More information about <literal>AntBuilder</literal> can be found in 'Groovy in Action' 8.4 or at the
            <ulink url="http://groovy-lang.org/scripting-ant.html">Groovy Wiki</ulink>
        </para>

        <section id="sec:using_custom_ant_tasks">
            <title>Using custom Ant tasks in your build</title>
            <para>To make custom tasks available in your build,
                you can use the <literal>taskdef</literal> (usually easier) or <literal>typedef</literal> Ant task,
                just as you would in a <literal>build.xml</literal> file. You can then refer to the custom Ant task as you
                would a built-in Ant task.
            </para>
            <sample id="useExternalAntTask" dir="userguide/ant/useExternalAntTask" title="Using a custom Ant task">
                <sourcefile file="build.gradle"/>
            </sample>
            <para>
                You can use Gradle's dependency management to assemble the classpath to use for the custom tasks.
                To do this, you need to define a custom configuration for the classpath, then add some dependencies
                to the configuration. This is described in more detail in <xref linkend='sec:how_to_declare_your_dependencies'/>.
            </para>
            <sample id="useExternalAntTaskWithConfig" dir="userguide/ant/useExternalAntTaskWithConfig" title="Declaring the classpath for a custom Ant task">
                <sourcefile file="build.gradle" snippet="define-classpath"/>
            </sample>
            <para>To use the classpath configuration, use the <literal>asPath</literal> property of the custom configuration.</para>
            <sample id="useExternalAntTaskWithConfig" dir="userguide/ant/useExternalAntTaskWithConfig" title="Using a custom Ant task and dependency management together">
                <sourcefile file="build.gradle" snippet="use-classpath"/>
                <test args="check"/>
            </sample>
        </section>
    </section>

    <section id="sec:import_ant_build">
        <title>Importing an Ant build</title>
        <para>You can use the <literal>ant.importBuild()</literal> method to import an Ant build into your Gradle
            project. When you import an Ant build, each Ant target is treated as a Gradle task. This means you can
            manipulate and execute the Ant targets in exactly the same way as Gradle tasks.
        </para>
        <sample id="antHello" dir="userguide/ant/hello" title="Importing an Ant build">
            <sourcefile file="build.gradle"/>
            <sourcefile file="build.xml"/>
            <output args="hello"/>
        </sample>
        <para>You can add a task which depends on an Ant target:
        </para>
        <sample id="dependsOnAntTarget" dir="userguide/ant/dependsOnAntTarget" title="Task that depends on Ant target">
            <sourcefile file="build.gradle"/>
            <output args="intro"/>
        </sample>
        <para>Or, you can add behaviour to an Ant target:</para>
        <sample id="addBehaviourToAntTarget" dir="userguide/ant/addBehaviourToAntTarget" title="Adding behaviour to an Ant target">
            <sourcefile file="build.gradle"/>
            <output args="hello"/>
        </sample>
        <para>It is also possible for an Ant target to depend on a Gradle task:</para>
        <sample id="dependsOnTask" dir="userguide/ant/dependsOnTask" title="Ant target that depends on Gradle task">
            <sourcefile file="build.gradle"/>
            <sourcefile file="build.xml"/>
            <output args="hello"/>
        </sample>
        <para>
            Sometimes it may be necessary to “rename” the task generated for an Ant target to avoid a naming collision with existing Gradle tasks.
            To do this, use the <apilink class="org.gradle.api.AntBuilder" method="importBuild(java.lang.Object, org.gradle.api.Transformer)" /> method.
        </para>
        <sample id="renameAntDelegate" dir="userguide/ant/renameTask" title="Renaming imported Ant targets">
            <sourcefile file="build.gradle"/>
            <sourcefile file="build.xml"/>
            <output args="a-hello"/>
        </sample>
        <para>
            Note that while the second argument to this method should be a <apilink class="org.gradle.api.Transformer"/>, when programming in Groovy we can simply
            use a closure instead of an anonymous inner class (or similar) due to <ulink url="http://mrhaki.blogspot.ie/2013/11/groovy-goodness-implicit-closure.html">Groovy's support for automatically coercing closures to single-abstract-method types</ulink>.
        </para>
    </section>

    <section id="sec:ant_properties">
        <title>Ant properties and references</title>

        <para>There are several ways to set an Ant property, so that the property can be used by Ant tasks. You can
            set the property directly on the <literal>AntBuilder</literal> instance. The Ant properties are also
            available as a Map which you can change. You can also use the Ant <literal>property</literal> task.
            Below are some examples of how to do this.
        </para>
        <sample id="antProperties" dir="userguide/ant/properties" title="Setting an Ant property">
            <sourcefile file="build.gradle" snippet="set-property"/>
            <sourcefile file="build.xml" snippet="set-property"/>
        </sample>
        <para>Many Ant tasks set properties when they execute. There are several ways to get the value of these properties.
            You can get the property directly from the <literal>AntBuilder</literal> instance. The Ant properties are
            also available as a Map. Below are some examples.</para>
        <sample id="antProperties" dir="userguide/ant/properties" title="Getting an Ant property">
            <sourcefile file="build.xml" snippet="get-property"/>
            <sourcefile file="build.gradle" snippet="get-property"/>
        </sample>
        <para>There are several ways to set an Ant reference:</para>
        <sample id="antProperties" dir="userguide/ant/properties" title="Setting an Ant reference">
            <sourcefile file="build.gradle" snippet="set-reference"/>
            <sourcefile file="build.xml" snippet="set-reference"/>
        </sample>
        <para>There are several ways to get an Ant reference:</para>
        <sample id="antProperties" dir="userguide/ant/properties" title="Getting an Ant reference">
            <sourcefile file="build.xml" snippet="get-reference"/>
            <sourcefile file="build.gradle" snippet="get-reference"/>
        </sample>
    </section>

    <section id="sec:ant_logging">
        <title>Ant logging</title>

        <para>Gradle maps Ant message priorities to Gradle log levels so that messages logged from Ant appear in the Gradle output.
            By default, these are mapped as follows:
        </para>

        <table>
            <title>Ant message priority mapping</title>
            <thead>
                <tr>
                    <td>Ant Message Priority</td>
                    <td>Gradle Log Level</td>
                </tr>
            </thead>
            <tr>
                <td><firstterm>VERBOSE</firstterm></td>
                <td><literal>DEBUG</literal></td>
            </tr>
            <tr>
                <td><firstterm>DEBUG</firstterm></td>
                <td><literal>DEBUG</literal></td>
            </tr>
            <tr>
                <td><firstterm>INFO</firstterm></td>
                <td><literal>INFO</literal></td>
            </tr>
            <tr>
                <td><firstterm>WARN</firstterm></td>
                <td><literal>WARN</literal></td>
            </tr>
            <tr>
                <td><firstterm>ERROR</firstterm></td>
                <td><literal>ERROR</literal></td>
            </tr>
        </table>

        <section id="sec:fine_tuning_ant_logging">
            <title>Fine tuning Ant logging</title>

            <para>The default mapping of Ant message priority to Gradle log level can sometimes be problematic.  For example,
                there is no message priority that maps directly to the <literal>LIFECYCLE</literal> log level, which is the
                default for Gradle.  Many Ant tasks log messages at the <firstterm>INFO</firstterm> priority, which means to expose
                those messages from Gradle, a build would have to be run with the log level set to <literal>INFO</literal>,
                potentially logging much more output than is desired.
            </para>

            <para>Conversely, if an Ant task logs messages at too high of a level, to suppress those messages would require the
                build to be run at a higher log level, such as <literal>QUIET</literal>.  However, this could result in other,
                desirable output being suppressed.
            </para>

            <para>To help with this, Gradle allows the user to fine tune the Ant logging and control the mapping of message priority
                to Gradle log level.  This is done by setting the priority that should map to the default Gradle <literal>LIFECYCLE</literal>
                log level using the <apilink class="org.gradle.api.AntBuilder" method="setLifecycleLogLevel(java.lang.String)"/> method.  When this value
                is set, any Ant message logged at the configured priority or above will be logged at least at <literal>LIFECYCLE</literal>.
                Any Ant message logged below this priority will be logged at most at <literal>INFO</literal>.
            </para>

            <para>For example, the following changes the mapping such that Ant <firstterm>INFO</firstterm> priority messages are exposed at the <literal>LIFECYCLE</literal>
                log level.
            </para>

            <sample id="antLogging" dir="userguide/ant/antLogging" title="Fine tuning Ant logging">
                <sourcefile file="build.gradle"/>
                <output args="hello"/>
            </sample>

            <para>On the other hand, if the <literal>lifecycleLogLevel</literal> was set to <firstterm>ERROR</firstterm>, Ant messages logged
                at the <firstterm>WARN</firstterm> priority would no longer be logged at the <literal>WARN</literal> log level.  They would now
                be logged at the <literal>INFO</literal> level and would be suppressed by default.
            </para>
        </section>
    </section>

    <section id="sec:ant_api">
        <title>API</title>
        <para>The Ant integration is provided by <apilink class="org.gradle.api.AntBuilder"/>.</para>
    </section>
</chapter>
