Gradle入門

# 概要
以下の書籍をもとにGradleの学習をすることになったので、
学んだことをかいつまんで復習用チートシートみたいなものを作成しようと
書いているのがこの記事です。学習が進んだら随時加筆していきます。

参考書籍：[Gradle徹底入門 次世代ビルドツールによる自動化基盤の構築](https://www.shoeisha.co.jp/book/detail/9784798136431)

これから本を買おうかどうか迷っている人向けに、
書籍に関する感想とかも挟んで行きたいなと思ってます。
当方、業務でJavaを触っているのでGroovyを読むのに不便は感じないが
ビルドツールをしっかりと触るのは初めてという感じの人なので、
そういうレベル感の人の感想だと思ってください。

# Hello Gradle!
## ビルドスクリプト(≒タスク)の定義
ビルドスクリプトとは、ビルドに必要なライブラリの定義、
フォルダの定義など様々なビルドに関する情報を書き込むファイル。
(後々、詳細を追記するのでJavaのソースコード(〜.java)程度に捉えておけばOK)

以下、Hello Gradle!を出力するだけのビルドスクリプト。

```gradle:build.gradle
task hello {
  doLast {
    println 'Hello Gradle'
  }
}
```
```gradle:extends.gradle
task hello {
  doLast {
    println 'Hello Gradle Ex'
  }
}
```

## タスクを実行する
Gradleでの基本的な流れは、タスクの定義→タスクの実行となっている。
このうち、タスクの実行を行うのがgradleコマンドである。

以下の例の通り、
オプションなしでgradleコマンドを実行するとデフォルトで
カレントディレクトリのbuilt.gradle内のタスクが読み込まれ、
-b(--build-file)オプションをつけると指定したgradleファイル内のタスクが読み込まれる。

```terminal
# オプションなし
gradle <タスク名>
# オプションあり
gradle --build-file <ビルドスクリプトのパス> <タスク名>
```
```terminal:実行結果
# オプションなし
$ exercise matsushitafuu$ gradle hello

> Task :hello
Hello Gradle

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

# オプションあり
$ exercise matsushitafuu$ gradle --build-file ./extends.gradle hello

> Task :hello
Hello Gradle Ex

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
```

# タスク

## tasks

実行できるタスクを確認したいときは、tasksタスクを実行する。(ややこしい)

```terminal
gradle tasks

> Task :tasks

------------------------------------------------------------
Tasks runnable from root project
------------------------------------------------------------

Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.

Help tasks
----------
buildEnvironment - Displays all buildscript dependencies declared in root project 'exercise'.
components - Displays the components produced by root project 'exercise'. [incubating]
dependencies - Displays all dependencies declared in root project 'exercise'.
dependencyInsight - Displays the insight into a specific dependency in root project 'exercise'.
dependentComponents - Displays the dependent components of components in root project 'exercise'. [incubating]
help - Displays a help message.
model - Displays the configuration model of root project 'exercise'. [incubating]
projects - Displays the sub-projects of root project 'exercise'.
properties - Displays the properties of root project 'exercise'.
tasks - Displays the tasks runnable from root project 'exercise'.

To see all tasks and more detail, run gradle tasks --all

To see more detail about a task, run gradle help --task <task>

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
```

## 組み込みタスク

Gradleには、あらかじめビルドスクリプトが定義された組み込みタスクというものが存在する。
これらは、独自にビルドスクリプトを書かなくとも実行でき、
上記の```gradle tasks```で表示されたタスクは組み込みタスクである。
タスクは、各種プラグインの導入などで追加することもできる。

## properties
自身で設定したプロパティだけでなく、
プラグインやGradleによって暗黙的に設定されたプロパティも確認することができる。
プロパティ周りで知りたいことがあった際に使用するなど。

```
$ exercise matsushitafuu$ gradle properties

> Task :properties

------------------------------------------------------------
Root project
------------------------------------------------------------

allprojects: [root project 'exercise']
ant: org.gradle.api.internal.project.DefaultAntBuilder@4ffe78ba
antBuilderFactory: org.gradle.api.internal.project.DefaultAntBuilderFactory@753d9b9e
〜省略〜
state: project state 'EXECUTED'
status: release
subprojects: []
tasks: task set
version: unspecified

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
```

# コマンドラインオプション
ビルドスクリプトを書いていると、エラーに直面することが多々ある。
こういった場合、スクリプト自体にprintメソッドを書き込んでデバック用のログ出力をする
という方法はあまり効率が良くない。

上記のデバッグ作業に必要な情報を提供するため、Gradleでは、タスク実行時の
ログ出力のレベルを変更できるコマンドラインオプションが備わっている。

デバッグ作業では、情報は多すぎると埋もれ、少なすぎると原因となっている部分が隠れる。
よって、調査手順は出力情報を徐々に増やしていくというのが定石である。

以下は、gradleコマンドに付与するオプションを出力情報の少ない順に紹介していく。

| オプション | 出力される情報 |
| :--- | :--- |
| -i(--info) | ビルドスクリプトのファイル名などの基本情報を出力する |
| -s(--stacktrace) | 例外発生時のみ、ユーザー例外に限りスタックトレースを出力する |
| -S(--full-stacktrace) | 例外発生時のみ、全てのスタックトレースを出力する |
| -d(--debug) | 詳細な情報まで出力されるようになり、例外発生時はスタックトレースも出力する |

# Gradleデーモン
Gradleでは、特に設定を行っていない場合、
gradle XXXを実行するたびにJVMの起動と停止が行われる。
Gradleデーモンを利用すると、JVMのプロセスを常駐させておくことができるので、
起動と停止にかかる時間が省略され、コマンドの実行が早くなる。

デーモンの使用方法には、オプションの指定とプロパティの設定の2つがある。

## オプションの指定
gradleコマンドの実行毎に--daemonオプションをつけて実行する。

```terminal
$ gradle --daemon hello
```

## プロパティの設定
毎回オプションを指定するのが面倒な場合は、プロパティに設定することで
デーモンの起動をデフォルトでONにすることができる。
### ターミナルから直接設定する
ターミナルで以下の記述を実行する。

```terminal
gradle -Dorg.gradle.daemon=true
```

### プロパティファイルに記載する
Gradleをインストールすると、端末のホームディレクトリに.gradleという隠しフォルダが
作成されるので、.gradle直下にgradle.propertiesというファイルを作成する。
プロパティを設定するには、作成したファイルに以下の記載をして保存する。

```properties
org.gradle.daemon=true
```

## デーモンの停止
Gradleデーモンは一定時間経過後に自動的に終了するが、
以下のコマンドで明示的に終了することも可能である。

```terminal
gradle --stop
```

# Gradleラッパー
Gradleのバイナリを自動的にダウンロード、セットアップするための機能。
Gradleラッパーを使用することにより、
ビルドスクリプトの利用者はGradleのインストールなどの初期コストを必要としないため、
導入、利用方法の説明といったツール導入時のコストを削減することができる。

## Gradleラッパーの作成方法
以下のコマンドを実行し、Gradleラッパーのファイル群を作成する。

```terminal
$ gradle wrapper
```

```text:作成されるファイル群
<PROJECT_ROOT>
┝ gradle
│  └ wrapper
│      ┝ gradle-wrapper.jar
│      └ gradle-wrapper.properties
┝ gradlew
└ gradlew.bat
```

利用者は、ビルドスクリプトと同じ階層にgradlewコマンドを配置して実行するだけで
gradleコマンドの利用を開始することが可能になる。

# 感想(CHAPTER 1〜3)

ビルド自動化ツールというだけあって守備範囲が広く、内容を体系立たせるのが難しい。
ひとまずは基礎編までをざっと読むことにする。
書籍が扱うGradleのバージョンが2.1と古いため、
新しい記法が生まれているものや、最悪の場合、バージョンによって使えないものもある。
ドキュメントを参照しながら学習を進めれば問題ないので、
ドキュメントを読む練習にもなっていいと思う。