Skip to content

Commit

Permalink
Align update-parent and display-parent-update (#1017)
Browse files Browse the repository at this point in the history
* Resolves #1016 - Align update-parent and display-parent-update

* Introduce DisplayParentUpdatesMojoOutputTest

* use SegmentUtils.determineUnchangedSegment

* Align DisplayParentUpdatesMojoTest and UpdateParentMojoTest

* Apply formatting rules

* update javadoc since annotation to 2.17.0 for newly introduced properties

* Align variable name between DisplayParentUpdatesMojo and UpdateParentMojo

* Align skipResolution && isBlank(parentVersion)

* Use Optional in favor of ternary operator
  • Loading branch information
cachescrubber committed Nov 16, 2023
1 parent 1136bf4 commit e56c8c4
Show file tree
Hide file tree
Showing 3 changed files with 547 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,33 @@

import javax.inject.Inject;

import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
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.Segment;
import org.codehaus.mojo.versions.api.VersionRetrievalException;
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.DefaultArtifactVersionCache;
import org.codehaus.mojo.versions.utils.DependencyBuilder;
import org.codehaus.mojo.versions.utils.SegmentUtils;

import static org.apache.maven.shared.utils.StringUtils.isBlank;

/**
* Displays any updates of the project's parent project
Expand All @@ -46,6 +60,78 @@ public class DisplayParentUpdatesMojo extends AbstractVersionsDisplayMojo {

public static final int MESSAGE_LENGTH = 68;

// ------------------------------ FIELDS ------------------------------

/**
* <p>If {@code skipResolution} is not set, specifies the <em>bottom</em> version considered
* for target version resolution. If it is a version range, the resolved version will be
* restricted by that range.</p>
*
* <p>If {@code skipResolution} is {@code true}, will specify the target version to which
* the parent artifact will be updated.</p>
* @since 2.17.0
*/
@Parameter(property = "parentVersion")
protected String parentVersion = null;

/**
* to update parent version by force when it is RELEASE or LATEST
*
* @since 2.17.0
*/
@Parameter(property = "forceUpdate", defaultValue = "false")
protected boolean forceUpdate = false;

/**
* Skips version resolution, only valid if {@code parentVersion} is set.
* Will effectively set the new parent version to the one from {@code parentVersion}
*
* @since 2.17.0
*/
@Parameter(property = "skipResolution", defaultValue = "false")
protected boolean skipResolution = false;

/**
* <p>Whether to downgrade a snapshot dependency if <code>allowSnapshots</code> is <code>false</code>
* and there exists a version within the range fulfilling the criteria.</p>
* <p>Default <code>false</code></p>
*
* @since 2.17.0
*/
@Parameter(property = "allowDowngrade", defaultValue = "false")
protected boolean allowDowngrade;

/**
* Whether to allow the major version number to be changed.
*
* @since 2.17.0
*/
@Parameter(property = "allowMajorUpdates", defaultValue = "true")
protected boolean allowMajorUpdates = true;

/**
* <p>Whether to allow the minor version number to be changed.</p>
*
* <p><b>Note: {@code false} also implies {@linkplain #allowMajorUpdates} {@code false}</b></p>
*
* @since 2.17.0
*/
@Parameter(property = "allowMinorUpdates", defaultValue = "true")
protected boolean allowMinorUpdates = true;

/**
* <p>Whether to allow the incremental version number to be changed.</p>
*
* <p><b>Note: {@code false} also implies {@linkplain #allowMajorUpdates}
* and {@linkplain #allowMinorUpdates} {@code false}</b></p>
*
* @since 2.17.0
*/
@Parameter(property = "allowIncrementalUpdates", defaultValue = "true")
protected boolean allowIncrementalUpdates = true;

// -------------------------- OTHER METHODS --------------------------

@Inject
public DisplayParentUpdatesMojo(
RepositorySystem repositorySystem,
Expand All @@ -68,36 +154,34 @@ public void execute() throws MojoExecutionException, MojoFailureException {
return;
}

String currentVersion = getProject().getParent().getVersion();
Artifact artifact = getHelper()
.createDependencyArtifact(DependencyBuilder.newBuilder()
.withGroupId(getProject().getParent().getGroupId())
.withArtifactId(getProject().getParent().getArtifactId())
.withVersion(currentVersion)
.withType("pom")
.build());

if (skipResolution && isBlank(parentVersion)) {
throw new MojoExecutionException("skipResolution is only valid if parentVersion is set");
}
String initialVersion = Optional.ofNullable(parentVersion)
.orElse(getProject().getParent().getVersion());
ArtifactVersion artifactVersion;
try {
artifactVersion = findLatestVersion(artifact, null, allowSnapshots, false);
} catch (VersionRetrievalException e) {
artifactVersion = skipResolution
? DefaultArtifactVersionCache.of(parentVersion)
: resolveTargetVersion(initialVersion);
} catch (VersionRetrievalException | InvalidVersionSpecificationException | InvalidSegmentException e) {
throw new MojoExecutionException(e.getMessage(), e);
}

if (artifactVersion == null || currentVersion.equals(artifactVersion.toString())) {
if (artifactVersion == null || initialVersion.equals(artifactVersion.toString())) {
logLine(false, "The parent project is the latest version:");
StringBuilder buf = new StringBuilder(MESSAGE_LENGTH);
buf.append(" ");
buf.append(getProject().getParent().getGroupId());
buf.append(':');
buf.append(getProject().getParent().getArtifactId());
buf.append(' ');
int padding = MESSAGE_LENGTH - currentVersion.length();
int padding = MESSAGE_LENGTH - initialVersion.length();
while (buf.length() < padding) {
buf.append('.');
}
buf.append(' ');
buf.append(currentVersion);
buf.append(initialVersion);
logLine(false, buf.toString());
} else {
logLine(false, "The parent project has a newer version:");
Expand All @@ -108,20 +192,70 @@ public void execute() throws MojoExecutionException, MojoFailureException {
buf.append(getProject().getParent().getArtifactId());
buf.append(' ');
int padding = MESSAGE_LENGTH
- currentVersion.length()
- initialVersion.length()
- artifactVersion.toString().length()
- " -> ".length();
while (buf.length() < padding) {
buf.append('.');
}
buf.append(' ');
buf.append(currentVersion);
buf.append(initialVersion);
buf.append(" -> ");
buf.append(artifactVersion);
logLine(false, buf.toString());
}
}

protected ArtifactVersion resolveTargetVersion(String initialVersion)
throws MojoExecutionException, VersionRetrievalException, InvalidVersionSpecificationException,
InvalidSegmentException {
Artifact artifact = getHelper()
.createDependencyArtifact(DependencyBuilder.newBuilder()
.withGroupId(getProject().getParent().getGroupId())
.withArtifactId(getProject().getParent().getArtifactId())
.withVersion(initialVersion)
.withType("pom")
.build());

VersionRange targetVersionRange = VersionRange.createFromVersionSpec(initialVersion);
if (targetVersionRange.getRecommendedVersion() != null) {
targetVersionRange = targetVersionRange.restrict(
VersionRange.createFromVersionSpec("[" + targetVersionRange.getRecommendedVersion() + ",)"));
}

final ArtifactVersions versions = getHelper().lookupArtifactVersions(artifact, false);
Optional<Segment> unchangedSegment = SegmentUtils.determineUnchangedSegment(
allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog());

// currentVersion (set to parentVersion here) is not included in the version range for searching upgrades
// unless we set allowDowngrade to true
for (ArtifactVersion candidate : reverse(versions.getNewerVersions(
initialVersion, unchangedSegment, allowSnapshots, !isBlank(parentVersion) || allowDowngrade))) {
if (allowDowngrade
|| targetVersionRange == null
|| ArtifactVersions.isVersionInRange(candidate, targetVersionRange)) {
if (shouldApplyUpdate(artifact, getProject().getParent().getVersion(), candidate, forceUpdate)) {
return candidate;
} else {
getLog().debug("Update not applied. Exiting.");
return null;
}
}
}

if (versions.isEmpty(allowSnapshots)) {
getLog().info("No versions found");
} else {
getLog().info("The parent project is the latest version");
}

return null;
}

private static <T> Iterable<T> reverse(T[] array) {
return Arrays.stream(array).sorted(Collections.reverseOrder()).collect(Collectors.toList());
}

@Override
protected void update(ModifiedPomXMLEventReader pom) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
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;
Expand All @@ -46,11 +45,9 @@
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.
Expand Down Expand Up @@ -166,7 +163,8 @@ protected void update(ModifiedPomXMLEventReader pom)
throw new MojoExecutionException("skipResolution is only valid if parentVersion is set");
}

String initialVersion = parentVersion == null ? getProject().getParent().getVersion() : parentVersion;
String initialVersion = Optional.ofNullable(parentVersion)
.orElse(getProject().getParent().getVersion());
try {
ArtifactVersion artifactVersion = skipResolution
? DefaultArtifactVersionCache.of(parentVersion)
Expand Down Expand Up @@ -215,27 +213,8 @@ protected ArtifactVersion resolveTargetVersion(String initialVersion)
}

final ArtifactVersions versions = getHelper().lookupArtifactVersions(artifact, false);
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<Segment> 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<Segment> unchangedSegment = unchangedSegment1;
Optional<Segment> unchangedSegment = SegmentUtils.determineUnchangedSegment(
allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog());

// currentVersion (set to parentVersion here) is not included in the version range for searching upgrades
// unless we set allowDowngrade to true
Expand Down

0 comments on commit e56c8c4

Please sign in to comment.