Hi, I think I have found some potential bug in Gra...
# community-support
g
Hi, I think I have found some potential bug in Gradle. Recently we added build metadata to a version in a form of short commit hash after + sign as permitted by https://semver.org/#spec-item-10 E.g.
0.2.223+fe72b17a
This should also work as accordingly to https://docs.gradle.org/current/userguide/dependency_versions.html#sec:version-ordering And it seems to work when specifying regular depencensies e.g.
implementation "com.example:somelib:[0.2.217,)"
It will use latest version
[0.2.217,) -> 0.2.223+fe72b17a
The problem is, this doesn't work for BOMs. When specifying version in Maven style range
Copy code
implementation platform("com.example:bom:[0.2.223, )
I am getting an error when trying to assemble project:
Copy code
Could not resolve all files for configuration ':module:runtimeClasspath'.
   > Could not find any version that matches com.example:bom:[0.2.223, ).
     Versions that do not match:
       - 0.2.223+fe72b17a
       - 0.2.222+3c83cb97
       - 0.2.221+ccea7dda
       - 0.2.220+bcf955ec
       - 0.2.219+a8f80552
       - + 102 more
When using gradle style with + sign version:
Copy code
implementation platform("com.example:bom:0.2.+)
it works fine and it correctly picks latest
0.2.223+fe72b17a
version.
j
Without thinking a lot about it, I think it makes sense as
Copy code
0.2.223+fe72b17a < 0.2.223
But I am thinking in how semver works in general, not sure about Gradle ordering in this case: You can check the docs about ordering here: https://docs.gradle.org/current/userguide/dependency_versions.html#sec:version-ordering
But I would bet that your use case is the part explained on > Special Non-numeric Parts That means that
1.0-zeta
is lower than
1.0-final
which would be the same as
1.0
So
0.2.223+fe72b17a
would be lower than
0.2.223+final
so lower than
0.2.223
Due: > Splitting Versions into Parts: > • Versions are divided into parts using the characters
[. - _ +]
.
c
for semver the build metaata (everything after
+
) is informational only, not used in sorting.
Build metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version. Identifiers MUST comprise only ASCII alphanumerics and hyphens [0-9A-Za-z-]. Identifiers MUST NOT be empty. Build metadata MUST be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence. Examples: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85, 1.0.0+21AF26D3----117B344092BD.
j
This is the reason I created the other thread, Gradle takes into account
+
in the ordering, so you end with a problem.
c
Yea. That’s some of the challenges that exist. Agree this could all be better supported.
j
Anyway TIL that SemVer is not doing the same, it is weird the metadata can be considered "final", not very intuitive. My library is adding the commit and I am thinking now it should append a stage like
dev
or whatever before the metadata.
c
For Maven-published stuff, yes, you have to play in that ecosystem. Elsewhere, for non-library stuff, we publish to CodeArtifact (could be any generic repo) generic binaries for various applications/components using SemVer, where we can consume it (outside of Gradle) as proper typed / sorted SemVer.
j
This is another topic I think is a problem in Gradle and I failed to think it should use only Maven -> not being enough abstract (but without using
String
). Not sure if using
GradleVersion
by default but it can be overridden so you can change the ordering algorithm or whatever. I mean, if you want to use fixtures in your plugin, even if it is Android or it will be KMP, you need to use
java-test-fixtures
, that looks very anti-intuitive. And there are a lot of APIs that are very oriented to Java. Same about test suites, it should be abstract, even in its name, so it can be extended by others to support test suites in KMP.
👍 1
v
But I would bet that your use case is the part explained on
> Special Non-numeric Parts
Almost, exactly one line above that actually:
• Extra Non-numeric Part: A version with an extra non-numeric part is lower:
1.1.a < 1.1
.
So after the splitting you compare
0.2.223
against
0.2.223.fe.72.b.17.a
. The second has an extra non-numeric part, so it is considered lower than the first and so the range "0.2.223 or newer" does not include the version, while the range "0.2 and newer" of course includes it.
Gradle does not know about the semver specification and does not adhere to it, just like most libraries out there do not or not really adhere to it. It has its own algorithm that is documented and tries to catch as many cases a possible in an optimal way.