From 693fe1189587746fa9ee8ee12679870b94f807b5 Mon Sep 17 00:00:00 2001 From: Andrzej Jarmoniuk Date: Sun, 9 Apr 2023 14:09:03 +0200 Subject: [PATCH] Resolves #960: displayDependencyUpdates should display updates from lesser segments Resolves #299: allowAnyUpdates should be ignored with a warning message if any of: allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates is set to false --- .../versions/api/AbstractVersionDetails.java | 213 ++++++------ .../mojo/versions/api/ArtifactVersions.java | 9 +- .../versions/api/ArtifactVersionsCache.java | 2 +- .../versions/api/DefaultVersionsHelper.java | 15 +- .../codehaus/mojo/versions/api/PomHelper.java | 10 +- .../mojo/versions/api/PropertyVersions.java | 2 +- .../versions/api/PropertyVersionsBuilder.java | 35 +- .../codehaus/mojo/versions/api/Segment.java | 22 ++ .../mojo/versions/api/VersionDetails.java | 123 +++---- .../mojo/versions/api/VersionsHelper.java | 2 + .../ordering/BoundArtifactVersion.java | 19 +- .../mojo/versions/utils/SegmentUtils.java | 7 +- .../api/AbstractVersionDetailsTest.java | 159 +++++++++ .../versions/api/ArtifactVersionsTest.java | 305 ++++++++++-------- .../versions/utils/ArtifactVersionUtils.java | 44 +++ .../mojo/versions/utils/SegmentUtilsTest.java | 26 +- .../enforcer/MaxDependencyUpdates.java | 6 +- .../it/it-compare-dependencies-006/verify.bsh | 2 +- .../DisplayDependencyUpdatesMojo.java | 101 +++--- .../versions/DisplayExtensionUpdatesMojo.java | 13 +- .../versions/DisplayPropertyUpdatesMojo.java | 29 +- .../mojo/versions/ResolveRangesMojo.java | 29 +- .../mojo/versions/UpdateParentMojo.java | 28 +- .../versions/UpdatePropertiesMojoBase.java | 28 +- .../mojo/versions/UseLatestReleasesMojo.java | 27 +- .../mojo/versions/UseLatestSnapshotsMojo.java | 27 +- .../mojo/versions/UseLatestVersionsMojo.java | 27 +- .../mojo/versions/UseNextSnapshotsMojo.java | 27 +- .../versions/reporting/OverviewStats.java | 7 +- .../reporting/PluginOverviewStats.java | 3 +- .../DependencyUpdatesXmlReportRenderer.java | 4 +- .../xml/PluginUpdatesXmlReportRenderer.java | 4 +- .../xml/PropertyUpdatesXmlReportRenderer.java | 4 +- .../DisplayDependencyUpdatesMojoTest.java | 222 ++++++------- .../DisplayPropertyUpdatesMojoTest.java | 69 ++-- .../issue-960/pom.xml | 18 ++ .../versions/utils/CloseableTempFile.java | 48 +++ 37 files changed, 1109 insertions(+), 607 deletions(-) create mode 100644 versions-common/src/test/java/org/codehaus/mojo/versions/api/AbstractVersionDetailsTest.java create mode 100644 versions-common/src/test/java/org/codehaus/mojo/versions/utils/ArtifactVersionUtils.java create mode 100644 versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-property-updates/issue-960/pom.xml create mode 100644 versions-test/src/main/java/org/codehaus/mojo/versions/utils/CloseableTempFile.java diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java index 02f7bae7d..604ecfe93 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java @@ -19,19 +19,13 @@ * under the License. */ -import java.util.Arrays; -import java.util.Collections; -import java.util.Iterator; -import java.util.Objects; -import java.util.Optional; -import java.util.TreeSet; +import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.versioning.ArtifactVersion; -import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.Restriction; import org.apache.maven.artifact.versioning.VersionRange; import org.codehaus.mojo.versions.ordering.BoundArtifactVersion; @@ -64,51 +58,93 @@ public abstract class AbstractVersionDetails implements VersionDetails { */ private ArtifactVersion currentVersion = null; + private VersionRange currentVersionRange = null; + protected boolean verboseDetail = true; protected AbstractVersionDetails() {} - @Override - public Restriction restrictionFor(Optional scope) throws InvalidSegmentException { - // one range spec can have multiple restrictions, and multiple 'lower bound', we want the highest one. - // [1.0,2.0),[3.0,4.0) -> 3.0 - ArtifactVersion highestLowerBound = currentVersion; - if (currentVersion != null) { - try { - highestLowerBound = - VersionRange.createFromVersionSpec(currentVersion.toString()).getRestrictions().stream() - .map(Restriction::getLowerBound) - .filter(Objects::nonNull) - .max(getVersionComparator()) - .orElse(currentVersion); - } catch (InvalidVersionSpecificationException ignored) { - ignored.printStackTrace(System.err); - } - } + /** + * If a version is a version range consisting of one or more version ranges, returns the highest lower + * bound. If a single version range is present, returns its value. + * @param lowerBoundVersion actual version used + * @return highest lower bound of the given version range or {@link #getCurrentVersion()} if there's no lower bound + */ + protected ArtifactVersion getHighestLowerBound(ArtifactVersion lowerBoundVersion) { + return getCurrentVersionRange().getRestrictions().stream() + .map(Restriction::getLowerBound) + .filter(Objects::nonNull) + .max(getVersionComparator()) + .orElse(lowerBoundVersion); + } - final ArtifactVersion currentVersion = highestLowerBound; - ArtifactVersion nextVersion = scope.filter(s -> s.isMajorTo(SUBINCREMENTAL)) - .map(s -> (ArtifactVersion) new BoundArtifactVersion(currentVersion, Segment.of(s.value() + 1))) - .orElse(currentVersion); + /** + * If the artifact is bound by one or more version ranges, returns the restriction that constitutes + * the version range containing the selected actual version. + * If there are no version ranges, returns the provided version. + * @param selectedVersion actual version used + * @return restriction containing the version range selected by the given version, + * or {@link Optional#empty()} if there are no ranges + */ + protected Optional getSelectedRestriction(ArtifactVersion selectedVersion) { + return Optional.ofNullable(getCurrentVersionRange()) + .map(VersionRange::getRestrictions) + .flatMap(r -> r.stream() + .filter(rr -> rr.containsVersion(selectedVersion)) + .findAny()); + } + + @Override + public Restriction restrictionForSelectedSegment(ArtifactVersion lowerBound, Optional selectedSegment) { + ArtifactVersion highestLowerBound = getHighestLowerBound(lowerBound); + ArtifactVersion nextVersion = selectedSegment + .filter(s -> s.isMajorTo(SUBINCREMENTAL)) + .map(Segment::minorTo) + .map(s -> (ArtifactVersion) new BoundArtifactVersion(highestLowerBound, s)) + .orElse(highestLowerBound); return new Restriction( nextVersion, false, - scope.filter(MAJOR::isMajorTo) - .map(s -> (ArtifactVersion) new BoundArtifactVersion(currentVersion, s)) + selectedSegment + .filter(MAJOR::isMajorTo) + .map(s -> (ArtifactVersion) new BoundArtifactVersion(highestLowerBound, s)) .orElse(null), false); } @Override - public Restriction restrictionForIgnoreScope(Optional ignored) { - ArtifactVersion nextVersion = ignored.map(s -> (ArtifactVersion) new BoundArtifactVersion(currentVersion, s)) - .orElse(currentVersion); - return new Restriction(nextVersion, false, null, false); + public Restriction restrictionForUnchangedSegment( + ArtifactVersion actualVersion, Optional unchangedSegment, boolean allowDowngrade) + throws InvalidSegmentException { + Optional selectedRestriction = getSelectedRestriction(actualVersion); + ArtifactVersion selectedRestrictionUpperBound = + selectedRestriction.map(Restriction::getUpperBound).orElse(actualVersion); + ArtifactVersion lowerBound = allowDowngrade + ? getLowerBound(selectedRestrictionUpperBound, unchangedSegment) + .map(DefaultArtifactVersionCache::of) + .orElse(null) + : selectedRestrictionUpperBound; + ArtifactVersion upperBound = unchangedSegment + .map(s -> (ArtifactVersion) new BoundArtifactVersion( + selectedRestrictionUpperBound, s.isMajorTo(SUBINCREMENTAL) ? Segment.minorTo(s) : s)) + .orElse(null); + return new Restriction( + lowerBound, + allowDowngrade + || selectedRestriction + .map(Restriction::isUpperBoundInclusive) + .map(b -> !b) + .orElse(false), + upperBound, + allowDowngrade); } @Override - public final boolean isCurrentVersionDefined() { - return getCurrentVersion() != null; + public Restriction restrictionForIgnoreScope(ArtifactVersion lowerBound, Optional ignored) { + ArtifactVersion highestLowerBound = getHighestLowerBound(lowerBound); + ArtifactVersion nextVersion = ignored.map(s -> (ArtifactVersion) new BoundArtifactVersion(highestLowerBound, s)) + .orElse(highestLowerBound); + return new Restriction(nextVersion, false, null, false); } @Override @@ -122,27 +158,23 @@ public final void setCurrentVersion(ArtifactVersion currentVersion) { } @Override - public final void setCurrentVersion(String currentVersion) { - setCurrentVersion(currentVersion == null ? null : DefaultArtifactVersionCache.of(currentVersion)); + public final VersionRange getCurrentVersionRange() { + return currentVersionRange; } @Override - public final ArtifactVersion[] getVersions(VersionRange versionRange, boolean includeSnapshots) { - return getVersions(versionRange, null, includeSnapshots); + public final void setCurrentVersionRange(VersionRange versionRange) { + currentVersionRange = versionRange; } @Override - public final ArtifactVersion[] getVersions( - ArtifactVersion lowerBound, ArtifactVersion upperBound, boolean includeSnapshots) { - Restriction restriction = new Restriction(lowerBound, false, upperBound, false); - return getVersions(restriction, includeSnapshots); + public final void setCurrentVersion(String currentVersion) { + setCurrentVersion(currentVersion == null ? null : DefaultArtifactVersionCache.of(currentVersion)); } @Override - public final ArtifactVersion getNewestVersion( - ArtifactVersion lowerBound, ArtifactVersion upperBound, boolean includeSnapshots) { - Restriction restriction = new Restriction(lowerBound, false, upperBound, false); - return getNewestVersion(restriction, includeSnapshots); + public final ArtifactVersion[] getVersions(VersionRange versionRange, boolean includeSnapshots) { + return getVersions(versionRange, null, includeSnapshots); } @Override @@ -187,24 +219,6 @@ public final boolean containsVersion(String version) { return false; } - private ArtifactVersion[] getNewerVersions(ArtifactVersion version, boolean includeSnapshots) { - Restriction restriction = new Restriction(version, false, null, false); - return getVersions(restriction, includeSnapshots); - } - - @Override - public final ArtifactVersion[] getNewerVersions(String version, boolean includeSnapshots) { - return getNewerVersions(DefaultArtifactVersionCache.of(version), includeSnapshots); - } - - @Deprecated - @Override - public final ArtifactVersion[] getNewerVersions( - String version, Optional upperBoundSegment, boolean includeSnapshots) - throws InvalidSegmentException { - return getNewerVersions(version, upperBoundSegment, includeSnapshots, false); - } - @Override public final ArtifactVersion[] getNewerVersions( String versionString, Optional unchangedSegment, boolean includeSnapshots, boolean allowDowngrade) @@ -216,8 +230,8 @@ public final ArtifactVersion[] getNewerVersions( .orElse(null) : currentVersion; ArtifactVersion upperBound = unchangedSegment - .map(s -> (ArtifactVersion) new BoundArtifactVersion( - currentVersion, s.isMajorTo(SUBINCREMENTAL) ? Segment.of(s.value() + 1) : s)) + .map(s -> (ArtifactVersion) + new BoundArtifactVersion(currentVersion, s.isMajorTo(SUBINCREMENTAL) ? Segment.minorTo(s) : s)) .orElse(null); Restriction restriction = new Restriction(lowerBound, allowDowngrade, upperBound, allowDowngrade); @@ -226,22 +240,21 @@ public final ArtifactVersion[] getNewerVersions( @Override public Optional getNewestVersion( - String versionString, Optional upperBoundSegment, boolean includeSnapshots, boolean allowDowngrade) + String actualVersion, Optional unchangedSegment, boolean includeSnapshots, boolean allowDowngrade) throws InvalidSegmentException { - ArtifactVersion currentVersion = DefaultArtifactVersionCache.of(versionString); - ArtifactVersion lowerBound = allowDowngrade - ? getLowerBound(currentVersion, upperBoundSegment) - .map(DefaultArtifactVersionCache::of) - .orElse(null) - : currentVersion; - ArtifactVersion upperBound = upperBoundSegment - .map(s -> (ArtifactVersion) new BoundArtifactVersion( - currentVersion, s.isMajorTo(SUBINCREMENTAL) ? Segment.of(s.value() + 1) : s)) - .orElse(null); - - Restriction restriction = new Restriction(lowerBound, allowDowngrade, upperBound, allowDowngrade); + Restriction segmentRestriction = restrictionForUnchangedSegment( + DefaultArtifactVersionCache.of(actualVersion), unchangedSegment, allowDowngrade); + Restriction lookupRestriction; + if (!allowDowngrade + && Optional.ofNullable(currentVersion) + .map(v -> v.compareTo(segmentRestriction.getLowerBound()) > 0) + .orElse(false)) { + lookupRestriction = new Restriction(currentVersion, false, null, false); + } else { + lookupRestriction = segmentRestriction; + } return Arrays.stream(getVersions(includeSnapshots)) - .filter(candidate -> isVersionInRestriction(restriction, candidate)) + .filter(candidate -> isVersionInRestriction(lookupRestriction, candidate)) .filter(candidate -> includeSnapshots || !ArtifactUtils.isSnapshot(candidate.toString())) .max(getVersionComparator()); } @@ -264,36 +277,28 @@ public final ArtifactVersion[] getVersions( } @Override - public final ArtifactVersion getNewestUpdate( + public final ArtifactVersion getNewestUpdateWithinSegment( ArtifactVersion currentVersion, Optional updateScope, boolean includeSnapshots) { - try { - return getNewestVersion(restrictionFor(updateScope), includeSnapshots); - } catch (InvalidSegmentException e) { - return null; - } + return getNewestVersion(restrictionForSelectedSegment(currentVersion, updateScope), includeSnapshots); } @Override public final ArtifactVersion[] getAllUpdates( ArtifactVersion currentVersion, Optional updateScope, boolean includeSnapshots) { - try { - return getVersions(restrictionFor(updateScope), includeSnapshots); - } catch (InvalidSegmentException e) { - return null; - } + return getVersions(restrictionForSelectedSegment(currentVersion, updateScope), includeSnapshots); } @Override - public final ArtifactVersion getNewestUpdate(Optional updateScope, boolean includeSnapshots) { - if (isCurrentVersionDefined()) { - return getNewestUpdate(getCurrentVersion(), updateScope, includeSnapshots); + public final ArtifactVersion getNewestUpdateWithinSegment(Optional updateScope, boolean includeSnapshots) { + if (getCurrentVersion() != null) { + return getNewestUpdateWithinSegment(getCurrentVersion(), updateScope, includeSnapshots); } return null; } @Override public final ArtifactVersion[] getAllUpdates(Optional updateScope, boolean includeSnapshots) { - if (isCurrentVersionDefined()) { + if (getCurrentVersion() != null) { return getAllUpdates(getCurrentVersion(), updateScope, includeSnapshots); } return null; @@ -433,15 +438,11 @@ public final ArtifactVersion[] getReportUpdates(Optional updateScope, b * @return all versions after currentVersion within the specified update scope. */ private Stream getArtifactVersionStream(Optional updateScope, boolean includeSnapshots) { - if (isCurrentVersionDefined()) { - try { - Restriction restriction = restrictionFor(updateScope); - - return Arrays.stream(getVersions(includeSnapshots)) - .filter(candidate -> isVersionInRestriction(restriction, candidate)); - } catch (InvalidSegmentException ignored) { - ignored.printStackTrace(System.err); - } + if (getCurrentVersion() != null) { + Restriction restriction = restrictionForSelectedSegment(getCurrentVersion(), updateScope); + + return Arrays.stream(getVersions(includeSnapshots)) + .filter(candidate -> isVersionInRestriction(restriction, candidate)); } return Stream.empty(); } diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java index 6197066cc..c10c628bb 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java @@ -75,12 +75,8 @@ public ArtifactVersions(Artifact artifact, List versions, Versi this.versionComparator = versionComparator; this.versions = new TreeSet<>(versionComparator); this.versions.addAll(versions); - // DefaultArtifact objects are often built from raw model, without a version set - // (where the actual version is taken from parent or dependency/plugin management) - // this probably isn't the case in an actual Maven execution - if (artifact.getVersion() != null) { - setCurrentVersion(artifact.getVersion()); - } + setCurrentVersion(artifact.getVersion()); + setCurrentVersionRange(artifact.getVersionRange()); } /** @@ -94,6 +90,7 @@ public ArtifactVersions(ArtifactVersions other) { versionComparator = other.versionComparator; versions = other.versions; setCurrentVersion(other.getCurrentVersion()); + setCurrentVersionRange(other.getCurrentVersionRange()); } @SuppressWarnings("checkstyle:InnerAssignment") diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersionsCache.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersionsCache.java index 8df888dfa..4eea8923c 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersionsCache.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersionsCache.java @@ -27,7 +27,7 @@ import org.apache.commons.lang3.tuple.Triple; /** - * Utility providing a cached {@link ArtifactVersions#getNewestUpdate(Optional, boolean)} API + * Utility providing a cached {@link ArtifactVersions#getNewestUpdateWithinSegment(Optional, boolean)} API */ public class ArtifactVersionsCache { private TriFunction, Boolean, ?> cachedFunction; diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java index 64032132f..11f266d4a 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java @@ -53,6 +53,7 @@ import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.Restriction; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.execution.MavenSession; @@ -688,11 +689,10 @@ public Map getVersionPropertiesMap(VersionProperties if (dependencies != null) { for (Dependency dependency : dependencies) { getLog().debug("Property ${" + property.getName() + "}: Adding association to " + dependency); - builder.addAssociation(this.createDependencyArtifact(dependency), false); + builder.withAssociation(this.createDependencyArtifact(dependency), false); } } try { - final PropertyVersions versions = builder.newPropertyVersions(); if (property.isAutoLinkDependencies() && StringUtils.isEmpty(property.getVersion()) && !StringUtils.isEmpty(builder.getVersionRange())) { @@ -702,8 +702,17 @@ public Map getVersionPropertiesMap(VersionProperties } final String currentVersion = request.getMavenProject().getProperties().getProperty(property.getName()); - versions.setCurrentVersion(currentVersion); property.setValue(currentVersion); + final PropertyVersions versions; + try { + if (currentVersion != null) { + builder.withCurrentVersion(DefaultArtifactVersionCache.of(currentVersion)) + .withCurrentVersionRange(VersionRange.createFromVersionSpec(currentVersion)); + } + } catch (InvalidVersionSpecificationException e) { + throw new RuntimeException(e); + } + versions = builder.build(); propertyVersions.put(property, versions); } catch (VersionRetrievalException e) { throw new MojoExecutionException(e.getMessage(), e); diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/PomHelper.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/PomHelper.java index 6ab8b56d1..81ecf17d4 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/PomHelper.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/PomHelper.java @@ -1021,7 +1021,7 @@ private static void addPluginAssociations( } // might as well capture the current value String evaluatedVersion = (String) expressionEvaluator.evaluate(plugin.getVersion()); - property.addAssociation( + property.withAssociation( helper.createPluginArtifact(groupId, artifactId, evaluatedVersion), true); if (!propertyRef.equals(version)) { addBounds(property, version, propertyRef); @@ -1066,7 +1066,7 @@ private static void addReportPluginAssociations( } // might as well capture the current value String versionEvaluated = (String) expressionEvaluator.evaluate(plugin.getVersion()); - property.addAssociation( + property.withAssociation( helper.createPluginArtifact(groupId, artifactId, versionEvaluated), true); if (!propertyRef.equals(version)) { addBounds(property, version, propertyRef); @@ -1111,7 +1111,7 @@ private static void addDependencyAssocations( } // might as well capture the current value String versionEvaluated = (String) expressionEvaluator.evaluate(dependency.getVersion()); - property.addAssociation( + property.withAssociation( helper.createDependencyArtifact( groupId, artifactId, @@ -1138,7 +1138,7 @@ private static void addBounds(PropertyVersionsBuilder builder, String rawVersion boolean includeLower = "[".equals(m.group(1)); String lowerLimit = m.group(2); if (StringUtils.isNotEmpty(lowerLimit)) { - builder.addLowerBound(lowerLimit, includeLower); + builder.withLowerBound(lowerLimit, includeLower); } } m = upperBound.matcher(rawVersionRange); @@ -1146,7 +1146,7 @@ private static void addBounds(PropertyVersionsBuilder builder, String rawVersion boolean includeUpper = "[".equals(m.group(3)); String upperLimit = m.group(2); if (StringUtils.isNotEmpty(upperLimit)) { - builder.addUpperBound(upperLimit, includeUpper); + builder.withUpperBound(upperLimit, includeUpper); } } } diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersions.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersions.java index b61b47990..bc695c9e3 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersions.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersions.java @@ -320,7 +320,7 @@ public ArtifactVersion getNewestVersion( ? null : upperBoundSegment .map(s -> (ArtifactVersion) new BoundArtifactVersion( - currentVersion, s.isMajorTo(SUBINCREMENTAL) ? Segment.of(s.value() + 1) : s)) + currentVersion, s.isMajorTo(SUBINCREMENTAL) ? Segment.minorTo(s) : s)) .orElse(null); if (helper.getLog().isDebugEnabled()) { helper.getLog().debug("Property ${" + property.getName() + "}: upperBound is: " + upperBound); diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersionsBuilder.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersionsBuilder.java index 3e32efecf..ab00675e0 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersionsBuilder.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersionsBuilder.java @@ -27,6 +27,7 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.VersionRange; import org.codehaus.mojo.versions.ordering.VersionComparator; /** @@ -48,6 +49,10 @@ class PropertyVersionsBuilder { private final Map lowerBounds = new LinkedHashMap<>(); + private ArtifactVersion currentVersion; + + private VersionRange currentVersionRange; + /** * Constructs a new {@link org.codehaus.mojo.versions.api.PropertyVersions}. * @@ -62,12 +67,9 @@ class PropertyVersionsBuilder { this.helper = helper; } - public void addAssociation(Artifact artifact, boolean usePluginRepositories) { + public PropertyVersionsBuilder withAssociation(Artifact artifact, boolean usePluginRepositories) { associations.add(new DefaultArtifactAssociation(artifact, usePluginRepositories)); - } - - public void removeAssociation(Artifact artifact, boolean usePluginRepositories) { - associations.remove(new DefaultArtifactAssociation(artifact, usePluginRepositories)); + return this; } public void clearAssociations() { @@ -82,8 +84,11 @@ public ArtifactAssociation[] getAssociations() { return associations.toArray(new ArtifactAssociation[0]); } - public PropertyVersions newPropertyVersions() throws VersionRetrievalException { - return new PropertyVersions(profileId, name, helper, associations); + public PropertyVersions build() throws VersionRetrievalException { + PropertyVersions instance = new PropertyVersions(profileId, name, helper, associations); + instance.setCurrentVersion(currentVersion); + instance.setCurrentVersionRange(currentVersionRange); + return instance; } public String getName() { @@ -150,7 +155,7 @@ public String getVersionRange() { return buf.toString(); } - public void addLowerBound(String lowerBound, boolean includeLower) { + public PropertyVersionsBuilder withLowerBound(String lowerBound, boolean includeLower) { Boolean value = lowerBounds.get(lowerBound); if (value == null) { value = includeLower; @@ -158,9 +163,10 @@ public void addLowerBound(String lowerBound, boolean includeLower) { value = includeLower && value; } lowerBounds.put(lowerBound, value); + return this; } - public void addUpperBound(String upperBound, boolean includeUpper) { + public PropertyVersionsBuilder withUpperBound(String upperBound, boolean includeUpper) { Boolean value = upperBounds.get(upperBound); if (value == null) { value = includeUpper; @@ -168,6 +174,7 @@ public void addUpperBound(String upperBound, boolean includeUpper) { value = includeUpper && value; } upperBounds.put(upperBound, value); + return this; } private VersionComparator[] lookupComparators() { @@ -202,4 +209,14 @@ private int innerCompare(ArtifactVersion v1, ArtifactVersion v2) { return result; } } + + public PropertyVersionsBuilder withCurrentVersion(ArtifactVersion currentVersion) { + this.currentVersion = currentVersion; + return this; + } + + public PropertyVersionsBuilder withCurrentVersionRange(VersionRange currentVersionRange) { + this.currentVersionRange = currentVersionRange; + return this; + } } diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/Segment.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/Segment.java index 9aa90ca05..20ccf4d21 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/Segment.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/Segment.java @@ -19,6 +19,8 @@ * under the License. */ +import java.util.Optional; + /** * Indicates the segment along with its 0-based index * @@ -46,6 +48,26 @@ public static Segment of(int index) { return values()[index]; } + /** + * Creates a segment that has a greater scope than the given segment or {@code null} + * if the segment is already {@link #MAJOR} + * @param other segment that the new segment is to be based on + * @return that has a greater scope than the given segment or {@code null} + * if the segment is already {@link #MAJOR} + */ + public static Segment majorTo(Segment other) { + return Optional.ofNullable(other).map(s -> of(s.value() - 1)).orElse(null); + } + + /** + * Creates a segment that has a lesser scope than the given segment + * @param other segment that the new segment is to be based on + * @return that has a lesser scope than the given segment + */ + public static Segment minorTo(Segment other) { + return Optional.ofNullable(other).map(s -> of(s.value() + 1)).orElse(MAJOR); + } + /** * Returns true if the given segment is more major than the other * @param other other segment to compare diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionDetails.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionDetails.java index 79b369bf6..f12699e51 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionDetails.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionDetails.java @@ -43,14 +43,6 @@ public interface VersionDetails { */ boolean containsVersion(String version); - /** - * Returns true if and only if getCurrentVersion() != null. - * - * @return true if and only if getCurrentVersion() != null. - * @since 1.0-beta-1 - */ - boolean isCurrentVersionDefined(); - /** * Sets the current version. * @@ -68,13 +60,27 @@ public interface VersionDetails { void setCurrentVersion(String currentVersion); /** - * Retrieves the current version. + * Returns the current version. * - * @return The current version (may be null). + * @return The current version (may be {@code null}). * @since 1.0-beta-1 */ ArtifactVersion getCurrentVersion(); + /** + * Returns the current version range (may be {@code null}) + * @return current version range (may be {@code null}) + * @since 2.16.0 + */ + VersionRange getCurrentVersionRange(); + + /** + * Sets the current version range (may be {@code null}) + * @param versionRange version range to set (may be {@code null}) + * @since 2.16.0 + */ + void setCurrentVersionRange(VersionRange versionRange); + /** * Gets the rule for version comparison of this artifact. * @@ -102,17 +108,6 @@ public interface VersionDetails { */ ArtifactVersion[] getVersions(VersionRange versionRange, boolean includeSnapshots); - /** - * Returns all available versions within the specified bounds. - * - * @param lowerBound the lower bound or null if the lower limit is unbounded. - * @param upperBound the upper bound or null if the upper limit is unbounded. - * @param includeSnapshots true if snapshots are to be included. - * @return all available versions within the specified version range. - * @since 1.0-beta-1 - */ - ArtifactVersion[] getVersions(ArtifactVersion lowerBound, ArtifactVersion upperBound, boolean includeSnapshots); - /** * Returns all available versions within the specified bounds. * @@ -148,18 +143,6 @@ public interface VersionDetails { ArtifactVersion getNewestVersion( VersionRange versionRange, Restriction restriction, boolean includeSnapshots, boolean allowDowngrade); - /** - * Returns the latest version newer than the specified lowerBound, but less than the specified upper bound or - * null if no such version exists. - * - * @param lowerBound the lower bound or null if the lower limit is unbounded. - * @param upperBound the upper bound or null if the upper limit is unbounded. - * @param includeSnapshots true if snapshots are to be included. - * @return the latest version between currentVersion and upperBound or null if no version is available. - * @since 1.0-alpha-3 - */ - ArtifactVersion getNewestVersion(ArtifactVersion lowerBound, ArtifactVersion upperBound, boolean includeSnapshots); - /** * Returns the latest version newer than the specified current version, but less than the specified upper bound or * null if no such version exists. @@ -199,7 +182,7 @@ ArtifactVersion getNewestVersion( * should be included. * * @param versionString current version - * @param upperBoundSegment the upper bound segment; empty() means no upper bound + * @param unchangedSegment segment that may not be changed; empty() means no upper bound * @param includeSnapshots whether snapshot versions should be included * @param allowDowngrade whether to allow downgrading if the current version is a snapshots and snapshots * are disallowed @@ -208,7 +191,7 @@ ArtifactVersion getNewestVersion( * the segment count) */ Optional getNewestVersion( - String versionString, Optional upperBoundSegment, boolean includeSnapshots, boolean allowDowngrade) + String versionString, Optional unchangedSegment, boolean includeSnapshots, boolean allowDowngrade) throws InvalidSegmentException; /** @@ -223,36 +206,10 @@ Optional getNewestVersion( * @throws InvalidSegmentException thrown if the updateScope is greater than the number of segments * @since 1.0-beta-1 */ - ArtifactVersion getNewestUpdate( + ArtifactVersion getNewestUpdateWithinSegment( ArtifactVersion currentVersion, Optional updateScope, boolean includeSnapshots) throws InvalidSegmentException; - /** - * Returns an array of newer versions than the given version, given whether snapshots - * should be included. - * - * @param version current version in String format - * @param includeSnapshots whether snapshot versions should be included - * @return array of newer versions fulfilling the criteria - */ - ArtifactVersion[] getNewerVersions(String version, boolean includeSnapshots); - - /** - * Returns an array of newer versions than the given version, given the upper bound segment and whether snapshots - * should be included. - * - * @param version current version - * @param upperBoundSegment the upper bound segment; empty() means no upper bound - * @param includeSnapshots whether snapshot versions should be included - * @return array of newer versions fulfilling the criteria - * @throws InvalidSegmentException if the requested segment is outside the bounds (less than 1 or greater than - * the segment count) - * @deprecated please use {@link AbstractVersionDetails#getNewerVersions(String, Optional, boolean, boolean)}, - * boolean, boolean)} instead - */ - ArtifactVersion[] getNewerVersions(String version, Optional upperBoundSegment, boolean includeSnapshots) - throws InvalidSegmentException; - /** * Returns an array of newer versions than the given version, given the upper bound segment and whether snapshots * should be included. @@ -285,8 +242,9 @@ ArtifactVersion[] getAllUpdates( throws InvalidSegmentException; /** - * Returns the newest version newer than the specified current version, but within the specified update scope or - * null if no such version exists. + *

Returns the newest version newer than the specified current version, only within the segment specified + * by {@code updateScope} or {@code null} if no such version exists.

+ *

If {@code updateScope} is {@link Optional#empty()}, will return all updates.

* * @param updateScope the update scope to include. * @param includeSnapshots true if snapshots are to be included. @@ -295,7 +253,7 @@ ArtifactVersion[] getAllUpdates( * @throws InvalidSegmentException thrown if the updateScope is greater than the number of segments * @since 1.0-beta-1 */ - ArtifactVersion getNewestUpdate(Optional updateScope, boolean includeSnapshots) + ArtifactVersion getNewestUpdateWithinSegment(Optional updateScope, boolean includeSnapshots) throws InvalidSegmentException; /** @@ -331,27 +289,40 @@ ArtifactVersion[] getAllUpdates(Optional updateScope, boolean includeSn /** *

Returns a {@linkplain Restriction} object for computing version upgrades - * with the given segment allowing updates, with all more major segments locked in place.

- *

The resulting restriction could be thought of as one - * retaining the versions on positions up to the held position, - * the position right after the position held in place will be incremented by one, - * and on all positions which are more minor than that, the range would contain -∞ - * for the bottom bound and +∞ for the above bound.

- *

This will allow matching the required versions while not matching versions which are considered - * inferior than the zeroth version, i.e. versions with a qualifier.

+ * within the given segment allowing updates, with all more major segments locked in place, + * but also ignoring all version updates from lesser scopes.

+ * + * @param lowerBound artifact version, for which the unchanged segment is computed + * @param selectedSegment segment, for which the restriction is to be built or {@link Optional#empty()} for no restriction + * @return {@linkplain Restriction} object based on the arguments + * @throws InvalidSegmentException if the requested segment is outside the bounds (less than 1 or greater than + * the segment count) + */ + Restriction restrictionForSelectedSegment(ArtifactVersion lowerBound, Optional selectedSegment) + throws InvalidSegmentException; + + /** + *

Returns a {@linkplain Restriction} object for computing version upgrades + * within the all segments minor/lesser to the provided {@code unchangedSegment}.

+ *

If the provided segment is {@link Optional#empty()}, all possible updates are returned.

* - * @param scope most major segment where updates are allowed Optional.empty() for no restriction + * @param lowerBound artifact version, for which the unchanged segment is computed + * @param unchangedSegment segment, which should not be changed or {@link Optional#empty()} for no restriction + * @param allowDowngrade whether downgrades are allowed * @return {@linkplain Restriction} object based on the arguments * @throws InvalidSegmentException if the requested segment is outside the bounds (less than 1 or greater than * the segment count) */ - Restriction restrictionFor(Optional scope) throws InvalidSegmentException; + Restriction restrictionForUnchangedSegment( + ArtifactVersion lowerBound, Optional unchangedSegment, boolean allowDowngrade) + throws InvalidSegmentException; /** * Returns the {@link Restriction} objects for a segemnt scope which is to be ignored. * + * @param lowerBound artifact version, for which the unchanged segment is computed * @param ignored most major segment where updates are to be ignored; Optional.empty() for no ignored segments * @return {@linkplain Restriction} object based on the arguments */ - Restriction restrictionForIgnoreScope(Optional ignored); + Restriction restrictionForIgnoreScope(ArtifactVersion lowerBound, Optional ignored); } diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionsHelper.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionsHelper.java index 102f0a6b3..8b1a56140 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionsHelper.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/VersionsHelper.java @@ -202,6 +202,7 @@ ArtifactVersions lookupArtifactVersions(Artifact artifact, VersionRange versionR * @param usePluginRepositories Search the plugin repositories. * @param allowSnapshots whether snapshots should be included * @return map containing the ArtifactVersions object per dependency + * @throws VersionRetrievalException thrown if a version cannot be retrieved */ Map lookupDependenciesUpdates( Set dependencies, boolean usePluginRepositories, boolean allowSnapshots) @@ -216,6 +217,7 @@ Map lookupDependenciesUpdates( * @param useProjectRepositories whether to use regular project repositories * @param allowSnapshots whether snapshots should be included * @return map containing the ArtifactVersions object per dependency + * @throws VersionRetrievalException thrown if a version cannot be retrieved */ Map lookupDependenciesUpdates( Set dependencies, diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/BoundArtifactVersion.java b/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/BoundArtifactVersion.java index 5612d05bf..1cd7067cd 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/BoundArtifactVersion.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/ordering/BoundArtifactVersion.java @@ -1,5 +1,20 @@ package org.codehaus.mojo.versions.ordering; +/* + * Copyright MojoHaus and Contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import java.util.ArrayList; import java.util.List; @@ -36,7 +51,7 @@ public class BoundArtifactVersion implements ArtifactVersion { /** * Constructs the instance given the version in a text format. - * @param artifactVersion version in a text format + * @param artifactVersion lower bound * @param segment most major segment that can change, i.e. not held in place */ public BoundArtifactVersion(String artifactVersion, Segment segment) { @@ -58,7 +73,7 @@ public BoundArtifactVersion(String artifactVersion, Segment segment) { /** * Constructs the instance given a {@link ArtifactVersion instance} - * @param artifactVersion artifact version containing the segment version values + * @param artifactVersion lower bound * @param segment most major segment that can change, i.e. not held in place */ public BoundArtifactVersion(ArtifactVersion artifactVersion, Segment segment) { diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/utils/SegmentUtils.java b/versions-common/src/main/java/org/codehaus/mojo/versions/utils/SegmentUtils.java index 791d954a8..e37a0349e 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/utils/SegmentUtils.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/utils/SegmentUtils.java @@ -26,9 +26,7 @@ import static java.util.Optional.empty; import static java.util.Optional.of; -import static org.codehaus.mojo.versions.api.Segment.INCREMENTAL; -import static org.codehaus.mojo.versions.api.Segment.MAJOR; -import static org.codehaus.mojo.versions.api.Segment.MINOR; +import static org.codehaus.mojo.versions.api.Segment.*; /** * Utility class for manipulating with {@link Segment} objects @@ -79,7 +77,8 @@ public static Optional determineUnchangedSegment( : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); if (log != null && log.isDebugEnabled()) { log.debug(unchangedSegment - .map(s -> Segment.of(s.value() + 1).toString()) + .map(Segment::minorTo) + .map(Segment::toString) .orElse("ALL") + " version changes allowed"); } return unchangedSegment; diff --git a/versions-common/src/test/java/org/codehaus/mojo/versions/api/AbstractVersionDetailsTest.java b/versions-common/src/test/java/org/codehaus/mojo/versions/api/AbstractVersionDetailsTest.java new file mode 100644 index 000000000..552c60b63 --- /dev/null +++ b/versions-common/src/test/java/org/codehaus/mojo/versions/api/AbstractVersionDetailsTest.java @@ -0,0 +1,159 @@ +package org.codehaus.mojo.versions.api; + +/* + * Copyright MojoHaus and Contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.artifact.versioning.VersionRange; +import org.codehaus.mojo.versions.ordering.InvalidSegmentException; +import org.codehaus.mojo.versions.ordering.MavenVersionComparator; +import org.codehaus.mojo.versions.ordering.VersionComparator; +import org.junit.Before; +import org.junit.Test; + +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.codehaus.mojo.versions.api.Segment.MAJOR; +import static org.codehaus.mojo.versions.utils.ArtifactVersionUtils.version; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +/** + * Unit tests for {@link AbstractVersionDetails} + */ +public class AbstractVersionDetailsTest { + + private AbstractVersionDetails instance; + + @Before + public void setUp() { + instance = new AbstractVersionDetails() { + @Override + public VersionComparator getVersionComparator() { + return new MavenVersionComparator(); + } + + @Override + public ArtifactVersion[] getVersions(boolean includeSnapshots) { + return new ArtifactVersion[0]; + } + }; + } + + @Test + public void testRestrictionForUnchangedSegmentWithSimpleVersion() throws InvalidSegmentException { + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.0"), of(MAJOR), false) + .containsVersion(version("1.0.0")), + is(false)); + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.0"), of(MAJOR), false) + .containsVersion(version("1.1.0")), + is(true)); + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.0"), of(MAJOR), false) + .containsVersion(version("1.0.1")), + is(true)); + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.0"), of(MAJOR), false) + .containsVersion(version("1.0.0-1")), + is(true)); + } + + @Test + public void testRestrictionForUnchangedSegmentWithRange() + throws InvalidSegmentException, InvalidVersionSpecificationException { + instance.setCurrentVersionRange(VersionRange.createFromVersionSpec("(0.0.1, 1.0.0]")); + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.0"), of(MAJOR), false) + .containsVersion(version("1.0.0")), + is(false)); + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.0"), of(MAJOR), false) + .containsVersion(version("1.1.0")), + is(true)); + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.0"), of(MAJOR), false) + .containsVersion(version("1.0.1")), + is(true)); + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.0"), of(MAJOR), false) + .containsVersion(version("1.0.0-1")), + is(true)); + } + + @Test + public void testRestrictionForUnchangedSegmentWithTwoRanges() + throws InvalidSegmentException, InvalidVersionSpecificationException { + instance.setCurrentVersionRange(VersionRange.createFromVersionSpec("(0.0.1, 1.0.0],(1.0.0,2.0.0]")); + assertThat( + instance.restrictionForUnchangedSegment(version("2.0.0"), of(MAJOR), false) + .containsVersion(version("1.0.0")), + is(false)); + assertThat( + instance.restrictionForUnchangedSegment(version("2.0.0"), of(MAJOR), false) + .containsVersion(version("1.1.0")), + is(false)); + assertThat( + instance.restrictionForUnchangedSegment(version("2.0.0"), of(MAJOR), false) + .containsVersion(version("2.0.0")), + is(false)); + assertThat( + instance.restrictionForUnchangedSegment(version("2.0.0"), of(MAJOR), false) + .containsVersion(version("2.0.0-1")), + is(true)); + } + + @Test + public void testRestrictionForUnchangedSegmentWithTwoNotConnectingRanges1() + throws InvalidSegmentException, InvalidVersionSpecificationException { + instance.setCurrentVersionRange(VersionRange.createFromVersionSpec("(0.0.1, 1.0.0),(1.0.0,2.0.0]")); + assertThat( + instance.restrictionForUnchangedSegment(version("0.9.0"), empty(), false) + .containsVersion(version("1.0.0")), + is(true)); + } + + @Test + public void testRestrictionForUnchangedSegmentWithTwoNotConnectingRanges2() + throws InvalidSegmentException, InvalidVersionSpecificationException { + instance.setCurrentVersionRange(VersionRange.createFromVersionSpec("(0.0.1, 1.0.0),(1.0.0,2.0.0]")); + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.1"), of(MAJOR), false) + .containsVersion(version("1.1.0")), + is(false)); + } + + @Test + public void testRestrictionForUnchangedSegmentWithTwoNotConnectingRanges3() + throws InvalidSegmentException, InvalidVersionSpecificationException { + instance.setCurrentVersionRange(VersionRange.createFromVersionSpec("(0.0.1, 1.0.0),(1.0.0,2.0.0]")); + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.1"), empty(), false) + .containsVersion(version("2.0.0")), + is(false)); + } + + @Test + public void testRestrictionForUnchangedSegmentWithTwoNotConnectingRanges4() + throws InvalidSegmentException, InvalidVersionSpecificationException { + instance.setCurrentVersionRange(VersionRange.createFromVersionSpec("(0.0.1, 1.0.0),(1.0.0,2.0.0]")); + assertThat( + instance.restrictionForUnchangedSegment(version("1.0.1"), empty(), false) + .containsVersion(version("2.0.0-1")), + is(true)); + } +} diff --git a/versions-common/src/test/java/org/codehaus/mojo/versions/api/ArtifactVersionsTest.java b/versions-common/src/test/java/org/codehaus/mojo/versions/api/ArtifactVersionsTest.java index 6f1342d6d..4d473d9b4 100644 --- a/versions-common/src/test/java/org/codehaus/mojo/versions/api/ArtifactVersionsTest.java +++ b/versions-common/src/test/java/org/codehaus/mojo/versions/api/ArtifactVersionsTest.java @@ -20,48 +20,40 @@ */ import java.util.Arrays; +import java.util.Optional; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.handler.DefaultArtifactHandler; import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.Restriction; import org.apache.maven.artifact.versioning.VersionRange; -import org.codehaus.mojo.versions.ordering.InvalidSegmentException; -import org.codehaus.mojo.versions.ordering.MavenVersionComparator; -import org.codehaus.mojo.versions.ordering.MercuryVersionComparator; -import org.codehaus.mojo.versions.utils.DefaultArtifactVersionCache; +import org.codehaus.mojo.versions.ordering.*; import org.junit.Test; import static java.util.Optional.of; -import static org.codehaus.mojo.versions.api.Segment.INCREMENTAL; -import static org.codehaus.mojo.versions.api.Segment.MAJOR; -import static org.codehaus.mojo.versions.api.Segment.MINOR; -import static org.codehaus.mojo.versions.api.Segment.SUBINCREMENTAL; +import static org.codehaus.mojo.versions.api.Segment.*; +import static org.codehaus.mojo.versions.utils.ArtifactVersionUtils.version; +import static org.codehaus.mojo.versions.utils.ArtifactVersionUtils.versions; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.arrayContaining; -import static org.hamcrest.Matchers.arrayWithSize; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; public class ArtifactVersionsTest { - @Test - public void test4DigitVersions() throws Exception { - ArtifactVersion[] versions = - versions("1.0.0.1", "1.0.0.2", "2.121.2.1", "2.100.0.1", "3.1.0.1", "1.1.1", "2.0.0-SNAPSHOT"); - final DefaultArtifact artifact = new DefaultArtifact( - "group", - "artifact", - VersionRange.createFromVersionSpec("[1.0,3.0]"), - "foo", - "bar", - "jar", - new DefaultArtifactHandler()); - // TODO This should also work for the MavenVersionComparator when using maven 3.x libraries - ArtifactVersions instance = - new ArtifactVersions(artifact, Arrays.asList(versions), new MercuryVersionComparator()); + private void test4DigitVersion(VersionComparator comparator) throws InvalidVersionSpecificationException { + ArtifactVersions instance = new ArtifactVersions( + new DefaultArtifact( + "group", + "artifact", + VersionRange.createFromVersionSpec("[1.0,3.0]"), + "foo", + "bar", + "jar", + new DefaultArtifactHandler()), + Arrays.asList( + versions("1.0.0.1", "1.0.0.2", "2.121.2.1", "2.100.0.1", "3.1.0.1", "1.1.1", "2.0.0-SNAPSHOT")), + comparator); assertEquals("artifact", instance.getArtifactId()); assertEquals("group", instance.getGroupId()); assertThat( @@ -72,180 +64,219 @@ public void test4DigitVersions() throws Exception { arrayContaining(versions( "1.0.0.1", "1.0.0.2", "1.1.1", "2.0.0-SNAPSHOT", "2.100.0.1", "2.121.2.1", "3.1.0.1"))); assertThat( - instance.getVersions(DefaultArtifactVersionCache.of("1.1"), null, false), + instance.getVersions(new Restriction(version("1.1"), false, null, false), false), arrayContaining(versions("1.1.1", "2.100.0.1", "2.121.2.1", "3.1.0.1"))); assertThat( - instance.getVersions(DefaultArtifactVersionCache.of("1.1"), null, true), + instance.getVersions(new Restriction(version("1.1"), false, null, false), true), arrayContaining(versions("1.1.1", "2.0.0-SNAPSHOT", "2.100.0.1", "2.121.2.1", "3.1.0.1"))); assertThat( - instance.getVersions(DefaultArtifactVersionCache.of("1.0.0.2"), null, false), + instance.getVersions(new Restriction(version("1.0.0.2"), false, null, false), false), // Matchers.arrayContaining(versions("1.1.1", "2.121.2.1", "2.100.0.1", "3.1.0.1"))); arrayContaining(versions("1.1.1", "2.100.0.1", "2.121.2.1", "3.1.0.1"))); assertThat( - instance.getVersions(DefaultArtifactVersionCache.of("1.0.0.2"), null, true), + instance.getVersions(new Restriction(version("1.0.0.2"), false, null, false), true), // Matchers.arrayContaining(versions("1.1.1", "2.121.2.1", "2.100.0.1", "3.1.0.1"))); arrayContaining(versions("1.1.1", "2.0.0-SNAPSHOT", "2.100.0.1", "2.121.2.1", "3.1.0.1"))); assertEquals( - DefaultArtifactVersionCache.of("2.121.2.1"), - instance.getNewestVersion( - DefaultArtifactVersionCache.of("1.0"), DefaultArtifactVersionCache.of("3.0"), false)); + version("2.121.2.1"), + instance.getNewestVersion(new Restriction(version("1.0"), false, version("3.0"), false), false)); - assertNull(instance.getNewestVersion( - DefaultArtifactVersionCache.of("1.1.1"), DefaultArtifactVersionCache.of("2.0"), false)); + assertNull(instance.getNewestVersion(new Restriction(version("1.1.1"), false, version("2.0"), false), false)); assertEquals( - DefaultArtifactVersionCache.of("2.0.0-SNAPSHOT"), - instance.getNewestVersion( - DefaultArtifactVersionCache.of("1.1.1"), DefaultArtifactVersionCache.of("2.0"), true)); + version("2.0.0-SNAPSHOT"), + instance.getNewestVersion(new Restriction(version("1.1.1"), false, version("2.0"), false), true)); + } + + @Test + public void test4DigitVersionsMercury() throws Exception { + test4DigitVersion(new MercuryVersionComparator()); + } + + @Test + public void test4DigitVersionsMaven() throws Exception { + test4DigitVersion(new MavenVersionComparator()); } @Test public void testIsEmpty() throws Exception { - ArtifactVersion[] versions = versions("1.0.1-SNAPSHOT", "1.0.2-SNAPSHOT"); - final DefaultArtifact artifact = new DefaultArtifact( - "group", - "artifact", - VersionRange.createFromVersionSpec("[1.0,3.0]"), - "foo", - "bar", - "jar", - new DefaultArtifactHandler()); - ArtifactVersions instance = - new ArtifactVersions(artifact, Arrays.asList(versions), new MavenVersionComparator()); + ArtifactVersions instance = new ArtifactVersions( + new DefaultArtifact( + "group", + "artifact", + VersionRange.createFromVersionSpec("[1.0,3.0]"), + "foo", + "bar", + "jar", + new DefaultArtifactHandler()), + Arrays.asList(versions("1.0.1-SNAPSHOT", "1.0.2-SNAPSHOT")), + new MavenVersionComparator()); assertThat(instance.isEmpty(false), is(true)); assertThat(instance.isEmpty(true), is(false)); } @Test public void testSmokes() throws Exception { - ArtifactVersion[] versions = versions("1.0", "3.0", "1.1", "1.0", "1.0.1"); - final DefaultArtifact artifact = new DefaultArtifact( - "group", - "artifact", - VersionRange.createFromVersionSpec("[1.0,3.0]"), - "foo", - "bar", - "jar", - new DefaultArtifactHandler()); - ArtifactVersions instance = - new ArtifactVersions(artifact, Arrays.asList(versions), new MavenVersionComparator()); + ArtifactVersions instance = new ArtifactVersions( + new DefaultArtifact( + "group", + "artifact", + VersionRange.createFromVersionSpec("[1.0,3.0]"), + "foo", + "bar", + "jar", + new DefaultArtifactHandler()), + Arrays.asList(versions("1.0", "3.0", "1.1", "1.0", "1.0.1")), + new MavenVersionComparator()); assertEquals("artifact", instance.getArtifactId()); assertEquals("group", instance.getGroupId()); assertArrayEquals(versions("1.0", "1.0.1", "1.1", "3.0"), instance.getVersions(true)); - assertArrayEquals(versions("3.0"), instance.getVersions(DefaultArtifactVersionCache.of("1.1"), null, true)); assertArrayEquals( - versions("1.1", "3.0"), instance.getVersions(DefaultArtifactVersionCache.of("1.0.1"), null, true)); + versions("3.0"), instance.getVersions(new Restriction(version("1.1"), false, null, false), true)); + assertArrayEquals( + versions("1.1", "3.0"), + instance.getVersions(new Restriction(version("1.0.1"), false, null, false), true)); assertEquals( - DefaultArtifactVersionCache.of("1.1"), - instance.getNewestVersion( - DefaultArtifactVersionCache.of("1.0"), DefaultArtifactVersionCache.of("3.0"), true)); - assertNull(instance.getNewestVersion( - DefaultArtifactVersionCache.of("1.1"), DefaultArtifactVersionCache.of("3.0"), true)); - } - - private ArtifactVersion[] versions(String... versions) { - ArtifactVersion[] artifactVersions = new ArtifactVersion[versions.length]; - for (int i = 0; i < versions.length; i++) { - artifactVersions[i] = DefaultArtifactVersionCache.of(versions[i]); - } - return artifactVersions; + version("1.1"), + instance.getNewestVersion(new Restriction(version("1.0"), false, version("3.0"), false), true)); + assertNull(instance.getNewestVersion(new Restriction(version("1.1"), false, version("3.0"), false), true)); } @Test public void testReportLabels() { - ArtifactVersion[] versions = versions( - "1.0.1", - "1.0", - "1.1.0-2", - "1.1.1", - "1.1.1-2", - "1.1.2", - "1.1.2-SNAPSHOT", - "1.1.3", - "1.1", - "1.1-SNAPSHOT", - "1.2.1", - "1.2.2", - "1.2", - "1.3", - "1.9.1-SNAPSHOT", - "2.0", - "2.1.1-SNAPSHOT", - "2.1", - "3.0", - "3.1.1-SNAPSHOT", - "3.1.5-SNAPSHOT", - "3.4.0-SNAPSHOT"); ArtifactVersions instance = new ArtifactVersions( new DefaultArtifact("default-group", "dummy-api", "1.1", "foo", "bar", "jar", null), - Arrays.asList(versions), + Arrays.asList(versions( + "1.0.1", + "1.0", + "1.1.0-2", + "1.1.1", + "1.1.1-2", + "1.1.2", + "1.1.2-SNAPSHOT", + "1.1.3", + "1.1", + "1.1-SNAPSHOT", + "1.2.1", + "1.2.2", + "1.2", + "1.3", + "1.9.1-SNAPSHOT", + "2.0", + "2.1.1-SNAPSHOT", + "2.1", + "3.0", + "3.1.1-SNAPSHOT", + "3.1.5-SNAPSHOT", + "3.4.0-SNAPSHOT")), new MavenVersionComparator()); - assertThat(instance.getNewestUpdate(of(SUBINCREMENTAL), false).toString(), is("1.1.0-2")); - assertThat(instance.getNewestUpdate(of(INCREMENTAL), false).toString(), is("1.1.3")); + assertThat(instance.getNewestUpdateWithinSegment(of(SUBINCREMENTAL), false), hasToString("1.1.0-2")); + assertThat(instance.getNewestUpdateWithinSegment(of(INCREMENTAL), false), hasToString("1.1.3")); } @Test public void testGetNewerVersionsWithSnapshot() throws InvalidSegmentException { - ArtifactVersion[] versions = versions("1.0.0-SNAPSHOT", "1.0.0"); ArtifactVersions instance = new ArtifactVersions( new DefaultArtifact("default-group", "dummy-api", "1.0.0-SNAPSHOT", "foo", "bar", "jar", null), - Arrays.asList(versions), + Arrays.asList(versions("1.0.0-SNAPSHOT", "1.0.0")), new MavenVersionComparator()); assertThat( instance.getNewerVersions("1.0.0-SNAPSHOT", of(SUBINCREMENTAL), false, false), - arrayContaining(DefaultArtifactVersionCache.of("1.0.0"))); + arrayContaining(version("1.0.0"))); } - @Test - public void testAllVersionsForIgnoreScopeSubIncremental() { - ArtifactVersion[] versions = versions("1.0.0", "1.0.0-1", "1.0.1"); - ArtifactVersions instance = new ArtifactVersions( + private static ArtifactVersions createInstance(ArtifactVersion[] versions) { + return new ArtifactVersions( new DefaultArtifact("default-group", "dummy-api", "1.0.0", "foo", "bar", "jar", null), Arrays.asList(versions), new MavenVersionComparator()); - Restriction restriction = instance.restrictionForIgnoreScope(of(SUBINCREMENTAL)); - ArtifactVersion[] filteredVersions = instance.getVersions(restriction, false); + } + + @Test + public void testAllVersionsForIgnoreScopeSubIncremental() { + ArtifactVersions instance = createInstance(versions("1.0.0", "1.0.0-1", "1.0.1")); + ArtifactVersion[] filteredVersions = instance.getVersions( + instance.restrictionForIgnoreScope(instance.getCurrentVersion(), of(SUBINCREMENTAL)), false); assertThat(filteredVersions, arrayWithSize(1)); - assertThat(filteredVersions, arrayContaining(DefaultArtifactVersionCache.of("1.0.1"))); + assertThat(filteredVersions, arrayContaining(version("1.0.1"))); } @Test public void testAllVersionsForIgnoreScopeIncremental() { - ArtifactVersion[] versions = versions("1.0.0", "1.0.0-1", "1.0.1", "1.1.0"); - ArtifactVersions instance = new ArtifactVersions( - new DefaultArtifact("default-group", "dummy-api", "1.0.0", "foo", "bar", "jar", null), - Arrays.asList(versions), - new MavenVersionComparator()); - Restriction restriction = instance.restrictionForIgnoreScope(of(INCREMENTAL)); - ArtifactVersion[] filteredVersions = instance.getVersions(restriction, false); + ArtifactVersions instance = createInstance(versions("1.0.0", "1.0.0-1", "1.0.1", "1.1.0")); + ArtifactVersion[] filteredVersions = instance.getVersions( + instance.restrictionForIgnoreScope(instance.getCurrentVersion(), of(INCREMENTAL)), false); assertThat(filteredVersions, arrayWithSize(1)); - assertThat(filteredVersions, arrayContaining(DefaultArtifactVersionCache.of("1.1.0"))); + assertThat(filteredVersions, arrayContaining(version("1.1.0"))); } @Test public void testAllVersionsForIgnoreScopeMinor() { - ArtifactVersion[] versions = versions("1.0.0", "1.0.0-1", "1.0.1", "1.1.0", "2.0.0"); - ArtifactVersions instance = new ArtifactVersions( - new DefaultArtifact("default-group", "dummy-api", "1.0.0", "foo", "bar", "jar", null), - Arrays.asList(versions), - new MavenVersionComparator()); - Restriction restriction = instance.restrictionForIgnoreScope(of(MINOR)); - ArtifactVersion[] filteredVersions = instance.getVersions(restriction, false); + ArtifactVersions instance = createInstance(versions("1.0.0", "1.0.0-1", "1.0.1", "1.1.0", "2.0.0")); + ArtifactVersion[] filteredVersions = instance.getVersions( + instance.restrictionForIgnoreScope(instance.getCurrentVersion(), of(MINOR)), false); assertThat(filteredVersions, arrayWithSize(1)); - assertThat(filteredVersions, arrayContaining(DefaultArtifactVersionCache.of("2.0.0"))); + assertThat(filteredVersions, arrayContaining(version("2.0.0"))); } @Test public void testAllVersionsForIgnoreScopeMajor() { - ArtifactVersion[] versions = versions("1.0.0", "1.0.0-1", "1.0.1", "1.1.0", "2.0.0"); - ArtifactVersions instance = new ArtifactVersions( - new DefaultArtifact("default-group", "dummy-api", "1.0.0", "foo", "bar", "jar", null), - Arrays.asList(versions), - new MavenVersionComparator()); - Restriction restriction = instance.restrictionForIgnoreScope(of(MAJOR)); - ArtifactVersion[] filteredVersions = instance.getVersions(restriction, false); + ArtifactVersions instance = createInstance(versions("1.0.0", "1.0.0-1", "1.0.1", "1.1.0", "2.0.0")); + ArtifactVersion[] filteredVersions = instance.getVersions( + instance.restrictionForIgnoreScope(instance.getCurrentVersion(), of(MAJOR)), false); assertThat(filteredVersions, arrayWithSize(0)); } + + @Test + public void testGetReportNewestUpdateWithOnlyMajorUpdate() { + ArtifactVersions instance = createInstance(versions("1.0.0", "2.0.0")); + assertThat(instance.getReportNewestUpdate(Optional.empty(), true).toString(), is("2.0.0")); + assertThat(instance.getReportNewestUpdate(of(MAJOR), true), hasToString("2.0.0")); + assertThat(instance.getReportNewestUpdate(of(MINOR), true), nullValue()); + assertThat(instance.getReportNewestUpdate(of(INCREMENTAL), true), nullValue()); + assertThat(instance.getReportNewestUpdate(of(SUBINCREMENTAL), true), nullValue()); + } + + @Test + public void testGetReportNewestUpdateWithMinorAndMajor() { + ArtifactVersions instance = createInstance(versions("1.0.0", "1.1.0", "2.0.0")); + assertThat(instance.getReportNewestUpdate(Optional.empty(), true).toString(), is("2.0.0")); + assertThat(instance.getReportNewestUpdate(of(MAJOR), true), hasToString("2.0.0")); + assertThat(instance.getReportNewestUpdate(of(MINOR), true), hasToString("1.1.0")); + assertThat(instance.getReportNewestUpdate(of(INCREMENTAL), true), nullValue()); + assertThat(instance.getReportNewestUpdate(of(SUBINCREMENTAL), true), nullValue()); + } + + @Test + public void testGetReportNewestUpdateWithIncrementalAndMajor() { + ArtifactVersions instance = createInstance(versions("1.0.0", "1.0.1", "2.0.0")); + assertThat(instance.getReportNewestUpdate(Optional.empty(), true).toString(), is("2.0.0")); + assertThat(instance.getReportNewestUpdate(of(MAJOR), true), hasToString("2.0.0")); + assertThat(instance.getReportNewestUpdate(of(MINOR), true), nullValue()); + assertThat(instance.getReportNewestUpdate(of(INCREMENTAL), true), hasToString("1.0.1")); + assertThat(instance.getReportNewestUpdate(of(SUBINCREMENTAL), true), nullValue()); + } + + @Test + public void testGetNewestVersionWithLesserSegment() throws InvalidSegmentException { + ArtifactVersions instance = createInstance(versions("1.0.0-1")); + assertThat(instance.getNewestVersion("1.0.0", of(MAJOR), false, false).get(), hasToString("1.0.0-1")); + assertThat(instance.getNewestVersion("1.0.0", of(MINOR), false, false).get(), hasToString("1.0.0-1")); + assertThat( + instance.getNewestVersion("1.0.0", of(INCREMENTAL), false, false) + .get(), + hasToString("1.0.0-1")); + } + + @Test + public void testGetNewestVersionWithLesserSegmentWithSnapshots() throws InvalidSegmentException { + ArtifactVersions instance = createInstance(versions("1.0.0-1-SNAPSHOT")); + assertThat(instance.getNewestVersion("1.0.0", of(MAJOR), true, false).get(), hasToString("1.0.0-1-SNAPSHOT")); + assertThat(instance.getNewestVersion("1.0.0", of(MINOR), true, false).get(), hasToString("1.0.0-1-SNAPSHOT")); + assertThat( + instance.getNewestVersion("1.0.0", of(INCREMENTAL), true, false).get(), + hasToString("1.0.0-1-SNAPSHOT")); + } } diff --git a/versions-common/src/test/java/org/codehaus/mojo/versions/utils/ArtifactVersionUtils.java b/versions-common/src/test/java/org/codehaus/mojo/versions/utils/ArtifactVersionUtils.java new file mode 100644 index 000000000..ed2da2e9d --- /dev/null +++ b/versions-common/src/test/java/org/codehaus/mojo/versions/utils/ArtifactVersionUtils.java @@ -0,0 +1,44 @@ +package org.codehaus.mojo.versions.utils; + +/* + * Copyright MojoHaus and Contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.Arrays; + +import org.apache.maven.artifact.versioning.ArtifactVersion; + +/** + * Misc utilities for manipulating {@link org.apache.maven.artifact.versioning.ArtifactVersion} objects + */ +public class ArtifactVersionUtils { + + /** + * Creates an {@link ArtifactVersion} from the given version string + * @param version string representation of the version + * @return {@link ArtifactVersion} from the given version string + */ + public static ArtifactVersion version(String version) { + return DefaultArtifactVersionCache.of(version); + } + + /** + * Produces an array of {@link ArtifactVersion} objects based on the array of version strings + * @param versions array of version strings + * @return array of {@link ArtifactVersion} objects based on the input array of version strings + */ + public static ArtifactVersion[] versions(String... versions) { + return Arrays.stream(versions).map(DefaultArtifactVersionCache::of).toArray(ArtifactVersion[]::new); + } +} diff --git a/versions-common/src/test/java/org/codehaus/mojo/versions/utils/SegmentUtilsTest.java b/versions-common/src/test/java/org/codehaus/mojo/versions/utils/SegmentUtilsTest.java index 7d22804b3..36a8c17de 100644 --- a/versions-common/src/test/java/org/codehaus/mojo/versions/utils/SegmentUtilsTest.java +++ b/versions-common/src/test/java/org/codehaus/mojo/versions/utils/SegmentUtilsTest.java @@ -18,6 +18,10 @@ * under the License. */ +import java.util.Optional; + +import org.apache.maven.plugin.logging.Log; +import org.codehaus.mojo.versions.api.Segment; import org.junit.Test; import static java.util.Optional.empty; @@ -53,6 +57,26 @@ public void testMajor() { @Test public void testEmpty() { - assertThat(determineUnchangedSegment(true, true, true, null), is(empty())); + Optional result; + boolean allowMinorUpdates = true; + boolean allowIncrementalUpdates = true; + Log log = null; + if (log != null && !allowIncrementalUpdates) { + log.info("Assuming allowMinorUpdates false because allowIncrementalUpdates is false."); + } + + Optional unchangedSegment = allowIncrementalUpdates + ? empty() + : allowMinorUpdates && allowIncrementalUpdates + ? of(MAJOR) + : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); + if (log != null && log.isDebugEnabled()) { + log.debug(unchangedSegment + .map(Segment::minorTo) + .map(Segment::toString) + .orElse("ALL") + " version changes allowed"); + } + result = unchangedSegment; + assertThat(result, is(empty())); } } diff --git a/versions-enforcer/src/main/java/org/apache/maven/plugins/enforcer/MaxDependencyUpdates.java b/versions-enforcer/src/main/java/org/apache/maven/plugins/enforcer/MaxDependencyUpdates.java index b3940e355..99f407a7a 100644 --- a/versions-enforcer/src/main/java/org/apache/maven/plugins/enforcer/MaxDependencyUpdates.java +++ b/versions-enforcer/src/main/java/org/apache/maven/plugins/enforcer/MaxDependencyUpdates.java @@ -361,7 +361,11 @@ public void execute(EnforcerRuleHelper ruleHelper) throws EnforcerRuleException : ignoreIncrementalUpdates ? of(INCREMENTAL) : ignoreMinorUpdates ? of(MINOR) : empty(); List upgradable = versionsHelper.lookupDependenciesUpdates(dependencies, false, allowSnapshots).values().stream() - .filter(v -> v.getVersions(v.restrictionForIgnoreScope(ignoredSegment), true).length > 0) + .filter(v -> v.getVersions( + v.restrictionForIgnoreScope(v.getCurrentVersion(), ignoredSegment), + true) + .length + > 0) .collect(Collectors.toList()); if (upgradable.size() > maxUpdates) { throw new EnforcerRuleException("More than " + maxUpdates + " upgradable artifacts detected: " diff --git a/versions-maven-plugin/src/it/it-compare-dependencies-006/verify.bsh b/versions-maven-plugin/src/it/it-compare-dependencies-006/verify.bsh index e946cfc7d..c21d99b4b 100644 --- a/versions-maven-plugin/src/it/it-compare-dependencies-006/verify.bsh +++ b/versions-maven-plugin/src/it/it-compare-dependencies-006/verify.bsh @@ -11,7 +11,7 @@ try System.err.println( "Version diff in maven artifact not found. it should be processed because its scope is compile" ); return false; } - if ( buf.indexOf( "4.0 -> 4.1" ) > 0 ) +if ( buf.indexOf( "4.0 -> 4.1" ) > 0 ) { System.err.println( "Version diff in junit artifact found. it should be excluded because its scope is test" ); return false; diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java index bb0600c73..cec1a8dfe 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java @@ -21,16 +21,11 @@ import javax.inject.Inject; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.TreeSet; +import java.util.*; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.Restriction; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -43,6 +38,7 @@ import org.codehaus.mojo.versions.api.VersionRetrievalException; import org.codehaus.mojo.versions.api.recording.ChangeRecorder; import org.codehaus.mojo.versions.filtering.WildcardMatcher; +import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; import org.codehaus.mojo.versions.utils.DependencyComparator; import org.codehaus.mojo.versions.utils.SegmentUtils; @@ -50,13 +46,9 @@ import static java.util.Collections.emptySet; import static java.util.Optional.empty; -import static java.util.Optional.of; import static org.apache.commons.lang3.StringUtils.countMatches; -import static org.codehaus.mojo.versions.api.Segment.MAJOR; import static org.codehaus.mojo.versions.filtering.DependencyFilter.filterDependencies; -import static org.codehaus.mojo.versions.utils.MavenProjectUtils.extractDependenciesFromDependencyManagement; -import static org.codehaus.mojo.versions.utils.MavenProjectUtils.extractDependenciesFromPlugins; -import static org.codehaus.mojo.versions.utils.MavenProjectUtils.extractPluginDependenciesFromPluginsInPluginManagement; +import static org.codehaus.mojo.versions.utils.MavenProjectUtils.*; /** * Displays all dependencies that have newer versions available. @@ -218,9 +210,6 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo { /** * Whether to allow the major version number to be changed. * - *

Note: {@code false} also implies {@linkplain #allowAnyUpdates} - * to be {@code false}

- * * @since 2.5 */ @Parameter(property = "allowMajorUpdates", defaultValue = "true") @@ -229,8 +218,7 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo { /** *

Whether to allow the minor version number to be changed.

* - *

Note: {@code false} also implies {@linkplain #allowAnyUpdates} - * and {@linkplain #allowMajorUpdates} to be {@code false}

+ *

Note: {@code false} also implies {@linkplain #allowMajorUpdates} to be {@code false}

* * @since 2.5 */ @@ -240,29 +228,14 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo { /** *

Whether to allow the incremental version number to be changed.

* - *

Note: {@code false} also implies {@linkplain #allowAnyUpdates}, - * {@linkplain #allowMajorUpdates}, and {@linkplain #allowMinorUpdates} - * to be {@code false}

+ *

Note: {@code false} also implies {@linkplain #allowMajorUpdates} + * and {@linkplain #allowMinorUpdates} to be {@code false}

* * @since 2.5 */ @Parameter(property = "allowIncrementalUpdates", defaultValue = "true") private boolean allowIncrementalUpdates = true; - /** - * Whether to allow any version change to be allowed. This keeps - * compatibility with previous versions of the plugin. - * If you set this to false you can control changes in version - * number by {@link #allowMajorUpdates}, {@link #allowMinorUpdates} or - * {@link #allowIncrementalUpdates}. - * - * @since 2.5 - * @deprecated This will be removed with version 3.0.0 - */ - @Deprecated - @Parameter(property = "allowAnyUpdates", defaultValue = "true") - private boolean allowAnyUpdates = true; - /** * Whether to show additional information such as dependencies that do not need updating. Defaults to false. * @@ -310,7 +283,7 @@ public class DisplayDependencyUpdatesMojo extends AbstractVersionsDisplayMojo { /** *

Only take these artifacts into consideration:
* Comma-separated list of {@code groupId:[artifactId[:version]]} patterns

- * + *

* The wildcard "*" can be used as the only, first, last or both characters in each token. * The version token does support version ranges. *

@@ -497,8 +470,8 @@ protected void validateInput() throws MojoExecutionException { /** * Validates a list of GAV strings - * @param gavList list of the input GAV strings - * @param numSections number of sections in the GAV to verify against + * @param gavList list of the input GAV strings + * @param numSections number of sections in the GAV to verify against * @param argumentName argument name to indicate in the exception * @throws MojoExecutionException if the argument is invalid */ @@ -509,40 +482,44 @@ static void validateGAVList(List gavList, int numSections, String argume } } - private Optional calculateUpdateScope() { - return allowAnyUpdates - ? empty() - : of(SegmentUtils.determineUnchangedSegment( - allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()) - .map(s -> Segment.of(s.value() + 1)) - .orElse(MAJOR)); - } - private void logUpdates(Map updates, String section) { List withUpdates = new ArrayList<>(); List usingCurrent = new ArrayList<>(); for (ArtifactVersions versions : updates.values()) { String left = " " + ArtifactUtils.versionlessKey(versions.getArtifact()) + " "; - final String current; - ArtifactVersion latest; - if (versions.isCurrentVersionDefined()) { - current = versions.getCurrentVersion().toString(); - latest = versions.getNewestUpdate(calculateUpdateScope(), allowSnapshots); + String currentVersion; + Optional latestVersion; + Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( + allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); + if (versions.getCurrentVersion() != null) { + currentVersion = versions.getCurrentVersion().toString(); + try { + latestVersion = versions.getNewestVersion(currentVersion, unchangedSegment, allowSnapshots, false); + } catch (InvalidSegmentException e) { + latestVersion = empty(); + } } else { - ArtifactVersion newestVersion = + currentVersion = versions.getArtifact().getVersionRange().toString(); + ArtifactVersion actualVersion = versions.getNewestVersion(versions.getArtifact().getVersionRange(), allowSnapshots); - current = versions.getArtifact().getVersionRange().toString(); - latest = newestVersion == null - ? null - : versions.getNewestUpdate(newestVersion, calculateUpdateScope(), allowSnapshots); - if (latest != null - && ArtifactVersions.isVersionInRange( - latest, versions.getArtifact().getVersionRange())) { - latest = null; + Restriction newVersionRestriction; + try { + Restriction segmentRestriction = + versions.restrictionForUnchangedSegment(actualVersion, unchangedSegment, false); + newVersionRestriction = new Restriction( + actualVersion, + false, + segmentRestriction.getUpperBound(), + segmentRestriction.isUpperBoundInclusive()); + } catch (InvalidSegmentException e) { + throw new RuntimeException(e); } + latestVersion = Optional.of(newVersionRestriction) + .map(restriction -> versions.getNewestVersion(restriction, allowSnapshots)); } - String right = " " + (latest == null ? current : current + " -> " + latest); - List t = latest == null ? usingCurrent : withUpdates; + String right = + " " + latestVersion.map(v -> currentVersion + " -> " + v).orElse(currentVersion); + List t = latestVersion.isPresent() ? withUpdates : usingCurrent; if (right.length() + left.length() + 3 > INFO_PAD_SIZE + getOutputLineWidthOffset()) { t.add(left + "..."); t.add(StringUtils.leftPad(right, INFO_PAD_SIZE + getOutputLineWidthOffset())); diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojo.java index 1b6d389e2..01103b968 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayExtensionUpdatesMojo.java @@ -42,10 +42,7 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.wagon.Wagon; -import org.codehaus.mojo.versions.api.ArtifactVersions; -import org.codehaus.mojo.versions.api.PomHelper; -import org.codehaus.mojo.versions.api.Segment; -import org.codehaus.mojo.versions.api.VersionRetrievalException; +import org.codehaus.mojo.versions.api.*; import org.codehaus.mojo.versions.api.recording.ChangeRecorder; import org.codehaus.mojo.versions.filtering.DependencyFilter; import org.codehaus.mojo.versions.filtering.WildcardMatcher; @@ -282,7 +279,7 @@ private List getRawModels() throws MojoFailureException { private Optional calculateUpdateScope() { return of(SegmentUtils.determineUnchangedSegment( allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()) - .map(s -> Segment.of(s.value() + 1)) + .map(Segment::minorTo) .orElse(MAJOR)); } @@ -293,16 +290,16 @@ private void logUpdates(Map updates) { String left = " " + ArtifactUtils.versionlessKey(versions.getArtifact()) + " "; final String current; ArtifactVersion latest; - if (versions.isCurrentVersionDefined()) { + if (versions.getCurrentVersion() != null) { current = versions.getCurrentVersion().toString(); - latest = versions.getNewestUpdate(calculateUpdateScope(), allowSnapshots); + latest = versions.getNewestUpdateWithinSegment(calculateUpdateScope(), allowSnapshots); } else { ArtifactVersion newestVersion = versions.getNewestVersion(versions.getArtifact().getVersionRange(), allowSnapshots); current = versions.getArtifact().getVersionRange().toString(); latest = newestVersion == null ? null - : versions.getNewestUpdate(newestVersion, calculateUpdateScope(), allowSnapshots); + : versions.getNewestUpdateWithinSegment(newestVersion, calculateUpdateScope(), allowSnapshots); if (latest != null && ArtifactVersions.isVersionInRange( latest, versions.getArtifact().getVersionRange())) { diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojo.java index ba5a0061e..34065d53a 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojo.java @@ -31,6 +31,7 @@ import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.repository.RepositorySystem; @@ -42,7 +43,10 @@ import org.codehaus.mojo.versions.api.recording.ChangeRecorder; import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; -import org.codehaus.mojo.versions.utils.SegmentUtils; + +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.codehaus.mojo.versions.api.Segment.*; /** * Displays properties that are linked to artifact versions and have updates available. @@ -168,8 +172,27 @@ public void execute() throws MojoExecutionException, MojoFailureException { continue; } - Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( - allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); + Log log = getLog(); + if (log != null && !allowIncrementalUpdates) { + log.info("Assuming allowMinorUpdates false because allowIncrementalUpdates is false."); + } + + if (log != null && !allowMinorUpdates) { + log.info("Assuming allowMajorUpdates false because allowMinorUpdates is false."); + } + + Optional unchangedSegment1 = allowMajorUpdates && allowMinorUpdates && allowIncrementalUpdates + ? empty() + : allowMinorUpdates && allowIncrementalUpdates + ? of(MAJOR) + : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); + if (log != null && log.isDebugEnabled()) { + log.debug(unchangedSegment1 + .map(Segment::minorTo) + .map(Segment::toString) + .orElse("ALL") + " version changes allowed"); + } + Optional unchangedSegment = unchangedSegment1; try { ArtifactVersion winner = version.getNewestVersion( currentVersion, diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/ResolveRangesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/ResolveRangesMojo.java index f9ccfdad0..e8c3acc3d 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/ResolveRangesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/ResolveRangesMojo.java @@ -35,6 +35,7 @@ import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.repository.RepositorySystem; @@ -48,7 +49,10 @@ import org.codehaus.mojo.versions.api.recording.ChangeRecorder; import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; -import org.codehaus.mojo.versions.utils.SegmentUtils; + +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.codehaus.mojo.versions.api.Segment.*; /** * Attempts to resolve dependency version ranges to the specific version being used in the build. For example a version @@ -288,8 +292,27 @@ private void resolvePropertyRanges(ModifiedPomXMLEventReader pom) property.setVersion(currentVersion); - Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( - allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); + Log log = getLog(); + if (log != null && !allowIncrementalUpdates) { + log.info("Assuming allowMinorUpdates false because allowIncrementalUpdates is false."); + } + + if (log != null && !allowMinorUpdates) { + log.info("Assuming allowMajorUpdates false because allowMinorUpdates is false."); + } + + Optional unchangedSegment1 = allowMajorUpdates && allowMinorUpdates && allowIncrementalUpdates + ? empty() + : allowMinorUpdates && allowIncrementalUpdates + ? of(MAJOR) + : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); + if (log != null && log.isDebugEnabled()) { + log.debug(unchangedSegment1 + .map(Segment::minorTo) + .map(Segment::toString) + .orElse("ALL") + " version changes allowed"); + } + Optional unchangedSegment = unchangedSegment1; // TODO: Check if we could add allowDowngrade ? try { updatePropertyToNewestVersion(pom, property, version, currentVersion, false, unchangedSegment); diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java index 376c95b2d..dbf78238c 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java @@ -30,6 +30,7 @@ import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.repository.RepositorySystem; @@ -45,9 +46,11 @@ import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; import org.codehaus.mojo.versions.utils.DefaultArtifactVersionCache; import org.codehaus.mojo.versions.utils.DependencyBuilder; -import org.codehaus.mojo.versions.utils.SegmentUtils; +import static java.util.Optional.empty; +import static java.util.Optional.of; import static org.apache.maven.shared.utils.StringUtils.isBlank; +import static org.codehaus.mojo.versions.api.Segment.*; /** * Sets the parent version to the latest parent version. @@ -212,8 +215,27 @@ protected ArtifactVersion resolveTargetVersion(String initialVersion) } final ArtifactVersions versions = getHelper().lookupArtifactVersions(artifact, false); - Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( - allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); + Log log = getLog(); + if (log != null && !allowIncrementalUpdates) { + log.info("Assuming allowMinorUpdates false because allowIncrementalUpdates is false."); + } + + if (log != null && !allowMinorUpdates) { + log.info("Assuming allowMajorUpdates false because allowMinorUpdates is false."); + } + + Optional unchangedSegment1 = allowMajorUpdates && allowMinorUpdates && allowIncrementalUpdates + ? empty() + : allowMinorUpdates && allowIncrementalUpdates + ? of(MAJOR) + : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); + if (log != null && log.isDebugEnabled()) { + log.debug(unchangedSegment1 + .map(Segment::minorTo) + .map(Segment::toString) + .orElse("ALL") + " version changes allowed"); + } + Optional unchangedSegment = unchangedSegment1; // currentVersion (set to parentVersion here) is not included in the version range for searching upgrades // unless we set allowDowngrade to true diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdatePropertiesMojoBase.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdatePropertiesMojoBase.java index 3274bb2f4..a8e7c232e 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdatePropertiesMojoBase.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdatePropertiesMojoBase.java @@ -23,6 +23,7 @@ import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.repository.RepositorySystem; import org.apache.maven.wagon.Wagon; @@ -37,7 +38,9 @@ import org.codehaus.mojo.versions.recording.DefaultPropertyChangeRecord; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; -import static org.codehaus.mojo.versions.utils.SegmentUtils.determineUnchangedSegment; +import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.codehaus.mojo.versions.api.Segment.*; /** * Common base class for {@link UpdatePropertiesMojo} @@ -133,8 +136,27 @@ protected void update(ModifiedPomXMLEventReader pom, Map unchangedSegment = determineUnchangedSegment( - allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); + Log log = getLog(); + if (log != null && !allowIncrementalUpdates) { + log.info("Assuming allowMinorUpdates false because allowIncrementalUpdates is false."); + } + + if (log != null && !allowMinorUpdates) { + log.info("Assuming allowMajorUpdates false because allowMinorUpdates is false."); + } + + Optional unchangedSegment1 = allowMajorUpdates && allowMinorUpdates && allowIncrementalUpdates + ? empty() + : allowMinorUpdates && allowIncrementalUpdates + ? of(MAJOR) + : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); + if (log != null && log.isDebugEnabled()) { + log.debug(unchangedSegment1 + .map(Segment::minorTo) + .map(Segment::toString) + .orElse("ALL") + " version changes allowed"); + } + Optional unchangedSegment = unchangedSegment1; try { ArtifactVersion targetVersion = updatePropertyToNewestVersion( pom, property, version, currentVersion, allowDowngrade, unchangedSegment); diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestReleasesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestReleasesMojo.java index ea316a38f..9f4118237 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestReleasesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestReleasesMojo.java @@ -33,6 +33,7 @@ import org.apache.maven.model.DependencyManagement; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.repository.RepositorySystem; @@ -44,10 +45,11 @@ import org.codehaus.mojo.versions.api.recording.DependencyChangeRecord; import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; -import org.codehaus.mojo.versions.utils.SegmentUtils; import static java.util.Collections.singletonList; import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.codehaus.mojo.versions.api.Segment.*; /** * Replaces any release versions (i.e. versions that are not snapshots and do not @@ -149,8 +151,27 @@ private void useLatestReleases( Collection dependencies, DependencyChangeRecord.ChangeKind changeKind) throws XMLStreamException, MojoExecutionException, VersionRetrievalException { - Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( - allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); + Log log = getLog(); + if (log != null && !allowIncrementalUpdates) { + log.info("Assuming allowMinorUpdates false because allowIncrementalUpdates is false."); + } + + if (log != null && !allowMinorUpdates) { + log.info("Assuming allowMajorUpdates false because allowMinorUpdates is false."); + } + + Optional unchangedSegment1 = allowMajorUpdates && allowMinorUpdates && allowIncrementalUpdates + ? empty() + : allowMinorUpdates && allowIncrementalUpdates + ? of(MAJOR) + : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); + if (log != null && log.isDebugEnabled()) { + log.debug(unchangedSegment1 + .map(Segment::minorTo) + .map(Segment::toString) + .orElse("ALL") + " version changes allowed"); + } + Optional unchangedSegment = unchangedSegment1; useLatestVersions( pom, diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestSnapshotsMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestSnapshotsMojo.java index 7b00dac7f..ca1de3046 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestSnapshotsMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestSnapshotsMojo.java @@ -29,6 +29,7 @@ import org.apache.maven.model.DependencyManagement; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.repository.RepositorySystem; @@ -40,10 +41,11 @@ import org.codehaus.mojo.versions.api.recording.DependencyChangeRecord; import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; -import org.codehaus.mojo.versions.utils.SegmentUtils; import static java.util.Collections.singletonList; import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.codehaus.mojo.versions.api.Segment.*; /** * Replaces any release versions with the latest snapshot version (if it has been deployed). @@ -128,8 +130,27 @@ private void useLatestSnapshots( Collection dependencies, DependencyChangeRecord.ChangeKind changeKind) throws XMLStreamException, MojoExecutionException, VersionRetrievalException { - Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( - allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); + Log log = getLog(); + if (log != null && !allowIncrementalUpdates) { + log.info("Assuming allowMinorUpdates false because allowIncrementalUpdates is false."); + } + + if (log != null && !allowMinorUpdates) { + log.info("Assuming allowMajorUpdates false because allowMinorUpdates is false."); + } + + Optional unchangedSegment1 = allowMajorUpdates && allowMinorUpdates && allowIncrementalUpdates + ? empty() + : allowMinorUpdates && allowIncrementalUpdates + ? of(MAJOR) + : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); + if (log != null && log.isDebugEnabled()) { + log.debug(unchangedSegment1 + .map(Segment::minorTo) + .map(Segment::toString) + .orElse("ALL") + " version changes allowed"); + } + Optional unchangedSegment = unchangedSegment1; useLatestVersions( pom, diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojo.java index 1dc4615cc..c324ef2d6 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojo.java @@ -27,6 +27,7 @@ import org.apache.maven.model.DependencyManagement; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.repository.RepositorySystem; @@ -38,10 +39,11 @@ import org.codehaus.mojo.versions.api.recording.DependencyChangeRecord; import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; -import org.codehaus.mojo.versions.utils.SegmentUtils; import static java.util.Collections.singletonList; import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.codehaus.mojo.versions.api.Segment.*; /** * Replaces any version with the latest version found in the artifactory. @@ -143,8 +145,27 @@ private void useLatestVersions( Collection dependencies, DependencyChangeRecord.ChangeKind changeKind) throws XMLStreamException, MojoExecutionException, VersionRetrievalException { - Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( - allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); + Log log = getLog(); + if (log != null && !allowIncrementalUpdates) { + log.info("Assuming allowMinorUpdates false because allowIncrementalUpdates is false."); + } + + if (log != null && !allowMinorUpdates) { + log.info("Assuming allowMajorUpdates false because allowMinorUpdates is false."); + } + + Optional unchangedSegment1 = allowMajorUpdates && allowMinorUpdates && allowIncrementalUpdates + ? empty() + : allowMinorUpdates && allowIncrementalUpdates + ? of(MAJOR) + : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); + if (log != null && log.isDebugEnabled()) { + log.debug(unchangedSegment1 + .map(Segment::minorTo) + .map(Segment::toString) + .orElse("ALL") + " version changes allowed"); + } + Optional unchangedSegment = unchangedSegment1; useLatestVersions( pom, diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextSnapshotsMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextSnapshotsMojo.java index 802528c54..8e4e96998 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextSnapshotsMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextSnapshotsMojo.java @@ -28,6 +28,7 @@ import org.apache.maven.model.DependencyManagement; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.repository.RepositorySystem; @@ -39,10 +40,11 @@ import org.codehaus.mojo.versions.api.recording.DependencyChangeRecord; import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; -import org.codehaus.mojo.versions.utils.SegmentUtils; import static java.util.Collections.singletonList; import static java.util.Optional.empty; +import static java.util.Optional.of; +import static org.codehaus.mojo.versions.api.Segment.*; /** * Replaces any release versions with the next snapshot version (if it has been deployed). @@ -127,8 +129,27 @@ private void useNextSnapshots( Collection dependencies, DependencyChangeRecord.ChangeKind changeKind) throws XMLStreamException, MojoExecutionException, VersionRetrievalException { - Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( - allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); + Log log = getLog(); + if (log != null && !allowIncrementalUpdates) { + log.info("Assuming allowMinorUpdates false because allowIncrementalUpdates is false."); + } + + if (log != null && !allowMinorUpdates) { + log.info("Assuming allowMajorUpdates false because allowMinorUpdates is false."); + } + + Optional unchangedSegment1 = allowMajorUpdates && allowMinorUpdates && allowIncrementalUpdates + ? empty() + : allowMinorUpdates && allowIncrementalUpdates + ? of(MAJOR) + : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); + if (log != null && log.isDebugEnabled()) { + log.debug(unchangedSegment1 + .map(Segment::minorTo) + .map(Segment::toString) + .orElse("ALL") + " version changes allowed"); + } + Optional unchangedSegment = unchangedSegment1; useLatestVersions( pom, diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/OverviewStats.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/OverviewStats.java index 1553ccdfa..f7fc0febd 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/OverviewStats.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/OverviewStats.java @@ -57,7 +57,7 @@ public class OverviewStats { * @param updates collection of all version updates, typically from * {@linkplain org.codehaus.mojo.versions.reporting.model.DependencyUpdatesModel#getAllUpdates()} * @param cache if not null, cache to retrieve the version information, initialised with - * the {@link ArtifactVersions#getNewestUpdate(Optional, boolean)} update information + * the {@link ArtifactVersions#getNewestUpdateWithinSegment(Optional, boolean)} update information * @param subclass of {@linkplain OverviewStats} * @param subclass of {@linkplain ArtifactVersions} * @param allowSnapshots whether snapshots should be included @@ -84,9 +84,8 @@ public static T from protected static ArtifactVersion getNewestUpdate( ArtifactVersionsCache cache, V details, Optional segment, boolean allowSnapshots) { - return cache != null - ? cache.get(details, segment, allowSnapshots) - : details.getNewestUpdate(segment, allowSnapshots); + assert cache != null; + return cache.get(details, segment, allowSnapshots); } public int getMajor() { diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/PluginOverviewStats.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/PluginOverviewStats.java index 5fa0e5632..7f8fcdc69 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/PluginOverviewStats.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/PluginOverviewStats.java @@ -1,4 +1,5 @@ package org.codehaus.mojo.versions.reporting; + /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -53,7 +54,7 @@ public void incrementDependencies() { * * @param updates collection of all version updates, typically from {@linkplain PluginUpdatesModel#getAllUpdates()} * @param cache if not null, cache to retrieve the version information, initialised with - * the {@link ArtifactVersions#getNewestUpdate(Optional, boolean)} update information + * the {@link ArtifactVersions#getNewestUpdateWithinSegment(Optional, boolean)} update information * @param always equal to {@linkplain PluginOverviewStats} * @param always equal to {@linkplain PluginUpdatesDetails} * @param allowSnapshots whether snapshots should be included diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/DependencyUpdatesXmlReportRenderer.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/DependencyUpdatesXmlReportRenderer.java index d009a3853..8cdec4a6a 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/DependencyUpdatesXmlReportRenderer.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/DependencyUpdatesXmlReportRenderer.java @@ -60,7 +60,7 @@ public class DependencyUpdatesXmlReportRenderer implements ReportRenderer { private final DependencyUpdatesModel model; private final Path outputFile; private final ArtifactVersionsCache newestUpdateCache = - new ArtifactVersionsCache(AbstractVersionDetails::getNewestUpdate); + new ArtifactVersionsCache(AbstractVersionDetails::getNewestUpdateWithinSegment); private final boolean allowSnapshots; @@ -126,7 +126,7 @@ private static List createDependencyInfo( setType(e.getKey().getType()); setClassifier(e.getKey().getClassifier()); - ofNullable(e.getValue().getNewestUpdate(empty(), allowSnapshots)) + ofNullable(e.getValue().getNewestUpdateWithinSegment(empty(), allowSnapshots)) .map(ArtifactVersion::toString) .ifPresent(this::setLastVersion); diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/PluginUpdatesXmlReportRenderer.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/PluginUpdatesXmlReportRenderer.java index c2921d3bd..7aac9e16a 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/PluginUpdatesXmlReportRenderer.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/PluginUpdatesXmlReportRenderer.java @@ -60,7 +60,7 @@ public class PluginUpdatesXmlReportRenderer implements ReportRenderer { private final PluginUpdatesModel model; private final Path outputFile; private final ArtifactVersionsCache newestUpdateCache = - new ArtifactVersionsCache(AbstractVersionDetails::getNewestUpdate); + new ArtifactVersionsCache(AbstractVersionDetails::getNewestUpdateWithinSegment); private final boolean allowSnapshots; @@ -126,7 +126,7 @@ private static List createPluginInfo( setType(e.getKey().getType()); setClassifier(e.getKey().getClassifier()); - ofNullable(e.getValue().getNewestUpdate(empty(), allowSnapshots)) + ofNullable(e.getValue().getNewestUpdateWithinSegment(empty(), allowSnapshots)) .map(ArtifactVersion::toString) .ifPresent(this::setLastVersion); diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/PropertyUpdatesXmlReportRenderer.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/PropertyUpdatesXmlReportRenderer.java index 5806f217f..8ad0e612f 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/PropertyUpdatesXmlReportRenderer.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/xml/PropertyUpdatesXmlReportRenderer.java @@ -59,7 +59,7 @@ public class PropertyUpdatesXmlReportRenderer implements ReportRenderer { private final PropertyUpdatesModel model; private final Path outputFile; private final ArtifactVersionsCache newestUpdateCache = - new ArtifactVersionsCache(AbstractVersionDetails::getNewestUpdate); + new ArtifactVersionsCache(AbstractVersionDetails::getNewestUpdateWithinSegment); private final boolean allowSnapshots; /** @@ -128,7 +128,7 @@ private static List createPropertyInfo( .collect(Collectors.toList())); } setCurrentVersion(e.getKey().getVersion()); - ofNullable(e.getValue().getNewestUpdate(empty(), allowSnapshots)) + ofNullable(e.getValue().getNewestUpdateWithinSegment(empty(), allowSnapshots)) .map(ArtifactVersion::toString) .ifPresent(this::setLastVersion); diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java index bb039104d..83a8c087e 100644 --- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java +++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojoTest.java @@ -1,40 +1,34 @@ package org.codehaus.mojo.versions; /* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at + * Copyright MojoHaus and Contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ import java.io.File; -import java.io.IOException; import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.apache.maven.model.Model; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.testing.AbstractMojoTestCase; import org.apache.maven.plugin.testing.MojoRule; import org.apache.maven.project.MavenProject; import org.codehaus.mojo.versions.filtering.WildcardMatcher; import org.codehaus.mojo.versions.model.TestIgnoreVersions; +import org.codehaus.mojo.versions.utils.CloseableTempFile; import org.codehaus.mojo.versions.utils.DependencyBuilder; import org.hamcrest.Matchers; import org.junit.Rule; @@ -45,16 +39,9 @@ import static java.util.Collections.singletonList; import static org.codehaus.mojo.versions.model.TestIgnoreVersions.TYPE_REGEX; import static org.codehaus.mojo.versions.model.TestIgnoreVersions.matches; -import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySystem; -import static org.codehaus.mojo.versions.utils.MockUtils.mockMavenSession; -import static org.codehaus.mojo.versions.utils.MockUtils.mockRepositorySystem; +import static org.codehaus.mojo.versions.utils.MockUtils.*; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.anyOf; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.*; /** * Basic tests for {@linkplain DisplayDependencyUpdatesMojo}. @@ -83,10 +70,7 @@ public void testValidateGAVListFailed() { @Test public void testRuleSetPresentAndWorking() throws Exception { - File outputFile = null; - try { - outputFile = File.createTempFile("display-dependency-updates", ""); - assert outputFile.exists(); + try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) { DisplayDependencyUpdatesMojo mojo = (DisplayDependencyUpdatesMojo) mojoRule.lookupConfiguredMojo( new File("target/test-classes/org/codehaus/mojo/display-dependency-updates/ruleset"), @@ -108,7 +92,7 @@ public void testRuleSetPresentAndWorking() throws Exception { .withVersion(".+-M\\d+")))); // This is just an example of how to create it-style tests as unit tests; the advantage is easier debugging - mojo.outputFile = outputFile; + mojo.outputFile = tempFile.getPath().toFile(); mojo.aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() { { put("dummy-api", new String[] {"1.0.0", "1.0.1", "1.1.0-M1", "1.2.0-SNAPSHOT"}); @@ -117,10 +101,8 @@ public void testRuleSetPresentAndWorking() throws Exception { assertThat(mojo.ruleSet.getIgnoreVersions(), Matchers.hasSize(3)); mojo.execute(); - List output = Files.readAllLines(outputFile.toPath(), UTF_8); + List output = Files.readAllLines(tempFile.getPath(), UTF_8); assertThat(output, not(hasItem(containsString("1.1.0-M1")))); - } finally { - assert outputFile == null || !outputFile.exists() || outputFile.delete(); } } @@ -145,12 +127,8 @@ private MavenProject createProject() { } @Test - public void testVersionsWithQualifiersNotConsideredAsMinorUpdates() - throws MojoExecutionException, MojoFailureException, IllegalAccessException, IOException { - Path tempPath = null; - try { - tempPath = Files.createTempFile("display-dependency-updates", ""); - final File tempFile = tempPath.toFile(); + public void testVersionsWithQualifiersNotConsideredAsMinorUpdates() throws Exception { + try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) { new DisplayDependencyUpdatesMojo( mockRepositorySystem(), mockAetherRepositorySystem(new HashMap() { @@ -164,13 +142,12 @@ public void testVersionsWithQualifiersNotConsideredAsMinorUpdates() null) { { setProject(createProject()); - setVariableValueToObject(this, "allowAnyUpdates", false); setVariableValueToObject(this, "allowMajorUpdates", false); setVariableValueToObject(this, "processDependencies", true); setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD)); setVariableValueToObject(this, "dependencyExcludes", emptyList()); this.allowSnapshots = true; - this.outputFile = tempFile; + this.outputFile = tempFile.getPath().toFile(); setPluginContext(new HashMap<>()); session = mockMavenSession(); @@ -178,25 +155,17 @@ public void testVersionsWithQualifiersNotConsideredAsMinorUpdates() }.execute(); assertThat( - String.join("", Files.readAllLines(tempPath)), + String.join("", Files.readAllLines(tempFile.getPath())), not(anyOf( containsString("2.0.0-SNAPSHOT"), containsString("2.0.0-beta"), containsString("2.0.0-rc1")))); - } finally { - if (tempPath != null && Files.exists(tempPath)) { - Files.delete(tempPath); - } } } @Test - public void testAllowMajorUpdatesFalse() - throws MojoExecutionException, MojoFailureException, IllegalAccessException, IOException { - Path tempPath = null; - try { - tempPath = Files.createTempFile("display-dependency-updates", ""); - final File tempFile = tempPath.toFile(); + public void testAllowMajorUpdatesFalse() throws Exception { + try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) { new DisplayDependencyUpdatesMojo( mockRepositorySystem(), mockAetherRepositorySystem(new HashMap() { @@ -208,36 +177,27 @@ public void testAllowMajorUpdatesFalse() null) { { setProject(createProject()); - setVariableValueToObject(this, "allowAnyUpdates", false); setVariableValueToObject(this, "allowMajorUpdates", false); setVariableValueToObject(this, "processDependencies", true); setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD)); setVariableValueToObject(this, "dependencyExcludes", emptyList()); - this.outputFile = tempFile; + this.outputFile = tempFile.getPath().toFile(); setPluginContext(new HashMap<>()); session = mockMavenSession(); } }.execute(); - String output = String.join("", Files.readAllLines(tempPath)); + String output = String.join("", Files.readAllLines(tempFile.getPath())); assertThat(output, containsString("1.1.0")); assertThat(output, not(containsString("2.0.0"))); - } finally { - if (tempPath != null && Files.exists(tempPath)) { - Files.delete(tempPath); - } } } @Test - public void testAllowMinorUpdatesFalse() - throws MojoExecutionException, MojoFailureException, IllegalAccessException, IOException { - Path tempPath = null; - try { - tempPath = Files.createTempFile("display-dependency-updates", ""); - final File tempFile = tempPath.toFile(); + public void testAllowMinorUpdatesFalse() throws Exception { + try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) { new DisplayDependencyUpdatesMojo( mockRepositorySystem(), mockAetherRepositorySystem(new HashMap() { @@ -249,37 +209,28 @@ public void testAllowMinorUpdatesFalse() null) { { setProject(createProject()); - setVariableValueToObject(this, "allowAnyUpdates", false); setVariableValueToObject(this, "allowMinorUpdates", false); setVariableValueToObject(this, "processDependencies", true); setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD)); setVariableValueToObject(this, "dependencyExcludes", emptyList()); - this.outputFile = tempFile; + this.outputFile = tempFile.getPath().toFile(); setPluginContext(new HashMap<>()); session = mockMavenSession(); } }.execute(); - String output = String.join("", Files.readAllLines(tempPath)); + String output = String.join("", Files.readAllLines(tempFile.getPath())); assertThat(output, containsString("1.0.1")); assertThat(output, not(containsString("1.1.0"))); assertThat(output, not(containsString("2.0.0"))); - } finally { - if (tempPath != null && Files.exists(tempPath)) { - Files.delete(tempPath); - } } } @Test - public void testAllowIncrementalUpdatesFalse() - throws MojoExecutionException, MojoFailureException, IllegalAccessException, IOException { - Path tempPath = null; - try { - tempPath = Files.createTempFile("display-dependency-updates", ""); - final File tempFile = tempPath.toFile(); + public void testAllowIncrementalUpdatesFalse() throws Exception { + try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) { new DisplayDependencyUpdatesMojo( mockRepositorySystem(), mockAetherRepositorySystem(new HashMap() { @@ -291,38 +242,29 @@ public void testAllowIncrementalUpdatesFalse() null) { { setProject(createProject()); - setVariableValueToObject(this, "allowAnyUpdates", false); setVariableValueToObject(this, "allowIncrementalUpdates", false); setVariableValueToObject(this, "processDependencies", true); setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD)); setVariableValueToObject(this, "dependencyExcludes", emptyList()); - this.outputFile = tempFile; + this.outputFile = tempFile.getPath().toFile(); setPluginContext(new HashMap<>()); session = mockMavenSession(); } }.execute(); - String output = String.join("", Files.readAllLines(tempPath)); + String output = String.join("", Files.readAllLines(tempFile.getPath())); assertThat(output, containsString("1.0.0-1")); assertThat(output, not(containsString("1.0.1"))); assertThat(output, not(containsString("1.1.0"))); assertThat(output, not(containsString("2.0.0"))); - } finally { - if (tempPath != null && Files.exists(tempPath)) { - Files.delete(tempPath); - } } } @Test - public void testVersionsWithQualifiersNotConsideredAsIncrementalUpdates() - throws MojoExecutionException, MojoFailureException, IllegalAccessException, IOException { - Path tempPath = null; - try { - tempPath = Files.createTempFile("display-dependency-updates", ""); - final File tempFile = tempPath.toFile(); + public void testVersionsWithQualifiersNotConsideredAsIncrementalUpdates() throws Exception { + try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) { new DisplayDependencyUpdatesMojo( mockRepositorySystem(), mockAetherRepositorySystem(new HashMap() { @@ -336,13 +278,12 @@ public void testVersionsWithQualifiersNotConsideredAsIncrementalUpdates() null) { { setProject(createProject()); - setVariableValueToObject(this, "allowAnyUpdates", false); setVariableValueToObject(this, "allowMinorUpdates", false); setVariableValueToObject(this, "processDependencies", true); setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD)); setVariableValueToObject(this, "dependencyExcludes", emptyList()); this.allowSnapshots = true; - this.outputFile = tempFile; + this.outputFile = tempFile.getPath().toFile(); setPluginContext(new HashMap<>()); session = mockMavenSession(); @@ -350,24 +291,17 @@ public void testVersionsWithQualifiersNotConsideredAsIncrementalUpdates() }.execute(); assertThat( - String.join("", Files.readAllLines(tempPath)), + String.join("", Files.readAllLines(tempFile.getPath())), not(anyOf( containsString("1.9.0-SNAPSHOT"), containsString("1.9.0-beta"), containsString("1.9.0-rc1")))); - } finally { - if (tempPath != null && Files.exists(tempPath)) { - Files.delete(tempPath); - } } } @Test public void testDetermineUpdatedSegment() throws Exception { - File outputFile = null; - try { - outputFile = File.createTempFile("display-dependency-updates", ""); - assert outputFile.exists(); + try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) { DisplayDependencyUpdatesMojo mojo = (DisplayDependencyUpdatesMojo) mojoRule.lookupConfiguredMojo( new File("target/test-classes/org/codehaus/mojo/display-dependency-updates/ruleset"), @@ -390,7 +324,7 @@ public void testDetermineUpdatedSegment() throws Exception { .withVersion(".+-M\\d+")))); // This is just an example of how to create it-style tests as unit tests; the advantage is easier debugging - mojo.outputFile = outputFile; + mojo.outputFile = tempFile.getPath().toFile(); mojo.aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() { { put("dummy-api", new String[] {"1.0.0", "1.0.1", "1.1.0-M1", "1.2.0-SNAPSHOT"}); @@ -399,26 +333,21 @@ public void testDetermineUpdatedSegment() throws Exception { assertThat(mojo.ruleSet.getIgnoreVersions(), Matchers.hasSize(3)); mojo.execute(); - List output = Files.readAllLines(outputFile.toPath(), UTF_8); + List output = Files.readAllLines(tempFile.getPath(), UTF_8); assertThat(output, not(hasItem(containsString("1.1.0-M1")))); - } finally { - assert outputFile == null || !outputFile.exists() || outputFile.delete(); } } @Test public void testVersionInterpolation() throws Exception { - File outputFile = null; - try { - outputFile = File.createTempFile("display-dependency-updates", ""); - assert outputFile.exists(); + try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) { DisplayDependencyUpdatesMojo mojo = (DisplayDependencyUpdatesMojo) mojoRule.lookupConfiguredMojo( new File("target/test-classes/org/codehaus/mojo/display-dependency-updates/version-interpolation"), "display-dependency-updates"); // This is just an example of how to create it-style tests as unit tests; the advantage is easier debugging - mojo.outputFile = outputFile; + mojo.outputFile = tempFile.getPath().toFile(); mojo.aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() { { put("dummy-api", new String[] {"2.0.1"}); @@ -426,25 +355,19 @@ public void testVersionInterpolation() throws Exception { }); setVariableValueToObject(mojo, "processDependencyManagementTransitive", false); mojo.execute(); - List output = Files.readAllLines(outputFile.toPath(), UTF_8); + List output = Files.readAllLines(tempFile.getPath(), UTF_8); assertThat(output, not(hasItem(containsString("mycomponent.version")))); - } finally { - assert outputFile == null || !outputFile.exists() || outputFile.delete(); } } @Test - public void testAllowSnapshots() - throws MojoExecutionException, MojoFailureException, IllegalAccessException, IOException { - Path tempPath = null; - try { - tempPath = Files.createTempFile("display-dependency-updates", ""); - File tempFile = tempPath.toFile(); + public void testAllowSnapshots() throws Exception { + try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) { new DisplayDependencyUpdatesMojo( mockRepositorySystem(), mockAetherRepositorySystem(new HashMap() { { - put("default-dependency", new String[] {"1.0.0", "1.0.1-SNAPSHOT"}); + put("default-dependency", new String[] {"2.0.0-SNAPSHOT"}); } }), null, @@ -455,20 +378,61 @@ public void testAllowSnapshots() setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD)); setVariableValueToObject(this, "dependencyExcludes", emptyList()); this.allowSnapshots = true; - this.outputFile = tempFile; + this.outputFile = tempFile.getPath().toFile(); setPluginContext(new HashMap<>()); session = mockMavenSession(); } }.execute(); - String output = String.join("", Files.readAllLines(tempPath)); + String output = String.join("", Files.readAllLines(tempFile.getPath())); - assertThat(output, containsString("1.0.1-SNAPSHOT")); - } finally { - if (tempPath != null && Files.exists(tempPath)) { - Files.delete(tempPath); - } + assertThat(output, containsString("2.0.0-SNAPSHOT")); + } + } + + private void testAllowUpdatesFromLesserSegments(String availableVersion) throws Exception { + try (CloseableTempFile tempFile = new CloseableTempFile("display-dependency-updates")) { + new DisplayDependencyUpdatesMojo( + mockRepositorySystem(), + mockAetherRepositorySystem(new HashMap() { + { + put("default-dependency", new String[] {availableVersion}); + } + }), + null, + null) { + { + setProject(createProject()); + setVariableValueToObject(this, "processDependencies", true); + setVariableValueToObject(this, "dependencyIncludes", singletonList(WildcardMatcher.WILDCARD)); + setVariableValueToObject(this, "dependencyExcludes", emptyList()); + setVariableValueToObject(this, "allowMajorUpdates", false); + this.outputFile = tempFile.getPath().toFile(); + setPluginContext(new HashMap<>()); + + session = mockMavenSession(); + } + }.execute(); + + String output = String.join("", Files.readAllLines(tempFile.getPath())); + + assertThat(output, containsString(availableVersion)); } } + + @Test + public void testAllowUpdatesFromLesserSegmentsMinor() throws Exception { + testAllowUpdatesFromLesserSegments("1.1.0"); + } + + @Test + public void testAllowUpdatesFromLesserSegmentsIncremental() throws Exception { + testAllowUpdatesFromLesserSegments("1.0.1"); + } + + @Test + public void testAllowUpdatesFromLesserSegmentsSubIncremental() throws Exception { + testAllowUpdatesFromLesserSegments("1.0.0-1"); + } } diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojoTest.java index fabb909a4..eb0bd1ccd 100644 --- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojoTest.java +++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayPropertyUpdatesMojoTest.java @@ -1,21 +1,17 @@ package org.codehaus.mojo.versions; /* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at + * Copyright MojoHaus and Contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ import java.nio.file.Files; @@ -34,8 +30,7 @@ import static org.apache.commons.codec.CharEncoding.UTF_8; import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySystem; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.matchesPattern; -import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.*; /** * Unit tests for {@link DisplayPropertyUpdatesMojo} @@ -46,10 +41,13 @@ public class DisplayPropertyUpdatesMojoTest extends AbstractMojoTestCase { private Path tempDir; + private Path tempFile; + @Before public void setUp() throws Exception { super.setUp(); tempDir = TestUtils.createTempDir("display-property-updates"); + tempFile = Files.createTempFile(tempDir, "output", ""); } @After @@ -63,8 +61,6 @@ public void tearDown() throws Exception { @Test public void testPropertiesFromParent() throws Exception { - Path tempFile = Files.createTempFile(tempDir, "output", ""); - TestUtils.copyDir( Paths.get("src/test/resources/org/codehaus/mojo/display-property-updates/issue-367"), tempDir); DisplayPropertyUpdatesMojo mojo = (DisplayPropertyUpdatesMojo) @@ -83,8 +79,6 @@ public void testPropertiesFromParent() throws Exception { @Test public void testDisablePropertiesFromParent() throws Exception { - Path tempFile = Files.createTempFile(tempDir, "output", ""); - TestUtils.copyDir( Paths.get("src/test/resources/org/codehaus/mojo/display-property-updates/issue-367"), tempDir); DisplayPropertyUpdatesMojo mojo = (DisplayPropertyUpdatesMojo) @@ -100,4 +94,39 @@ public void testDisablePropertiesFromParent() throws Exception { String.join("", Files.readAllLines(tempFile)), not(matchesPattern(".*\\$\\{ver} \\.* 1\\.0\\.0 -> 2\\.0\\.0.*"))); } + + private void testAllowUpdatesFromLesserSegments(String availableVersion) throws Exception { + TestUtils.copyDir( + Paths.get("src/test/resources/org/codehaus/mojo/display-property-updates/issue-960"), tempDir); + DisplayPropertyUpdatesMojo mojo = (DisplayPropertyUpdatesMojo) + mojoRule.lookupConfiguredMojo(tempDir.toFile(), "display-property-updates"); + mojo.outputEncoding = UTF_8; + mojo.outputFile = tempFile.toFile(); + mojo.setPluginContext(new HashMap<>()); + mojo.aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() { + { + put("artifactA", new String[] {availableVersion, "2"}); + } + }); + mojo.includeParent = false; + setVariableValueToObject(mojo, "allowMajorUpdates", false); + mojo.execute(); + + assertThat(String.join("", Files.readAllLines(tempFile)), containsString(availableVersion)); + } + + @Test + public void testAllowUpdatesFromLesserSegmentsMinor() throws Exception { + testAllowUpdatesFromLesserSegments("1.1"); + } + + @Test + public void testAllowUpdatesFromLesserSegmentsIncremental() throws Exception { + testAllowUpdatesFromLesserSegments("1.0.1"); + } + + @Test + public void testAllowUpdatesFromLesserSegmentsSubIncremental() throws Exception { + testAllowUpdatesFromLesserSegments("1.0.0-1"); + } } diff --git a/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-property-updates/issue-960/pom.xml b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-property-updates/issue-960/pom.xml new file mode 100644 index 000000000..4a10fbd62 --- /dev/null +++ b/versions-maven-plugin/src/test/resources/org/codehaus/mojo/display-property-updates/issue-960/pom.xml @@ -0,0 +1,18 @@ + + 4.0.0 + default-group + parent + 1.0.0 + + + 1.0.0 + + + + + default-group + artifactA + ${ver} + + + diff --git a/versions-test/src/main/java/org/codehaus/mojo/versions/utils/CloseableTempFile.java b/versions-test/src/main/java/org/codehaus/mojo/versions/utils/CloseableTempFile.java new file mode 100644 index 000000000..a1d67b723 --- /dev/null +++ b/versions-test/src/main/java/org/codehaus/mojo/versions/utils/CloseableTempFile.java @@ -0,0 +1,48 @@ +package org.codehaus.mojo.versions.utils; + +/* + * Copyright MojoHaus and Contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +/** + * Closeable temporary file + */ +public class CloseableTempFile implements AutoCloseable { + private final Path path; + + /** + * @return path of the temporary file + */ + public Path getPath() { + return path; + } + + /** + * Creates a new temporary file with the given prefix + * @param prefix prefix of the temporary file + * @throws IOException thrown if file creation fails + */ + public CloseableTempFile(String prefix) throws IOException { + path = Files.createTempFile(prefix, ".tmp"); + } + + @Override + public void close() throws Exception { + Files.deleteIfExists(path); + } +}