0

I'm trying to define libraries in a common location. So in an our.libraries.gradle.kts script in a shared build plugin, I have this:

inner class Libraries {
    val junit get() = ...
    val junitParams get() = ...
}

val libraries = Libraries()
project.extra["libraries"] = libraries

In one of the Groovy build scripts elsewhere in the project, this is referred to like this:

allprojects {
    dependencies {
        testImplementation libraries.junit
    }
}

This works fine.

So I try converting that script to Kotlin:

allprojects {
    dependencies {
        "testImplementation"(libraries.junit)
    }
}

And now this fails, because it can't see the libraries property on the project, so I try explicitly pulling it out at the start:

val libraries: Libraries by project.extra
allprojects {
    dependencies {
        "testImplementation"(libraries.junit)
    }
}

But this doesn't work either, because the script can't find the Libraries class.

I also tried putting Libraries in Libraries.kt, but then I can't seem to call methods like exclude using named parameters because for whatever reason Gradle doesn't support using the DSL when it's moved to a top-level class.

This is sort of similar to this question, but in the case of wanting to put in simple types, everything works fine. Which is to say, I can put the libraries in as a Map, but then any time I want to reference one, I have to write this:

        "testImplementation"(libraries["junit"]!!)

This is obviously ugly, so I have been trying to avoid it.

So I'm stumped again.

This is part of a long saga trying to get this to work in many different ways, so the essential question is still the same: how can we define all our libraries in one location, and then refer to those in a type-safe way from other build scripts?

Recently, Gradle added shared dependencies via a TOML file, but that method only supports the version numbers, whereas our library definitions also include the excluded dependencies.

It was hard to put a completely self-contained example in the question because multiple files are involved, so here's a test repo.

Hakanai
  • 12,010
  • 10
  • 62
  • 132
  • From looking at your example repo you're using `apply(...)` to directly reference the plugin. This only configures the Gradle build, and doesn't share your `Libraries` class. Instead either define a 'proper' plugin and use [`includeBuild(...)`](https://docs.gradle.org/current/userguide/composite_builds.html), or publish it to a Maven repo and access it via the plugin ID. – aSemy May 29 '22 at 13:25
  • I think using the [`version-catalog` plugin](https://docs.gradle.org/current/userguide/platforms.html#sec:version-catalog-plugin) will achieve what you want. You essentially define your own BOM, and you can also set exclusions or more complex logic. [See this answer for an intro](https://stackoverflow.com/a/71562588/4161471). – aSemy May 29 '22 at 13:40
  • @aSemy as far as I could tell when I evaluated it (and this is also mentioned in the question already), the version catalogs literally only let you declare the versions, not the exclusions and other things. – Hakanai May 30 '22 at 09:30
  • You're right, I made a mistake. I meant to link the [`java-platform` plugin](https://docs.gradle.org/current/userguide/dependency_version_alignment.html#aligning_versions_natively_with_gradle). – aSemy May 30 '22 at 10:44

0 Answers0