You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by cs...@apache.org on 2025/07/07 11:03:38 UTC

(maven) branch master updated: Ability to control which repositories to be queried to resolve ranges. Introduced new property: (#2575)

This is an automated email from the ASF dual-hosted git repository.

cstamas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git


The following commit(s) were added to refs/heads/master by this push:
     new 37b069920a Ability to control which repositories to be queried to resolve ranges. Introduced new property: (#2575)
37b069920a is described below

commit 37b069920a554b8c8b9ab81de6189adac2f973db
Author: Tamas Cservenak <ta...@cservenak.net>
AuthorDate: Mon Jul 7 13:03:32 2025 +0200

    Ability to control which repositories to be queried to resolve ranges. Introduced new property: (#2575)
    
    Ability to control which repositories to be queried to resolve ranges. Introduced new property: `maven.versionRangeResolver.natureOverride` that is used in VersionRangeResolver, and means:
    * not set; behave as before (default)
    * "auto" string; will check lower and upper bounds, and if any is snapshot, will querty snapshot reposes otherwise not
    * any valid value of resolver Metadata.Nature enum; then will use that
    
    Fixes: #2558
---
 .../main/java/org/apache/maven/api/Constants.java  | 16 +++++++++
 .../internal/DefaultVersionRangeResolver.java      | 38 ++++++++++++++++++--
 .../impl/resolver/DefaultVersionRangeResolver.java | 41 +++++++++++++++++++---
 src/site/markdown/configuration.properties         | 18 ++++++----
 src/site/markdown/configuration.yaml               |  6 ++++
 src/site/markdown/maven-configuration.md           |  1 +
 6 files changed, 106 insertions(+), 14 deletions(-)

diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Constants.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Constants.java
index 925268361f..871731fb17 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Constants.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Constants.java
@@ -523,6 +523,22 @@ public final class Constants {
     @Config(type = "java.lang.Integer", defaultValue = "100")
     public static final String MAVEN_BUILDER_MAX_PROBLEMS = "maven.builder.maxProblems";
 
+    /**
+     * Configuration property for version range resolution used metadata "nature".
+     * It may contain following string values:
+     * <ul>
+     *     <li>"auto" - decision done based on range being resolver: if any boundary is snapshot, use "release_or_snapshot", otherwise "release"</li>
+     *     <li>"release_or_snapshot" - the default</li>
+     *     <li>"release" - query only release repositories to discover versions</li>
+     *     <li>"snapshot" - query only snapshot repositories to discover versions</li>
+     * </ul>
+     * Default (when unset) is existing Maven behaviour: "release_or_snapshots".
+     * @since 4.0.0
+     */
+    @Config(defaultValue = "release_or_snapshot")
+    public static final String MAVEN_VERSION_RANGE_RESOLVER_NATURE_OVERRIDE =
+            "maven.versionRangeResolver.natureOverride";
+
     /**
      * All system properties used by Maven Logger start with this prefix.
      *
diff --git a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java
index 5c5eb0cd0c..693e5c1002 100644
--- a/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java
+++ b/compat/maven-resolver-provider/src/main/java/org/apache/maven/repository/internal/DefaultVersionRangeResolver.java
@@ -28,9 +28,11 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 
+import org.apache.maven.api.Constants;
 import org.apache.maven.artifact.ArtifactUtils;
 import org.apache.maven.artifact.repository.metadata.Versioning;
 import org.apache.maven.metadata.v4.MetadataStaxReader;
@@ -53,6 +55,7 @@
 import org.eclipse.aether.resolution.VersionRangeResolutionException;
 import org.eclipse.aether.resolution.VersionRangeResult;
 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
+import org.eclipse.aether.util.ConfigUtils;
 import org.eclipse.aether.version.InvalidVersionSpecificationException;
 import org.eclipse.aether.version.Version;
 import org.eclipse.aether.version.VersionConstraint;
@@ -107,11 +110,37 @@ public VersionRangeResult resolveVersionRange(RepositorySystemSession session, V
             result.addVersion(versionConstraint.getVersion());
         } else {
             VersionRange.Bound lowerBound = versionConstraint.getRange().getLowerBound();
+            VersionRange.Bound upperBound = versionConstraint.getRange().getUpperBound();
             if (lowerBound != null
                     && lowerBound.equals(versionConstraint.getRange().getUpperBound())) {
                 result.addVersion(lowerBound.getVersion());
             } else {
-                Map<String, ArtifactRepository> versionIndex = getVersions(session, result, request);
+                Metadata.Nature wantedNature;
+                String natureString = ConfigUtils.getString(
+                        session,
+                        Metadata.Nature.RELEASE_OR_SNAPSHOT.name(),
+                        Constants.MAVEN_VERSION_RANGE_RESOLVER_NATURE_OVERRIDE);
+                if ("auto".equals(natureString)) {
+                    org.eclipse.aether.artifact.Artifact lowerArtifact = lowerBound != null
+                            ? request.getArtifact()
+                                    .setVersion(lowerBound.getVersion().toString())
+                            : null;
+                    org.eclipse.aether.artifact.Artifact upperArtifact = upperBound != null
+                            ? request.getArtifact()
+                                    .setVersion(upperBound.getVersion().toString())
+                            : null;
+
+                    if (lowerArtifact != null && lowerArtifact.isSnapshot()
+                            || upperArtifact != null && upperArtifact.isSnapshot()) {
+                        wantedNature = Metadata.Nature.RELEASE_OR_SNAPSHOT;
+                    } else {
+                        wantedNature = Metadata.Nature.RELEASE;
+                    }
+                } else {
+                    wantedNature = Metadata.Nature.valueOf(natureString.toUpperCase(Locale.ROOT));
+                }
+
+                Map<String, ArtifactRepository> versionIndex = getVersions(session, result, request, wantedNature);
 
                 List<Version> versions = new ArrayList<>();
                 for (Map.Entry<String, ArtifactRepository> v : versionIndex.entrySet()) {
@@ -135,7 +164,10 @@ public VersionRangeResult resolveVersionRange(RepositorySystemSession session, V
     }
 
     private Map<String, ArtifactRepository> getVersions(
-            RepositorySystemSession session, VersionRangeResult result, VersionRangeRequest request) {
+            RepositorySystemSession session,
+            VersionRangeResult result,
+            VersionRangeRequest request,
+            Metadata.Nature wantedNature) {
         RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
 
         Map<String, ArtifactRepository> versionIndex = new HashMap<>();
@@ -144,7 +176,7 @@ private Map<String, ArtifactRepository> getVersions(
                 request.getArtifact().getGroupId(),
                 request.getArtifact().getArtifactId(),
                 MAVEN_METADATA_XML,
-                Metadata.Nature.RELEASE_OR_SNAPSHOT);
+                wantedNature);
 
         List<MetadataRequest> metadataRequests =
                 new ArrayList<>(request.getRepositories().size());
diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultVersionRangeResolver.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultVersionRangeResolver.java
index 2adbff9826..696a919b87 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultVersionRangeResolver.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/resolver/DefaultVersionRangeResolver.java
@@ -24,9 +24,11 @@
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 
+import org.apache.maven.api.Constants;
 import org.apache.maven.api.di.Inject;
 import org.apache.maven.api.di.Named;
 import org.apache.maven.api.di.Singleton;
@@ -52,6 +54,7 @@
 import org.eclipse.aether.resolution.VersionRangeResolutionException;
 import org.eclipse.aether.resolution.VersionRangeResult;
 import org.eclipse.aether.spi.synccontext.SyncContextFactory;
+import org.eclipse.aether.util.ConfigUtils;
 import org.eclipse.aether.version.InvalidVersionSpecificationException;
 import org.eclipse.aether.version.Version;
 import org.eclipse.aether.version.VersionConstraint;
@@ -104,11 +107,36 @@ public VersionRangeResult resolveVersionRange(RepositorySystemSession session, V
             result.addVersion(versionConstraint.getVersion());
         } else {
             VersionRange.Bound lowerBound = versionConstraint.getRange().getLowerBound();
-            if (lowerBound != null
-                    && lowerBound.equals(versionConstraint.getRange().getUpperBound())) {
+            VersionRange.Bound upperBound = versionConstraint.getRange().getUpperBound();
+            if (lowerBound != null && lowerBound.equals(upperBound)) {
                 result.addVersion(lowerBound.getVersion());
             } else {
-                Map<String, ArtifactRepository> versionIndex = getVersions(session, result, request);
+                Metadata.Nature wantedNature;
+                String natureString = ConfigUtils.getString(
+                        session,
+                        Metadata.Nature.RELEASE_OR_SNAPSHOT.name(),
+                        Constants.MAVEN_VERSION_RANGE_RESOLVER_NATURE_OVERRIDE);
+                if ("auto".equals(natureString)) {
+                    org.eclipse.aether.artifact.Artifact lowerArtifact = lowerBound != null
+                            ? request.getArtifact()
+                                    .setVersion(lowerBound.getVersion().toString())
+                            : null;
+                    org.eclipse.aether.artifact.Artifact upperArtifact = upperBound != null
+                            ? request.getArtifact()
+                                    .setVersion(upperBound.getVersion().toString())
+                            : null;
+
+                    if (lowerArtifact != null && lowerArtifact.isSnapshot()
+                            || upperArtifact != null && upperArtifact.isSnapshot()) {
+                        wantedNature = Metadata.Nature.RELEASE_OR_SNAPSHOT;
+                    } else {
+                        wantedNature = Metadata.Nature.RELEASE;
+                    }
+                } else {
+                    wantedNature = Metadata.Nature.valueOf(natureString.toUpperCase(Locale.ROOT));
+                }
+
+                Map<String, ArtifactRepository> versionIndex = getVersions(session, result, request, wantedNature);
 
                 List<Version> versions = new ArrayList<>();
                 for (Map.Entry<String, ArtifactRepository> v : versionIndex.entrySet()) {
@@ -132,7 +160,10 @@ public VersionRangeResult resolveVersionRange(RepositorySystemSession session, V
     }
 
     private Map<String, ArtifactRepository> getVersions(
-            RepositorySystemSession session, VersionRangeResult result, VersionRangeRequest request) {
+            RepositorySystemSession session,
+            VersionRangeResult result,
+            VersionRangeRequest request,
+            Metadata.Nature wantedNature) {
         RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
 
         Map<String, ArtifactRepository> versionIndex = new HashMap<>();
@@ -141,7 +172,7 @@ private Map<String, ArtifactRepository> getVersions(
                 request.getArtifact().getGroupId(),
                 request.getArtifact().getArtifactId(),
                 MAVEN_METADATA_XML,
-                Metadata.Nature.RELEASE_OR_SNAPSHOT);
+                wantedNature);
 
         List<MetadataRequest> metadataRequests =
                 new ArrayList<>(request.getRepositories().size());
diff --git a/src/site/markdown/configuration.properties b/src/site/markdown/configuration.properties
index fd338133c5..859836cc4f 100644
--- a/src/site/markdown/configuration.properties
+++ b/src/site/markdown/configuration.properties
@@ -20,7 +20,7 @@
 # Generated from: maven-resolver-tools/src/main/resources/configuration.properties.vm
 # To modify this file, edit the template and regenerate.
 #
-props.count = 64
+props.count = 65
 props.1.key = maven.build.timestamp.format
 props.1.configurationType = String
 props.1.description = Build timestamp format.
@@ -397,9 +397,15 @@ props.63.description = Maven snapshot: contains "true" if this Maven is a snapsh
 props.63.defaultValue = 
 props.63.since = 4.0.0
 props.63.configurationSource = system_properties
-props.64.key = maven.versionResolver.noCache
-props.64.configurationType = Boolean
-props.64.description = User property for disabling version resolver cache.
-props.64.defaultValue = false
-props.64.since = 3.0.0
+props.64.key = maven.versionRangeResolver.natureOverride
+props.64.configurationType = String
+props.64.description = Configuration property for version range resolution used metadata "nature". It may contain following string values: <ul> <li>"auto" - decision done based on range being resolver: if any boundary is snapshot, use "release_or_snapshot", otherwise "release"</li> <li>"release_or_snapshot" - the default</li> <li>"release" - query only release repositories to discover versions</li> <li>"snapshot" - query only snapshot repositories to discover versions</li> </ul> Default  [...]
+props.64.defaultValue = release_or_snapshot
+props.64.since = 4.0.0
 props.64.configurationSource = User properties
+props.65.key = maven.versionResolver.noCache
+props.65.configurationType = Boolean
+props.65.description = User property for disabling version resolver cache.
+props.65.defaultValue = false
+props.65.since = 3.0.0
+props.65.configurationSource = User properties
diff --git a/src/site/markdown/configuration.yaml b/src/site/markdown/configuration.yaml
index ce0e719b85..c9f60fb60c 100644
--- a/src/site/markdown/configuration.yaml
+++ b/src/site/markdown/configuration.yaml
@@ -397,6 +397,12 @@ props:
       defaultValue: 
       since: 4.0.0
       configurationSource: system_properties
+    - key: maven.versionRangeResolver.natureOverride
+      configurationType: String
+      description: "Configuration property for version range resolution used metadata \"nature\". It may contain following string values: <ul> <li>\"auto\" - decision done based on range being resolver: if any boundary is snapshot, use \"release_or_snapshot\", otherwise \"release\"</li> <li>\"release_or_snapshot\" - the default</li> <li>\"release\" - query only release repositories to discover versions</li> <li>\"snapshot\" - query only snapshot repositories to discover versions</li> </u [...]
+      defaultValue: release_or_snapshot
+      since: 4.0.0
+      configurationSource: User properties
     - key: maven.versionResolver.noCache
       configurationType: Boolean
       description: "User property for disabling version resolver cache."
diff --git a/src/site/markdown/maven-configuration.md b/src/site/markdown/maven-configuration.md
index 7baae846d2..29fff1f782 100644
--- a/src/site/markdown/maven-configuration.md
+++ b/src/site/markdown/maven-configuration.md
@@ -94,5 +94,6 @@ To modify this file, edit the template and regenerate.
 | `maven.version.minor` | `String` | Maven minor version: contains the minor segment of this Maven version. |  -  | 4.0.0 | system_properties |
 | `maven.version.patch` | `String` | Maven patch version: contains the patch segment of this Maven version. |  -  | 4.0.0 | system_properties |
 | `maven.version.snapshot` | `String` | Maven snapshot: contains "true" if this Maven is a snapshot version. |  -  | 4.0.0 | system_properties |
+| `maven.versionRangeResolver.natureOverride` | `String` | Configuration property for version range resolution used metadata "nature". It may contain following string values: <ul> <li>"auto" - decision done based on range being resolver: if any boundary is snapshot, use "release_or_snapshot", otherwise "release"</li> <li>"release_or_snapshot" - the default</li> <li>"release" - query only release repositories to discover versions</li> <li>"snapshot" - query only snapshot repositories to d [...]
 | `maven.versionResolver.noCache` | `Boolean` | User property for disabling version resolver cache. |  `false`  | 3.0.0 | User properties |