<!--
  ~ 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='tutorial_using_tasks'>
    <title>Build Script Basics</title>
    <section><title>Projects and tasks</title>
    <para>Everything in Gradle sits on top of two basic concepts: <firstterm>projects</firstterm> and <firstterm>tasks</firstterm>.</para>
    <para>
        Every Gradle build is made up of one or more <firstterm>projects</firstterm>.
        What a project represents depends on what it is that you are doing with Gradle.
        For example, a project might represent a library JAR or a web application. It might represent a
        distribution ZIP assembled from the JARs produced by other projects. A project does not necessarily represent
        a thing to be built. It might represent a thing to be done, such as deploying your application to staging or
        production environments. Don't worry if this seems a little vague for now. Gradle's build-by-convention support adds
        a more concrete definition for what a project is.
    </para>
    <para>Each project is made up of one or more <firstterm>tasks</firstterm>. A task represents some atomic piece
        of work which a build performs. This might be compiling some classes, creating a JAR, generating Javadoc,
        or publishing some archives to a repository.</para>
    <para>For now, we will look at defining some simple tasks in a build with one project. Later chapters will look at
        working with multiple projects and more about working with projects and tasks.</para>
    </section>
    <section>
        <title>Hello world</title>
        <para>You run a Gradle build using the <command>gradle</command> command. The <command>gradle</command> command
            looks for a file called <filename>build.gradle</filename> in the current directory.
            <footnote><para>There are command line switches to change this behavior. See <xref linkend='gradle_command_line'/>)</para></footnote>
            We call this <filename>build.gradle</filename> file a <firstterm>build script</firstterm>, although strictly speaking it is
            a build configuration script, as we will see later. The build script defines a project and its tasks.
        </para>
        <para>To try this out, create the following build script named <filename>build.gradle</filename>.
        </para>
        <sample id="hello" dir="userguide/tutorial/hello" title="Your first build script">
            <sourcefile file="build.gradle"/>
        </sample>
        <para>In a command-line shell, move to the containing directory and execute the build script with
            <userinput>gradle -q hello</userinput>:
        </para>
        <tip>
            <title>What does <option>-q</option> do?</title>
            <para>Most of the examples in this user guide are run with the <option>-q</option> command-line option.
                This suppresses Gradle's log messages, so that only the output of the tasks is shown. This keeps the example
                output in this user guide a little clearer. You don't need to use this option if you don't want to.
                See <xref linkend="logging"/> for more details about the command-line options which affect Gradle's output.
            </para>
        </tip>
        <sample id="hello" dir="userguide/tutorial/hello" title="Execution of a build script">
            <output args="-q hello"/>
        </sample>
        <para>What's going on here? This build script defines a single task, called <literal>hello</literal>, and
            adds an action to it. When you run <userinput>gradle hello</userinput>, Gradle executes the
            <literal>hello</literal> task, which in turn executes the action you've provided. The action is simply a
            closure containing some Groovy code to execute.
        </para>
        <para>If you think this looks similar to Ant's targets, you would be right. Gradle tasks are the equivalent to
            Ant targets, but as you will see, they are much more powerful. We have used a different terminology than Ant
            as we think the word <emphasis>task</emphasis> is more expressive than the word <emphasis>target</emphasis>.
            Unfortunately this introduces a terminology clash with Ant, as Ant calls its commands, such as
            <literal>javac</literal> or <literal>copy</literal>, tasks. So when we talk about tasks,
            we <emphasis>always</emphasis> mean Gradle tasks, which are the equivalent to Ant's targets. If we talk
            about Ant tasks (Ant commands), we explicitly say <emphasis>Ant task</emphasis>.
        </para>
    </section>
    <section>
        <title>A shortcut task definition</title>
        <para>There is a shorthand way to define a task like our <literal>hello</literal> task above, which is more
            concise.</para>
        <sample id="helloShortcut" dir="userguide/tutorial/helloShortcut" title="A task definition shortcut">
            <sourcefile file="build.gradle"/>
        </sample>
        <para>Again, this defines a task called <literal>hello</literal> with a single closure to execute.
            We will use this task definition style throughout the user guide.</para>
    </section>
    <section>
        <title>Build scripts are code</title>
        <para>Gradle's build scripts give you the full power of Groovy. As an appetizer, have a look at this:
        </para>
        <sample id="upper" dir="userguide/tutorial/upper" title="Using Groovy in Gradle's tasks">
            <sourcefile file="build.gradle"/>
            <output args="-q upper"/>
        </sample>
        <para>or</para>
        <sample id="count" dir="userguide/tutorial/count" title="Using Groovy in Gradle's tasks">
            <sourcefile file="build.gradle"/>
            <output args="-q count"/>
        </sample>
    </section>
    <section id='sec:task_dependencies'>
        <title>Task dependencies</title>
        <para>As you probably have guessed, you can declare tasks that depend on other tasks.
        </para>
        <sample id="intro" dir="userguide/tutorial/intro" title="Declaration of task that depends on other task">
            <sourcefile file="build.gradle"/>
            <output args="-q intro"/>
        </sample>
        <para>To add a dependency, the corresponding task does not need to exist.</para>
        <sample id="lazyDependsOn" dir="userguide/tutorial/lazyDependsOn" title="Lazy dependsOn - the other task does not exist (yet)">
            <sourcefile file="build.gradle"/>
            <output args="-q taskX"/>
        </sample>
        <para>The dependency of <literal>taskX</literal> to <literal>taskY</literal> is declared before
            <literal>taskY</literal> is defined. This is very important for multi-project builds. Task dependencies are
            discussed in more detail in <xref linkend='sec:adding_dependencies_to_tasks'/>.
        </para>
        <para>Please notice that you can't use shortcut notation (see <xref linkend='sec:shortcut_notations' />)
        when referring to a task that is not yet defined.</para>
    </section>
    <section>
        <title>Dynamic tasks</title>
        <para>The power of Groovy can be used for more than defining what a task does. For example, you can also use it
            to dynamically create tasks.
        </para>
        <sample id="dynamic" dir="userguide/tutorial/dynamic" title="Dynamic creation of a task">
            <sourcefile file="build.gradle"/>
            <output args="-q task1"/>
        </sample>
    </section>
    <section>
        <title>Manipulating existing tasks</title>
        <para>Once tasks are created they can be accessed via an <emphasis>API</emphasis>. For instance, you could use this to
        dynamically add dependencies to a task, at runtime.  Ant doesn't allow anything like this.
        </para>
        <sample id="dynamicDepends" dir="userguide/tutorial/dynamicDepends" title="Accessing a task via API - adding a dependency">
            <sourcefile file="build.gradle"/>
            <output args="-q task0"/>
        </sample>
        <para>Or you can add behavior to an existing task.</para>
        <sample id="helloEnhanced" dir="userguide/tutorial/helloEnhanced" title="Accessing a task via API - adding behaviour">
            <sourcefile file="build.gradle"/>
            <output args="-q hello"/>
        </sample>
        <para>The calls <literal>doFirst</literal> and <literal>doLast</literal> can be executed multiple times.
            They add an action to the beginning or the end of the task's actions list. When the task executes, the
            actions in the action list are executed in order. The <literal>&lt;&lt;</literal> operator is simply an
            alias for <literal>doLast</literal>.
        </para>
    </section>
    <section id='sec:shortcut_notations'>
        <title>Shortcut notations</title>
        <para>As you might have noticed in the previous examples, there is a convenient notation for accessing an
            <emphasis>existing</emphasis> task. Each task is available as a property of the build script:
        </para>
        <sample id="helloWithShortCut" dir="userguide/tutorial/helloWithShortCut" title="Accessing task as a property of the build script">
            <sourcefile file="build.gradle"/>
            <output args="-q hello"/>
        </sample>
        <para>This enables very readable code, especially when using the tasks provided by the plugins,
              like the <literal>compile</literal> task.
        </para>
    </section>
    <section id='sec:extra_task_properties'>
        <title>Extra task properties</title>
        <para>You can add your own properties to a task. To add a property named <literal>myProperty</literal>,
            set <literal>ext.myProperty</literal> to an initial value. From that point on, the property can be read
            and set like a predefined task property.
        </para>
        <sample id="extraTaskProperties" dir="userguide/tutorial/extraProperties" title="Adding extra properties to a task">
            <sourcefile file="build.gradle" snippet="taskProperties"/>
            <output args="-q printTaskProperties"/>
        </sample>
        Extra properties aren't limited to tasks. You can read more about them in <xref linkend='sec:extra_properties'/>.
    </section>
    <section>
        <title>Using Ant Tasks</title>
        <para>Ant tasks are first-class citizens in Gradle. Gradle provides excellent integration for Ant tasks by simply
            relying on Groovy. Groovy is shipped with the fantastic <literal>AntBuilder</literal>. Using Ant tasks
            from Gradle is as convenient and more powerful than using Ant tasks from a <filename>build.xml</filename>
            file. From the example below, you can learn how to execute Ant tasks and how to access Ant properties:
        </para>
        <sample id="antLoadfile" dir="userguide/tutorial/antLoadfile" title="Using AntBuilder to execute ant.loadfile target">
            <sourcefile file="build.gradle"/>
            <output args="-q loadfile"/>
        </sample>

        <para>There is lots more you can do with Ant in your build scripts. You can find out more in <xref linkend="ant"/>.</para>
    </section>
    <section>
        <title>Using methods</title>
        <para>Gradle scales in how you can organize your build logic. The first level of organizing your build logic for
            the example above, is extracting a method.
        </para>
        <sample id="antLoadfileWithMethod" dir="userguide/tutorial/antLoadfileWithMethod" title="Using methods to organize your build logic">
            <sourcefile file="build.gradle"/>
            <output args="-q loadfile"/>
        </sample>
        <para>Later you will see that such methods can be shared among subprojects in multi-project builds. If your
            build logic becomes more complex, Gradle offers you other very convenient ways to organize it. We have
            devoted a whole chapter to this. See <xref linkend='organizing_build_logic'/>.
        </para>
    </section>
    <section id='sec:default_tasks'>
        <title>Default tasks</title>
        <para>Gradle allows you to define one or more default tasks that are executed if no other tasks are specified.
        </para>
        <sample id="defaultTasks" dir="userguide/tutorial/defaultTasks" title="Defining a default task">
            <sourcefile file="build.gradle"/>
            <output args="-q"/>
        </sample>
        <para>This is equivalent to running <userinput>gradle clean run</userinput>. In a multi-project build every
            subproject can have its own specific default tasks. If a subproject does not specify default tasks, the
            default tasks of the parent project are used (if defined).
        </para>
    </section>
    <section id="configure-by-dag">
        <title>Configure by DAG</title>
        <para>As we later describe in full detail (see <xref linkend='build_lifecycle'/>), Gradle has a
            configuration phase and an execution phase. After the configuration phase, Gradle knows all tasks that should
            be executed. Gradle offers you a hook to make use of this information. A use-case for this would be to check
            if the release task is among the tasks to be executed. Depending on this, you can assign different values
            to some variables.
        </para>
        <para>In the following example, execution of the <literal>distribution</literal> and <literal>release</literal> tasks results in different value of the <literal>version</literal> variable.</para>
        <sample id="configByDagNoRelease" dir="userguide/tutorial/configByDag" title="Different outcomes of build depending on chosen tasks">
            <sourcefile file="build.gradle"/>
            <output args="-q distribution"/>
            <output args="-q release" outputFile="configByDag.out"/>
        </sample>
        <para>The important thing is that <literal>whenReady</literal> affects the release task <emphasis>before</emphasis> the release task is executed.
        This works even when the release task is not the <emphasis>primary</emphasis> task (i.e., the task passed to the <command>gradle</command> command).
        </para>
    </section>
    <section>
        <title>Where to next?</title>
        <para>
            In this chapter, we have had a first look at tasks. But this is not the end of the story for tasks. If you want to jump into more of the details,
            have a look at <xref linkend='more_about_tasks'/>.
        </para>
        <para>
            Otherwise, continue on to the tutorials in <xref linkend="tutorial_java_projects"/> and <xref linkend="artifact_dependencies_tutorial"/>.
        </para>
    </section>
</chapter>
