<!--
  ~ 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'>
    <title>Tutorial - 'This and That'</title>
    <section id='sec:directory_creation'>
        <title>Directory creation</title>
        <para>There is a common situation where 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 it's almost always a bad idea to repeat a sequence of code
            that you only need once (Look up the <firstterm>DRY</firstterm> principle). A better solution would use the
            <emphasis>dependsOn</emphasis> relationship between tasks to reuse the task to create the directory:
        </para>
        <sample id="makeDirectory" dir="userguide/tutorial/makeDirectory" title="Directory creation with mkdir">
            <sourcefile file="build.gradle"/>
            <output args="-q compile"/>
        </sample>
    </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 add properties to your project objects using properties files. You can place a
            <filename>gradle.properties</filename> file in the Gradle user home directory (defined by the
            “<literal>GRADLE_USER_HOME</literal>” environment variable, which if not set 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 set in a <filename>gradle.properties</filename> file 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.
        </para>
        <para>Gradle can also set project properties when it sees specially-named system properties or
            environment variables. This feature is very useful when you don't have admin rights to a continuous integration
            server and you need to set property values that should not be easily visible, typically for security reasons.
            In that situation, you can't use the <option>-P</option> option, and you can't change the system-level
            configuration files.  The correct strategy is to change the configuration of your continuous integration
            build job, adding an environment variable setting that matches an expected pattern.  This won't be visible
            to normal users on the system.
            <footnote>
                <para>
                    <emphasis>Jenkins</emphasis>, <emphasis>Teamcity</emphasis>, or <emphasis>Bamboo</emphasis> are some CI servers which offer this functionality.
                </para>
            </footnote>
        </para>
        <para>
            If the environment variable name looks like
            <literal>ORG_GRADLE_PROJECT_<replaceable>prop</replaceable>=somevalue</literal>,
            then Gradle will set a <literal>prop</literal> property on your project object, with the value
            of <literal>somevalue</literal>. Gradle also supports this for
            system properties, but with a different naming pattern, which looks like
            <literal>org.gradle.project.<replaceable>prop</replaceable></literal>.
        </para>
        <para>You can also set system properties in the <filename>gradle.properties</filename> file. If a property
            name in such a file has the prefix “<literal>systemProp.</literal>”, like “<literal>systemProp.propName</literal>”,
            then the property and its value will be set as a system property, without the prefix. In a multi project
            build, “<literal>systemProp.</literal>” properties set in any project except the root will be ignored.
            That is, only the root project's <filename>gradle.properties</filename> file will be checked for
            properties that begin with the “<literal>systemProp.</literal>” 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. If this property does not exist, an exception will be thrown and the build will fail. If your
                build script relies on optional properties the user might set, perhaps in a <literal>gradle.properties</literal> file,
                you need to check for existence before you 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: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>--recompile-scripts</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>
