<!--
  ~ 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='writing_build_scripts' xmlns:xi="http://www.w3.org/2001/XInclude">
    <title>Writing Build Scripts</title>
    <para>This chapter looks at some of the details of writing a build script.</para>

    <section id='sec:project_api'>
        <title>Project API</title>
        <para>In the tutorial in <xref linkend='tutorial_java_projects'/> we used, for example, the
            <literal>apply()</literal> method. Where does this method come from? We said earlier that the build script
            defines a project in Gradle. For each project in the build creates an instance of type
            <apilink class='org.gradle.api.Project'/> and associates this <classname>Project</classname> object with
            the build script. As the build script executes, it configures this <classname>Project</classname> object:
        </para>
        <tip>
            <title>Getting help writing build scripts</title>
            <para>Don't forget that your build script is simply Groovy code that drives the Gradle API. And the
                <apilink class='org.gradle.api.Project'/> interface is your starting point for accessing everything
                in the Gradle API. So, if you're wondering what 'tags' are available in your build script, you can
                start with the javadocs for the <classname>Project</classname> interface.
            </para>
        </tip>
        <itemizedlist>
            <listitem>
                <para>Any method you call in your build script, which <emphasis>is not defined</emphasis>
                    in the build script, is delegated to the <classname>Project</classname> object.
                </para>
            </listitem>
            <listitem>
                <para>Any property you access in your build script, which <emphasis>is not defined</emphasis>
                    in the build script, is delegated to the <classname>Project</classname> object.
                </para>
            </listitem>
        </itemizedlist>
        <para>Let's try this out and try to access the <literal>name</literal> property of the
            <classname>Project</classname> object.
        </para>
        <sample id="projectApi" dir="userguide/tutorial/projectApi" title="Accessing property of the Project object">
            <sourcefile file="build.gradle"/>
            <output args="-q check"/>
        </sample>
        <para>Both <literal>println</literal> statements print out the same property. The first uses auto-delegation to
            the <classname>Project</classname> object, for properties not defined in the build script. The other
            statement uses the <literal>project</literal> property available to any build script, which returns the
            associated <classname>Project</classname> object. Only if you define a property or a method which has the
            same name as a member of the <classname>Project</classname> object, you need to use the <literal>project</literal>
            property.
        </para>
        <section>
            <title>Standard project properties</title>
            <para>The <classname>Project</classname> object provides some standard properties, which are available in
                your build script. The following table lists a few of the commonly used ones.
            </para>
            <table>
                <title>Project Properties</title>
                <thead>
                    <tr>
                        <td>Name</td>
                        <td>Type</td>
                        <td>Default Value</td>
                    </tr>
                </thead>
                <tr>
                    <td><literal>project</literal></td>
                    <td><apilink class='org.gradle.api.Project'/></td>
                    <td>The <classname>Project</classname> instance</td>
                </tr>
                <tr>
                    <td><literal>name</literal></td>
                    <td><classname>String</classname></td>
                    <td>The name of the directory containing the build script.</td>
                </tr>
                <tr>
                    <td><literal>path</literal></td>
                    <td><classname>String</classname></td>
                    <td>The absolute path of the project.</td>
                </tr>
                <tr>
                    <td><literal>description</literal></td>
                    <td><classname>String</classname></td>
                    <td>A description for the project.</td>
                </tr>
                <tr>
                    <td><literal>buildFile</literal></td>
                    <td><classname>File</classname></td>
                    <td>The build script.</td>
                </tr>
                <tr>
                    <td><literal>projectDir</literal></td>
                    <td><classname>File</classname></td>
                    <td>The directory containing the build script.</td>
                </tr>
                <tr>
                    <td><literal>buildDirName</literal></td>
                    <td><classname>String</classname></td>
                    <td><filename>build</filename></td>
                </tr>
                <tr>
                    <td><literal>buildDir</literal></td>
                    <td><classname>File</classname></td>
                    <td><filename><replaceable>projectDir</replaceable>/build</filename></td>
                </tr>
                <tr>
                    <td><literal>group</literal></td>
                    <td><classname>Object</classname></td>
                    <td><literal>unspecified</literal></td>
                </tr>
                <tr>
                    <td><literal>version</literal></td>
                    <td><classname>Object</classname></td>
                    <td><literal>unspecified</literal></td>
                </tr>
                <tr>
                    <td><literal>ant</literal></td>
                    <td><apilink class="org.gradle.api.AntBuilder"/></td>
                    <td>An <classname>AntBuilder</classname> instance</td>
                </tr>
            </table>

            <para>Below is a sample build which demonstrates some of these properties.</para>
            <sample id="projectCoreProperties" dir="userguide/tutorial/projectCoreProperties" title="Project properties">
                <layout>
                    build.gradle
                    subProject
                    subProject/build.gradle
                </layout>
                <sourcefile file="build.gradle"/>
                <output args="-q check"/>
            </sample>
        </section>
    </section>
    <section>
        <title>Script API</title>
        <para>When Gradle executes a script, it compiles the script into a class which implements <apilink class="org.gradle.api.Script"/>.</para>
    </section>

</chapter>
