pgpainless icon indicating copy to clipboard operation
pgpainless copied to clipboard

Ecosystem: Set up a version catalog system to better sync dependencies

Open vanitasvitae opened this issue 2 years ago • 4 comments

To simplify gradle dependency resolution management, a dependency version catalog can be used. This is essentially a list of GAV (group, artifact, version) tuples. A catalog can be imported in a gradle build, such that dependency versions are looked up in the catalog.

Futhermore, we can publish a catalog from our main project (the pgpainless repository) and reuse that not only in direct subprojects (pgpainless-core, pgpainless-sop etc.), but also from external project repositories (sop-java, wkd-java etc.).

That way we can have the main repository define all the dependencies and then simply bump the catalog version for stable, synced releases.

https://docs.gradle.org/current/userguide/platforms.html#sec:version-catalog-plugin

vanitasvitae avatar Jul 07 '23 11:07 vanitasvitae

@jerbell do you happen to know what is the usual approach for that in gradle? In case you have any input. If you don't, no worries :shrug:

tomholub avatar Aug 04 '23 16:08 tomholub

The usual approach tends to change over time, but I can tell you what I'd do.

  • (Optional) switch from Groovy to Kotlin DSL. This is personal preference.
  • Update Gradle (currently 8.2.1)
  • Use a libs.versions.toml file which will be picked up by Gradle and used. I'll cover this below (this covers most of this issue)

libs.versions.toml file: gradle Here's an example:

[versions]
# plugins
kotlin = "1.9.0"
shadow = "8.1.1"
# main
jackson = "2.15.2"
bouncy-castle = "1.70"
# test
junit = "5.10.0"
assertj = "3.24.2"

[plugins]
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" }

[libraries]
# main
jackson-bom = { module = "com.fasterxml.jackson:jackson-bom", version.ref = "jackson" }
jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind" }
jackson-module-kotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin" }
jackson-datatype-jsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" }
bouncy-castle = { module = "org.bouncycastle:bcpkix-jdk15on", version.ref = "bouncy-castle" }
# test
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" }
junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" }
assertj = { module = "org.assertj:assertj-core", version.ref = "assertj" }

Then in your core/base lib module build.gradle.kts you can look like: (this is Kotlin DSL - need to adjust for Groovy)

plugins {
  kotlin("jvm")
}

dependencies {
  api(kotlin("stdlib-jdk8"))
  api(libs.jackson.databind)
  api(libs.jackson.module.kotlin)
  api(libs.jackson.datatype.jsr310)
  api(libs.bouncy.castle)

  testApi(libs.junit.jupiter)
  testApi(libs.junit.jupiter.params)
  testApi(libs.assertj)
}

Anyway - those lib dependencies will be available in any build.gradle(.kts) file. I'd never heard of a toml format before using this, but it all works.

Jerbell avatar Aug 09 '23 02:08 Jerbell

Thanks for the insights! I will see if I can adopt this for PGPainless.

vanitasvitae avatar Aug 11 '23 08:08 vanitasvitae

If you need assistance just ask.

Jerbell avatar Aug 14 '23 06:08 Jerbell