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 604ecfe93..503a216ed 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 @@ -82,11 +82,12 @@ protected ArtifactVersion getHighestLowerBound(ArtifactVersion lowerBoundVersion * 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 + * @param selectedVersion actual version used, may not be {@code null} * @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) { + assert selectedVersion != null; return Optional.ofNullable(getCurrentVersionRange()) .map(VersionRange::getRestrictions) .flatMap(r -> r.stream() @@ -116,7 +117,8 @@ public Restriction restrictionForSelectedSegment(ArtifactVersion lowerBound, Opt public Restriction restrictionForUnchangedSegment( ArtifactVersion actualVersion, Optional unchangedSegment, boolean allowDowngrade) throws InvalidSegmentException { - Optional selectedRestriction = getSelectedRestriction(actualVersion); + Optional selectedRestriction = + Optional.ofNullable(actualVersion).flatMap(this::getSelectedRestriction); ArtifactVersion selectedRestrictionUpperBound = selectedRestriction.map(Restriction::getUpperBound).orElse(actualVersion); ArtifactVersion lowerBound = allowDowngrade 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 11f266d4a..8f10bc99c 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 @@ -519,7 +519,7 @@ public ArtifactVersion createArtifactVersion(String version) { } public Map lookupDependenciesUpdates( - Set dependencies, + Stream dependencies, boolean usePluginRepositories, boolean useProjectRepositories, boolean allowSnapshots) @@ -527,7 +527,7 @@ public Map lookupDependenciesUpdates( ExecutorService executor = Executors.newFixedThreadPool(LOOKUP_PARALLEL_THREADS); try { Map dependencyUpdates = new TreeMap<>(DependencyComparator.INSTANCE); - List>> futures = dependencies.stream() + List>> futures = dependencies .map(dependency -> executor.submit(() -> new ImmutablePair<>( dependency, lookupDependencyUpdates( @@ -549,7 +549,7 @@ public Map lookupDependenciesUpdates( @Override public Map lookupDependenciesUpdates( - Set dependencies, boolean usePluginRepositories, boolean allowSnapshots) + Stream dependencies, boolean usePluginRepositories, boolean allowSnapshots) throws VersionRetrievalException { return lookupDependenciesUpdates(dependencies, usePluginRepositories, !usePluginRepositories, allowSnapshots); } @@ -570,13 +570,13 @@ public ArtifactVersions lookupDependencyUpdates( } @Override - public Map lookupPluginsUpdates(Set plugins, boolean allowSnapshots) + public Map lookupPluginsUpdates(Stream plugins, boolean allowSnapshots) throws VersionRetrievalException { ExecutorService executor = Executors.newFixedThreadPool(LOOKUP_PARALLEL_THREADS); try { Map pluginUpdates = new TreeMap<>(PluginComparator.INSTANCE); - List>> futures = plugins.stream() - .map(p -> executor.submit(() -> new ImmutablePair<>(p, lookupPluginUpdates(p, allowSnapshots)))) + List>> futures = plugins.map( + p -> executor.submit(() -> new ImmutablePair<>(p, lookupPluginUpdates(p, allowSnapshots)))) .collect(Collectors.toList()); for (Future> details : futures) { Pair pair = details.get(); @@ -602,7 +602,7 @@ public PluginUpdatesDetails lookupPluginUpdates(Plugin plugin, boolean allowSnap pluginDependencies.addAll(plugin.getDependencies()); } Map pluginDependencyDetails = - lookupDependenciesUpdates(pluginDependencies, false, allowSnapshots); + lookupDependenciesUpdates(pluginDependencies.stream(), false, allowSnapshots); ArtifactVersions allVersions = lookupArtifactVersions( createPluginArtifact(plugin.getGroupId(), plugin.getArtifactId(), version), true); 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 8b1a56140..c8bdd23aa 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 @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Stream; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.resolver.ArtifactResolutionException; @@ -198,21 +199,21 @@ ArtifactVersions lookupArtifactVersions(Artifact artifact, VersionRange versionR * Returns a map of all possible updates per dependency. The lookup is done in parallel using * {@code LOOKUP_PARALLEL_THREADS} threads. * - * @param dependencies The set of {@link Dependency} instances to look up. + * @param dependencyStream a stream of {@link Dependency} instances to look up. * @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) + Stream dependencyStream, boolean usePluginRepositories, boolean allowSnapshots) throws VersionRetrievalException; /** * Returns a map of all possible updates per dependency. The lookup is done in parallel using * {@code LOOKUP_PARALLEL_THREADS} threads. * - * @param dependencies The set of {@link Dependency} instances to look up. + * @param dependencies stream of {@link Dependency} instances to look up. * @param usePluginRepositories Search the plugin repositories. * @param useProjectRepositories whether to use regular project repositories * @param allowSnapshots whether snapshots should be included @@ -220,7 +221,7 @@ Map lookupDependenciesUpdates( * @throws VersionRetrievalException thrown if a version cannot be retrieved */ Map lookupDependenciesUpdates( - Set dependencies, + Stream dependencies, boolean usePluginRepositories, boolean useProjectRepositories, boolean allowSnapshots) @@ -247,13 +248,13 @@ ArtifactVersions lookupDependencyUpdates( /** * Looks up the updates for a set of plugins. * - * @param plugins The set of {@link Plugin} instances to look up. + * @param plugins A stream of {@link Plugin} instances to look up. * @param allowSnapshots Include snapshots in the list of updates. * @return A map, keyed by plugin, with values of type {@link org.codehaus.mojo.versions.api.PluginUpdatesDetails}. * @throws VersionRetrievalException thrown if version resolution fails * @since 1.0-beta-1 */ - Map lookupPluginsUpdates(Set plugins, boolean allowSnapshots) + Map lookupPluginsUpdates(Stream plugins, boolean allowSnapshots) throws VersionRetrievalException; /** 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 index 552c60b63..d2308eda8 100644 --- 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 @@ -30,6 +30,7 @@ import static org.codehaus.mojo.versions.utils.ArtifactVersionUtils.version; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import static org.junit.Assert.fail; /** * Unit tests for {@link AbstractVersionDetails} @@ -156,4 +157,24 @@ public void testRestrictionForUnchangedSegmentWithTwoNotConnectingRanges4() .containsVersion(version("2.0.0-1")), is(true)); } + + @Test + public void testRestrictionForUnchangedSegmentWithoutVersionInformation() + throws InvalidSegmentException, InvalidVersionSpecificationException { + instance.setCurrentVersionRange(VersionRange.createFromVersionSpec("[,0]")); + assertThat( + instance.restrictionForUnchangedSegment(null, empty(), false).containsVersion(version("1.0.0")), + is(true)); + } + + @Test + public void testGetSelectedRestrictionForNoVersion() + throws InvalidVersionSpecificationException, InvalidSegmentException { + instance.setCurrentVersionRange(VersionRange.createFromVersionSpec("[,0]")); + try { + instance.getSelectedRestriction(null); + fail("Expected a NullPointerException to be thrown or assertions are not enabled."); + } catch (AssertionError ignored) { + } + } } 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 99f407a7a..9ec90f8bc 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 @@ -359,14 +359,15 @@ public void execute(EnforcerRuleHelper ruleHelper) throws EnforcerRuleException Optional ignoredSegment = ignoreSubIncrementalUpdates ? of(SUBINCREMENTAL) : ignoreIncrementalUpdates ? of(INCREMENTAL) : ignoreMinorUpdates ? of(MINOR) : empty(); - List upgradable = - versionsHelper.lookupDependenciesUpdates(dependencies, false, allowSnapshots).values().stream() - .filter(v -> v.getVersions( - v.restrictionForIgnoreScope(v.getCurrentVersion(), ignoredSegment), - true) - .length - > 0) - .collect(Collectors.toList()); + List upgradable = versionsHelper + .lookupDependenciesUpdates( + dependencies.stream().filter(d -> d.getVersion() != null), false, allowSnapshots) + .values() + .stream() + .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: " + upgradable.stream() diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-issue-973-versionless/invoker.properties b/versions-maven-plugin/src/it/it-display-dependency-updates-issue-973-versionless/invoker.properties new file mode 100644 index 000000000..4e78536d9 --- /dev/null +++ b/versions-maven-plugin/src/it/it-display-dependency-updates-issue-973-versionless/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:display-dependency-updates +invoker.mavenOpts = -Dversions.outputFile=./output.txt -DoutputEncoding=UTF-8 diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-issue-973-versionless/pom.xml b/versions-maven-plugin/src/it/it-display-dependency-updates-issue-973-versionless/pom.xml new file mode 100644 index 000000000..11a4dc2dc --- /dev/null +++ b/versions-maven-plugin/src/it/it-display-dependency-updates-issue-973-versionless/pom.xml @@ -0,0 +1,37 @@ + + 4.0.0 + localhost + it-display-dependency-updates-002 + 1.0 + pom + display-dependency-updates-from-plugins + + + + + localhost + dummy-api + 1.1 + + + + + + + + + localhost + dummy-maven-plugin + + + localhost + dummy-api + + + + + + + + diff --git a/versions-maven-plugin/src/it/it-display-dependency-updates-issue-973-versionless/verify.groovy b/versions-maven-plugin/src/it/it-display-dependency-updates-issue-973-versionless/verify.groovy new file mode 100644 index 000000000..3a8bf3ad7 --- /dev/null +++ b/versions-maven-plugin/src/it/it-display-dependency-updates-issue-973-versionless/verify.groovy @@ -0,0 +1,4 @@ +def output = new File(basedir, "output.txt").text +def matcher = output =~ /\Qlocalhost:dummy-api\E.*->\s+\Q3.0\E\b/ +assert matcher.find() : "localhost:dummy-api should have been bumped to version 3.0" +assert !matcher.find() : "localhost:dummy-api may only appear once in the updates list" diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractDependencyUpdatesReportMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractDependencyUpdatesReportMojo.java index edc527bdb..91d7bafab 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractDependencyUpdatesReportMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractDependencyUpdatesReportMojo.java @@ -145,11 +145,16 @@ protected void doGenerateReport(Locale locale, Sink sink) throws MavenReportExce try { - Map dependencyUpdates = - getHelper().lookupDependenciesUpdates(dependencies, false, allowSnapshots); + Map dependencyUpdates = getHelper() + .lookupDependenciesUpdates( + dependencies.stream().filter(d -> d.getVersion() != null), false, allowSnapshots); Map dependencyManagementUpdates = processDependencyManagement - ? getHelper().lookupDependenciesUpdates(dependencyManagement, false, allowSnapshots) + ? getHelper() + .lookupDependenciesUpdates( + dependencyManagement.stream().filter(d -> d.getVersion() != null), + false, + allowSnapshots) : emptyMap(); if (onlyUpgradable) { diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractPluginUpdatesReportMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractPluginUpdatesReportMojo.java index 2682fc7ef..738ccd1bb 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractPluginUpdatesReportMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractPluginUpdatesReportMojo.java @@ -126,9 +126,9 @@ protected void doGenerateReport(Locale locale, Sink sink) throws MavenReportExce try { Map pluginUpdates = - getHelper().lookupPluginsUpdates(plugins, getAllowSnapshots()); + getHelper().lookupPluginsUpdates(plugins.stream(), getAllowSnapshots()); Map pluginManagementUpdates = - getHelper().lookupPluginsUpdates(pluginManagement, getAllowSnapshots()); + getHelper().lookupPluginsUpdates(pluginManagement.stream(), getAllowSnapshots()); if (onlyUpgradable) { pluginUpdates = filter(pluginUpdates, p -> !p.isEmpty(allowSnapshots)); 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 cec1a8dfe..186a3555a 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 @@ -399,7 +399,11 @@ public void execute() throws MojoExecutionException, MojoFailureException { getLog()); logUpdates( - getHelper().lookupDependenciesUpdates(dependencyManagement, false, allowSnapshots), + getHelper() + .lookupDependenciesUpdates( + dependencyManagement.stream().filter(d -> d.getVersion() != null), + false, + allowSnapshots), "Dependency Management"); } if (isProcessingDependencies()) { @@ -408,17 +412,21 @@ public void execute() throws MojoExecutionException, MojoFailureException { getHelper() .lookupDependenciesUpdates( filterDependencies( - getProject().getDependencies().stream() - .filter(dep -> finalDependencyManagement.stream() - .noneMatch(depMan -> dependenciesMatch(dep, depMan))) - .collect( - () -> new TreeSet<>(DependencyComparator.INSTANCE), - Set::add, - Set::addAll), - dependencyIncludes, - dependencyExcludes, - "Dependencies", - getLog()), + getProject().getDependencies().stream() + .filter(dep -> finalDependencyManagement.stream() + .noneMatch(depMan -> + dependenciesMatch(dep, depMan))) + .collect( + () -> new TreeSet<>( + DependencyComparator.INSTANCE), + Set::add, + Set::addAll), + dependencyIncludes, + dependencyExcludes, + "Dependencies", + getLog()) + .stream() + .filter(d -> d.getVersion() != null), false, allowSnapshots), "Dependencies"); @@ -428,11 +436,14 @@ public void execute() throws MojoExecutionException, MojoFailureException { getHelper() .lookupDependenciesUpdates( filterDependencies( - extractPluginDependenciesFromPluginsInPluginManagement(getProject()), - pluginManagementDependencyIncludes, - pluginManagementDependencyExcludes, - "Plugin Management Dependencies", - getLog()), + extractPluginDependenciesFromPluginsInPluginManagement( + getProject()), + pluginManagementDependencyIncludes, + pluginManagementDependencyExcludes, + "Plugin Management Dependencies", + getLog()) + .stream() + .filter(d -> d.getVersion() != null), false, allowSnapshots), "pluginManagement of plugins"); @@ -442,11 +453,13 @@ public void execute() throws MojoExecutionException, MojoFailureException { getHelper() .lookupDependenciesUpdates( filterDependencies( - extractDependenciesFromPlugins(getProject()), - pluginDependencyIncludes, - pluginDependencyExcludes, - "Plugin Dependencies", - getLog()), + extractDependenciesFromPlugins(getProject()), + pluginDependencyIncludes, + pluginDependencyExcludes, + "Plugin Dependencies", + getLog()) + .stream() + .filter(d -> d.getVersion() != null), false, allowSnapshots), "Plugin Dependencies"); 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 01103b968..e6c62580d 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 @@ -255,7 +255,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { } try { - logUpdates(getHelper().lookupDependenciesUpdates(dependencies, true, true, allowSnapshots)); + logUpdates(getHelper().lookupDependenciesUpdates(dependencies.stream(), true, true, allowSnapshots)); } catch (VersionRetrievalException e) { throw new MojoExecutionException(e.getMessage(), e); }