Moving versions into gradle/libs.versions.toml, with shared setup in convention plugins under buildSrc. The idea was one place for versions. Three cases, in order.
In a subproject's build script, alias(libs.plugins.kotlin.jvm) and libs both work. No complaints.
The build script of buildSrc itself doesn't inherit the main project's catalog. It has to be imported by hand in buildSrc/settings.gradle.kts.
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
Still as documented. A little odd that buildSrc needs telling where its own repository keeps the file, but it works and the accessors appear.
The third case is where it stops being pleasant. Inside a precompiled script plugin in buildSrc there is no type-safe libs. The docs say to look the catalog up by name with extensions.getByType(VersionCatalogsExtension::class.java).named("libs") and then ask it for each entry by alias. And that plugin's plugins block can't reach the catalog at all, so a convention plugin that applies another plugin names it by id, and the version comes from wherever buildSrc declared the plugin artifact.
So the picture is uneven. The build scripts that matter least get the nicest accessors. The convention plugins, where most of the shared setup now lives, get lookups by string.
There's always one place left where entries come out by name. At that point I wonder whether plain strings for coordinates inside convention plugins would be the more honest choice.