This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_10x in repository https://gitbox.apache.org/repos/asf/solr.git
commit 11ebc82c4a70c6393135348ed78feb9b2f8fc32c Author: David Smiley <[email protected]> AuthorDate: Thu Oct 29 15:22:39 2026 -0400 SOLR-18432: SolrVersion tolerates prerelease qualifier (#5254) SolrVersion now tolerates a prerelease qualifier such as -SNAPSHOT. Package version constraints are matched ignoring the qualifier, the cluster version-compatibility warning no longer treats a prerelease as older than its release, and /api/node/system reports the correct Solr implementation version. Co-authored-by: Claude Sonnet 5.5 <[email protected]> Co-authored-by: Nick Shanin <[email protected]> (cherry picked from commit 852b427c1154ce9eec988b9adaeb212294442126) --- .../SOLR-18432-solrversion-prerelease.yml | 7 +++ .../apache/solr/client/api/util/SolrVersion.java | 12 ++++- .../test/org/apache/solr/util/TestSolrVersion.java | 60 ++++++++++++++++++++++ .../java/org/apache/solr/cloud/ZkController.java | 2 +- .../solr/handler/admin/SystemInfoProvider.java | 3 +- .../handler/admin/NodeSystemInfoProviderTest.java | 2 +- 6 files changed, 80 insertions(+), 6 deletions(-) diff --git a/changelog/unreleased/SOLR-18432-solrversion-prerelease.yml b/changelog/unreleased/SOLR-18432-solrversion-prerelease.yml new file mode 100644 index 00000000000..ee6404c23cd --- /dev/null +++ b/changelog/unreleased/SOLR-18432-solrversion-prerelease.yml @@ -0,0 +1,7 @@ +title: SolrVersion now tolerates a prerelease qualifier such as -SNAPSHOT. Package version constraints are matched ignoring the qualifier, the cluster version-compatibility warning no longer treats a prerelease as older than its release, and /api/node/system reports the correct Solr implementation version. +type: fixed +authors: + - name: David Smiley +links: + - name: SOLR-18432 + url: https://issues.apache.org/jira/browse/SOLR-18432 diff --git a/solr/api/src/java/org/apache/solr/client/api/util/SolrVersion.java b/solr/api/src/java/org/apache/solr/client/api/util/SolrVersion.java index 42629f8900a..d85f92da9bb 100644 --- a/solr/api/src/java/org/apache/solr/client/api/util/SolrVersion.java +++ b/solr/api/src/java/org/apache/solr/client/api/util/SolrVersion.java @@ -76,12 +76,20 @@ public final class SolrVersion implements Comparable<SolrVersion> { /** * Returns true if this version satisfies the provided <a href="https://devhints.io/semver">SemVer - * Expression</a> + * Expression</a>. Any prerelease qualifier (e.g. "-SNAPSHOT") is ignored, unlike plain SemVer + * range semantics where a prerelease satisfies no range that doesn't name one. * * @param semVerExpression the expression to test */ public boolean satisfies(String semVerExpression) { - return version.satisfies(semVerExpression); + return version.withClearedPreRelease().satisfies(semVerExpression); + } + + /** + * Returns this version with any prerelease qualifier removed, e.g. "10.1.0-SNAPSHOT" to "10.1.0" + */ + public SolrVersion withoutPrerelease() { + return new SolrVersion(version.withClearedPreRelease()); } public int getMajorVersion() { diff --git a/solr/api/src/test/org/apache/solr/util/TestSolrVersion.java b/solr/api/src/test/org/apache/solr/util/TestSolrVersion.java index ff55514e4ab..cb2394468fe 100644 --- a/solr/api/src/test/org/apache/solr/util/TestSolrVersion.java +++ b/solr/api/src/test/org/apache/solr/util/TestSolrVersion.java @@ -59,4 +59,64 @@ public class TestSolrVersion extends SolrTestCase { assertFalse(SOLR_9_0_1.satisfies("8.x")); assertTrue(SOLR_9_0_1.satisfies("8 - 9")); } + + public void testPrereleaseIgnoredBySatisfies() { + SolrVersion snapshot = SolrVersion.valueOf("10.1.0-SNAPSHOT"); + assertTrue(snapshot.satisfies(">=9.0.0")); + assertTrue(snapshot.satisfies("10.x")); + assertTrue(snapshot.satisfies("~10.1")); + assertFalse(snapshot.satisfies("<10.1")); + } + + public void testPrereleaseRangeBoundaries() { + SolrVersion release = SolrVersion.valueOf("10.1.0"); + for (String versionString : new String[] {"10.1.0-SNAPSHOT", "10.1.0-rc.1+b123"}) { + SolrVersion version = SolrVersion.valueOf(versionString); + assertTrue(versionString, version.satisfies(">=10.1.0")); + assertTrue(versionString, version.satisfies("<=10.1.0")); + assertTrue(versionString, version.satisfies("10.1.0")); + assertFalse(versionString, version.satisfies("<10.1.0")); + assertFalse(versionString, version.satisfies(">10.1.0")); + assertTrue(versionString, version.compareTo(release) < 0); + assertNotEquals(release, version); + } + } + + public void testWithoutPrerelease() { + SolrVersion snapshot = SolrVersion.valueOf("10.1.0-SNAPSHOT"); + assertTrue(snapshot.lessThan(SolrVersion.valueOf("10.1.0"))); + assertEquals(SolrVersion.valueOf("10.1.0"), snapshot.withoutPrerelease()); + } + + public void testWithoutPrereleasePreservesBuildMetadata() { + SolrVersion prerelease = SolrVersion.valueOf("10.1.0-rc.1+build.123"); + SolrVersion normalized = prerelease.withoutPrerelease(); + assertEquals("10.1.0+build.123", normalized.toString()); + assertEquals("10.1.0-rc.1+build.123", prerelease.toString()); + assertTrue(prerelease.lessThan(normalized)); + } + + public void testWithoutPrereleaseOnRelease() { + for (String versionString : new String[] {"10.1.2", "10.1.2+build.123"}) { + SolrVersion release = SolrVersion.valueOf(versionString); + SolrVersion normalized = release.withoutPrerelease(); + assertEquals(versionString, normalized.toString()); + assertEquals(versionString, normalized.withoutPrerelease().toString()); + } + } + + public void testWithoutPrereleaseOrdering() { + SolrVersion normalized = SolrVersion.valueOf("10.1.0-SNAPSHOT").withoutPrerelease(); + for (String versionString : new String[] {"10.1.0", "10.1.0-alpha.1", "10.1.0-rc.1+b123"}) { + SolrVersion sameRelease = SolrVersion.valueOf(versionString).withoutPrerelease(); + assertFalse(versionString, normalized.lessThan(sameRelease)); + assertFalse(versionString, sameRelease.lessThan(normalized)); + } + for (String versionString : + new String[] {"10.1.1-SNAPSHOT", "10.2.0-SNAPSHOT", "11.0.0-SNAPSHOT"}) { + SolrVersion higherRelease = SolrVersion.valueOf(versionString).withoutPrerelease(); + assertTrue(versionString, normalized.lessThan(higherRelease)); + assertFalse(versionString, higherRelease.lessThan(normalized)); + } + } } diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index d34a25f9a9e..c2e24e142d4 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -642,7 +642,7 @@ public class ZkController implements Closeable { SolrVersion ourVersion = SolrVersion.LATEST; SolrVersion clusterVersion = lowestVersion.get(); - if (ourVersion.lessThan(clusterVersion)) { + if (ourVersion.withoutPrerelease().lessThan(clusterVersion.withoutPrerelease())) { log.warn( "Our Solr version {} is older than cluster version {}", ourVersion, clusterVersion); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoProvider.java b/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoProvider.java index 3006fb624a4..737d963d91f 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoProvider.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoProvider.java @@ -339,8 +339,7 @@ public class SystemInfoProvider { String implVersion = p.getImplementationVersion(); // non-null mostly for testing info.solrSpecVersion = specVersion == null ? SolrVersion.LATEST_STRING : specVersion; - info.solrImplVersion = - implVersion == null ? SolrVersion.LATEST.getPrereleaseVersion() : implVersion; + info.solrImplVersion = implVersion == null ? SolrVersion.LATEST_STRING : implVersion; info.luceneSpecVersion = Version.LATEST.toString(); info.luceneImplVersion = Version.getPackageImplementationVersion(); diff --git a/solr/core/src/test/org/apache/solr/handler/admin/NodeSystemInfoProviderTest.java b/solr/core/src/test/org/apache/solr/handler/admin/NodeSystemInfoProviderTest.java index 13b3ee4ce3e..5d2e29a5119 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/NodeSystemInfoProviderTest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/NodeSystemInfoProviderTest.java @@ -67,7 +67,7 @@ public class NodeSystemInfoProviderTest extends SolrTestCaseJ4 { Assert.assertEquals(h.getCoreContainer().getCoreRootDirectory().toString(), info.coreRoot); Assert.assertNotNull(info.lucene); Assert.assertNotNull(info.lucene.solrImplVersion); - Assert.assertEquals(info.lucene.solrImplVersion, SolrVersion.LATEST.getPrereleaseVersion()); + Assert.assertEquals(info.lucene.solrImplVersion, SolrVersion.LATEST_STRING); Assert.assertNotNull(info.lucene.solrSpecVersion); Assert.assertEquals(info.lucene.solrSpecVersion, SolrVersion.LATEST_STRING); Assert.assertNotNull(info.lucene.luceneImplVersion);
