# Chapter 12. Tutorial - 'This and That'

## 12.1. Directory creation

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 `mkdir` 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 dependsOn relationship):

Example 12.1. Directory creation with mkdir

`build.gradle`

    classesDir = new File('build/classes')
    task resources << {
        classesDir.mkdirs()
        // do something
    }
    task compile(dependsOn: 'resources') << {
        if (classesDir.isDirectory()) {
            println 'The class directory exists. I can operate'
        }
        // do something
    }

Output of `gradle -q compile`

    > gradle -q compile
    The class directory exists. I can operate

But Gradle offers you also Directory Tasks to deal with this.

Example 12.2. Directory creation with Directory tasks

`build.gradle`

    classes = dir('build/classes')
    task resources(dependsOn: classes) << {
        // do something
    }
    task otherResources(dependsOn: classes) << {
        if (classes.dir.isDirectory()) {
            println 'The class directory exists. I can operate'
        }
        // do something
    }

Output of `gradle -q otherResources`

    > gradle -q otherResources
    The class directory exists. I can operate

A Directory Task is a simple task whose name is a relative path to the project dir [5] . 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.

## 12.2. Gradle properties and system properties

Gradle offers a variety of ways to add properties to your build. With the `-D` command line option you can pass a system property to the JVM which runs Gradle. The `-D` option of the gradle command has the same effect as the `-D` option of the java command.

You can also directly add properties to your project objects using properties files. You can place a `gradle.properties` file in the Gradle user home directory (defaults to ``USER_HOME`/.gradle`) or in your project directory. For multi-project builds you can place `gradle.properties` files in any subproject directory. The properties of the `gradle.properties` 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.

You can also add properties directly to your project object via the `-P` command line option. For more exotic use cases you can even pass properties directly 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 machine. Your build script needs properties which values should not be seen by others. Therefore you can't use the `-P` option. In this case you can add an environment property in the project administration section (invisible to normal users). [6] If the environment property follows the pattern `ORG_GRADLE_PROJECT_`propertyName`=somevalue`, `propertyName` 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 `org.gradle.project.`propertyName``.

With the `gradle.properties` files you can also set system properties. If a property in such a file has the prefix `systemProp.` the property and its value are added to the system properties, without the prefix.

Example 12.3. Setting properties with a gradle.properties file

`gradle.properties`

    gradlePropertiesProp=gradlePropertiesValue
    systemPropertiesProp=shouldBeOverWrittenBySystemProp
    envPropertiesProp=shouldBeOverWrittenByEnvProp
    systemProp.system=systemValue

`build.gradle`

    task printProps << {
        println commandLineProjectProp
        println gradlePropertiesProp
        println systemProjectProp
        println envProjectProp
        println System.properties['system']
    }

Output of `gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps`

    > gradle -q -PcommandLineProjectProp=commandLineProjectPropValue -Dorg.gradle.project.systemProjectProp=systemPropertyValue printProps
    commandLineProjectPropValue
    gradlePropertiesValue
    systemPropertyValue
    envPropertyValue
    systemValue

### 12.2.1. Checking for project properties

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 `hasProperty('propertyName')` which returns `true` or `false`.

## 12.3. Accessing the web via a proxy

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 `System.properties['proxy.proxyUser'] = 'userid'`. An arguably nicer way is shown in Section 12.2, “Gradle properties and system properties”. Your gradle.properties file could look like this:

Example 12.4. Accessing the web via a proxy

`gradle.properties`

    systemProp.http.proxyHost=www.somehost.org
    systemProp.http.proxyPort=8080
    systemProp.http.proxyUser=userid
    systemProp.http.proxyPassword=password
    systemProp.http.nonProxyHosts=*.nonproxyrepos.com|localhost

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 link to the svn view. The other is a Networking Properties page from the JDK docs. If anyone knows a better overview please let us know via the mailing list.

## 12.4. Configuring the project using an external build script

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.

Example 12.5. Configuring the project using an external build script

`build.gradle`

    apply from: 'other.gradle'

`other.gradle`

    println "configuring $project"
    task hello << {
        println 'hello from other script'
    }

Output of `gradle -q hello`

    > gradle -q hello
    configuring root project 'configureProjectUsingScript'
    hello from other script

## 12.5. Configuring arbitrary objects

You can configure arbitrary objects in the following very readable way.

Example 12.6. Configuring arbitrary objects

`build.gradle`

    task configure << {
        pos = configure(new java.text.FieldPosition(10)) {
            beginIndex = 1
            endIndex = 5
        }
        println pos.beginIndex
        println pos.endIndex
    }

Output of `gradle -q configure`

    > gradle -q configure
    1
    5

## 12.6. Configuring arbitrary objects using an external script

You can also configure arbitrary objects using an external script.

Example 12.7. Configuring arbitrary objects using a script

`build.gradle`

    task configure << {
        pos = new java.text.FieldPosition(10)
        // Apply the script
        apply from: 'other.gradle', to: pos
        println pos.beginIndex
        println pos.endIndex
    }

`other.gradle`

    beginIndex = 1;
    endIndex = 5;

Output of `gradle -q configure`

    > gradle -q configure
    1
    5

## 12.7. Caching

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 `.gradle` 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 `-C rebuild` 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.

[5] The notation `dir('/somepath')` is a convenience method for `tasks.add('somepath', type: Directory)`

[6] Teamcity or Bamboo are for example CI servers which offer this functionality.