Skip to content

Commit

Permalink
feat: Added functionality to Gradle ChangeDependency to avoid duplica…
Browse files Browse the repository at this point in the history
…te already existing new dependencies

Refs: #4514
  • Loading branch information
Andrei Shakirin committed Sep 25, 2024
1 parent 25d374b commit 47dfbaf
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import lombok.EqualsAndHashCode;
import lombok.Value;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import org.openrewrite.*;
import org.openrewrite.gradle.marker.GradleDependencyConfiguration;
Expand All @@ -36,9 +37,11 @@
import org.openrewrite.maven.MavenDownloadingException;
import org.openrewrite.maven.tree.GroupArtifact;
import org.openrewrite.maven.tree.GroupArtifactVersion;
import org.openrewrite.maven.tree.ResolvedDependency;
import org.openrewrite.maven.tree.ResolvedGroupArtifactVersion;
import org.openrewrite.semver.DependencyMatcher;
import org.openrewrite.semver.Semver;
import org.openrewrite.semver.VersionComparator;

import java.util.*;

Expand Down Expand Up @@ -156,7 +159,10 @@ public Validated<Object> validate() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new FindGradleProject(FindGradleProject.SearchCriteria.Marker).getVisitor(), new GroovyIsoVisitor<ExecutionContext>() {
final DependencyMatcher depMatcher = requireNonNull(DependencyMatcher.build(oldGroupId + ":" + oldArtifactId).getValue());
final DependencyMatcher oldDepMatcher = requireNonNull(DependencyMatcher.build(oldGroupId + ":" + oldArtifactId).getValue());
final VersionComparator versionComparator = newVersion != null ? Semver.validate(newVersion, versionPattern).getValue() : null;
final DependencyMatcher newDepMatcher = new DependencyMatcher(newGroupId, newArtifactId, versionComparator);
boolean isNewDependencyPresent;

GradleProject gradleProject;

Expand All @@ -168,6 +174,7 @@ public G.CompilationUnit visitCompilationUnit(G.CompilationUnit cu, ExecutionCon
}

gradleProject = maybeGp.get();
isNewDependencyPresent = checkForNewDependencyPresence(gradleProject, newDepMatcher);

G.CompilationUnit g = super.visitCompilationUnit(cu, ctx);
if (g != cu) {
Expand All @@ -176,6 +183,20 @@ public G.CompilationUnit visitCompilationUnit(G.CompilationUnit cu, ExecutionCon
return g;
}

private boolean checkForNewDependencyPresence(GradleProject gp, DependencyMatcher dependencyMatcher) {
boolean isPresent = false;
Map<String, GradleDependencyConfiguration> nameToConfiguration = gp.getNameToConfiguration();
for (GradleDependencyConfiguration gdc : nameToConfiguration.values()) {
List<ResolvedDependency> resolvedDependencies = gdc.getDirectResolved();
isPresent = resolvedDependencies.stream()
.anyMatch(r -> dependencyMatcher.matches(r.getGroupId(), r.getArtifactId(), r.getVersion()));
if (isPresent) {
break;
}
}
return isPresent;
}

@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
J.MethodInvocation m = super.visitMethodInvocation(method, ctx);
Expand All @@ -198,13 +219,17 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu
return m;
}

@NullMarked
private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionContext ctx) {
List<Expression> depArgs = m.getArguments();
if (depArgs.get(0) instanceof J.Literal) {
String gav = (String) ((J.Literal) depArgs.get(0)).getValue();
if (gav != null) {
Dependency original = DependencyStringNotationConverter.parse(gav);
if (original != null && depMatcher.matches(original.getGroupId(), original.getArtifactId())) {
if (original != null && oldDepMatcher.matches(original.getGroupId(), original.getArtifactId())) {
if (isNewDependencyPresent) {
return null;
}
Dependency updated = original;
if (!StringUtils.isBlank(newGroupId) && !updated.getGroupId().equals(newGroupId)) {
updated = updated.withGroupId(newGroupId);
Expand Down Expand Up @@ -238,7 +263,10 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionConte

J.Literal literal = (J.Literal) strings.get(0);
Dependency original = DependencyStringNotationConverter.parse((String) requireNonNull(literal.getValue()));
if (original != null && depMatcher.matches(original.getGroupId(), original.getArtifactId())) {
if (original != null && oldDepMatcher.matches(original.getGroupId(), original.getArtifactId())) {
if (isNewDependencyPresent) {
return null;
}
Dependency updated = original;
if (!StringUtils.isBlank(newGroupId) && !updated.getGroupId().equals(newGroupId)) {
updated = updated.withGroupId(newGroupId);
Expand Down Expand Up @@ -307,9 +335,12 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionConte
if (groupId == null || artifactId == null) {
return m;
}
if (!depMatcher.matches(groupId, artifactId)) {
if (!oldDepMatcher.matches(groupId, artifactId)) {
return m;
}
if (isNewDependencyPresent && oldDepMatcher.matches(groupId, artifactId)) {
return null;
}
String updatedGroupId = groupId;
if (!StringUtils.isBlank(newGroupId) && !updatedGroupId.equals(newGroupId)) {
updatedGroupId = newGroupId;
Expand Down Expand Up @@ -364,7 +395,7 @@ private GradleProject updateGradleModel(GradleProject gp) {
for (GradleDependencyConfiguration gdc : nameToConfiguration.values()) {
GradleDependencyConfiguration newGdc = gdc;
newGdc = newGdc.withRequested(ListUtils.map(gdc.getRequested(), requested -> {
if (depMatcher.matches(requested.getGroupId(), requested.getArtifactId())) {
if (oldDepMatcher.matches(requested.getGroupId(), requested.getArtifactId())) {
GroupArtifactVersion gav = requested.getGav();
if (newGroupId != null) {
gav = gav.withGroupId(newGroupId);
Expand All @@ -379,7 +410,7 @@ private GradleProject updateGradleModel(GradleProject gp) {
return requested;
}));
newGdc = newGdc.withDirectResolved(ListUtils.map(gdc.getDirectResolved(), resolved -> {
if (depMatcher.matches(resolved.getGroupId(), resolved.getArtifactId())) {
if (oldDepMatcher.matches(resolved.getGroupId(), resolved.getArtifactId())) {
ResolvedGroupArtifactVersion gav = resolved.getGav();
if (newGroupId != null) {
gav = gav.withGroupId(newGroupId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,43 @@ void relocateDependency() {
);
}

@Test
void removeOldDependenciesIfNewAlreadyPresents() {
rewriteRun(
spec -> spec.recipe(new ChangeDependency("commons-lang", "commons-lang", "org.apache.commons", "commons-lang3", "3.11.x", null, null)),
buildGradle(
"""
plugins {
id "java-library"
}
repositories {
mavenCentral()
}
dependencies {
implementation "commons-lang:commons-lang:2.6"
implementation group: "commons-lang", name: "commons-lang", version: "2.6"
implementation "org.apache.commons:commons-lang3:3.11"
}
""",
"""
plugins {
id "java-library"
}
repositories {
mavenCentral()
}
dependencies {
implementation "org.apache.commons:commons-lang3:3.11"
}
"""
)
);
}

@Test
void changeGroupIdOnly() {
rewriteRun(
Expand Down

0 comments on commit 47dfbaf

Please sign in to comment.