Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,18 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
.resolve(emptyList(), mpd, ctx);
ResolvedPom newParent = mpd.download(new GroupArtifactVersion(targetGroupId, targetArtifactId, targetVersion.get()), null, resolvedPom, resolvedPom.getRepositories())
.resolve(emptyList(), mpd, ctx);
List<ResolvedManagedDependency> dependenciesWithoutExplicitVersions = getDependenciesUnmanagedByNewParent(mrr, newParent);
// Inspect this pom plus any descendant modules that inherit from it, so dependency
// management dropped by the new parent can be restored in this (local) parent on
// behalf of child modules that declare those dependencies without an explicit version.
List<MavenResolutionResult> modulesToInspect = new ArrayList<>();
modulesToInspect.add(mrr);
ResolvedGroupArtifactVersion thisGav = mrr.getPom().getGav();
for (MavenResolutionResult candidate : acc.gavToOriginalMarker.values()) {
if (isDescendantOf(candidate, thisGav)) {
modulesToInspect.add(candidate);
}
}
List<ResolvedManagedDependency> dependenciesWithoutExplicitVersions = getDependenciesUnmanagedByNewParent(modulesToInspect, newParent);
for (ResolvedManagedDependency dep : dependenciesWithoutExplicitVersions) {
changeParentTagVisitors.add(new AddManagedDependencyVisitor(
dep.getGroupId(), dep.getArtifactId(), dep.getVersion() == null ? "" : dep.getVersion(),
Expand Down Expand Up @@ -530,7 +541,31 @@ private boolean isGlobalProperty(String propertyName) {
.collect(toMap(p -> p, cascadedProps::get));
}

private List<ResolvedManagedDependency> getDependenciesUnmanagedByNewParent(MavenResolutionResult mrr, ResolvedPom newParent) {
private static boolean isDescendantOf(MavenResolutionResult module, ResolvedGroupArtifactVersion ancestorGav) {
for (MavenResolutionResult parent = module.getParent(); parent != null; parent = parent.getParent()) {
if (parent.getPom().getGav().equals(ancestorGav)) {
return true;
}
}
return false;
}

private List<ResolvedManagedDependency> getDependenciesUnmanagedByNewParent(List<MavenResolutionResult> modules, ResolvedPom newParent) {
// Remove from the list any that would still be managed under the new parent
Set<GroupArtifact> newParentManagedGa = newParent.getDependencyManagement().stream()
.map(dep -> new GroupArtifact(dep.getGav().getGroupId(), dep.getGav().getArtifactId()))
.collect(toSet());

Map<GroupArtifact, ResolvedManagedDependency> unmanaged = new LinkedHashMap<>();
for (MavenResolutionResult module : modules) {
for (ResolvedManagedDependency dep : getDependenciesUnmanagedByNewParentForModule(module, newParentManagedGa)) {
unmanaged.putIfAbsent(new GroupArtifact(dep.getGav().getGroupId(), dep.getGav().getArtifactId()), dep);
}
}
return new ArrayList<>(unmanaged.values());
}

private List<ResolvedManagedDependency> getDependenciesUnmanagedByNewParentForModule(MavenResolutionResult mrr, Set<GroupArtifact> newParentManagedGa) {
ResolvedPom resolvedPom = mrr.getPom();

// Dependencies managed by the current pom's own dependency management are irrelevant to parent upgrade
Expand Down Expand Up @@ -567,11 +602,6 @@ private List<ResolvedManagedDependency> getDependenciesUnmanagedByNewParent(Mave
return emptyList();
}

// Remove from the list any that would still be managed under the new parent
Set<GroupArtifact> newParentManagedGa = newParent.getDependencyManagement().stream()
.map(dep -> new GroupArtifact(dep.getGav().getGroupId(), dep.getGav().getArtifactId()))
.collect(toSet());

return depsWithoutExplicitVersion.stream()
.filter(it -> !newParentManagedGa.contains(new GroupArtifact(it.getGav().getGroupId(), it.getGav().getArtifactId())))
.collect(toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,105 @@ void bringsDownRemovedManagedVersion() {
)
);
}

@Issue("https://github.com/moderneinc/customer-requests/issues/2589")
@Test
void bringsDownRemovedManagedVersionDeclaredInChildModuleOfLocalParent() {
rewriteRun(
spec -> spec.recipe(new ChangeParentPom(
"org.springframework.boot", "org.springframework.boot",
"spring-boot-starter-parent", "spring-boot-starter-parent",
"3.2.4",
null, null, null, null, null)),
mavenProject("parent",
pomXml(
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/>
</parent>
<modules>
<module>child</module>
</modules>
</project>
""",
"""
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
<relativePath/>
</parent>
<modules>
<module>child</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
"""
),
mavenProject("child",
pomXml(
"""
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>child</artifactId>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
</dependencies>
</project>
""",
"""
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany</groupId>
<artifactId>parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>child</artifactId>
<dependencies>
<!--~~(No version provided for direct dependency javax.servlet:javax.servlet-api:compile)~~>--><dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
</dependencies>
</project>
"""
)
)
)
);
}
}

@Issue("https://github.com/openrewrite/rewrite/issues/1753")
Expand Down
Loading