Everything in Gradle sits on top of two basic concepts: projects and tasks.
Gradleの根本にあるのは、プロジェクトとタスクという二つの基本的な概念です。
Every Gradle build is made up of one or more projects. What a project represents depends on what it is that you are doing with Gradle. For example, a project might represent a library JAR or a web application. It might represent a distribution ZIP assembled from the JARs produced by other projects. A project does not necessarily represent a thing to be built. It might represent a thing to be done, such as deploying your application to staging or production environments. Don't worry if this seems a little vague for now. Gradle's build-by-convention support adds a more concrete definition for what a project is.
Gradleによるビルドは、一つ以上のプロジェクトから構成されます。プロジェクトとは、ビルドされるソフトウェアを構成するコンポーネントのことですが、正確な意味は何をビルドするかによって変わります。たとえば、あるプロジェクトはライブラリjarやWebアプリケーションをビルドするものかもしれません。または、別のプロジェクトによってビルドされたjarを集めて配布用のzipファイルを作成するものかもしれません。何か具体的なものを組み立てるのではなく、処理を行うだけというプロジェクトもありえます。アプリケーションを本番環境にステージするというプロジェクトがその一例です。今は少しあいまいな印象を受けられるかもしれませんが、心配する必要はありません。Gradleは規約によるビルドをサポートしており、プロジェクトの定義については明確に規定されています。
Each project is made up of one or more tasks. A task represents some atomic piece of work which a build performs. This might be compiling some classes, creating a JAR, generating Javadoc, or publishing some archives to a repository.
それぞれのプロジェクトは、一つ以上のタスクから構成されます。タスクとは、分割不能な何らかの作業単位を表す概念です。たとえば、クラスをコンパイルしたり、JARファイルを作成したり、Javadocを生成したり、アーカイブをリポジトリに公開したりするタスクが考えられます。
For now, we will look at defining some simple tasks in a build with one project. Later chapters will look at working with multiple projects and more about working with projects and tasks.
では、実際にプロジェクト上でいくつか簡単なタスクを定義してビルドしてみましょう。マルチプロジェクトでのビルド例やプロジェクト/タスクのもっと詳しい情報については後の章をご参照ください。
You run a Gradle build using the gradle command. The gradle command
looks for a file called build.gradle
in the current directory.
[3]
We call this build.gradle
file a build script, although strictly speaking it is
a build configuration script, as we will see later. The build script defines a project and its tasks.
Gradleのビルドは、gradleコマンドで実行します。gradleコマンドはカレントディレクトリのbuild.gradle
ファイルを参照してビルドを行います。[4]このファイルは、一般的にはビルドスクリプトと呼ばれます(後述しますが、正確には「ビルドの設定を行うスクリプト」です)。Gradleのプロジェクトとタスクは、このビルドスクリプトで定義されます。
To try this out, create the following build script named build.gradle
.
次のようなスクリプトを、build.gradle
という名前で作成して試してみてください。
In a command-line shell, move to the containing directory and execute the build script with
gradle -q hello
:
コンソールを開いてこのbuild.gradle
のあるディレクトリに移動して、gradle -q hello
と打ち込んでください。ビルドスクリプトが実行され、以下のように出力されるはずです。
-q
オプションって何?What does -q
do?Most of the examples in this user guide are run with the -q
command-line option.
This suppresses Gradle's log messages, so that only the output of the tasks is shown. This keeps the example
output in this user guide a little clearer. You don't need to use this option if you don't want to.
See 18章ロギング for more details about the command-line options which affect Gradle's output.
このユーザーガイドでは、ほぼすべての例で-q
をつけてコマンドを実行しています。このオプションはGradleのログメッセージを抑制するもので、タスクによる出力のみが表示されるようになります。おかげでユーザーガイドの出力例はちょっとすっきりしていますが、もちろん使いたくなければこのオプションを使う必要はありません。Gradleの出力に関係するオプションについては、18章ロギングにもっと詳しく記載されています。
What's going on here? This build script defines a single task, called hello
, and
adds an action to it. When you run gradle hello
, Gradle executes the
hello
task, which in turn executes the action you've provided. The action is simply a
closure containing some Groovy code to execute.
何が起こったのでしょう。ビルドスクリプトは、hello
というタスクを一つ定義していて、このタスクにアクションを一つ追加しています。gradle hello
と実行することで、Gradleがこのhello
を実行し、hello
に追加したアクションが実行されたのです。アクションはGroovyコードを含む単なるクロージャです。
If you think this looks similar to Ant's targets, well, you would be right. Gradle tasks are the equivalent to
Ant targets, but as you will see, they are much more powerful. We have used a different terminology than Ant
as we think the word task is more expressive than the word target.
Unfortunately this introduces a terminology clash with Ant, as Ant calls its commands, such as
javac
or copy
, tasks. So when we talk about tasks,
we always mean Gradle tasks, which are the equivalent to Ant's targets. If we talk
about Ant tasks (Ant commands), we explicitly say Ant task.
Antのtargetに似ているなと思われたかもしれません。実際、GradleのtaskはAntでいえばtargetに相当するものです。ただ、これから見ていきますがGradleのtaskはAntのtargetよりもずっと強力なものです。Gradleではtaskという、Antとは異なる用語を採用しました。これはtaskという言葉が、targetという言葉よりも実態に合った表現だと考えたためです。しかし、残念ながらtaskという用語はAntでもcopy
やjavac
といったコマンドを示すものとして使われており、Gradleのtaskと競合してしまいます。このため、Antのtaskについて述べるときには常にant taskと明示的にいい、単にtaskとしたときはGradleのタスクのことを示すものとします。
There is a shorthand way to define a task like our hello
task above, which is more
concise.
タスク定義は、実際にはもっと短く書けます。先ほどのhello
タスクも、次のように簡潔に書くことができます。
Again, this defines a task called hello
with a single closure to execute.
We will use this task definition style throughout the user guide.
この例も先ほどと同様、実行するクロージャを一つだけもったhello
を定義するものです。このユーザーガイドではこちらの定義方法を使用します。
Gradle's build scripts give you the full power of Groovy. As an appetizer, have a look at this:
GradleのビルドスクリプトではGroovyの機能をすべて使うことができます。手始めに次の例をご覧ください。
例6.4 GradleタスクでGroovyを使う
build.gradle
task upper << { String someString = 'mY_nAmE' println "Original: " + someString println "Upper case: " + someString.toUpperCase() }
gradle -q upper
の出力
> gradle -q upper Original: mY_nAmE Upper case: MY_NAME
or
さらに
例6.5 GradleタスクでGroovyを使う
build.gradle
task count << {
4.times { print "$it " }
}
gradle -q count
の出力
> gradle -q count 0 1 2 3
As you probably have guessed, you can declare tasks that depend on other tasks.
ご想像の通り、タスク間の依存関係を宣言できます。
例6.6 タスク間の依存関係を宣言する
build.gradle
task hello << { println 'Hello world!' } task intro(dependsOn: hello) << { println "I'm Gradle" }
gradle -q intro
の出力
> gradle -q intro Hello world! I'm Gradle
To add a dependency, the corresponding task does not need to exist.
依存関係にタスクを追加するときは、そのタスクがその時点で宣言されていなくてもかまいません。
例6.7 遅延評価のdependsOn - タスクがまだ宣言されていない場合
build.gradle
task taskX(dependsOn: 'taskY') << { println 'taskX' } task taskY << { println 'taskY' }
gradle -q taskX
の出力
> gradle -q taskX taskY taskX
The dependency of taskX
to taskY
is declared before
taskY
is defined. This is very important for multi-project builds. Task dependencies are
discussed in more detail in 「タスクに依存関係を追加するAdding dependencies to a task」.
taskX
がtaskY
に依存していることが宣言されていますが、宣言した時点ではtaskY
の定義文はありません。このことは、マルチプロジェクトのビルドで非常に重要になってきます。タスク間の依存関係については、「タスクに依存関係を追加するAdding dependencies to a task」でさらに詳しく述べられています。
Please notice, that you can't use a shortcut notation (see 「略記法Shortcut notations」) when referring to a task that is not yet defined.
なお、未定義のタスクを参照する場合、略記法(「略記法Shortcut notations」参照)は使えませんので注意してください。
The power of Groovy can be used for more than defining what a task does. For example, you can also use it to dynamically create tasks.
Groovyが力を発揮するのは、タスクが実行するアクションを記述するときだけではありません。たとえば、次のようにタスクを動的に定義することもできます。
例6.8 動的なタスク定義
build.gradle
4.times { counter -> task "task$counter" << { println "I'm task number $counter" } }
gradle -q task1
の出力
> gradle -q task1 I'm task number 1
Once tasks are created they can be accessed via an API. For instance, you could use this to dynamically add dependencies to a task, at runtime. Ant doesn't allow anything like this.
タスクが公開しているAPIを使えば、既存のタスクにアクセスして定義内容を操作することができます。これはAntと異なるGradleの特長の一つです。たとえば、次のように後からタスクの依存関係を追加することができます。
例6.9 APIからタスクにアクセスする - 依存関係の追加
build.gradle
4.times { counter -> task "task$counter" << { println "I'm task number $counter" } } task0.dependsOn task2, task3
gradle -q task0
の出力
> gradle -q task0 I'm task number 2 I'm task number 3 I'm task number 0
Or you can add behavior to an existing task.
また、既存のタスクにアクションを追加することもできます。
例6.10 APIからタスクにアクセスする - アクションの追加
build.gradle
task hello << { println 'Hello Earth' } hello.doFirst { println 'Hello Venus' } hello.doLast { println 'Hello Mars' } hello << { println 'Hello Jupiter' }
gradle -q hello
の出力
> gradle -q hello Hello Venus Hello Earth Hello Mars Hello Jupiter
The calls doFirst
and doLast
can be executed multiple times.
They add an action to the beginning or the end of the task's actions list. When the task executes, the
actions in the action list are executed in order. The <<
operator is simply an
alias for doLast
.
doFirst
やdoLast
は何回でも呼び出すことができ、既存のタスクが実行する一連のアクションの最初や最後に、新しいアクションを追加します。タスクに追加されたアクションは、タスクが実行されたときに順番に実行されます。<<
はdoLast
の単なるエイリアスです。
As you might have noticed in the previous examples, there is a convenient notation for accessing an existing task. Each task is available as a property of the build script:
先ほどの例をみたとき、おやっと思われたかもしれません。既存のタスクにアクセスするときは、便利な略記法を使うことができます。ただのプロパティとしてすべてのタスクにアクセスできるのです。
例6.11 ビルドスクリプトのプロパティとして既存のタスクにアクセスする
build.gradle
task hello << { println 'Hello world!' } hello.doLast { println "Greetings from the $hello.name task." }
gradle -q hello
の出力
> gradle -q hello Hello world! Greetings from the hello task.
This enables very readable code, especially when using the tasks provided by the plugins,
like the compile
task.
この略記法は、コードをとても読みやすいものにします。特に、プラグインなどで外部から提供されるタスク(たとえばcompile
)にアクセスするときには威力を発揮します。
You can add your own properties to a task. To add a property named myProperty
,
set ext.myProperty
to an initial value. From that point on, the property can be read
and set like a predefined task property.
独自のプロパティをタスクに追加することができます。例えば、myProperty
というプロパティを追加するには、ext.myProperty
に初期値を設定してください。
その時点で、このプロパティを定義済みのプロパティと同じように読み書きできるようになります。
例6.12 拡張プロパティをタスクに追加する
build.gradle
task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties << {
println myTask.myProperty
}
gradle -q printTaskProperties
の出力
> gradle -q printTaskProperties myValue
Extra properties aren't limited to tasks. You can read more about them in 「拡張プロパティ Extra properties」.
拡張プロパティを追加できるのは、タスクだけではありません。詳細については、「拡張プロパティ Extra properties」を参照してください。
Ant tasks are first-class citizens in Gradle. Gradle provides excellent integration for Ant tasks by simply
by relying on Groovy. Groovy is shipped with the fantastic AntBuilder
. Using Ant tasks
from Gradle is as convenient and more powerful than using Ant tasks from a build.xml
file. From the example below, you can learn how to execute Ant tasks and how to access Ant properties:
AntのタスクはGradleのファーストクラス・オブジェクトであり、デフォルトで使用できるようになっています。Groovyの持つ機能のおかげで、GradleはAntを非常に高いレベルで統合しています。Groovyには素晴らしきAntBuilder
が組み込まれているのです。Antのタスクは、build.xml
で使うよりGradleで使ったほうが便利で強力です。次の例を見てください。Antのタスクを実行する方法やAntのプロパティにアクセスする方法を示しています。
例6.13 AntBuilderを使ってant.loadfileターゲットを実行する
build.gradle
task loadfile << { def files = file('../antLoadfileResources').listFiles().sort() files.each { File file -> if (file.isFile()) { ant.loadfile(srcFile: file, property: file.name) println " *** $file.name ***" println "${ant.properties[file.name]}" } } }
gradle -q loadfile
の出力
> gradle -q loadfile *** agile.manifesto.txt *** Individuals and interactions over processes and tools Working software over comprehensive documentation Customer collaboration over contract negotiation Responding to change over following a plan *** gradle.manifesto.txt *** Make the impossible possible, make the possible easy and make the easy elegant. (inspired by Moshe Feldenkrais)
There is lots more you can do with Ant in your build scripts. You can find out more in 17章GradleからAntを使う.
Antのタスクを使ってできることはもっとたくさんあります。17章GradleからAntを使うをご参照ください。
Gradle scales in how you can organize your build logic. The first level of organizing your build logic for the example above, is extracting a method.
Gradleでは、段階的にビルドロジックを体系化していくことができます。最初の一歩として、上の例をメソッドの抽出を使ってリファクタリングしてみましょう。
例6.14 メソッドを抽出してビルドロジックを整理する
build.gradle
task checksum << { fileList('../antLoadfileResources').each {File file -> ant.checksum(file: file, property: "cs_$file.name") println "$file.name Checksum: ${ant.properties["cs_$file.name"]}" } } task loadfile << { fileList('../antLoadfileResources').each {File file -> ant.loadfile(srcFile: file, property: file.name) println "I'm fond of $file.name" } } File[] fileList(String dir) { file(dir).listFiles({file -> file.isFile() } as FileFilter).sort() }
gradle -q loadfile
の出力
> gradle -q loadfile I'm fond of agile.manifesto.txt I'm fond of gradle.manifesto.txt
Later you will see that such methods can be shared among subprojects in multi-project builds. If your build logic becomes more complex, Gradle offers you other very convenient ways to organize it. We have devoted a whole chapter to this. See 60章ビルドロジックの体系化.
後でマルチプロジェクトの各プロジェクトでメソッドを共有する方法について学びます。それでもビルドロジックが複雑になってくることもあるでしょう。Gradleでは、ロジックを体系化する便利な方法をいくつも用意しています。ビルドロジックの体系化については一つの章をすべて割り当てて取り扱っていますのでご参照ください。(60章ビルドロジックの体系化)
Gradle allows you to define one or more default tasks for your build.
Gradleでは、ビルドに一つ以上のデフォルトタスクを定義することができます。
例6.15 デフォルトタスクの定義
build.gradle
defaultTasks 'clean', 'run' task clean << { println 'Default Cleaning!' } task run << { println 'Default Running!' } task other << { println "I'm not a default task!" }
gradle -q
の出力
> gradle -q Default Cleaning! Default Running!
This is equivalent to running gradle clean run
. In a multi-project build every
subproject can have its own specific default tasks. If a subproject does not specify default tasks, the
default tasks of the parent project are used (if defined).
これは、gradle clean run
と入力するのと同じです。マルチプロジェクトのビルドでは、すべてのサブプロジェクトが個別にデフォルトタスクを持つことができます。サブプロジェクトにデフォルトタスクが定義されていない時は、(定義されていれば)親プロジェクトの定義が使用されます。
As we later describe in full detail (See 56章ビルドのライフサイクル) Gradle has a configuration phase and an execution phase. After the configuration phase, Gradle knows all tasks that should be executed. Gradle offers you a hook to make use of this information. A use-case for this would be to check if the release task is among the tasks to be executed. Depending on this, you can assign different values to some variables.
詳しくは56章ビルドのライフサイクルで説明しますが、Gradleのビルドはいくつかのフェーズに分かれて実行されます。Gradleはどのタスクを実行するのかを設定フェーズで決定しますが、この情報を使うためのフックが提供されています。実行タスクにあるタスクが含まれるかどうかによって、変数に別の値を割り当てたりできるわけです。ユースケースとしては、releaseタスクが実行されるタスクに入っているかどうかチェックするといったものが考えられるでしょう。
In the following example, execution of the distribution
and release
tasks results in different value of the version
variable.
次の例では、distribution
タスクを実行するかrelease
タスクを実行するかでversion
変数に違う値を割り当てています。
例6.16 選択したタスクによって異なる結果を得る
build.gradle
task distribution << { println "We build the zip with version=$version" } task release(dependsOn: 'distribution') << { println 'We release now' } gradle.taskGraph.whenReady {taskGraph -> if (taskGraph.hasTask(release)) { version = '1.0' } else { version = '1.0-SNAPSHOT' } }
gradle -q distribution
の出力
> gradle -q distribution We build the zip with version=1.0-SNAPSHOT
gradle -q release
の出力
> gradle -q release We build the zip with version=1.0 We release now
The important thing is that whenReady
affects the release task before the release task is executed.
This works even when the release task is not the primary task (i.e., the task passed to the gradle command).
ここで大事なことは、releaseタスクが実行予定にあるという事実を、releaseタスクが実行される前に利用できる点です。releaseタスクがプライマリタスク、つまりgradleコマンドに引き渡されているタスクでなくてもかまいません。
In this chapter, we have had a first look at tasks. But this is not the end of the story for tasks. If you want to jump into more of the details, have a look at 15章タスク詳解.
この章で、私たちは初めてタスクというものに触れました。しかし、タスクについての話はこれで全部ではありません。さらに詳しくタスクについて知りたい場合は、15章タスク詳解を見てみてください。
Otherwise, continue on to the tutorials in 7章Javaクイックスタート and 8章依存関係管理の基本 .
そうでなければ、7章Javaクイックスタートと8章依存関係管理の基本 に進み、チュートリアルを続けてください。[3] There are command line switches to change this behavior. See 付録D Gradle コマンドラインGradle Command Line)
[4] この動作はコマンドラインスイッチを使用して変更できます。付録D Gradle コマンドラインGradle Command Lineを参照してください。