This message was deleted.
# community-support
s
This message was deleted.
v
of generating a catalog from an existing bom
A BOM is conceptually very different to a version catalog. A BOM is conceptually equivalent to a platform. It influences resolution, can control transitive dependencies, the dependency on it can be published as part of your metadata, ... A version catalog is as its name states just a catalog of libraries, plugins, and versions your build scripts can pick from which is absolutely transparent to downstream projects or resolution engine.
but as far as i know, i cannot consume & expose catalogs A, B FROM my own catalog C.
Why not?
Copy code
versionCatalogs {
    create("C") {
        from("A")
        from("B")
    }
}
it seems like it would be feasible to programmatically generate catalog entries from existing BOMs allowing for the type-safe / autocompletion benefits, without waiting for say, the spring-boot team (šŸ˜„) to provide a native catalog
I guess they are just too conceptually different to do that in any good way. For example would you then just have the coordinates without version? Or with version too? Or ...? You could maybe write a plugin that does it for you how you think you need it and makes sense. šŸ™‚ Or you can post a feature request to GitHub for the consideration of the Gradle guys if you really think this is something Gradle should support built-in.
g
IIRC you can use from only once in catalog definition
b
ideally i think every platform would have a corresponding catalog. when you’re using a catalog, you’re by definition getting all of its declared dependency versions (as recommendations at least) so having a corresponding catalog without versions makes sense to me. micronaut for example does this, and publishes the the catalog alongside the platform (BOM) https://melix.github.io/blog/2022/02/micronaut-version-catalog.htmlp unless i’m missing something it seems like this would be feasible to do for any arbitrary bom.
v
IIRC you can use from only once in catalog definition
Oh, really? I didn't try it, but the JavaDoc of it made me think it should work.
unless i’m missing something it seems like this would be feasible to do for any arbitrary bom.
Quite possible. As I said, you should maybe open a feature request about it.
c
Note that the micronaut example is solely about providing type-safety (and IDE completion, where available) for references. As they publish a BOM, the version numbers for components are not required (as shown in their examples). It would make sense to do it in this manner (without versions); adding versions into a generated-from-BOM catalog is unnecessary and adds a layer of confusion.
…and the type-safety is only available for Gradle Kotlin DSL (Groovy isn’t type safe).
g
@Vampire, I remembered correctly, Gradle has relevant guard both for several imports and one import from several files: https://github.com/gradle/gradle/blob/master/subprojects/dependency-management/src/main/java/org/gradle/api/internal/catalog/DefaultVersionCatalogBuilder.java#L252-L263
😟 1
m
So I don't think auto-generating catalogs from BOMs is a good idea. We considered this in the past, but there are several problems with it. First of all, BOMs and catalogs serve, as described in this thread, different purposes, but that's not a blocker. BOMs, however, are "Maven-centric" in the sense that their model is the one from Maven. They use GAV coordinates and properties. Catalogs use GAV coordinates, properties, and aliases. This means that if you use a BOM to generate a catalog, there's one piece of information missing, that you have to generate: an alias. Automated aliases are doable, say if you use the artifactId, but it's a poor man's solution and can lead to non user friendly aliases or conflicts. That's why Micronaut takes the other approach, which is to generate a BOM from a catalog. It even composes catalogs by inlining aliases from other catalogs.
As for composing catalogs when importing them in Gradle, as you noticed, this idea was dismissed (see https://github.com/gradle/gradle/issues/20383 for discussion)
b
@melix thanks so much for the response! i agree about the auto-generated aliases, though, i am not sure that referencing an autogenerated alias
implementation(<http://libs.org|libs.org>)
is in any appreciable way worse than the traditional string version of
implementation(org.springframework.boot:spring-boot-starter-web)"
and could in some cases be preferable (users don’t need to learn new aliases, they just get autocomplete on the gavs they may already be familiar with) I also agree that micronaut’s approach is of course preferable, but i hate to say that this seems like another example of gradle refusing to meet users where they are - and valuing the ideal over the pragmatic (see ability to centrally overriding bom properties ala spring dep mgmt plugin). In an ideal world all 3rd parties would follow the approach micronaut took, but we don’t live in that world. IMO it’s best to strive to make the end-user experience more ā€œgoodā€ than to say there’s nothing that can be done until upstreams get their shiz together. Re: composing, i (surprise!) also think that is the wrong choice from a user’s perspective, of course the code-defined workaround is fine for self-managed catalogs, but stinks for combining self & third party into a single consumable (i.e. single enterprise-wide catalog that composes internal & 3rd party ). Could you possibly link me to the micronaut code that handles the catalog inlining?
regarding "not sure that referencing an autogenerated alias implementation(libs.org) is in any appreciable way worse" you have to remember why catalogs were introduced. Basically to avoid having to remember GAV coordinates, so if you have to know them to know what to type, then it kind of defeats the concept. That said, I'm sure somehow can hack a settings plugin which converts a BOM into a catalog. Should be quite straightforward (except for parsing the BOM and its parents).
v
this seems like another example of gradle refusing to meet users where they are
Could well be and some of these occurrences are really unnerving like "optional" support and similar. But if Gradle would just meet the users where they are, we would not have the amazingly great new build tool Gradle is, but a Maven clone that helps noone.
g
If configuration allows to read constraints than reading bom or platform could easily be delegated to gradle via resolvable detached configuration. I'm not sure if there's public API to do it
For me absence of
optional
is much less painful than absence of
provided
in non-war environment. Maybe because I write agree with Gradle team about fallacy of
optional
.
c
isn’t `provided`satisfied by
compileOnly
?
v
The
optional
was just one example where it needed ages until the Gradle guys came up with a proper solution and refused to do a pragmatic but unclean intermediary solution. And yeah, what is wrong with
compileOnly
? Just that it is not added to the POM?
b
I agree not having to remember is a big plus… but at least a generated autocomplete is more discoverable than a string. The autocomplete can help guide you, even if not as optimally as with a nice human-considered alias. I definitely wouldn’t advocate for a maven clone šŸ™‚ gradle is a zillion times better. and if everyone was publishing native gradle concepts the world would be more gooder. Though i think gradle could do a lot more to improve ergonomics for folks who need to rely on the fact that maven exists and for the forseeable future the vast majority of people’s upstream dependencies are publishing only maven concepts (POM/BOM). even if the features are Opt-In (again, overriding maven properties is my biggest pet-peeve in this regard) it would go a long way methinks. If one could live in a 100% gradle-native ecosystem, it would be awesome - but literally no one using any 3rd party dependencies can - so why not shave off the sharp edges for folks (everyone) who has a foot in both worlds. šŸ™‚ /rant
g
For some things
compileOnly/compileOnlyApi
are exactly right, I'm huge fan of these configurations. I don't actually need gradle to define
providedCompile/providedRuntime
since I could easily create similar configurations it in a convention plugin. But sometimes I need some deps to have
provided
scope in
pom.xml
for maven consumers and it was a bit of pain last time I did it.
b
from being the champion of catalogs at my org, i can tell you that people absolutely hate working with (adding new entries) into the toml file. so we end up with various in-lined ā€œstringā€ dependency declarations containing... whatever version number folks pick (ugh!). anything i can do short of manually copying every single entry from every bom we use into the catalog is a win for consistency.