Как повторно использовать части конфигурации Android в Kotlin Gradle DSL для нескольких модулей?

У меня есть многомодульный проект Android и Kotlin Gradle DSL. Есть некоторая конфигурация, которую нужно повторять в каждом модуле, и я хотел бы повторно использовать код. Я бы хотел, например, повторно использовать этот код:

android {
    sourceSets {
        getByName("main").java.srcDirs("src/main/kotlin")
        getByName("test").java.srcDirs("src/test/kotlin")
    }
}

В примерах Kotlin DSL описаны два метода:

apply(from = "foo.gradle.kts")

и функции расширения в buildSrc, например:

fun Project.kotlinProject() {
   dependencies {
     "compile"(kotlin("stdlib"))
   }
}

Однако оба эти метода работают только для конфигурации верхнего уровня, я не могу получить доступ к материалам плагина Android. Я получаю такие ошибки, как Unresolved reference: BaseExtension


person David Vávra    schedule 28.12.2018    source источник


Ответы (2)


В конце концов меня вдохновил код SUPERCILEX:

allprojects {
    val parent = (group as String).split(".").getOrNull(1)
    when {
        name == "app" -> {
            apply(plugin = "com.android.application")
            configureAndroidModule()
        }
        parent == "common-android" -> {
            apply(plugin = "com.android.library")
            configureAndroidModule()
        }
    }
}

fun Project.configureAndroidModule() {
    configure<BaseExtension> {
        sourceSets {
            getByName("main").java.srcDirs("src/main/kotlin")
            getByName("test").java.srcDirs("src/test/kotlin")
        }
    }
}​
person David Vávra    schedule 02.01.2019

Как насчет использования блока подпроектов? У меня есть многомодульный Android-проект, и именно так я повторно использую код в своих сценариях сборки.

subprojects {
    apply plugin: 'com.android.library'
    android {
        sourceSets {
            getByName("main").java.srcDirs("src/main/kotlin")
            getByName("test").java.srcDirs("src/test/kotlin")
        }
    }
}

Неразрешенная ссылка: BaseExtension

Что касается приведенного выше сообщения об ошибке, если вы хотите использовать блок Android, вы должны объявить свои модули как приложение или библиотеку Android, применив плагины, подобные приведенному выше сценарию сборки.

Если вы хотите, чтобы настройки повторялись только в некоторых модулях, вы можете использовать такой блок настройки:

configure(subprojects - project(':${module_name}')) {
    dependencies {
        implementation 'com.x.y.z:abc:1.0.0'
    }
}

Вышеупомянутый блок будет определять зависимость для всех модулей, кроме модуля с данным именем.

person CoderSpinoza    schedule 28.12.2018
comment
Я не могу использовать блок подпроектов, потому что общая конфигурация должна применяться только к библиотекам Android, у меня также есть библиотеки только для Java и приложение. Я попробовал блок настройки с исключением модулей JVM и приложения. Но все та же проблема - неразрешенные ссылки на материалы Android, даже если я использую плагин com.android.library. - person David Vávra; 29.12.2018