In regards to your question about libs.versions.toml not being available to plugins, I’ve got a fairly simple work around.
I have a custom plug that reads the libs.version.toml and converts each entry section into a Properties file that I make globally available. Here’s some code showing the version section of the lib.version.toml file being added to a Properties class. I put version, libs, plugins and bundles each in there own properties file.
enum class PropertyType {
versions:{
override fun writeProperties(writer: WriteProperties, catalog: VersionCatalog) {
catalog.versionAliases.forEach {
//println("key: " + it + " value: " + catalog.findVersion(it).get().toString())
if (it.isNotEmpty()) {
//val versionConstraint = catalog.findVersion(it)
writer.property(it, catalog.findVersion(it).get().toString())
}
}
writer.writeProperties()
}
}
... repeat for each libs section you want to capture, adjusting accordingly:
}
fun createPropertiesFile(project: Project, type: PropertyType, properties: Properties) {
project.tasks.create(type.name,WriteProperties::class.javaObjectType) {
val projDirPath:String = project.rootProject.path
val tomlFile = projDirPath + "/gradle/libs.versions.toml"
inputs.file(tomlFile)
val propertiesFile = project.rootProject.projectDir.resolve("src/main/resources/" + type.name.toLowerCase() + ".properties")
outputFile = propertiesFile
//println("output file - " + writer.outputFile.absolutePath)
if (!outputFile.exists()) {
outputFile.parentFile.mkdirs()
if (!outputFile.exists()) outputFile.createNewFile()
}
comment =
"this file is automatically created in the build process DO NOT MANUALLY MODIFY THIS FILE"
val vc = project.extensions.getByType(VersionCatalogsExtension::class.java).named("libs")
type.writeProperties(this, vc)
properties.load(FileInputStream(propertiesFile))
}
}
And here’s how it gets called:
class MyCustomProjectPlugin : Plugin {
companion object {
var versions: Properties = Properties()
var libraries: Properties = Properties()
var plugins: Properties = Properties()
var bundles: Properties = Properties()
}
override fun apply(project: Project) {
//println("is root " + project.name)
if (project == project.rootProject) {
println("MyCustomPlugin applied")
createPropertiesFile(project, PropertyType.versions, versions)
createPropertiesFile(project, PropertyType.libraries, libraries)
createPropertiesFile(project, PropertyType.plugins, plugins)
createPropertiesFile(project, PropertyType.bundles, bundles)
The disadvantage of this approach is that you don’t get the typesafe behavior of using the libs.versions.toml file directly. I’ve written custom plugins that get version information that is consistent with the version data contained in the libs.versions.toml file. The libs key is used as the key for the corresponding properties file. Although not shown, I also write the properties file to the resources directory, which means my runtime also has access to all the build version information.
I also create a version number for the toml file and store it in the toml file. That version number gets manually changed each time I make a change to the toml file. I actually wish that the Gradle Team would support the libs.versions.toml as a versioned artifact that could be retrieved from a repository. I also wish they’d allow root project reference plugin using version numbers obtained from the libs.version.toml file. I hate hardwiring version data in any build scripts. That contributes to unmanageable build script maintenance. I just don’t see how that would violate Idempotency if all version data is derived from the versions catalog. I certainly understand the argument that version data derived from environment variables potentially breaks Idempotency, but I don’t see that with using versions catalog data.