Skip to content

Commit

Permalink
Resolves #1016 - Align update-parent and display-parent-update
Browse files Browse the repository at this point in the history
  • Loading branch information
cachescrubber committed Oct 23, 2023
1 parent 8fefd9d commit 5b5f97a
Show file tree
Hide file tree
Showing 2 changed files with 599 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,39 @@

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.plugin.logging.Log;
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 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.INCREMENTAL;
import static org.codehaus.mojo.versions.api.Segment.MAJOR;
import static org.codehaus.mojo.versions.api.Segment.MINOR;

/**
* Displays any updates of the project's parent project
*
Expand All @@ -46,6 +65,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.16.1
*/
@Parameter(property = "parentVersion")
protected String parentVersion = null;

/**
* to update parent version by force when it is RELEASE or LATEST
*
* @since 2.16.1
*/
@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.16.1
*/
@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.16.1
*/
@Parameter(property = "allowDowngrade", defaultValue = "false")
protected boolean allowDowngrade;

/**
* Whether to allow the major version number to be changed.
*
* @since 2.16.1
*/
@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.16.1
*/
@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.16.1
*/
@Parameter(property = "allowIncrementalUpdates", defaultValue = "true")
protected boolean allowIncrementalUpdates = true;

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

@Inject
public DisplayParentUpdatesMojo(
RepositorySystem repositorySystem,
Expand All @@ -67,20 +158,13 @@ public void execute() throws MojoExecutionException, MojoFailureException {
logLine(false, "Parent project is part of the reactor.");
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());

String currentVersion = parentVersion == null ? getProject().getParent().getVersion() : parentVersion;
ArtifactVersion artifactVersion;
try {
artifactVersion = findLatestVersion(artifact, null, allowSnapshots, false);
} catch (VersionRetrievalException e) {
artifactVersion = skipResolution
? DefaultArtifactVersionCache.of(parentVersion)
: resolveTargetVersion(currentVersion);
} catch (VersionRetrievalException | InvalidVersionSpecificationException | InvalidSegmentException e) {
throw new MojoExecutionException(e.getMessage(), e);
}

Expand Down Expand Up @@ -122,6 +206,75 @@ public void execute() throws MojoExecutionException, MojoFailureException {
}
}

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);
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;

// 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) {}
}
Loading

0 comments on commit 5b5f97a

Please sign in to comment.