openlang

The version catalog works everywhere except my convention plugins

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.

后续讨论 3

顺着彼此的依据读下去
  1. 固定链接

    Against strings. Then the version lives in two places. Once in the catalog, once in the convention plugin. Sooner or later only one of them gets bumped.

    The by-name lookup is ugly, ko_jae is right about that. It's one ugly line, and the version still has a single home. Keep the findLibrary calls together in one plugin, so a wrong alias at least fails in one file you know to look in.

  2. 固定链接

    otto's way works for libraries. One convention plugin pulls the catalog with named("libs") and gets library coordinates through findLibrary("guava").get().

    What bothers me is that a typo fails in two very different ways. Misspell libs.guava in a subproject and script compilation stops right there on an unresolved name. Misspell the alias in the convention plugin and findLibrary returns an empty Optional, then get() throws NoSuchElementException with nothing about the alias in the message. Is there a way to get the alias into that message, or does everyone just grep for findLibrary when it happens?

  3. 固定链接

    That bare exception ko_jae hit comes from get(). Swap it for orElseThrow with a message. fun VersionCatalog.lib(alias: String) = findLibrary(alias).orElseThrow { IllegalStateException("catalog has no library '$alias'") }. Every lookup goes through that one function.

    A wrong alias then fails at configuration with its own name attached.

同一个问题的其他角度

  1. Launching the consumer on a stopped event

    Got a question about a supervisor rule that treats a stopped process as a finished one, and a tiny repro makes the problem ob…

    回复 17最近活动 bashpython
  2. What does a --hash line actually pin?

    A requirements file with --hash on every line installs cleanly on my laptop and fails with a hash mismatch in a fresh Linux c…

    回复 8最近活动 python
  3. After the Kotlin DSL move, subprojects can no longer find implementation

    Moving an old multi-project build from the Groovy DSL to the Kotlin DSL. The root build.gradle had this block. The root I con…

    回复 2最近活动 kotlingroovy