Androidアプリ開発探求記（その７）

# 概要
今回は、*buildSrc* を導入しつつ、*build.gradle* を *build.gradle.kts* に書き換えてみようと思います。

# 現行ソース
## ◆ build.gradle
[source](https://github.com/beyondseeker/chrono0015/blob/c5009917501cbce49fc31e86a793000026071b85/build.gradle)

```grooby
buildscript {
    // 『この位置』でのバージョン情報定義は、結構他の多くのプロジェクトでも踏襲してるっぽい。
    //
    // - mockk(https://github.com/mockk/mockk/blob/master/build.gradle)の場合は結構愚直にやってる。
    //
    // - picasso(https://github.com/square/picasso/blob/master/build.gradle)の場合は
    //   ext.versions = [..] と ext.deps = [..] に分けている。
    //
    // - kotlinpoet(https://github.com/square/kotlinpoet/blob/master/buildSrc/src/main/java/Dependencies.kt)の場合は
    //   buildSrc を利用して version, deps を定義している。picasso の方式を buildSrc に移行しただけっぽい感じですね。
    //
    ext.kotlin_version = "1.3.72"

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.0.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
```

## ◆ app/build.gradle
[source](https://github.com/beyondseeker/chrono0015/blob/c5009917501cbce49fc31e86a793000026071b85/app/build.gradle)

```groovy
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 29

    defaultConfig {
        applicationId "com.objectfanatics.chrono0015"
        minSdkVersion 23
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

    compileOptions {
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }
}

dependencies {
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'

    implementation fileTree(dir: "libs", include: ["*.jar"])

    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"

    testImplementation 'junit:junit:4.12'

    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
}
```

# kts化＆buildSrc 適用後

[diff](https://github.com/beyondseeker/chrono0015/commit/bbc487f44d7908ba68ef9f5024174ab73e397435)

## ◆ build.gradle.kts
[source](https://github.com/beyondseeker/chrono0015/blob/bbc487f44d7908ba68ef9f5024174ab73e397435/build.gradle.kts)

```kotlin:build.gradle.kts
buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath("com.android.tools.build:gradle:4.0.1")
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}")
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task("clean", Delete::class) {
    delete = setOf(rootProject.buildDir)
}
```

## ◆ app/build.gradle.kts
[source](https://github.com/beyondseeker/chrono0015/blob/bbc487f44d7908ba68ef9f5024174ab73e397435/app/build.gradle.kts)

```kotlin:app/build.gradle.kts
plugins {
    id("com.android.application")
    // TODO: この extension って逆にわかりづらい気がする。
    kotlin("android")
    id("kotlin-android-extensions")
}

android {
    compileSdkVersion(29)

    defaultConfig {
        applicationId = "com.objectfanatics.chrono0015"
        minSdkVersion(23)
        targetSdkVersion(29)
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        getByName("release") {
            isMinifyEnabled = false
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }

    compileOptions {
        coreLibraryDesugaringEnabled = true
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.0.10")

    implementation(fileTree("dir" to "libs", "include" to listOf("*.jar")))

    implementation("androidx.appcompat:appcompat:1.1.0")
    implementation("androidx.constraintlayout:constraintlayout:1.1.3")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}")

    testImplementation("junit:junit:4.12")

    androidTestImplementation("androidx.test.espresso:espresso-core:3.2.0")
    androidTestImplementation("androidx.test.ext:junit:1.1.1")
}
```

## ◆ Dependencies.kt
[source](https://github.com/beyondseeker/chrono0015/blob/bbc487f44d7908ba68ef9f5024174ab73e397435/buildSrc/src/main/java/Dependencies.kt)

```kotlin:buildSrc/src/main/java/Dependencies.kt
// - kotlinpoet(https://github.com/square/kotlinpoet/blob/master/buildSrc/src/main/java/Dependencies.kt)の場合は
//   buildSrc を利用して version, deps を定義している。picasso の方式を buildSrc に移行しただけっぽい感じですね。
object versions {
    const val kotlin = "1.3.72"
}

// TODO: 要検討
//object deps {
//}
```

# 懸念点

現在、以下のように *PluginDependenciesSpec* の extension を用いた個所があります。

```kotlin
plugins {
    id("com.android.application")
    // TODO: この extension って逆にわかりづらい気がする。
    kotlin("android")
    id("kotlin-android-extensions")
}
```

しかし、個人的な感覚としては、以下のような id 指定のほうが分かりやすいような気がします。

```kotlin
plugins {
    id("com.android.application")
    // TODO: こっちのほうが分かりやすいように思える。
    id("org.jetbrains.kotlin.android")
    id("kotlin-android-extensions")
}
```

extension を利用するメリットとしては、コードが短くなることや、コンパイルエラーにならない typo の発生を抑えるなどがあると思います。

しかし、下記 *deps* のような仕組みを設けてしまえば、IDEのコード補完により extension を利用するメリットはほぼ無くなるような気がします。

```kotlin:buildSrc/src/main/java/Dependencies.kt
object versions {
    const val kotlin = "1.3.72"
}

// TODO: 要検討
//object deps {
//}
```

*deps* 側での extension の利用に関しては、extension が *buildSrc* 側からデフォルトで参照できないことや、id で揃ったほうが右脳の処理負荷が圧倒的に少ない(おいら調べ)という点で、やはり、extension を利用するメリットを感じません。

# まとめ
今回は、*buildSrc* を導入しつつ、*build.gradle* を *build.gradle.kts* に書き換えてみました。

次回は、前出の懸念点について対応してみようと思います。