第14章 色々なチュートリアル

14.1. ディレクトリの作成 Directory creation

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 mkdir 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 DRY principle). A better solution would use the dependsOn relationship between tasks to reuse the task to create the directory:

複数のタスクが、ある一つのディレクトリが存在していることを前提としている、ということがよくあります。 それらのタスク全てでmkdirを呼ぶことももちろんできますが、それではやはり冗長です。 この場合、次のように、ディレクトリを必要とするタスクにdependsOn関係を追加するのが良い方法です。

例14.1 mkdirでディレクトリを作成する

build.gradle

def 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
}

gradle -q compile の出力

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

14.2. Gradleプロパティとシステムプロパティ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.

Gradleでは、さまざまな方法でビルドにプロパティ値を渡すことができます。 -Dオプションを使えばGradleを実行しているJVMにシステムプロパティを渡すことができます。 gradleコマンドは-Dオプションをjavaコマンドへの-Dオプションと同じように処理します。

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 (defined by the “GRADLE_USER_HOME” environment variable, which if not set 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 set in a gradle.properties 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.

propertiesファイルを記述することで、projectオブジェクトに直接プロパティを追加することもできます。 このプロパティファイルgradle.propertiesはGradleのホームディレクトリ (デフォルトではUSER_HOME/.gradle)かプロジェクトディレクトリに作成します。 マルチプロジェクトの場合、gradle.properteisはすべてのサブプロジェクトディレクトリに置くことができます。 gradle.propertiesに記述されたプロパティはprojectオブジェクトからアクセスすることができます。 なお、ホームディレクトリのgradle.propertiesは、プロジェクトディレクトリのgradle.propertiesの定義を上書きし、優先的に使用されます。

You can also add properties directly to your project object via the -P command line option.

projectオブジェクトに追加するプロパティは、コマンドラインオプションの-Pオプションで直接設定することもできます。

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 -P 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. [10]

projectオブジェクトに追加するプロパティは、コマンドラインオプションの-Pオプションで設定することもできます。また、さらにエキゾチックな使い方に備えて、環境変数やシステムプロパティからプロパティを直接取り込む機能もあります。たとえば、管理権限のないマシン上のCIサーバーで継続的なビルドを行う場合について考えてみましょう。自分のビルドスクリプトに、他人から見られたくない値をプロパティとして設定する必要がある場合、-Pオプションは使えません。このときは、プロジェクトの管理者のみアクセスできるようなCIサーバー上のページで環境変数を設定することで、ビルドスクリプトにプロパティを渡すことができます。 [11] ここで設定する環境変数名にはあるパターンがあり、ORG_GRADLE_PROJECT_propertyName=somevalueという環境変数を設定した場合propertyNameというプロパティがプロジェクトに設定されます。また、システムプロパティでも同様のメカニズムを実装しています。パターンがorg.gradle.project.propertyNameとなっていること以外は環境変数の場合と同じです。

If the environment variable name looks like ORG_GRADLE_PROJECT_prop=somevalue, then Gradle will set a prop property on your project object, with the value of somevalue. Gradle also supports this for system properties, but with a different naming pattern, which looks like org.gradle.project.prop.

You can also set system properties in the gradle.properties file. If a property name in such a file has the prefix “systemProp.”, like “systemProp.propName”, then the property and its value will be set as a system property, without the prefix. In a multi project build, “systemProp.” properties set in any project except the root will be ignored. That is, only the root project's gradle.properties file will be checked for properties that begin with the “systemProp.” prefix.

gradle.propertiesファイルでもシステムプロパティを設定することができます。 ファイル内でプレフィックスにsystemPropをつけてプロパティを設定することで、プレフィックス部分をのぞいたプロパティ名でシステムプロパティに追加されます。

例14.2 gradle.propertiesでプロパティを設定する

gradle.properties

gradlePropertiesProp=gradlePropertiesValue
sysProp=shouldBeOverWrittenBySysProp
envProjectProp=shouldBeOverWrittenByEnvProp
systemProp.system=systemValue

build.gradle

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

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

14.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. 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 gradle.properties file, you need to check for existence before you access them. You can do this by using the method hasProperty('propertyName') which returns true or false.

プロジェクトに設定されたプロパティは、ビルドスクリプト内では単にプロパティ名でアクセスできます。この場合、アクセスしたプロパティがプロジェクトに設定されてなければ、例外が発生してビルドは失敗します。プロパティをオプションにして、必要なときのみgradle.propertiesなどでユーザーにプロパティをセットさせたい場合などは、アクセスする前にプロパティがセットされているかどうか確認しなければなりません。hasProperty('propertyName')がtrueやfalseを返すので、それでプロパティの存在を確認できます。

14.3. 外部のビルドスクリプトをプロジェクトに取り込む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.

外部のビルドスクリプトを取り込んでプロジェクトを設定することができます。取り込む外部スクリプト内では、Gradleの文法がすべて使用できます。その外部スクリプトから、さらに別の外部スクリプトを取り込むことさえ可能です。

例14.3 外部のビルドスクリプトファイルでプロジェクトの設定を行う

build.gradle

apply from: 'other.gradle'

other.gradle

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

gradle -q hello の出力

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

14.4. 任意のオブジェクトを組み立てる Configuring arbitrary objects

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

次のような非常に読みやすい方法で、あらゆるオブジェクトを設定することができます。

例14.4 任意のオブジェクトを組み立てる

build.gradle

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

gradle -q configure の出力

> gradle -q configure
1
5

14.5. 外部スクリプトで任意のオブジェクトを組み立てる Configuring arbitrary objects using an external script

You can also configure arbitrary objects using an external script.

外部スクリプトを使って、任意のオブジェクトを組み立てることもできます。

例14.5 外部スクリプトで任意のオブジェクトを組み立てる

build.gradle

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

other.gradle

gradle -q configure の出力

> gradle -q configure
1
5

14.6. キャッシング 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 --recompile-scripts 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.

応答速度を上げるため、Gradleはコンパイル済みのスクリプトをデフォルトですべてキャッシュします。キャッシュ対象には、すべてのビルドスクリプトや初期化スクリプトなどが含まれます。最初にプロジェクトをビルドしたとき、Gradleは.gradleディレクトリをプロジェクトディレクトリに作成します。そこにコンパイル済みのスクリプトが保存され、次回のビルドからは、そのコンパイル済みのスクリプトが使用されるのです。もし前回コンパイルしたときからスクリプトが変更されていれば、キャッシュは再度コンパイルされます。--recompile-scriptsオプションをつけてGradleを実行すれば、キャッシュはすべて破棄され、再度コンパイル、保存されます。これにより、Gradleにキャッシュを再構築させることができます。



[10] Jenkins, Teamcity, or Bamboo are some CI servers which offer this functionality.

[11] TeamcityBambooといったCIサーバーがこの機能を持っています。