DroidKaigi 2022のsettings.gradle.ktsを読んでみて、わからなかったことのメモ

# はじめに

DroidKaigi 2022のリポジトリの**settings.gradle.kts**を読んでいました。

https://github.com/DroidKaigi/conference-app-2022/blob/main/settings.gradle.kts

普段シングルプロジェクトで開発を行なっている場合には出会わないようなブロックやメソッドが散りばめられていて、gradle初心者にはかなりの圧迫感がありました。

そこで、自分のメモとして**settings.gradle.kts**に登場する各ブロックやメソッドの意味などをまとめてみました。

参考程度にお読みいただけたら幸いです。

# build.gradleとは

**build.gradle**にはビルドの内容がGroovy言語によって記述されています。
ビルドの内容とは、依存関係や依存関係の解決に使われるMavenなどのリポジトリのことを指します。

# settings.gradleとは

**settings.gradle**は、Gradleによって自動的に生成されるファイルです。
このファイルもまた、Groovy言語によって内容を記述します。
マルチプロジェクトでは、**build.gradle**はプロジェクトごとに複数用意されますが、**settings.gradle**はGradle ビルドごとに必ずひとつの**settings.gradle**のみが実行されます。

つまり、**settings.gradle**には、プロジェクト全体の依存関係の解消に関する内容が記述されています。


# pluginManagement {}

`pluginManagement {}`は、ファイルの最初に記述する必要があります。

通常、`plugins {}`を使ってプラグインを指定した時、Gradleは**Gradle Plugin Portal**を使ってプラグインを解決します。
しかし時には、プライベートなMavenやIvyリポジトリを使ってプラグインを解決したい場合があると思います。
そうした場合に、`pluginManagement{}`内に存在する`repositories{}`を使って、カスタムプラグインリポジトリを指定することができます。

https://docs.gradle.org/current/userguide/plugins.html#sec:custom_plugin_repositories

また、`resolutionStrategy {}`を使用することで、特定のプラグインを`plugins{}`で使用可能なID名に変換して解決するといったことも可能になります。

https://star-zero.medium.com/gradle%E3%81%AEversion-catalog%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E7%AE%A1%E7%90%86-eb81f8e88444

https://star-zero.medium.com/gradle%E3%81%AEresolutionstrategy-dc948fb05b54


`includeBuild()`を使うことで、第一引数に指定したパスに含まれるプラグインビルドをComposite Buildにインクルードすることができます。
インクルードされたプラグインビルドは、設定の共通化に寄与したり、プロジェクトプラグインとしての機能を提供してくれます。

## Composite Buildとは

公式ドキュメントには次のように書かれています。

> A composite build is simply a build that includes other builds. In many ways a composite build is similar to a Gradle multi-project build, except that instead of including single projects, complete builds are included.

つまり、他のビルドを含むビルドのことをComposite Buildと呼びます。そして複数のプロジェクトがインクルードされているわけではなく、完全なビルドがインクルードされています。そして、このインクルードされているビルドのことを**Included Build**と呼びます。それぞれの**Included Build**は互いに独立していて、設定も共有されていませんし個別に実行されるものです。

https://qiita.com/irgaly/items/b735b61ff73d43e8741d#composite-build-%E3%81%AE%E5%B0%8E%E5%85%A5

https://docs.gradle.org/current/userguide/composite_builds.html

# enableFeaturePreview()

`enableFeaturePreview()`は実験的機能を有効にしたい場合に使用します。

例えば、`enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")`は、型安全性の提供とIDEでのコード補完を可能にしてくれるプロジェクトアクセサとして実験的機能を有効化します。

これにより、以前は`project(":some:path")`で参照していたものを`projects.some.path`で参照できるようになります。

https://docs.gradle.org/7.0/release-notes.html

# dependencyResolutionManagement{}

`dependencyResolutionManagement{}`を使用すると、慣習的に各**build.gradle**で宣言されていたリポジトリを１箇所で中央集権的に宣言することができます。そしてデフォルトでは、各プロジェクトで宣言されたリポジトリの設定は、`dependencyResolutionManagement{}`での設定を上書きします。この設定は変更することもできます。

# include()

`include()`を使って、ビルドに含めるプロジェクトを指定することができます。このパスに指定するのは絶対パスや相対パスといったファイルベースのパスではなく、プロジェクトのヒエラルキー上のパスを指定します。そのため、区切りには`:`を使います。

パスの最後の要素がプロジェクト名として使用されます。例えばパスが`:a:b`なら、`b`がプロジェクト名として採用されます。

例えば、`include(":a:b")`を呼び出した場合、次のような構成になります。

|ラベル|実際の値|
|---|---|
|パス|`:a:b`|
|名前|`b`|
|プロジェクトディレクトリ|`$rootDir/a/b`|

`project().projectDir`を使うことで、プロジェクトディレクトリを任意のものに変更することができます。

```groovy
include(":appioscombined")

project(":appioscombined").projectDir = file("app-ios-combined")

```

https://waman.hatenablog.com/entry/2014/05/25/064736

# まとめ

Gradleは一見すると難しそうに見えますが、やっていることはとてもシンプルなので理解度次第でハードルは一気に下がるんだろうなと思いました。まる。

# 参考にした記事

https://zenn.dev/aa/articles/4ee69840056ac4

https://www.baeldung.com/gradle-build-settings-properties