-
Notifications
You must be signed in to change notification settings - Fork 4.6k
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
Version Catalog API: Allow version variable in library coordinate string #17168
Comments
A version variable would also allow specifying a classifier, e.g. [libraries]
groovy-core-sources = "org.codehaus.groovy:groovy:${groovy}:sources" See: #17169 |
We ruled out this during design: our goal is not to design a DSL within the DSL: TOML has its own syntax and doesn't support string interpolation. |
Hm but that decision might result in people not using the versions table in the toml file at all. Let me explain: In the typical case dependencies are declared as "group:artifact:version" string with a strict version. You would only use a more complex notation if you absolutely have to. So when migrating a project to use the new version catalog toml file, you would start with something like [libraries]
common-lib1 = "com.example.common:lib1:1.0.0"
common-lib2 = "com.example.common:lib2:1.0.0"
common-lib3 = "com.example.common:lib3:1.0.0"
guava = "com.google.guava:guava:30-jre" since you can relatively easy copy the GAV coordinates from the build.gradle files. Finally you would update all the build.gradle files to use the data declared in the toml file. That is basically the bare minimum you need to do. However transforming the above to [versions]
common = "1.0.0"
guava = "30-jre"
[libraries]
common-lib1 = { module = "com.example.common:lib1", version.ref = "common" }
common-lib2 = { module = "com.example.common:lib2", version.ref = "common" }
common-lib3 = { module = "com.example.common:lib3", version.ref = "common" }
guava = { module = "com.google.guava:guava", version.ref = "guava" } requires quite some additional work, is less readable and provides only very little benefit compared to the first version. In addition all kinds of websites publishing GAV coordinates usually provide them in the "group:artifact:version" notation for Gradle, e.g. search.maven.org or all kinds of READMEs of Github projects. Basically ready to copy and paste into build files. Some of these projects even use "group:artifact:$version" in its README and tell you to replace $version with the version you want to use. So as a consequence I would never use the second form of the toml file and always stick to the first version, as it is more readable, easier to copy/paste coordinates into it and does not have a significant overhead in updating a version number compared to the second form. So supporting something like [versions]
common = "1.0.0"
guava = "30-jre"
[libraries]
common-lib1 = "com.example.common:lib1:${common}"
common-lib2 = "com.example.common:lib2:${common}"
common-lib3 = "com.example.common:lib3:${common}"
guava = "com.google.guava:guava:${guava}" would be a fair compromise. |
To clarify one thing about the classifier part: this will not happen because we want the catalog to be about dependency coordinates only, not about which variant of the dependency to use, since that is usually a contextual decision. |
I recently ported a larger project to use the version catalog. Though it usually works fine, and I'm also not concerned with the syntax being not concise, I still had a problem: sparkCore = { module = "org.apache.spark:spark-core_2.11", version.ref = "spark" } And this problem is quite prevalent for scala libraries, and is quite annoying to duplicate the scala version everywhere (which was obviously not the case with having a dependencies.gradle). Though I understand that interpolating something from the version block can be problematic (since it is not necessarily just a string), can we have some other way to interpolate some parts (even if with an additional block simply for interpolatable variables alongside the current 3)? |
Hello, just please note that interpolation in |
Same problem here. Cannot understand how to have string interpolations going.
Can you advise what features to use to avoid hardcoding |
I understand why you'd like to do this but I'd strongly recommend against adding this. It's a feature which should be part of the language (TOML), not something that Gradle builds on top of it. It also makes it very confusing, because the For advanced usages like this, using the settings API might actually be preferable. |
For our use-case, it would be sufficient to support Gradle properties interpolation. So we could have |
As a workaround I am trying to use the following.
It seem to work. |
Yes, that's what I mean by using the settings API. Note that you don't need |
Is there a way to reference the |
Another use case is to have references in a rich versions: dependencyResolutionManagement {
versionCatalogs {
libs {
version("guava", "30.0-jre")
alias("guava").to("com.google.guava", "guava").version {
strictly "[${versions.groovy.get()}, )"
}
}
}
} this doesn't seem to work. Perhaps there is a better way to do it? |
|
I find myself in the same boat as @iilyak with their Scala & Zio versions, but with Kotlin & KSP versions: [versions]
kotlin = "1.9.0"
ksp = "1.9.0-1.0.13" # FIXME: 1.9.0 looks like magic numbers, is actually Kotlin version Having to repeat the Kotlin version in the KSP version makes the process of upgrading Kotlin more prone to compatibility accidents. Is there an idiomatic way to declare versions that depend on other versions? |
@Khazbs in TOML? That's probably impossible without hacking Gradle via plugins and/or basically making a TOML generator or preprocessor. Still, you can do that somewhat easily in the buildscript itself, if that's OK for you. |
@FyiurAmron, thank you for answering my question! To clarify, I'm not saying TOML syntax needs to somehow get support for that. In fact, since this discussion is a Gradle feature request, "hacking Gradle" is exactly what I'm suggesting! I see this as a potential feature of how Gradle (or a Gradle plugin) could work with version catalogs. Support for dependent versions could be implemented by introducing specialized semantics, like: kotlin = "1.9.0"
ksp = [{ref = "kotlin"}, "-", "1.0.13"] Given the main purpose of maintaining a version catalog in the first place — consistently reusing version declarations — I think this feature is at least "nice to have". |
The new Version Catalog API is great, but as soon as you want to extract the library version into its own section the required syntax in the libraries block is way too complex for the typical use case.
Expected Behavior
Current Behavior
The text was updated successfully, but these errors were encountered: