Alexandre Brown
03/28/2023, 7:27 PMsubprojects {
apply(plugin = "org.jetbrains.kotlin.jvm")
apply(plugin = "com.google.devtools.ksp")
repositories {
maven(url = "<https://repo.osgeo.org/repository/release/>")
mavenCentral()
}
...
dependencies {
implementation(project(":core:core-logging"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinxCoroutinesVersion")
...
}
I have heard that using this approach is not recommended and that one should use buildSrc
instead.
I also use gradle.properties
to write the dependencies version : eg kotlinxCoroutinesVersion=1.6.4
but I am not sure if this is the recommended approach.
For Plugins I have the following in the root module (eg: backend:build.gradle.kts
):
plugins {
kotlin("jvm") version "1.7.21" apply false
kotlin("plugin.serialization") version "1.7.21" apply false
id("com.google.devtools.ksp") version "1.7.21-1.0.8" apply false
}
Then in the module that needs it I do the following :
eg: backend:backend-frameworks:build.gradle.kts
subprojects {
apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
dependencies {
...
I would love some feedback and some pointers on how I should structure the dependencies using gradle recommended approach.
Some bullet points could help : eg: To share dependencies use ABC, to version dependencies use XYZ.
I'm pretty sure the way I set it up is not the recommended approach nowadays and I'm willing to change it.Vampire
03/28/2023, 8:24 PMI am looking for recommendation on how to structure it following the latest gradle recommendation (did not look into gradle for a while).https://github.com/jjohannes/idiomatic-gradle
I have heard that using this approach is not recommendedExact, practically any usage of
allprojects { ... }
or subprojects { ... }
is bad and instead convention plugins should be used. Whether you write them in buildSrc
or an included build or a standalone build that you publish doesn't matter and is totally up to you. I personally prefer an included build, or multiple.
I also useNope, the recommended approach is using a version catalog: https://docs.gradle.org/current/userguide/platforms.htmlto write the dependencies version : eggradle.properties
but I am not sure if this is the recommended approach.kotlinxCoroutinesVersion=1.6.4
Then in the module that needs it I do the following :Well, again - and here even more as it is in an intermediate project -
subprojects { ... }
is bad as it introduces project coupling and so prevents more sophisticated features like configure-on-demand or parallel configuration, besides that it makes builds harder to understand and harder to maintain.
And also requires to use the legacy way of applying plugins apply(...)
instead of using the recommended plugins {... }
block.Alexandre Brown
03/28/2023, 8:26 PMVampire
03/28/2023, 8:31 PMtask("...")
, no tasks.withType<...> { ... }
, no tasks.getByName(...)
, only very conservative tasks....matching { ... }
if at all, no tasks.create
, ...
https://docs.gradle.org/current/userguide/task_configuration_avoidance.htmlAlexandre Brown
03/28/2023, 8:32 PMextensions.getByType<KspExtension>().apply {
arg("mockative.stubsUnitByDefault", "true")
}
But I will try to minimize such cases, thanks!Vampire
03/28/2023, 10:14 PMconfigure<KspExtension> {
arg("mockative.stubsUnitByDefault", "true")
}
(yes, without extensions.
)tasks.withType
, withType
!= getByType
.
And also while you can follow the same rules for all containers (always using bla.register
, not bla.create
and so on, it is currently mostly relevant for task collections.
As far as I know no other collection is really used lazily yet, so while more future proof, it is not tragic if you don't follow the rules on them.
And besides that, tasks.withType<...>().configureEach { ... }
is fine, that is lazy.
But tasks.withType<...> { ... }
is bad as it would always realize and configure all tasks of that type whether needed or not.
(don't ask why, this is because the bad API was there before the task configuration avoidance approach, so it cannot change its meaning easily)