Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create BOMs for dependency versions #1419

Open
vlsi opened this issue Apr 27, 2023 · 6 comments
Open

Create BOMs for dependency versions #1419

vlsi opened this issue Apr 27, 2023 · 6 comments

Comments

@vlsi
Copy link
Collaborator

vlsi commented Apr 27, 2023

Platform (all, jvm, js): all
Extension (none, kotlin 1.3): none

Non-Code related feature

Currently the build uses rootProject.extra for declaring dependency versions which is cumbersome for usage (e.g. it does not support precompiled script plugins), and it can't be reused.

I suggest creating BOMs with dependency constraints, so the dependencies can be declared without versions.

I think the following BOMs make sense:
a) Atrium modules, without third-party dependencies. In other words, something like junit-bom: https://junit.org/junit5/docs/current/user-guide/#dependency-metadata-junit-bom
b) BOM with third-party runtime dependencies (if any)
c) BOM with test dependencies

@robstoll
Copy link
Owner

Just as info, Atrium already provides BOMs for consumers of atrium (the bundle modules), I guess that covers a)
What's your use case that you need b) and c) ?

@vlsi
Copy link
Collaborator Author

vlsi commented Apr 28, 2023

The current bundle modules are not BOMs.
See https://blog.gradle.org/alignment-with-gradle-module-metadata for the description of "a".

In other words, "a" should be dependency constraints rather than versions:

  • atrium-bom would apply java-platform and it would declare constraints on atrium modules
  • every atrium module which is listed in atrium-bom would add platform(project(":atrium-bom")) dependency

In that case, every atrium module could depend on such bom, and Gradle would automatically align versions.
For instance, consider user declares dependency on api-fluent-en_GB:0.18 and translations-en_GB:0.19.
api-fluent-en_GB:0.18 brings atrium-bom:0.18 while translations-en_GB:0.19 brings atrium-bom:0.19.
atrium-bom:0.19 will bring constraints on both modules to 0.19, so final resolution would align both dependencies to 0.19.

In JUnit, junit-bom is <type>pom</type>: https://repo1.maven.org/maven2/org/junit/junit-bom/5.9.3/junit-bom-5.9.3.pom
In other words, it specifies only versions rather than explicit dependencies.

@vlsi
Copy link
Collaborator Author

vlsi commented Apr 28, 2023

The use cases for b and c are to remove the current pattern of storing versions in extra properties:

atrium/build.gradle.kts

Lines 20 to 29 in cca39fc

val jacocoToolVersion by extra("0.8.9")
val junitPlatformVersion by extra("1.9.2")
val jupiterVersion by extra("5.9.2")
// need to use an old version of spek as the newer contains a bug which causes that no tests are discovered and executed
val spekVersion by extra("2.0.12")
//TODO v1.1.0 decide whether we drop kotest again or not
//val kotestVersion by extra("4.6.4")
val spekExtensionsVersion by extra("1.2.1")
val mockkVersion by extra("1.10.0")
val mockitoKotlinVersion by extra("2.2.0")

project.extra was a thing ~7 years ago, however, it did not work great overall, especially for declaring versions.
For instance, you have to remember the exact name of the extra every time you use a dependency, and you have to invent a name for a dependency every time you add new one.

The modern approach for naming dependencies is version catalogs, however, there are issues with using precompiled script plugins + version catalogs together.

Another (accompanying) approach to align versions is creating platforms. In that case, you import that platform once, and declare the dependencies without versions, so you don't need refer to extra names.

@vlsi
Copy link
Collaborator Author

vlsi commented Apr 28, 2023

One of the major drawbacks of having val jacocoToolVersion by extra("0.8.9") is that you miss Renovate / Dependabot support for the custom syntax. You have to manually discover which versions are available, and it is unclear what to watch for.

For instance, consider val spekVersion by extra("2.0.12"). How do I check if there's an update available? Which maven coordinate do I search for?
It would be way easier to have it as a constraint (e.g. see https://github.com/apache/jmeter/blob/b76c5f73025b21ec9a17605910a9b4a3e2c4321f/src/bom-thirdparty/build.gradle.kts#L78 ), so both robots and humans could suggest and evaluate upgrades.

@robstoll
Copy link
Owner

robstoll commented Apr 28, 2023

regarding a) you are totally right. would make sense to have a proper BOM in addition where the bundle modules would use it.

project.extra was a thing ~7 years ago,

Oho.. looks like I am getting old-school 😆 Thanks for your input, easy way for me to catch up on new gradle stuff

regard b, c)
I see, the use cases are more contributor oriented. Good with me.

@robstoll
Copy link
Owner

robstoll commented Nov 29, 2023

we no longer use rootProject.extra but libs.versions.toml but an additional BOM would still be nice

@robstoll robstoll changed the title Create BOMs for dependency versions instead of rootProject.extra Create BOMs for dependency versions Nov 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants