-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Feat: Improve matching of Toolchains versions #11786
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
base: maven-3.9.x
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,9 +18,12 @@ | |
| */ | ||
| package org.apache.maven.toolchain; | ||
|
|
||
| import org.apache.maven.artifact.versioning.DefaultArtifactVersion; | ||
| import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; | ||
| import org.apache.maven.artifact.versioning.VersionRange; | ||
| import java.util.Locale; | ||
| import java.util.Objects; | ||
|
|
||
| import org.eclipse.aether.util.version.GenericVersionScheme; | ||
| import org.eclipse.aether.version.InvalidVersionSpecificationException; | ||
| import org.eclipse.aether.version.VersionScheme; | ||
|
|
||
| /** | ||
| * | ||
|
|
@@ -38,16 +41,17 @@ public static RequirementMatcher createVersionMatcher(String provideValue) { | |
| } | ||
|
|
||
| private static final class ExactMatcher implements RequirementMatcher { | ||
|
|
||
| private String provides; | ||
| private final String provides; | ||
|
|
||
| private ExactMatcher(String provides) { | ||
| this.provides = provides; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean matches(String requirement) { | ||
| return provides.equalsIgnoreCase(requirement); | ||
| return Objects.equals( | ||
| provides != null ? provides.toLowerCase(Locale.ENGLISH) : null, | ||
| requirement != null ? requirement.toLowerCase(Locale.ENGLISH) : null); | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -57,31 +61,78 @@ public String toString() { | |
| } | ||
|
|
||
| private static final class VersionMatcher implements RequirementMatcher { | ||
| DefaultArtifactVersion version; | ||
| private final String version; | ||
|
|
||
| private VersionMatcher(String version) { | ||
| this.version = new DefaultArtifactVersion(version); | ||
| this.version = version; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean matches(String requirement) { | ||
| try { | ||
| VersionRange range = VersionRange.createFromVersionSpec(requirement); | ||
| if (range.hasRestrictions()) { | ||
| return range.containsVersion(version); | ||
| String r = requirement != null ? requirement.toLowerCase(Locale.ENGLISH) : null; | ||
| String v = version != null ? version.toLowerCase(Locale.ENGLISH) : null; | ||
| if (v == null && r == null) { | ||
| return true; // null == null | ||
| } | ||
| if (v == null || r == null) { | ||
| return false; // null != non-null | ||
| } | ||
| if (v.equals(r)) { | ||
| return true; // str == str (ignoring case) | ||
| } | ||
| return matchesRequirement(v, r); | ||
| } | ||
|
|
||
| private static final VersionScheme VERSION_SCHEME = new GenericVersionScheme(); | ||
|
|
||
| private static boolean matchesRequirement(String version, String requirement) { | ||
| boolean interval = false; | ||
| boolean included = false; | ||
| if (requirement.endsWith("+")) { | ||
| interval = true; | ||
| included = true; | ||
| requirement = requirement.substring(0, requirement.length() - 1); | ||
| } else if (requirement.endsWith("-")) { | ||
| interval = true; | ||
| requirement = requirement.substring(0, requirement.length() - 1); | ||
| } | ||
| final String req = requirement; | ||
|
|
||
| // if requirement is not a version range itself | ||
| if (!req.contains("[") && !req.contains("(") && !req.contains(",")) { | ||
| if (!interval) { | ||
| return version.startsWith(req + "."); // "11" -> "11.xxx" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was about to propose that logic as well for #11770, i.e. when one just specifies a version requirement that the actual version should just start with the requirement to handle cases like
Of course one has to handle the Java-8 and older versions. But maybe this can be done by removing a leading In this case I wonder how it works if one requires
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before this call the normalized strings are tested for equality. This is what I missed in my comment above as well. So
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Re 1.8 support (or older): IMHO, user must write versions as reported by JDK, especially as toolchains XML may be generated today. And if user consistently writes
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For possible 1.8 support, see this similar case: c2e4be2
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Legacy code for sure wrote "1.4", "1.6" or "1.8"... and given toolchain does not have "feature version" to match against (nor could?) I'd say we are fine IF users use versions "as reported by Java". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Oversaw that, thanks.
Sounds good. I would try to keep it simple and as long as there is a way to handle it, it's fine. |
||
| } else { | ||
| return range.getRecommendedVersion().compareTo(version) == 0; | ||
| try { | ||
| if (included) { | ||
| return VERSION_SCHEME | ||
| .parseVersionRange("[" + req + ",)") | ||
| .containsVersion(VERSION_SCHEME.parseVersion(version)); // "11+" -> "[11,)" | ||
| } else { | ||
| return VERSION_SCHEME | ||
| .parseVersionRange("(," + req + ")") | ||
| .containsVersion(VERSION_SCHEME.parseVersion(version)); // "11-" -> "(,11)" | ||
| } | ||
| } catch (InvalidVersionSpecificationException e) { | ||
| // nope; GenericVersionScheme never throes but we need to make compiler happy | ||
| throw new RuntimeException(e); | ||
| } | ||
| } | ||
| } else { | ||
| try { | ||
| return VERSION_SCHEME | ||
| .parseVersionRange(req) | ||
| .containsVersion(VERSION_SCHEME.parseVersion(version)); // "range" -> "range" | ||
| } catch (InvalidVersionSpecificationException e) { | ||
| // nope; GenericVersionScheme never throes but we need to make compiler happy | ||
| throw new RuntimeException(e); | ||
| } | ||
| } catch (InvalidVersionSpecificationException ex) { | ||
| // TODO error reporting | ||
| ex.printStackTrace(); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return version.toString(); | ||
| return version; | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't this code be moved into the if block that has checked that the requirement isn't a version-range? In case of the latter this seems to be ignored any-ways.