I want to share solution we ended up using on the account it might help someone
First, the problem we tried to solving were:
- Use toml version catalog libraries within buildSrc plugins
- Use toml version catalog plugins within buildSrc plugins
For #1 all the the posts up to this point explain how this was solved
For #2, we ended up with changing the problem to: “write a plugin act as a facade to other plugins”.
The Rational behind this is simple - we actually want a single point of through. The reason we want a version catalog is to have a single place to update the specific version we need. If this single point exist in a different location (gradle file) it is also a valid solution.
Specifically our applications uses JIB
and application
plugins. Initially we wanted to make sure that all apps use the same JIB version, but thinking it over we noticed that actually both plugins share the same configuration and we figured this could also be addressed
So, we defined a custom extension!
Here is AppConventionExtension.kt
class
open class AppConventionExtension(private val project: Project) {
var mainClass: String = ""
var artifactName: String = ""
var jvmFlags: List<String> = ...
val baseImage: String = ...
val imageTag: String by lazy { ... }
}
It is a class that will be used to carry information from our subproject apps to the inner plugins
And, a matching custom plugin called app-common-conventions.gradle.kts
plugins {
application
id("com.google.cloud.tools.jib")
}
// Register the custom extension
val app = extensions.create("app", AppConventionExtension::class.java, project)
/**
* make sure the app {} block is evaluated before running JIB/application
*/
gradle.projectsEvaluated {
application {
if (app.mainClass.isEmpty()) {
logger.warn("While building application: app.mainClass is empty, please define where you apply the 'app-common-conventions.gradle.kts' plugin")
}
if (app.artifactName.isEmpty()) {
logger.warn("While building application: app.artifactName is empty, please define where you apply the 'app-common-conventions.gradle.kts' plugin")
}
mainClass.set(app.mainClass)
applicationDefaultJvmArgs = app.jvmFlags
}
jib {
if (app.mainClass.isEmpty()) {
logger.warn("While building JIB: app.mainClass is empty, please define where you apply the 'app-common-conventions.gradle.kts' plugin")
}
if (app.artifactName.isEmpty()) {
logger.warn("While building JIB: app.artifactName is empty, please define where you apply the 'app-common-conventions.gradle.kts' plugin")
}
from {
image = app.baseImage
}
container {
appRoot = "/app-${app.artifactName}"
mainClass = app.mainClass
jvmFlags = app.jvmFlags
}
to {
image = "ghcr.io/ssi-dnn/${app.artifactName}"
tags = setOf(app.imageTag, "latest")
}
}
}
One last thing in the configuration side - in buildSrc/build.gradle.kts
we also added a dependency to the specific version of the JIB
plugin
dependencies {
implementation(libs.kotlin.gradle.plugin)
implementation("com.google.cloud.tools:jib-gradle-plugin:3.3.1")
}
This is how we use it in our subprojects
plugins {
// Add the app plugin
id("app-common-conventions")
}
// Add the app block
app {
mainClass = ...
artifactName = ...
}
And that’s it!
Next step will be to publish this as a plugins so all of our different repos can share this