Skip to content
Draft
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 @@ -427,20 +427,26 @@ private boolean isDependencyManaged(Scope scope, String groupId, String artifact
MavenResolutionResult result = getResolutionResult();
for (ResolvedManagedDependency managedDependency : result.getPom().getDependencyManagement()) {
if (groupId.equals(managedDependency.getGroupId()) && artifactId.equals(managedDependency.getArtifactId())) {
return scope.isInClasspathOf(managedDependency.getScope());
return scopeIsManagedBy(scope, managedDependency.getScope());
}
}
return false;
}

// A managed version applies whenever coordinates match regardless of scope, so an identical scope
// qualifies; isInClasspathOf alone wrongly returns false for provided/provided and test/test.
private boolean scopeIsManagedBy(Scope dependencyScope, @Nullable Scope managedScope) {
return managedScope == null || dependencyScope == managedScope || dependencyScope.isInClasspathOf(managedScope);
}

private boolean canAffectManagedDependency(MavenResolutionResult result, Scope scope, String groupId, String artifactId) {
// We're only going to be able to effect managed dependencies that are either direct or are brought in as direct via a local parent

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be the word affect rather than effect, but not worth fixing separately.

// `ChangeManagedDependencyGroupIdAndArtifactId` cannot manipulate BOM imported managed dependencies nor direct dependencies from remote parents
Pom requestedPom = result.getPom().getRequested();
for (ManagedDependency requestedManagedDependency : requestedPom.getDependencyManagement()) {
if (matchesGlob(requestedManagedDependency.getGroupId(), groupId) && matchesGlob(requestedManagedDependency.getArtifactId(), artifactId)) {
if (requestedManagedDependency instanceof ManagedDependency.Defined) {
return scope.isInClasspathOf(Scope.fromName(((ManagedDependency.Defined) requestedManagedDependency).getScope()));
return scopeIsManagedBy(scope, Scope.fromName(((ManagedDependency.Defined) requestedManagedDependency).getScope()));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
Expand Down Expand Up @@ -199,28 +198,22 @@ private MavenResolutionResult updateResult(ExecutionContext ctx, MavenResolution
MavenPomDownloader downloader = new MavenPomDownloader(projectPoms, ctx, getResolutionResult().getMavenSettings(),
getResolutionResult().getActiveProfiles());

AtomicReference<MavenDownloadingExceptions> exceptions = new AtomicReference<>();
try {
ResolvedPom resolved = resolutionResult.getPom().resolve(ctx, downloader);
MavenResolutionResult mrr = resolutionResult
return resolutionResult
.withPom(resolved)
// Re-resolve modules best-effort: a module that is transiently unresolvable mid-recipe keeps
// its previous resolution rather than discarding this pom's own valid update.
.withModules(ListUtils.map(resolutionResult.getModules(), module -> {
try {
return updateResult(ctx, module, projectPoms);
} catch (MavenDownloadingExceptions e) {
exceptions.set(MavenDownloadingExceptions.append(exceptions.get(), e));
return module;
}
}))
.resolveDependencies(downloader, ctx);
if (exceptions.get() != null) {
throw exceptions.get();
}
return mrr;
} catch (MavenDownloadingExceptions e) {
throw MavenDownloadingExceptions.append(exceptions.get(), e);
} catch (MavenDownloadingException e) {
throw MavenDownloadingExceptions.append(exceptions.get(), e);
throw MavenDownloadingExceptions.append(null, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1501,6 +1501,101 @@ void unmanagedToManagedExternalizedDepMgmt() {
);
}

@Issue("https://github.com/openrewrite/rewrite/issues/8145")
@Test
void providedDependencyManagedByLocalParentDoesNotGetExplicitVersion() {
rewriteRun(
spec -> spec.recipe(new ChangeDependencyGroupIdAndArtifactId(
"javax.servlet", "javax.servlet-api",
"jakarta.servlet", "jakarta.servlet-api",
"5.0.x", null)),
mavenProject("parent",
pomXml(
"""
<project>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>child</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
""",
"""
<project>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>child</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
"""
),
mavenProject("child",
pomXml(
"""
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>child</artifactId>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
""",
"""
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>child</artifactId>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
"""
)
)
)
);
}

@Test
void latestPatch() {
rewriteRun(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,108 @@ void upgradeVersionWithGroupIdAndArtifactIdDefinedAsProperty() {
);
}

@Issue("https://github.com/openrewrite/rewrite/issues/8145")
@Test
void changeDependencyThenUpgradeManagedVersionInParentOfMultiModule() {
rewriteRun(
spec -> spec.recipes(
// Phase 1: rename javax -> jakarta (EE9 migration)
new ChangeDependencyGroupIdAndArtifactId(
"javax.servlet", "javax.servlet-api",
"jakarta.servlet", "jakarta.servlet-api",
"5.0.x", null),
// Phase 2: bump jakarta EE9 -> EE10, which must upgrade the parent's managed version
new UpgradeDependencyVersion(
"jakarta.servlet", "jakarta.servlet-api",
"6.0.x", null, null, null)
),
mavenProject("parent",
pomXml(
"""
<project>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>child</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
""",
"""
<project>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>child</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
"""
),
mavenProject("child",
pomXml(
"""
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>child</artifactId>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
""",
"""
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>child</artifactId>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
"""
)
)
)
);
}

@Test
void upgradeVersionSuccessively() {
rewriteRun(
Expand Down
Loading