Skip to content

Instantly share code, notes, and snippets.

@sahara-ooga
Last active December 19, 2019 04:59
Show Gist options
  • Save sahara-ooga/d0e63235dbc0cfb3d2a4f5db54514e54 to your computer and use it in GitHub Desktop.
Save sahara-ooga/d0e63235dbc0cfb3d2a4f5db54514e54 to your computer and use it in GitHub Desktop.
Kotlinメモ

gradleをgroovyからkotlinスクリプトファイルに置き換える

前準備

以下の正規表現で、Kotlin移行の準備をする。

文字列リテラルの扱い

groovyでは、文字列リテラルは'"のどちらかで文字列を囲むことになっており、Kotlinは後者しか認められていないため、前者から後者へ置き換える。

置換対象: '([^']+)'

置換後: "$1"

### メソッド呼び出し

置換対象: (classpath|delete) (\S+)

置換後: $1($2)

ただし、app/build.gradleではこれではたりず、

(\w+(?:ion|Files)) (.+)$

で候補を一個一個見ていくのが確実。

plugins

apply plugin: "com.android.application"
apply plugin: "kotlin-android-extensions"
apply plugin: "kotlin-android"
apply plugin: "com.github.gfx.ribbonizer"
plugins {
    id("com.android.application")
    id("kotlin-android-extensions")
    id("kotlin-android")
    id("com.github.gfx.ribbonizer")
}

ファイル名変更

プロジェクトナビゲーターでShift F6

完成品

一部ぼかしています

plugins {
    id("com.android.application")
    id("kotlin-android-extensions")
    id("kotlin-android")
    id("com.github.gfx.ribbonizer")
}

android {
    compileSdkVersion(28)

    defaultConfig {
        applicationId = "com.example.kotlin-script"
        minSdkVersion(25)
        targetSdkVersion(29)
        versionCode = 1
        versionName = "1.0.0"
        vectorDrawables.useSupportLibrary = true
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

        /**
        *実機インストール用にSigningConfigsの設定が必要!
        */
        signingConfigs {
            getByName("debug") {
                storeFile = getDefaultDebugKeystoreLocation()
            }
            register("release") {
                storeFile = getDefaultDebugKeystoreLocation()
            }
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
//    kotlinOptions {
//        jvmTarget = "1.8"
//    }
    buildTypes {
        getByName("debug") {
            //デバッグ時のインストールでは、アプリケーションIDを分ける
            //Google Play Store版、リリースビルドと共存するため
            applicationIdSuffix = ".debug"

            //バージョン名に区別をつける
            versionNameSuffix = "debug"

            signingConfig = signingConfigs.getByName("debug")
        }

        getByName("release") {
            //圧縮、難読化、最適化の有効化
            //公開前にテストするアプリの最終バージョンをビルドするときに有効にする
            // Enables code shrinking, obfuscation, and optimization for only
            // your project's release build type.
            isMinifyEnabled = true

            // Enables resource shrinking, which is performed by the
            // Android Gradle plugin.
            isShrinkResources = true

            // Includes the default ProGuard rules files that are packaged with
            // the Android Gradle plugin.
            proguardFiles(
                    getDefaultProguardFile("proguard-android-optimize.txt"),
                    "proguard-rules.pro"
            )
            /**実機インストール用に必要な設定*/
            signingConfig = signingConfigs.getByName("release")
        }
    }

    aaptOptions {
        noCompress("tflite")
        noCompress("lite")
    }
    testOptions {
        unitTests.isReturnDefaultValues = true
        unitTests.isIncludeAndroidResources = true
    }
//    sourceSets {
//        getByName(test).java.srcDirs( "src/test/kotlin")
//        androidTest.java.srcDirs += "src/androidTest/kotlin"
//    }
    lintOptions {
        isAbortOnError = false
    }
}

/*
* ribbonizerは、必要なインターフェイスが`public`になっていないため、`withGroovyBuilder`で囲む必要がある
*/
ribbonizer {
    withGroovyBuilder {
        "builder"(com.github.gfx.ribbonizer.FilterBuilder { variant, iconFile ->
            return@FilterBuilder when (variant.buildType.name) {
                "debug" -> com.github.gfx.ribbonizer.GrayRibbonBuilder().apply(variant, iconFile)
                else -> com.github.gfx.ribbonizer.GreenRibbonBuilder().apply(variant, iconFile)
            }
        })
    }
}

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

    // Layout
    implementation("androidx.appcompat:appcompat:1.1.0")
    implementation("androidx.constraintlayout:constraintlayout:1.1.3")
    implementation("com.google.android.material:material:1.0.0")

    //kotlin
    val ktxVersion = "1.1.0"
    val kotlinVersion: String by project
    implementation("androidx.core:core-ktx:$ktxVersion")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion")
    implementation("androidx.activity:activity-ktx:$ktxVersion-rc02")
    implementation("androidx.fragment:fragment-ktx:$ktxVersion")

    //tensorflow
    implementation("org.tensorflow:tensorflow-android:1.13.1")
    implementation("org.tensorflow:tensorflow-lite:0.0.0-nightly")
    implementation("org.tensorflow:tensorflow-lite-gpu:0.0.0-nightly")

    // Android Architecture Components
    val lifecycleVersion = "2.1.0"
    implementation("androidx.lifecycle:lifecycle-extensions:$lifecycleVersion")
    implementation("androidx.lifecycle:lifecycle-runtime:$lifecycleVersion")
    //annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
    //according to inspection suggestion and official site ( https://developer.android.com/jetpack/androidx/releases/lifecycle )
    implementation("android.arch.lifecycle:common-java8:$lifecycleVersion")

    //viewmodel-ktx viewModelScopeを使うため
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion")

    // retrofit
    implementation("com.squareup.retrofit2:retrofit:2.6.2")

    // OkHttp
    implementation("com.squareup.okhttp3:okhttp:4.2.2")
    implementation("com.squareup.okhttp3:logging-interceptor:4.2.2")

    // gson
    implementation("com.google.code.gson:gson:2.8.6")
    implementation("com.squareup.retrofit2:converter-gson:2.6.2")

    //Kotlin Coroutines
    val coroutineVersion = "1.3.2"
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutineVersion")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutineVersion")

    //test
    testImplementation("junit:junit:4.12")
    testImplementation("io.kotlintest:kotlintest:2.0.7")
    testImplementation("org.robolectric:robolectric:4.3.1")
    testImplementation("org.assertj:assertj-core:3.14.0")
    testImplementation("com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0")
    //openがついていないクラスをモックするため
    testImplementation("org.mockito:mockito-inline:3.2.0")
    //for testing LiveData
    testImplementation("androidx.arch.core:core-testing:$lifecycleVersion")

    //for testing activity and context
    testImplementation("androidx.test.ext:junit:1.1.1")
    testImplementation("androidx.test:runner:1.2.0")
    testImplementation("androidx.test:rules:1.2.0")
    testImplementation("androidx.test.espresso:espresso-core:3.2.0")
    testImplementation("org.robolectric:robolectric:4.3.1")
    testImplementation("com.google.truth:truth:1.0")

    //for debug coroutine
    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-debug:$coroutineVersion")
    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutineVersion")

    /**中略**/

}
repositories {
    mavenCentral()
}

Reference

今回のきっかけになった発表。

Let's migrate to build.gradle.kts - Speaker Deck

DroidKaigi 2019 - build.gradle.kts に移行しよう / tnj [JA] - YouTube

全体的に参考になった記事

build.gradle.ktsへの書き換えとハマリポイント part 2 - Qiita

AndroidのGradleでKotlin DSLを使う

Kotlin DSLを理解してみる / Understanding Kotlin DSL - Speaker Deck

The New Way of Writing Build Gradle with Kotlin DSL

Androidのビルドシステム自体の記事

Androidプロジェクトのビルドシステムを理解するのに役立ったサイト一覧 - Qiita

SigningConfigsのヒントになった

Converting your Android Gradle scripts to Kotlin

実例系

gradle/kotlin-dsl-samples: Samples builds using the Gradle Kotlin DSL

build.gradle.kts.diff

Gists Gradle-Kotlin-DSL

fun main() {
println("a" to "b")
}
//レシーバー指定のラムダ式
data class Fruit(val name: String, val num: Int)
fun foo(lambda: Fruit.() -> Unit) {
val apple = Fruit("りんご", 10)
apple.lambda()
}
fun main() {
foo {
println("${this.name}が${this.num}個あります。")
println("${name}が${num}個あります")
}
val apple = Fruit("りんご", 10)
with(apple) {
println("${name}を${num}個ほしい!")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment