Slackbot
02/15/2022, 8:22 PMtony
02/15/2022, 8:33 PMplugins { ... }
?Vampire
02/15/2022, 8:34 PMproject.apply
instead of project.pluginManager.apply
2. You only get type-safe accessors for plugins you apply using the plugins { }
DSL. Using the legacy API you use to apply your own plugin does not work for that. If you insist on applying your custom plugin the legacy way, you have to use the cumbersome way for configuring extensions like configure<WhateverClassTheAndroidExtensionWas> { ... }
instead of android { ... }
. But preferable is to apply your custom plugin using the plugins { }
dslAlexander Gherschon
02/15/2022, 8:35 PMVampire
02/15/2022, 8:37 PMAlexander Gherschon
02/15/2022, 8:38 PMVampire
02/15/2022, 8:38 PMAlexander Gherschon
02/15/2022, 8:38 PMAlexander Gherschon
02/15/2022, 9:01 PMopen class ConvenientLibraryPlugin : Plugin<Project> {
@Suppress("UNCHECKED_CAST")
override fun apply(project: Project) {
project.plugins.apply("com.android.library")
project.plugins.apply("org.jetbrains.kotlin.android")
// first test
val androidComponents = project.extensions.getByType(AndroidComponentsExtension::class.java)
androidComponents.finalizeDsl { extension ->
extension.apply {
compileSdk = 31
defaultConfig.apply {
minSdk = 23
// targetSdk = 31 <- Unknown here
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
//consumerProguardFiles("<http://consumer-rules.pro|consumer-rules.pro>") <- Unknown here
}
}
}
// second try getting the extension and setting the DSL here
val extension = project.extensions.getByName("android")
val libraryExtension = extension as AndroidComponentsExtension<LibraryExtension, LibraryVariantBuilder, LibraryVariant>
libraryExtension.finalizeDsl { extension ->
extension.apply {
compileSdk = 31
defaultConfig.apply {
minSdk = 23
targetSdk = 31
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("<http://consumer-rules.pro|consumer-rules.pro>")
}
}
}
}
}
Alexander Gherschon
02/15/2022, 9:02 PMAndroidComponentsExtension<LibraryExtension, LibraryVariantBuilder, LibraryVariant>
if you’re asking me, but couldn’t find a way to get the right object out of project.extensions
Alexander Gherschon
02/15/2022, 9:04 PMbuild.gradle.kts
:
apply<il.co.galex.convenience.plugin.ConvenientLibraryPlugin>()
android {
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "<http://proguard-rules.pro|proguard-rules.pro>")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation("androidx.core:core-ktx:1.7.0")
implementation("androidx.appcompat:appcompat:1.3.0")
implementation("com.google.android.material:material:1.4.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
}
Alexander Gherschon
02/15/2022, 9:05 PMandroid {}
extension there, but I’d like to setup the common ones for many modules in the Gradle Plugin itselfVampire
02/15/2022, 9:10 PMapply()
way, then you don't get accessors like android { ... }
.
You need to apply your plugin using the plugins { ... }
DSL to get those accessors generated as described above.
Within your plugin, you should not use project.plugins.apply
, but project.apply
as also written above.
Within your plugin, you can do configure<AndroidComponentsExtension<LibraryExtension, LibraryVariantBuilder, LibraryVariant>> { ... }
to get the extension by type without the need to cast as also already described above.
If you want to do android { ... }
within your plugin, you have to either create that accessor yourself, of you have to switch from a full Kotlin class plugin to a precompiled script plugin.
Those are looking almost exactly like normal build scripts and there you also get the accessors generated.Alexander Gherschon
02/15/2022, 9:13 PMAlexander Gherschon
02/16/2022, 12:10 PMbuild.gradle
:
plugins {
id("il.co.galex.library")
}
dependencies {
implementation("androidx.core:core-ktx:1.7.0")
implementation("androidx.appcompat:appcompat:1.3.0")
implementation("com.google.android.material:material:1.4.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.3")
androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0")
}
And here is the Gradle Plugin:
open class ConvenientLibraryPlugin : Plugin<Project> {
override fun apply(project: Project) {
with(project) {
apply {
it.plugin("com.android.library")
it.plugin("org.jetbrains.kotlin.android")
}
extensions.configure(LibraryExtension::class.java) { libExtension ->
libExtension.apply {
compileSdk = 31
defaultConfig {
minSdk = 23
targetSdk = 31
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("<http://consumer-rules.pro|consumer-rules.pro>")
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "<http://proguard-rules.pro|proguard-rules.pro>")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
// doesn't work
// kotlinOptions {
// jvmTarget = "1.8"
// }
}
}
}
}
}
So the only missing piece is how do I get to have a kotlinOptions
in that extension? I guess it has to do with importing the gradle-plugin
and configuring the tasks of type KotlinCompile
maybe?Vampire
02/16/2022, 1:10 PMkotlinOptions
is an accessor that you don't get generated for that type of plugins.
So you again use a configure
call with type.
So what you want is probably this:
import com.android.build.api.dsl.LibraryExtension
import org.gradle.api.JavaVersion
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
open class ConvenientLibraryPlugin : Plugin<Project> {
override fun apply(project: Project) {
with(project) {
apply(plugin = "com.android.library")
apply(plugin = "org.jetbrains.kotlin.android")
configure<LibraryExtension> {
compileSdk = 31
defaultConfig {
minSdk = 23
targetSdk = 31
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("<http://consumer-rules.pro|consumer-rules.pro>")
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "<http://proguard-rules.pro|proguard-rules.pro>")
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
configure<KotlinJvmOptions> {
jvmTarget = "1.8"
}
}
}
}
}
Paul Blundell
02/17/2022, 9:42 AMConsider the sample build script shown above that demonstrates the use of type-safe accessors. The following sample is exactly the same except that is uses themethod to apply the plugin. The build script can not use type-safe accessors in this case because theapply()
call happens in the body of the build script. You have to use other techniques instead, as demonstrated here:apply()
Alexander Gherschon
02/18/2022, 1:21 PM