Gradleについてちょこっと調べて、Spring Initializrで生成されたbuild.gradleを読む

[Spring Boot + MySQLでシンプルなWeb REST APIサーバを実装する - Qiita](https://qiita.com/YutaKase6/items/007f6b7d12d342c1330c)

# Outline
Spring Initializrで自動生成されたbuild.gradleを読んでみる。  
読むためにGradleをちょっと調べる。

# References
[Gradle Build Tool](https://gradle.org/)
[Gradle User Guide](http://gradle.monochromeroad.com/docs/userguide/userguide.html)

# What is Gradle
<img width=512 src="https://qiita-image-store.s3.amazonaws.com/0/90526/821fcc2a-e645-a895-ec7c-ab515b6399f8.png">

[第1章 はじめに](http://gradle.monochromeroad.com/docs/userguide/introduction.html)
> Gradleは、Java(JVM)環境におけるビルドシステム

mavenの代わりに使う。
依存ライブラリのインポートや、コンパイル、jar生成とかテスト実行とかいろいろやってくれる。  

# Install
IntelliJを利用している場合、一緒にインストールされてる。
Homebrewでもインストールできる。
私の環境ではここにあった。

```
% ~/.gradle/wrapper/dists/gradle-4.5.1-bin/a5vbgfvpwtoqz8v2cdivxz28k/gradle-4.5.1/bin/gradle -v  

------------------------------------------------------------
Gradle 4.5.1
------------------------------------------------------------

Build time:   2018-02-05 13:22:49 UTC
Revision:     37007e1c012001ff09973e0bd095139239ecd3b3

Groovy:       2.4.12
Ant:          Apache Ant(TM) version 1.9.9 compiled on February 2 2017
JVM:          1.8.0_162 (Oracle Corporation 25.162-b12)
OS:           Mac OS X 10.13.3 x86_64
```

# build.gradle
基本的にこのファイルを編集する。pom.xmlみたいなもん。
プロジェクトの作成によって自動生成されたものがこちら。

```build.gradle
buildscript {
    ext {
        springBootVersion = '2.0.2.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.springframework.boot:spring-boot-starter-web')
    runtime('mysql:mysql-connector-java')
    compileOnly('org.projectlombok:lombok')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}
```

上から順番に何が書いてあるのか見ていく。

# buildscript
依存関係を解決するgradle.build自身の依存関係を解決するためのブロック。
Spring Bootで生成したGradleプロジェクトはどうやらSpring BootのGradleプラグインを使うらしい。

## ext
変数宣言するとこ。

## repositories
依存ライブラリのリポジトリを指定するとこ。
MavenのCentralリポジトリを指定している。  
URLでの指定方法はこんな感じ。

```gradle
repositories {
    maven {
        url 'https://repo.spring.io/libs-snapshot'
    }
}
```
[第51章 依存関係の管理](http://gradle.monochromeroad.com/docs/userguide/dependency_management.html#sec:repositories)

## dependencies
ライブラリを指定するとこ。
springbootのgradleプラグインを使ってるんだね。

# apply
プラグインを宣言するとこ。  
この二つがspring Bootに依存してるプラグイン。

```gradle
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
```

## org.springframework.boot
こんなが追加されてた。

```
Application tasks
-----------------
bootRun - Runs this project as a Spring Boot application.
```
アプリケーションの実行までやっちゃうタスク。
これでSpring Bootのアプリケーションを起動できるね。

## io.spring.dependency-management
こいつがすごそう。
Maven の BOM (bill of materials) という仕組みを再現するプラグイン。
### ※BOM (bill of materials)
各ライブラリが自身の依存関係を定義する仕組み。
要は使いたいライブラリがあったら、そのライブラリとそのライブラリのBOMを記述すれば使えるよ。

Gradleには残念ながらこの仕組みが無い。
このプラグイン使えばできる。

ただ、今回のbuild.gradleではBOMを使ってない。

実際使うときは以下のようなブロックで使う。
spring-cloud-streamの例

```gradle
dependencyManagement {
     imports {
          mavenBom 'org.springframework.cloud:spring-cloud-stream-dependencies:Fishtown.BUILD-SNAPSHOT'
     }
}
```

#  成果物関係
バージョンとかはここで運用していく
いっちゃん下のはjdkのversion

```gradle
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
```

# repositories
buildscriptのやつと一緒

# dependencies
依存ライブラリを記述。
先頭に書いてあるのはconfigurationって呼ばれてる。
[第23章 Javaプラグイン](http://gradle.monochromeroad.com/docs/userguide/java_plugin.html#tab:configurations)

|名前 | 拡張元 | 利用するタスク | 意味|
|:--: | :--: | :--: | :-- |
|compile | - | compileJava | コンパイル時の依存関係|
|runtime | compile | - | 実行時の依存関係|
|testCompile | compile | compileTestJava | テストのコンパイル時の追加依存関係|
|testRuntime | runtime, testCompile | test | テストの実行時の追加依存関係|
|archives | - | uploadArchives | このプロジェクトが生成するアーティファクト(jarファイルなど)|
|default | runtime | - | このプロジェクトに依存するプロジェクトが使用する、デフォルトのコンフィグレーション。アーティファクトと、このプロジェクトが実行時に要求する依存関係が含まれる。|
<img width=512 src="https://qiita-image-store.s3.amazonaws.com/0/90526/aa661e2c-87aa-fe78-1859-974423403a5f.png">

書き方は以下のように他にもいろいろある。

```gradle
dependencies {
    runtime group: 'org.springframework', name: 'spring-core', version: '2.5'
    runtime 'org.springframework:spring-core:2.5',
            'org.springframework:spring-aop:2.5'
    runtime(
        [group: 'org.springframework', name: 'spring-core', version: '2.5'],
        [group: 'org.springframework', name: 'spring-aop', version: '2.5']
    )
    runtime('org.hibernate:hibernate:3.0.5') {
        transitive = true
    }
    runtime group: 'org.hibernate', name: 'hibernate', version: '3.0.5', transitive: true
    runtime(group: 'org.hibernate', name: 'hibernate', version: '3.0.5') {
        transitive = true
    }
}
```

# おまけ
## Hello World
しょせんこいつはスクリプトなのです。

```
% cat build.gradle
task hello {
    doLast {
        println 'Hello world!'
    }
}

% gradle hello 

> Task :hello
Hello world!


BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

```