<!--
  ~ 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_this_and_that' xmlns:xi="http://www.w3.org/2001/XInclude">
    <title>Tutorial - 'This and That'</title>
    <section id='sec:directory_creation'>
        <title>Directory creation</title>
        <para>There is a common situation, that multiple tasks depend on the existence of a directory. Of course you can
            deal with this by adding a
            <literal>mkdir</literal>
            to the beginning of those tasks. But this is kind of bloated. There is a better solution (works only if the
            tasks that need the directory have a
            <emphasis>dependsOn</emphasis>
            relationship):
        </para>
        <sample id="makeDirectory" dir="userguide/tutorial/makeDirectory" title="Directory creation with mkdir">
            <sourcefile file="build.gradle"/>
            <output args="-q compile"/>
        </sample>
        <para>But Gradle offers you also <emphasis>Directory Tasks</emphasis> to deal with this.</para>
        <sample id="directoryTask" dir="userguide/tutorial/directoryTask" title="Directory creation with Directory tasks">
            <sourcefile file="build.gradle"/>
            <output args="-q otherResources"/>
        </sample>
        <para>A <emphasis>Directory Task</emphasis>
            is a simple task whose name is a relative path to the project dir
            <footnote>
                <para>The notation <literal>dir('/somepath')</literal> is a convenience method for
                    <literal>tasks.add('somepath', type: Directory)</literal>
                </para>
            </footnote>
            . During the execution phase the directory corresponding to this path gets created if it does not exist yet.
            Another interesting thing to note in this example, is that you can also pass tasks objects to the dependsOn
            declaration of a task.
        </para>
    </section>
    <section id='sec:gradle_properties_and_system_properties'>
        <title>Gradle properties and system properties</title>
        <para>Gradle offers a variety of ways to add properties to your build. With the <option>-D</option> command line
            option you can pass a system property to the JVM which runs Gradle. The <option>-D</option> option of the
            <command>gradle</command> command has the same effect as the <option>-D</option> option of the
            <command>java</command> command.
        </para>
        <para>You can also directly add properties to your project objects using properties files. You can place a
            <filename>gradle.properties</filename> file in the Gradle user home directory (defaults to
            <filename><replaceable>USER_HOME</replaceable>/.gradle</filename>) or in your project directory. For
            multi-project builds you can place <filename>gradle.properties</filename> files in any subproject directory.
            The properties of the <filename>gradle.properties</filename> can be accessed via the project object. The
            properties file in the user's home directory has precedence over property files in the project directories.
        </para>
        <para>You can also add properties directly to your project object via the <option>-P</option>
            command line option. For more exotic use cases you can even pass properties <emphasis>directly</emphasis>
            to the project object via system and environment properties. For example if you run a build on a continuous
            integration server where you have no admin rights for the <emphasis>machine</emphasis>. Your build script
            needs properties which values should not be seen by others. Therefore you can't use the <option>-P</option>
            option. In this case you can add an environment property in the project administration section (invisible to
            normal users).
            <footnote>
                <para>
                    <emphasis>Teamcity</emphasis> or <emphasis>Bamboo</emphasis> are for example CI servers which
                    offer this functionality.
                </para>
            </footnote>
            If the environment property follows the pattern
            <literal>ORG_GRADLE_PROJECT_<replaceable>propertyName</replaceable>=somevalue</literal>,
            <literal>propertyName</literal> is added to your project object. If in the future CI servers support Gradle
            directly, they might start Gradle via its main method. Therefore we already support the same mechanism for
            system properties. The only difference is the pattern, which is
            <literal>org.gradle.project.<replaceable>propertyName</replaceable></literal>.
        </para>
        <para>With the <filename>gradle.properties</filename> files you can also set system properties. If a property
            in such a file has the prefix <literal>systemProp.</literal> the property and its value are added to the 
            system properties, without the prefix.
        </para>
        <sample id="properties" dir="userguide/tutorial/properties" title="Setting properties with a gradle.properties file">
            <sourcefile file="gradle.properties"/>
            <sourcefile file="build.gradle"/>
            <output args="-q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps"/>
        </sample>
        <section id='sub:checking_for_project_properties'>
            <title>Checking for project properties</title>
            <para>You can access a project property in your build script simply by using its name as you would use a
                variable. In case this property does not exists, an exception is thrown and the build fails. If your
                build script relies on optional properties the user might set for example in a gradle.properties file,
                you need to check for existence before you can access them. You can do this by using the method
                <literal>hasProperty('propertyName')</literal>
                which returns
                <literal>true</literal>
                or <literal>false</literal>.
            </para>
        </section>
    </section>
    <section id='sec:accessing_the_web_via_a_proxy'>
        <title>Accessing the web via a proxy</title>
        <para>Setting a proxy for web access (for example for downloading dependencies) is easy. Gradle does not need to
            provide special functionality for this. The JVM can be instructed to go via proxy by setting certain system
            properties. You could set these system properties directly in your build script with <literal>
                System.properties['proxy.proxyUser'] = 'userid'</literal>. An arguably nicer way is shown in
            <xref linkend='sec:gradle_properties_and_system_properties'/>. Your gradle.properties file could look like
            this:
        </para>
        <example>
            <title>Accessing the web via a proxy</title>
            <para><filename>gradle.properties</filename></para>
            <programlisting><![CDATA[
systemProp.http.proxyHost=www.somehost.org
systemProp.http.proxyPort=8080
systemProp.http.proxyUser=userid
systemProp.http.proxyPassword=password
systemProp.http.nonProxyHosts=*.nonproxyrepos.com|localhost	
]]></programlisting>
        </example>
        <para>We could not find a good overview for all possible proxy settings. One place to look are the constants
            in a file from the ant project. Here a
            <ulink url='http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/util/ProxySetup.java?view=markup&amp;pathrev=556977'>
                link
            </ulink> to the svn view. The other is a
            <ulink url='http://java.sun.com/javase/6/docs/technotes/guides/net/properties.html'>
                Networking Properties page
            </ulink> from the JDK docs. If anyone knows a better overview please let us know via the mailing list.
        </para>
    </section>
    <section id="sec:configuring_using_external_script">
        <title>Configuring the project using an external build script</title>
        <para>You can configure the current project using an external build script. All of the Gradle build language
            is available in the external script. You can even apply other scripts from the external script.
        </para>
        <sample id="configureProjectUsingScript" dir="userguide/tutorial/configureProjectUsingScript" title="Configuring the project using an external build script">
            <sourcefile file="build.gradle"/>
            <sourcefile file="other.gradle"/>
            <output args="-q hello"/>
        </sample>
    </section>
    <section id='sec:configuring_arbitrary_objects'>
        <title>Configuring arbitrary objects</title>
        <para>You can configure arbitrary objects in the following very readable way.
        </para>
        <sample id="configureObject" dir="userguide/tutorial/configureObject" title="Configuring arbitrary objects">
            <sourcefile file="build.gradle"/>
            <output args="-q configure"/>
        </sample>
    </section>
    <section>
        <title>Configuring arbitrary objects using an external script</title>
        <para>You can also configure arbitrary objects using an external script.
        </para>
        <sample id="configureObjectUsingScript" dir="userguide/tutorial/configureObjectUsingScript" title="Configuring arbitrary objects using a script">
            <sourcefile file="build.gradle"/>
            <sourcefile file="other.gradle"/>
            <output args="-q configure"/>
        </sample>
    </section>
    <section id='sec:caching'>
        <title>Caching</title>
        <para>To improve responsiveness Gradle caches all compiled scripts by default. This includes all build scripts,
            initialization scripts, and other scripts. The first time you run a build for a project, Gradle creates a
            <filename>.gradle</filename> directory in which it puts the compiled script. The next time you run this
            build, Gradle uses the compiled script, if the script has not changed since it was compiled.  Otherwise the
            script gets compiled and the new version is stored in the cache. If you run Gradle with the
            <option>-C rebuild</option> option, the cached script is discarded and the script is compiled and stored
            in the cache. This way you can force Gradle to rebuild the cache.
        </para>
    </section>
</chapter>
