Skip to content

Commit

Permalink
Fixed #1191: Processes (all) profiles from original model if transiti…
Browse files Browse the repository at this point in the history
…ve is false (#1193)
  • Loading branch information
andrzejj0 authored Nov 30, 2024
1 parent e454b4f commit a6f4ffb
Show file tree
Hide file tree
Showing 15 changed files with 195 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@
* under the License.
*/

import java.util.List;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Stream;

import org.apache.maven.model.Build;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.PluginManagement;
import org.apache.maven.model.Profile;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.codehaus.mojo.versions.api.VersionRetrievalException;
Expand All @@ -45,7 +49,7 @@ public class MavenProjectUtils {
*
* @param project {@link MavenProject} instance
* @return set of {@link Dependency} objects
* or an empty set if none have been retrieveddependencies or an empty set if none have been retrieved
* or an empty set if none have been retrieveddependencies or an empty set if none have been retrieved
*/
public static Set<Dependency> extractPluginDependenciesFromPluginsInPluginManagement(MavenProject project) {
return ofNullable(project.getBuild())
Expand Down Expand Up @@ -89,48 +93,72 @@ public static Set<Dependency> extractDependenciesFromPlugins(MavenProject projec
public static Set<Dependency> extractDependenciesFromDependencyManagement(
MavenProject project, boolean processDependencyManagementTransitive, Log log)
throws VersionRetrievalException {
Set<Dependency> dependencyManagement = new TreeSet<>(DependencyComparator.INSTANCE);
DependencyManagement projectDependencyManagement = processDependencyManagementTransitive
? project.getDependencyManagement()
: project.getOriginalModel().getDependencyManagement();
if (projectDependencyManagement != null) {
Stream<Dependency> dependencies = processDependencyManagementTransitive
? ofNullable(project.getDependencyManagement())
.map(DependencyManagement::getDependencies)
.map(Collection::stream)
.orElse(Stream.empty())
: Stream.concat(
ofNullable(project.getOriginalModel().getDependencyManagement())
.map(DependencyManagement::getDependencies)
.map(Collection::stream)
.orElse(Stream.empty()),
ofNullable(project.getOriginalModel().getProfiles())
.flatMap(profiles -> profiles.stream()
.map(Profile::getDependencyManagement)
.filter(Objects::nonNull)
.map(DependencyManagement::getDependencies)
.map(Collection::stream)
.reduce(Stream::concat))
.orElse(Stream.empty()));

// log and try to correct versions where they don't appear in the original pom.xml
try {
return dependencies
.peek(dependency -> log.debug("dependency from pom: "
+ dependency.getGroupId() + ":" + dependency.getArtifactId() + ":" + dependency.getVersion()
+ ":" + dependency.getScope()))
.map(dependency -> dependency.getVersion() != null
? interpolateVersion(dependency, project)
: getVersionFromParent(dependency, project, processDependencyManagementTransitive, log)
.orElse(dependency))
.collect(() -> new TreeSet<>(DependencyComparator.INSTANCE), Set::add, Set::addAll);
} catch (IllegalArgumentException e) {
throw new VersionRetrievalException(e.getMessage());
}
}

List<Dependency> dependenciesFromPom = projectDependencyManagement.getDependencies();
for (Dependency dependency : dependenciesFromPom) {
log.debug("dependency from pom: " + dependency.getGroupId() + ":" + dependency.getArtifactId() + ":"
+ dependency.getVersion() + ":" + dependency.getScope());
if (dependency.getVersion() == null) {
// getModel parent and getModel the information from there.
if (project.hasParent()) {
log.debug("Reading parent dependencyManagement information");
DependencyManagement parentProjectDependencyManagement = processDependencyManagementTransitive
? project.getParent().getDependencyManagement()
: project.getParent().getOriginalModel().getDependencyManagement();
if (parentProjectDependencyManagement != null) {
List<Dependency> parentDeps = parentProjectDependencyManagement.getDependencies();
for (Dependency parentDep : parentDeps) {
// only groupId && artifactId needed cause version is null
if (dependency.getGroupId().equals(parentDep.getGroupId())
&& dependency.getArtifactId().equals(parentDep.getArtifactId())
&& dependency.getType().equals(parentDep.getType())) {
dependencyManagement.add(parentDep);
}
}
}
} else {
String message = "We can't getModel the version for the dependency " + dependency.getGroupId()
+ ":" + dependency.getArtifactId() + " because there does not exist a parent.";
log.error(message);
// Throw error because we will not able to getModel a version for a dependency.
throw new VersionRetrievalException(message);
}
} else {
dependencyManagement.remove(dependency);
dependencyManagement.add(interpolateVersion(dependency, project));
}
}
/**
* Tries to retrieve dependency version from parent
* @param dependency {@link Dependency} for which we're trying to retrieve version
* @param project {@link MavenProject} instance
* @param processDependencyManagementTransitive if {@code true}, the original model will be considered
* instead of the interpolated model, which does not contain
* imported dependencies
* @param log {@link Log} instance (may not be null)
* @return a {@link Optional} object containing a dependency from parent containing version filled in,
* if that could be retrieved or {@link Optional#empty()}
*/
private static Optional<Dependency> getVersionFromParent(
Dependency dependency, MavenProject project, boolean processDependencyManagementTransitive, Log log) {
if (project.hasParent()) {
log.debug("Reading parent dependencyManagement information");
return ofNullable(
processDependencyManagementTransitive
? project.getParent().getDependencyManagement()
: project.getParent().getOriginalModel().getDependencyManagement())
.map(DependencyManagement::getDependencies)
.map(Collection::stream)
.flatMap(s -> s.filter(d -> dependency.getGroupId().equals(d.getGroupId()))
.filter(d -> dependency.getArtifactId().equals(d.getArtifactId()))
.filter(d -> dependency.getType().equals(d.getType()))
.findAny());
}
return dependencyManagement;

String message = "We can't getModel the version for the dependency " + dependency.getGroupId() + ":"
+ dependency.getArtifactId() + " because there does not exist a parent.";
log.warn(message);
return Optional.empty();
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import groovy.xml.XmlSlurper

def changes = new XmlSlurper().parse( new File( basedir, 'target/versions-changes.xml' ) )
assert changes.dependencyUpdate.find { node -> node.@kind == 'parent-update'
assert !(changes.dependencyUpdate.find { node -> node.@kind == 'parent-update'
&& node.@groupId == 'localhost'
&& node.@artifactId == 'dummy-parent'
&& node.@oldVersion == '1.0'
&& node.@newVersion == '3.0' } != null
&& node.@newVersion == '3.0' }.isEmpty())
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import groovy.xml.XmlSlurper

def changes = new XmlSlurper().parse( new File( basedir, 'target/versions-changes.xml' ) )
assert changes.dependencyUpdate.find { node -> node.@kind == 'property-update'
assert !(changes.dependencyUpdate.find { node -> node.@kind == 'property-update'
&& node.@groupId == 'localhost'
&& node.@artifactId == 'dummy-api'
&& node.@oldVersion == '1.0'
&& node.@newVersion == '3.0' } != null
assert changes.propertyUpdate.find { node -> node.@property == 'api'
&& node.@newVersion == '3.0' }.isEmpty())
assert !(changes.propertyUpdate.find { node -> node.@property == 'api'
&& node.@oldValue == '1.0'
&& node.@newValue == '3.0' } != null
&& node.@newValue == '3.0' }.isEmpty())
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import groovy.xml.XmlSlurper

def changes = new XmlSlurper().parse( new File( basedir, 'target/versions-changes.xml' ) )
assert changes.dependencyUpdate.find { node -> node.@kind == 'dependency-update'
assert !(changes.dependencyUpdate.find { node -> node.@kind == 'dependency-update'
&& node.@groupId == 'localhost'
&& node.@artifactId == 'dummy-api'
&& node.@oldVersion == '1.1.1-2'
&& node.@newVersion == '3.0' } != null
&& node.@newVersion == '3.0' }.isEmpty())
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import groovy.xml.XmlSlurper

def changes = new XmlSlurper().parse( new File( basedir, 'target/versions-changes.xml' ) )
assert changes.dependencyUpdate.find { node -> node.@kind == 'dependency-update'
assert !(changes.dependencyUpdate.find { node -> node.@kind == 'dependency-update'
&& node.@groupId == 'localhost'
&& node.@artifactId == 'dummy-api'
&& node.@oldVersion == '1.0'
&& node.@newVersion == '1.9.1-SNAPSHOT' } != null
&& node.@newVersion == '1.9.1-SNAPSHOT' }.isEmpty())
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import groovy.xml.XmlSlurper

def changes = new XmlSlurper().parse( new File( basedir, 'target/versions-changes.xml' ) )
assert changes.dependencyUpdate.find { node -> node.@kind == 'dependency-update'
assert !(changes.dependencyUpdate.find { node -> node.@kind == 'dependency-update'
&& node.@groupId == 'localhost'
&& node.@artifactId == 'dummy-api'
&& node.@oldVersion == '1.1.1-2'
&& node.@newVersion == '3.0' } != null
&& node.@newVersion == '3.0' }.isEmpty())
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import groovy.xml.XmlSlurper

def changes = new XmlSlurper().parse( new File( basedir, 'target/versions-changes.xml' ) )
assert changes.dependencyUpdate.find { node -> node.@kind == 'dependency-update'
assert !(changes.dependencyUpdate.find { node -> node.@kind == 'dependency-update'
&& node.@groupId == 'localhost'
&& node.@artifactId == 'dummy-api'
&& node.@oldVersion == '1.1.1-2'
&& node.@newVersion == '1.1.2' } != null
&& node.@newVersion == '1.1.2' }.isEmpty())
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:dependency-updates-report
invoker.mavenOpts = -DdependencyUpdatesReportFormats=xml -DprocessDependencyManagementTransitive=false
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>localhost</groupId>
<artifactId>issue-1191</artifactId>
<version>1.0</version>

<description>display-dependency-updates should consider dependencyManagement in enabled profiles</description>

<profiles>
<profile>
<id>test-profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>localhost</groupId>
<artifactId>dummy-api</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
</profile>
</profiles>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import groovy.xml.XmlSlurper

def report = new XmlSlurper().parse(new File(basedir, "target/dependency-updates-report.xml"))
assert !(report
.dependencyManagements
.dependencyManagement
.find { node -> node.artifactId == 'dummy-api' }.isEmpty())

Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.MavenReportException;
Expand All @@ -49,8 +48,6 @@
import org.eclipse.aether.RepositorySystem;

import static java.util.Collections.emptyMap;
import static java.util.Optional.ofNullable;
import static org.codehaus.mojo.versions.utils.MavenProjectUtils.interpolateVersion;
import static org.codehaus.mojo.versions.utils.MiscUtils.filter;

/**
Expand Down Expand Up @@ -206,31 +203,11 @@ protected void doGenerateReport(Locale locale, Sink sink) throws MavenReportExce

protected void handleDependencyManagementTransitive(
MavenProject project, Set<Dependency> dependencyManagementCollector) {
if (processDependencyManagementTransitive) {
if (hasDependencyManagement(project)) {
if (getLog().isDebugEnabled()) {
project.getDependencyManagement().getDependencies().forEach(dep -> getLog().debug(
"Dpmg: " + dep.getGroupId() + ":" + dep.getArtifactId() + ":" + dep.getVersion()
+ ":" + dep.getType() + ":" + dep.getScope()));
}
dependencyManagementCollector.addAll(
project.getDependencyManagement().getDependencies());
}
} else {
// Using the original model to getModel the original dependencyManagement entries and
// not the interpolated model.
// TODO: I'm not 100% sure if this will work correctly in all cases.
ofNullable(project.getOriginalModel().getDependencyManagement())
.map(DependencyManagement::getDependencies)
.ifPresent(list -> list.stream()
.map(dep -> interpolateVersion(dep, project))
.peek(dep -> {
if (getLog().isDebugEnabled()) {
getLog().debug("Original Dpmg: " + dep.getGroupId() + ":" + dep.getArtifactId()
+ ":" + dep.getVersion() + ":" + dep.getType() + ":" + dep.getScope());
}
})
.forEach(dependencyManagementCollector::add));
try {
dependencyManagementCollector.addAll(MavenProjectUtils.extractDependenciesFromDependencyManagement(
project, processDependencyManagementTransitive, getLog()));
} catch (VersionRetrievalException e) {
throw new RuntimeException(e);
}
}

Expand Down
Loading

0 comments on commit a6f4ffb

Please sign in to comment.