Gradleってなんだ？JavaやKotlinのビルドってどうやっているの？

# Gradleとは？
Gradleは、主にJava，Kotlin，ScalaのようなJVMベースの言語で開発されたソフトウェアプロジェクトの**ビルド自動化ツール**．実はPythonやC++にも対応している．

:::note info
**ビルドツールとは**
ビルドツールとは、以下のようなプログラムのビルドや実行を自動化するツールのこと．
 - 必要なライブラリのインストール
 - コンパイル
 - オートテスト
 - パッケージ(Jarファイル)の作成
 - 実行
:::

# なんで作られたのか
Antや Maven などの従来のビルドツールの欠点を克服するために開発された．

### Antの欠点
 - **XMLベースの設定**
Antは、XMLを使用してビルドスクリプトを記述する．XMLは冗長で読みにくく，大規模なプロジェクトではスクリプトが複雑になりがち...また，スクリプトのロジックを表現するために，XMLにカスタムタスクを埋め込む必要がある．
   
 - **依存関係管理の欠如**
Antには、依存関係管理のための組み込みの仕組みがない．外部ライブラリの依存関係を手動で管理する必要があり，バージョン競合の解決が難しい．

 - **拡張性の制限**
Antはカスタムタスクを作成することで拡張できるが，プラグインシステムが限定的．ビルドロジックの再利用性が低く，プロジェクト間での設定の共有が難しくなる．

### Mavenの欠点
 - **設定の複雑さ**
MavenはXMLベースのプロジェクト設定（pom.xml）を使用する．設定ファイルが大きくなりがちで，読みにくくなることがある．設定の柔軟性が限られており，プロジェクト固有の要件に対応するのが難しい場合がある．
 - **固定的なプロジェクト構造**
Mavenは，規約に基づいたプロジェクト構造を強制する．規約から外れるプロジェクトでは，設定が複雑になり，保守性が低下する．

 - **ビルドのパフォーマンス**
Mavenは，インクリメンタルビルドのサポートが限定的．大規模なプロジェクトでは，ビルド時間が長くなる傾向がある．

 - **プラグインの制限**
Mavenのプラグインは，設定が複雑で，カスタマイズが難しい．プラグインの実行順序を細かく制御することが困難．

これらの欠点に対して，Gradleは次のような機能が実装された．
 - 読みやすく柔軟なビルドスクリプト（Groovy/Kotlin DSL）
 - 強力な依存関係管理
 - 豊富なプラグインエコシステムと高い拡張性
 - 優れたビルドパフォーマンスとインクリメンタルビルドのサポート
 - 柔軟なプロジェクト構造

:::note info
GradleはGroovyで作成されている．
:::


# Gradleの主要ファイル
Gradleのスクリプトは，Groovy（または Kotlin）で記述され，プロジェクトの設定と構成を定義する．主要なスクリプトファイルは以下の通りである．

### settings.gradle（settings.gradle.kts)
マルチプロジェクトビルドの構成を定義する．ビルドに含まれるサブプロジェクトを指定する．

### build.gradle（build.gradle.kts)
各プロジェクトのビルド設定を定義する．プラグインの適用，依存関係の宣言，タスクの定義などを行う．必要に応じて，カスタムタスクや拡張機能を追加できる．

# Gradleの実行のステップ
Gradleのビルドプロセスは、以下の主要なステップで構成されている．
 - **1．初期化フェーズ**
Gradleは，ビルドを実行するために必要なプロジェクト情報を収集する．`settings.gradle（Kotlinの場合はsettings.gradle.kts）`ファイルを読み込み，ビルドに含まれるプロジェクトとそのサブプロジェクトを特定する．その後，ビルドスクリプト`build.gradle / build.gradle.kts`の場所を決定する．

 - **2．設定フェーズ**
Gradleは，各プロジェクトのビルドスクリプトを評価し，プロジェクトオブジェクトを構築する．ビルドスクリプトには，プロジェクトの設定，依存関係，タスクの定義などが含まれる．各プロジェクトに対して，適用されるプラグインや設定が処理される．タスク間の依存関係が解決され，タスクのグラフが作成される．

 - **3．実行フェーズ**
コマンドラインで指定されたタスクや，タスクの依存関係に基づいて，タスクが実行される．
各タスクは，定義されたアクションを実行する（コンパイル、テスト、Jarの作成など）その後，タスクの実行結果が出力され，ビルドの成功または失敗が出力される．

# Gradleのインストール
```bash
brew install gradle
```
# Gradleのよく使うコマンド集
プロジェクトのルートディレクトリ（build.gradleファイルがある場所）で実行する．

:::note warn
Windows環境では，`./gradlew`の代わりに`gradlew`を使用してほしい．
:::


###タスクの実行
```
./gradlew <タスク名>
```
:::note info
プロジェクトのビルドを実行
```
./gradlew build 
```
:::

### プロジェクトのクリーン
ビルドディレクトリを削除し、プロジェクトをクリーンな状態にする．
```
./gradlew clean
```

### 依存関係のリスト
プロジェクトの依存関係をツリー形式で表示する．
```
./gradlew dependencies
```

### タスクのリスト
プロジェクトで利用可能なタスクを一覧表示する．
```
./gradlew tasks
```

### テストの実行
プロジェクトのテストを実行する．
```
./gradlew test
```
:::note info
**特定のテストの実行**
特定のテストクラスを実行する．
```
./gradlew test --tests <テストクラス名>
```
:::


### Gradleバージョンの確認
現在使用しているGradleのバージョンを表示する．
```
./gradlew --version
```

### ヘルプの表示
Gradleのヘルプ情報を表示する．
```
./gradlew help
```

### 依存関係のアップデートチェック
プロジェクトの依存関係のアップデートを確認する．
```
./gradlew dependencyUpdates
```

### プロジェクトのJavadoc生成
プロジェクトのJavadocを生成する．
```
./gradlew javadoc
```

# PythonでGradleを使ってみよう
## JDKをインストール
Java Development Kit (JDK) をインストール
https://docs.oracle.com/javase/jp/13/install/overview-jdk-installation.html

## Gradleをインストール
macなら
```bash
brew install gradle
```
windowsなら
https://gradle.org

## build.gradleの作成
Pythonプロジェクトのルートディレクトリに，`build.gradle`ファイルを作成する．
```bash
touch build.gradle
```
中身を以下のようにする．
```groovy
plugins {
    id 'com.palantir.python' version '0.4.0'
}

python {
    version = '3.8'
    pip {
        requirements = ['requirements.txt']
    }
}

task runApp(type: PythonTask) {
    script = 'src/main.py'
}
```

## Pythonファイルを作成
以下のようなディレクトリ構造にして作成する．
```
project/
├── build.gradle
├── requirements.txt
└── src/
    └── main.py
```
:::note info
`requirements.txt`にPythonの依存関係を書く．
:::


## ビルドと実行
Gradleコマンドを使ってPythonプロジェクトをビルドおよび実行する．
```
./gradlew pythonSetup
./gradlew runApp
```