From 9936a7a70a4792aa73e7f2d1f1378c05b3507123 Mon Sep 17 00:00:00 2001 From: Shannon Pamperl Date: Tue, 3 Dec 2024 21:27:48 -0600 Subject: [PATCH] Enrich GradleDependency.Matcher to match on cases where a ResolvedDependency is unavailable --- .../openrewrite/gradle/ChangeDependency.java | 96 +++++++++- .../gradle/ChangeDependencyArtifactId.java | 164 ++++++++++------- .../gradle/ChangeDependencyClassifier.java | 160 +++++++++++++++-- .../gradle/ChangeDependencyConfiguration.java | 77 ++++++-- .../gradle/ChangeDependencyExtension.java | 81 ++++++--- .../gradle/ChangeDependencyGroupId.java | 164 ++++++++++------- .../gradle/DependencyUseMapNotation.java | 5 +- .../gradle/DependencyUseStringNotation.java | 5 +- .../openrewrite/gradle/RemoveDependency.java | 168 ++++++------------ .../gradle/UpgradeDependencyVersion.java | 12 +- .../gradle/trait/GradleDependency.java | 100 ++++++++--- 11 files changed, 688 insertions(+), 344 deletions(-) diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependency.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependency.java index 0ff50885dee..9312fa96c3b 100644 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependency.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependency.java @@ -180,14 +180,16 @@ public G.CompilationUnit visitCompilationUnit(G.CompilationUnit cu, ExecutionCon public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { J.MethodInvocation m = super.visitMethodInvocation(method, ctx); - GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); + GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher() + .groupId(oldGroupId) + .artifactId(oldArtifactId); if (!gradleDependencyMatcher.get(getCursor()).isPresent()) { return m; } List depArgs = m.getArguments(); - if (depArgs.get(0) instanceof J.Literal || depArgs.get(0) instanceof G.GString || depArgs.get(0) instanceof G.MapEntry) { + if (depArgs.get(0) instanceof J.Literal || depArgs.get(0) instanceof G.GString || depArgs.get(0) instanceof G.MapEntry || depArgs.get(0) instanceof G.MapLiteral) { m = updateDependency(m, ctx); } else if (depArgs.get(0) instanceof J.MethodInvocation && (((J.MethodInvocation) depArgs.get(0)).getSimpleName().equals("platform") || @@ -204,7 +206,7 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionConte 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) { Dependency updated = original; if (!StringUtils.isBlank(newGroupId) && !updated.getGroupId().equals(newGroupId)) { updated = updated.withGroupId(newGroupId); @@ -238,7 +240,7 @@ 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) { Dependency updated = original; if (!StringUtils.isBlank(newGroupId) && !updated.getGroupId().equals(newGroupId)) { updated = updated.withGroupId(newGroupId); @@ -352,6 +354,92 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionConte return arg; })); } + } else if (m.getArguments().get(0) instanceof G.MapLiteral) { + G.MapLiteral map = (G.MapLiteral) depArgs.get(0); + G.MapEntry groupEntry = null; + G.MapEntry artifactEntry = null; + G.MapEntry versionEntry = null; + String groupId = null; + String artifactId = null; + String version = null; + + for (G.MapEntry arg : map.getElements()) { + if (!(arg.getKey() instanceof J.Literal) || !(arg.getValue() instanceof J.Literal)) { + continue; + } + J.Literal key = (J.Literal) arg.getKey(); + J.Literal value = (J.Literal) arg.getValue(); + if (!(key.getValue() instanceof String) || !(value.getValue() instanceof String)) { + continue; + } + String keyValue = (String) key.getValue(); + String valueValue = (String) value.getValue(); + switch (keyValue) { + case "group": + groupEntry = arg; + groupId = valueValue; + break; + case "name": + artifactEntry = arg; + artifactId = valueValue; + break; + case "version": + versionEntry = arg; + version = valueValue; + break; + } + } + if (groupId == null || artifactId == null) { + return m; + } + if (!depMatcher.matches(groupId, artifactId)) { + return m; + } + String updatedGroupId = groupId; + if (!StringUtils.isBlank(newGroupId) && !updatedGroupId.equals(newGroupId)) { + updatedGroupId = newGroupId; + } + String updatedArtifactId = artifactId; + if (!StringUtils.isBlank(newArtifactId) && !updatedArtifactId.equals(newArtifactId)) { + updatedArtifactId = newArtifactId; + } + String updatedVersion = version; + if (!StringUtils.isBlank(newVersion) && (!StringUtils.isBlank(version) || Boolean.TRUE.equals(overrideManagedVersion))) { + String resolvedVersion; + try { + resolvedVersion = new DependencyVersionSelector(null, gradleProject, null) + .select(new GroupArtifact(updatedGroupId, updatedArtifactId), m.getSimpleName(), newVersion, versionPattern, ctx); + } catch (MavenDownloadingException e) { + return e.warn(m); + } + if (resolvedVersion != null && !resolvedVersion.equals(updatedVersion)) { + updatedVersion = resolvedVersion; + } + } + + if (!updatedGroupId.equals(groupId) || !updatedArtifactId.equals(artifactId) || updatedVersion != null && !updatedVersion.equals(version)) { + G.MapEntry finalGroup = groupEntry; + String finalGroupIdValue = updatedGroupId; + G.MapEntry finalArtifact = artifactEntry; + String finalArtifactIdValue = updatedArtifactId; + G.MapEntry finalVersion = versionEntry; + String finalVersionValue = updatedVersion; + m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> { + G.MapLiteral mapLiteral = (G.MapLiteral) arg; + return mapLiteral.withElements(ListUtils.map(mapLiteral.getElements(), e -> { + if (e == finalGroup) { + return finalGroup.withValue(ChangeStringLiteral.withStringValue((J.Literal) finalGroup.getValue(), finalGroupIdValue)); + } + if (e == finalArtifact) { + return finalArtifact.withValue(ChangeStringLiteral.withStringValue((J.Literal) finalArtifact.getValue(), finalArtifactIdValue)); + } + if (e == finalVersion) { + return finalVersion.withValue(ChangeStringLiteral.withStringValue((J.Literal) finalVersion.getValue(), finalVersionValue)); + } + return e; + })); + })); + } } return m; diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyArtifactId.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyArtifactId.java index ba98f950ca9..02e028fd305 100755 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyArtifactId.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyArtifactId.java @@ -25,21 +25,18 @@ import org.openrewrite.gradle.util.ChangeStringLiteral; import org.openrewrite.gradle.util.Dependency; import org.openrewrite.gradle.util.DependencyStringNotationConverter; -import org.openrewrite.groovy.GroovyVisitor; +import org.openrewrite.groovy.GroovyIsoVisitor; import org.openrewrite.groovy.tree.G; import org.openrewrite.internal.ListUtils; import org.openrewrite.internal.StringUtils; -import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; -import org.openrewrite.maven.tree.GroupArtifact; -import org.openrewrite.maven.tree.ResolvedDependency; import org.openrewrite.semver.DependencyMatcher; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; +import java.util.Optional; import static java.util.Objects.requireNonNull; @@ -90,38 +87,42 @@ public Validated validate() { @Override public TreeVisitor getVisitor() { - return Preconditions.check(new IsBuildGradle<>(), new GroovyVisitor() { + return Preconditions.check(new IsBuildGradle<>(), new GroovyIsoVisitor() { final DependencyMatcher depMatcher = requireNonNull(DependencyMatcher.build(groupId + ":" + artifactId).getValue()); - final MethodMatcher dependencyDsl = new MethodMatcher("DependencyHandlerSpec *(..)"); - final Map updatedDependencies = new HashMap<>(); + GradleProject gradleProject; @Override - public G visitCompilationUnit(G.CompilationUnit compilationUnit, ExecutionContext ctx) { - G.CompilationUnit cu = (G.CompilationUnit) super.visitCompilationUnit(compilationUnit, ctx); - if(cu != compilationUnit) { - cu = cu.withMarkers(cu.getMarkers().withMarkers(ListUtils.map(cu.getMarkers().getMarkers(), m -> { - if (m instanceof GradleProject) { - return updateModel((GradleProject) m, updatedDependencies); - } - return m; - }))); + public G.CompilationUnit visitCompilationUnit(G.CompilationUnit cu, ExecutionContext ctx) { + Optional maybeGp = cu.getMarkers().findFirst(GradleProject.class); + if (!maybeGp.isPresent()) { + return cu; + } + + gradleProject = maybeGp.get(); + + G.CompilationUnit g = super.visitCompilationUnit(cu, ctx); + if (g != cu) { + g = g.withMarkers(g.getMarkers().setByType(updateGradleModel(gradleProject))); } - return cu; + return g; } @Override - public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { - J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { + J.MethodInvocation m = super.visitMethodInvocation(method, ctx); - GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); + GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher() + .configuration(configuration) + .groupId(groupId) + .artifactId(artifactId); - if (!((gradleDependencyMatcher.get(getCursor()).isPresent() || dependencyDsl.matches(m)) && (StringUtils.isBlank(configuration) || m.getSimpleName().equals(configuration)))) { + if (!gradleDependencyMatcher.get(getCursor()).isPresent()) { return m; } List depArgs = m.getArguments(); - if (depArgs.get(0) instanceof J.Literal || depArgs.get(0) instanceof G.GString || depArgs.get(0) instanceof G.MapEntry) { + if (depArgs.get(0) instanceof J.Literal || depArgs.get(0) instanceof G.GString || depArgs.get(0) instanceof G.MapEntry || depArgs.get(0) instanceof G.MapLiteral) { m = updateDependency(m); } else if (depArgs.get(0) instanceof J.MethodInvocation && (((J.MethodInvocation) depArgs.get(0)).getSimpleName().equals("platform") || @@ -138,11 +139,8 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m) { String gav = (String) ((J.Literal) depArgs.get(0)).getValue(); if (gav != null) { Dependency dependency = DependencyStringNotationConverter.parse(gav); - if (dependency != null && !newArtifactId.equals(dependency.getArtifactId()) && - ((dependency.getVersion() == null && depMatcher.matches(dependency.getGroupId(), dependency.getArtifactId())) || - (dependency.getVersion() != null && depMatcher.matches(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion())))) { + if (dependency != null && !newArtifactId.equals(dependency.getArtifactId())) { Dependency newDependency = dependency.withArtifactId(newArtifactId); - updatedDependencies.put(dependency.getGav().asGroupArtifact(), newDependency.getGav().asGroupArtifact()); m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> ChangeStringLiteral.withStringValue((J.Literal) arg, newDependency.toStringNotation()))); } } @@ -151,10 +149,8 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m) { if (strings.size() >= 2 && strings.get(0) instanceof J.Literal) { Dependency dependency = DependencyStringNotationConverter.parse((String) requireNonNull(((J.Literal) strings.get(0)).getValue())); - if (dependency != null && !newArtifactId.equals(dependency.getArtifactId()) && - depMatcher.matches(dependency.getGroupId(), dependency.getArtifactId())) { + if (dependency != null && !newArtifactId.equals(dependency.getArtifactId())) { Dependency newDependency = dependency.withArtifactId(newArtifactId); - updatedDependencies.put(dependency.getGav().asGroupArtifact(), newDependency.getGav().asGroupArtifact()); String replacement = newDependency.toStringNotation(); m = m.withArguments(ListUtils.mapFirst(depArgs, arg -> { G.GString gString = (G.GString) arg; @@ -166,7 +162,6 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m) { G.MapEntry artifactEntry = null; String groupId = null; String artifactId = null; - String version = null; String versionStringDelimiter = "'"; for (Expression e : depArgs) { @@ -192,13 +187,9 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m) { } artifactEntry = arg; artifactId = valueValue; - } else if ("version".equals(keyValue)) { - version = valueValue; } } - if (groupId == null || artifactId == null || - (version == null && !depMatcher.matches(groupId, artifactId)) || - (version != null && !depMatcher.matches(groupId, artifactId, version))) { + if (groupId == null || artifactId == null) { return m; } String delimiter = versionStringDelimiter; @@ -211,35 +202,86 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m) { } return arg; })); + } else if (depArgs.get(0) instanceof G.MapLiteral) { + G.MapLiteral map = (G.MapLiteral) depArgs.get(0); + G.MapEntry artifactEntry = null; + String groupId = null; + String artifactId = null; + + String versionStringDelimiter = "'"; + for (G.MapEntry arg : map.getElements()) { + if (!(arg.getKey() instanceof J.Literal) || !(arg.getValue() instanceof J.Literal)) { + continue; + } + J.Literal key = (J.Literal) arg.getKey(); + J.Literal value = (J.Literal) arg.getValue(); + if (!(key.getValue() instanceof String) || !(value.getValue() instanceof String)) { + continue; + } + String keyValue = (String) key.getValue(); + String valueValue = (String) value.getValue(); + if ("group".equals(keyValue)) { + groupId = valueValue; + } else if ("name".equals(keyValue) && !newArtifactId.equals(valueValue)) { + if (value.getValueSource() != null) { + versionStringDelimiter = value.getValueSource().substring(0, value.getValueSource().indexOf(valueValue)); + } + artifactEntry = arg; + artifactId = valueValue; + } + } + if (groupId == null || artifactId == null) { + return m; + } + String delimiter = versionStringDelimiter; + G.MapEntry finalArtifact = artifactEntry; + m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> { + G.MapLiteral mapLiteral = (G.MapLiteral) arg; + return mapLiteral.withElements(ListUtils.map(mapLiteral.getElements(), e -> { + if (e == finalArtifact) { + return finalArtifact.withValue(((J.Literal) finalArtifact.getValue()) + .withValue(newArtifactId) + .withValueSource(delimiter + newArtifactId + delimiter)); + } + return e; + })); + })); } return m; } - }); - } - private GradleProject updateModel(GradleProject gp, Map updatedDependencies) { - Map nameToConfigurations = gp.getNameToConfiguration(); - Map updatedNameToConfigurations = new HashMap<>(); - for (Map.Entry nameToConfiguration : nameToConfigurations.entrySet()) { - String configurationName = nameToConfiguration.getKey(); - GradleDependencyConfiguration configuration = nameToConfiguration.getValue(); - - List newRequested = configuration.getRequested() - .stream() - .map(requested -> requested.withGav(requested.getGav() - .withGroupArtifact(updatedDependencies.getOrDefault(requested.getGav().asGroupArtifact(), requested.getGav().asGroupArtifact())))) - .collect(Collectors.toList()); - - List newResolved = configuration.getResolved().stream() - .map(resolved -> - resolved.withGav(resolved.getGav() - .withGroupArtifact(updatedDependencies.getOrDefault(resolved.getGav().asGroupArtifact(), resolved.getGav().asGroupArtifact())))) - .collect(Collectors.toList()); - - updatedNameToConfigurations.put(configurationName, configuration.withRequested(newRequested).withDirectResolved(newResolved)); - } - - return gp.withNameToConfiguration(updatedNameToConfigurations); + private GradleProject updateGradleModel(GradleProject gp) { + Map nameToConfiguration = gp.getNameToConfiguration(); + Map newNameToConfiguration = new HashMap<>(nameToConfiguration.size()); + boolean anyChanged = false; + for (GradleDependencyConfiguration gdc : nameToConfiguration.values()) { + if (!StringUtils.isBlank(configuration) && configuration.equals(gdc.getName())) { + newNameToConfiguration.put(gdc.getName(), gdc); + continue; + } + + GradleDependencyConfiguration newGdc = gdc; + newGdc = newGdc.withRequested(ListUtils.map(gdc.getRequested(), requested -> { + if (depMatcher.matches(requested.getGroupId(), requested.getArtifactId())) { + return requested.withGav(requested.getGav().withArtifactId(newArtifactId)); + } + return requested; + })); + newGdc = newGdc.withDirectResolved(ListUtils.map(gdc.getDirectResolved(), resolved -> { + if (depMatcher.matches(resolved.getGroupId(), resolved.getArtifactId())) { + return resolved.withGav(resolved.getGav().withArtifactId(newArtifactId)); + } + return resolved; + })); + anyChanged |= newGdc != gdc; + newNameToConfiguration.put(newGdc.getName(), newGdc); + } + if (anyChanged) { + gp = gp.withNameToConfiguration(newNameToConfiguration); + } + return gp; + } + }); } } diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyClassifier.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyClassifier.java index c11f7ccd68d..fcc162cea02 100644 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyClassifier.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyClassifier.java @@ -19,21 +19,21 @@ import lombok.Value; import org.jspecify.annotations.Nullable; import org.openrewrite.*; +import org.openrewrite.gradle.marker.GradleDependencyConfiguration; +import org.openrewrite.gradle.marker.GradleProject; import org.openrewrite.gradle.trait.GradleDependency; import org.openrewrite.gradle.util.ChangeStringLiteral; import org.openrewrite.gradle.util.Dependency; import org.openrewrite.gradle.util.DependencyStringNotationConverter; -import org.openrewrite.groovy.GroovyVisitor; +import org.openrewrite.groovy.GroovyIsoVisitor; import org.openrewrite.groovy.tree.G; import org.openrewrite.internal.ListUtils; import org.openrewrite.internal.StringUtils; -import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.*; import org.openrewrite.marker.Markers; import org.openrewrite.semver.DependencyMatcher; -import java.util.List; -import java.util.Objects; +import java.util.*; import static java.util.Objects.requireNonNull; @@ -86,16 +86,36 @@ public Validated validate() { @Override public TreeVisitor getVisitor() { - return Preconditions.check(new IsBuildGradle<>(), new GroovyVisitor() { + return Preconditions.check(new IsBuildGradle<>(), new GroovyIsoVisitor() { final DependencyMatcher depMatcher = requireNonNull(DependencyMatcher.build(groupId + ":" + artifactId).getValue()); - final MethodMatcher dependencyDsl = new MethodMatcher("DependencyHandlerSpec *(..)"); + + GradleProject gradleProject; + + @Override + public G.CompilationUnit visitCompilationUnit(G.CompilationUnit cu, ExecutionContext ctx) { + Optional maybeGp = cu.getMarkers().findFirst(GradleProject.class); + if (!maybeGp.isPresent()) { + return cu; + } + + gradleProject = maybeGp.get(); + + G.CompilationUnit g = super.visitCompilationUnit(cu, ctx); + if (g != cu) { + g = g.withMarkers(g.getMarkers().setByType(updateGradleModel(gradleProject))); + } + return g; + } @Override - public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { - J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); - GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { + J.MethodInvocation m = super.visitMethodInvocation(method, ctx); + GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher() + .configuration(configuration) + .groupId(groupId) + .artifactId(artifactId); - if (!((gradleDependencyMatcher.get(getCursor()).isPresent() || dependencyDsl.matches(m)) && (StringUtils.isBlank(configuration) || m.getSimpleName().equals(configuration)))) { + if (!gradleDependencyMatcher.get(getCursor()).isPresent()) { return m; } @@ -104,8 +124,7 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) String gav = (String) ((J.Literal) depArgs.get(0)).getValue(); if (gav != null) { Dependency dependency = DependencyStringNotationConverter.parse(gav); - if (dependency != null && dependency.getVersion() != null && !Objects.equals(newClassifier, dependency.getClassifier()) && - depMatcher.matches(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion())) { + if (dependency != null && dependency.getVersion() != null && !Objects.equals(newClassifier, dependency.getClassifier())) { Dependency newDependency = dependency.withClassifier(newClassifier); m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> ChangeStringLiteral.withStringValue((J.Literal) arg, newDependency.toStringNotation()))); } @@ -157,10 +176,7 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) } index++; } - if (groupId == null || artifactId == null || - (version == null && !depMatcher.matches(groupId, artifactId)) || - (version != null && !depMatcher.matches(groupId, artifactId, version)) || - Objects.equals(newClassifier, classifier)) { + if (groupId == null || artifactId == null || Objects.equals(newClassifier, classifier)) { return m; } @@ -187,12 +203,122 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) })); } } + } else if (depArgs.get(0) instanceof G.MapLiteral) { + G.MapLiteral map = (G.MapLiteral) depArgs.get(0); + G.MapEntry classifierEntry = null; + String groupId = null; + String artifactId = null; + String classifier = null; + String groupDelimiter = "'"; + G.MapEntry mapEntry = null; + String classifierStringDelimiter = null; + int index = 0; + for (Expression e : depArgs) { + if (!(e instanceof G.MapEntry)) { + continue; + } + G.MapEntry arg = (G.MapEntry) e; + if (!(arg.getKey() instanceof J.Literal) || !(arg.getValue() instanceof J.Literal)) { + continue; + } + J.Literal key = (J.Literal) arg.getKey(); + J.Literal value = (J.Literal) arg.getValue(); + if (!(key.getValue() instanceof String) || !(value.getValue() instanceof String)) { + continue; + } + String keyValue = (String) key.getValue(); + String valueValue = (String) value.getValue(); + if ("group".equals(keyValue)) { + groupId = valueValue; + if (value.getValueSource() != null) { + groupDelimiter = value.getValueSource().substring(0, value.getValueSource().indexOf(valueValue)); + } + } else if ("name".equals(keyValue)) { + if (index > 0 && mapEntry == null) { + mapEntry = arg; + } + artifactId = valueValue; + } else if ("classifier".equals(keyValue)) { + if (value.getValueSource() != null) { + classifierStringDelimiter = value.getValueSource().substring(0, value.getValueSource().indexOf(valueValue)); + } + classifierEntry = arg; + classifier = valueValue; + } + index++; + } + if (groupId == null || artifactId == null || Objects.equals(newClassifier, classifier)) { + return m; + } + + if (classifier == null) { + String delimiter = groupDelimiter; + G.MapEntry finalMapEntry = mapEntry; + J.Literal keyLiteral = new J.Literal(Tree.randomId(), mapEntry == null ? Space.EMPTY : mapEntry.getKey().getPrefix(), Markers.EMPTY, "classifier", "classifier", null, JavaType.Primitive.String); + J.Literal valueLiteral = new J.Literal(Tree.randomId(), mapEntry == null ? Space.EMPTY : mapEntry.getValue().getPrefix(), Markers.EMPTY, newClassifier, delimiter + newClassifier + delimiter, null, JavaType.Primitive.String); + m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> { + G.MapLiteral mapLiteral = (G.MapLiteral) arg; + return mapLiteral.withElements(ListUtils.concat(mapLiteral.getElements(), new G.MapEntry(Tree.randomId(), finalMapEntry == null ? Space.EMPTY : finalMapEntry.getPrefix(), Markers.EMPTY, JRightPadded.build(keyLiteral), valueLiteral, null))); + })); + } else { + G.MapEntry finalClassifier = classifierEntry; + if (newClassifier == null) { + m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> { + G.MapLiteral mapLiteral = (G.MapLiteral) arg; + return mapLiteral.withElements(ListUtils.map(mapLiteral.getElements(), e -> e == finalClassifier ? null : e)); + })); + } else { + String delimiter = classifierStringDelimiter; // `classifierStringDelimiter` cannot be null + m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> { + G.MapLiteral mapLiteral = (G.MapLiteral) arg; + return mapLiteral.withElements(ListUtils.map(mapLiteral.getElements(), e -> { + if (e == finalClassifier) { + return finalClassifier.withValue(((J.Literal) finalClassifier.getValue()) + .withValue(newClassifier) + .withValueSource(delimiter + newClassifier + delimiter)); + } + return e; + })); + })); + } + } } return m; } + + private GradleProject updateGradleModel(GradleProject gp) { + Map nameToConfiguration = gp.getNameToConfiguration(); + Map newNameToConfiguration = new HashMap<>(nameToConfiguration.size()); + boolean anyChanged = false; + for (GradleDependencyConfiguration gdc : nameToConfiguration.values()) { + if (!StringUtils.isBlank(configuration) && !configuration.equals(gdc.getName())) { + newNameToConfiguration.put(gdc.getName(), gdc); + continue; + } + + GradleDependencyConfiguration newGdc = gdc; + newGdc = newGdc.withRequested(ListUtils.map(gdc.getRequested(), requested -> { + if (depMatcher.matches(requested.getGroupId(), requested.getArtifactId()) && !Objects.equals(requested.getClassifier(), newClassifier)) { + return requested.withClassifier(newClassifier); + } + return requested; + })); + newGdc = newGdc.withDirectResolved(ListUtils.map(gdc.getDirectResolved(), resolved -> { + if (depMatcher.matches(resolved.getGroupId(), resolved.getArtifactId()) && !Objects.equals(resolved.getClassifier(), newClassifier)) { + return resolved.withClassifier(newClassifier); + } + return resolved; + })); + anyChanged |= newGdc != gdc; + newNameToConfiguration.put(newGdc.getName(), newGdc); + } + if (anyChanged) { + gp = gp.withNameToConfiguration(newNameToConfiguration); + } + return gp; + } }); } - } diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyConfiguration.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyConfiguration.java index dd2e0275e5c..ad6747d3a41 100644 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyConfiguration.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyConfiguration.java @@ -22,9 +22,8 @@ import org.openrewrite.gradle.trait.GradleDependency; import org.openrewrite.gradle.util.Dependency; import org.openrewrite.gradle.util.DependencyStringNotationConverter; -import org.openrewrite.groovy.GroovyVisitor; +import org.openrewrite.groovy.GroovyIsoVisitor; import org.openrewrite.groovy.tree.G; -import org.openrewrite.internal.StringUtils; import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; @@ -86,16 +85,18 @@ public Duration getEstimatedEffortPerOccurrence() { @Override public TreeVisitor getVisitor() { - return Preconditions.check(new IsBuildGradle<>(), new GroovyVisitor() { + return Preconditions.check(new IsBuildGradle<>(), new GroovyIsoVisitor() { + // Still need to be able to change the configuration for project dependencies which are not yet supported by the `GradleDependency.Matcher` final MethodMatcher dependencyDsl = new MethodMatcher("DependencyHandlerSpec *(..)"); @Override - public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { - J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { + J.MethodInvocation m = super.visitMethodInvocation(method, ctx); - GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); + GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher() + .configuration(configuration); - if (!((gradleDependencyMatcher.get(getCursor()).isPresent() || dependencyDsl.matches(m)) && (StringUtils.isBlank(configuration) || m.getSimpleName().equals(configuration)))) { + if (!(gradleDependencyMatcher.get(getCursor()).isPresent() || dependencyDsl.matches(m))) { return m; } @@ -127,19 +128,65 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) if (dependency == null || !dependencyMatcher.matches(dependency.getGroupId(), dependency.getArtifactId())) { return m; } - } else if (args.get(0) instanceof G.MapEntry && args.size() >= 2) { - Expression groupValue = ((G.MapEntry) args.get(0)).getValue(); - Expression artifactValue = ((G.MapEntry) args.get(1)).getValue(); - if (!(groupValue instanceof J.Literal) || !(artifactValue instanceof J.Literal)) { + } else if (args.get(0) instanceof G.MapEntry) { + if (args.size() < 2) { return m; } - J.Literal groupLiteral = (J.Literal) groupValue; - J.Literal artifactLiteral = (J.Literal) artifactValue; - if (!(groupLiteral.getValue() instanceof String) || !(artifactLiteral.getValue() instanceof String)) { + + String groupId = null; + String artifactId = null; + for (Expression e : args) { + if (!(e instanceof G.MapEntry)) { + continue; + } + G.MapEntry arg = (G.MapEntry) e; + if (!(arg.getKey() instanceof J.Literal) || !(arg.getValue() instanceof J.Literal)) { + continue; + } + J.Literal key = (J.Literal) arg.getKey(); + J.Literal value = (J.Literal) arg.getValue(); + if (!(key.getValue() instanceof String) || !(value.getValue() instanceof String)) { + continue; + } + String keyValue = (String) key.getValue(); + String valueValue = (String) value.getValue(); + if ("group".equals(keyValue)) { + groupId = valueValue; + } else if ("name".equals(keyValue)) { + artifactId = valueValue; + } + } + + if (artifactId == null || !dependencyMatcher.matches(groupId, artifactId)) { return m; } + } else if (args.get(0) instanceof G.MapLiteral) { + if (args.size() < 2) { + return m; + } + + G.MapLiteral map = (G.MapLiteral) args.get(0); + String groupId = null; + String artifactId = null; + for (G.MapEntry arg : map.getElements()) { + if (!(arg.getKey() instanceof J.Literal) || !(arg.getValue() instanceof J.Literal)) { + continue; + } + J.Literal key = (J.Literal) arg.getKey(); + J.Literal value = (J.Literal) arg.getValue(); + if (!(key.getValue() instanceof String) || !(value.getValue() instanceof String)) { + continue; + } + String keyValue = (String) key.getValue(); + String valueValue = (String) value.getValue(); + if ("group".equals(keyValue)) { + groupId = valueValue; + } else if ("name".equals(keyValue)) { + artifactId = valueValue; + } + } - if (!dependencyMatcher.matches((String) groupLiteral.getValue(), (String) artifactLiteral.getValue())) { + if (artifactId == null || !dependencyMatcher.matches(groupId, artifactId)) { return m; } } else if (args.get(0) instanceof J.MethodInvocation) { diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyExtension.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyExtension.java index a6a617f627b..dc103c00f75 100644 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyExtension.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyExtension.java @@ -23,19 +23,15 @@ import org.openrewrite.gradle.util.ChangeStringLiteral; import org.openrewrite.gradle.util.Dependency; import org.openrewrite.gradle.util.DependencyStringNotationConverter; -import org.openrewrite.groovy.GroovyVisitor; +import org.openrewrite.groovy.GroovyIsoVisitor; import org.openrewrite.groovy.tree.G; import org.openrewrite.internal.ListUtils; -import org.openrewrite.internal.StringUtils; -import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; import org.openrewrite.semver.DependencyMatcher; import java.util.List; -import static java.util.Objects.requireNonNull; - @Value @EqualsAndHashCode(callSuper = false) public class ChangeDependencyExtension extends Recipe { @@ -83,17 +79,17 @@ public Validated validate() { @Override public TreeVisitor getVisitor() { - return Preconditions.check(new IsBuildGradle<>(), new GroovyVisitor() { - final DependencyMatcher depMatcher = requireNonNull(DependencyMatcher.build(groupId + ":" + artifactId).getValue()); - final MethodMatcher dependencyDsl = new MethodMatcher("DependencyHandlerSpec *(..)"); - + return Preconditions.check(new IsBuildGradle<>(), new GroovyIsoVisitor() { @Override - public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { - J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { + J.MethodInvocation m = super.visitMethodInvocation(method, ctx); - GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); + GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher() + .configuration(configuration) + .groupId(groupId) + .artifactId(artifactId); - if (!((gradleDependencyMatcher.get(getCursor()).isPresent() || dependencyDsl.matches(m)) && (StringUtils.isBlank(configuration) || m.getSimpleName().equals(configuration)))) { + if (!gradleDependencyMatcher.get(getCursor()).isPresent()) { return m; } @@ -102,9 +98,7 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) String gav = (String) ((J.Literal) depArgs.get(0)).getValue(); if (gav != null) { Dependency dependency = DependencyStringNotationConverter.parse(gav); - if (dependency != null && !newExtension.equals(dependency.getExt()) && - ((dependency.getVersion() == null && depMatcher.matches(dependency.getGroupId(), dependency.getArtifactId())) || - (dependency.getVersion() != null && depMatcher.matches(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion())))) { + if (dependency != null && !newExtension.equals(dependency.getExt())) { Dependency newDependency = dependency.withExt(newExtension); m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> ChangeStringLiteral.withStringValue((J.Literal) arg, newDependency.toStringNotation()))); } @@ -113,7 +107,6 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) G.MapEntry extensionEntry = null; String groupId = null; String artifactId = null; - String version = null; String extension = null; String extensionStringDelimiter = "'"; @@ -136,8 +129,6 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) groupId = valueValue; } else if ("name".equals(keyValue)) { artifactId = valueValue; - } else if ("version".equals(keyValue)) { - version = valueValue; } else if ("ext".equals(keyValue) && !newExtension.equals(valueValue)) { if (value.getValueSource() != null) { extensionStringDelimiter = value.getValueSource().substring(0, value.getValueSource().indexOf(valueValue)); @@ -146,10 +137,7 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) extension = valueValue; } } - if (groupId == null || artifactId == null || - (version == null && !depMatcher.matches(groupId, artifactId)) || - (version != null && !depMatcher.matches(groupId, artifactId, version)) || - extension == null) { + if (groupId == null || artifactId == null || extension == null) { return m; } String delimiter = extensionStringDelimiter; @@ -162,6 +150,53 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) } return arg; })); + } else if (depArgs.get(0) instanceof G.MapLiteral) { + G.MapLiteral map = (G.MapLiteral) depArgs.get(0); + G.MapEntry extensionEntry = null; + String groupId = null; + String artifactId = null; + String extension = null; + + String extensionStringDelimiter = "'"; + for (G.MapEntry arg : map.getElements()) { + if (!(arg.getKey() instanceof J.Literal) || !(arg.getValue() instanceof J.Literal)) { + continue; + } + J.Literal key = (J.Literal) arg.getKey(); + J.Literal value = (J.Literal) arg.getValue(); + if (!(key.getValue() instanceof String) || !(value.getValue() instanceof String)) { + continue; + } + String keyValue = (String) key.getValue(); + String valueValue = (String) value.getValue(); + if ("group".equals(keyValue)) { + groupId = valueValue; + } else if ("name".equals(keyValue)) { + artifactId = valueValue; + } else if ("ext".equals(keyValue) && !newExtension.equals(valueValue)) { + if (value.getValueSource() != null) { + extensionStringDelimiter = value.getValueSource().substring(0, value.getValueSource().indexOf(valueValue)); + } + extensionEntry = arg; + extension = valueValue; + } + } + if (groupId == null || artifactId == null || extension == null) { + return m; + } + String delimiter = extensionStringDelimiter; + G.MapEntry finalExtension = extensionEntry; + m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> { + G.MapLiteral mapLiteral = (G.MapLiteral) arg; + return mapLiteral.withElements(ListUtils.map(mapLiteral.getElements(), e -> { + if (e == finalExtension) { + return finalExtension.withValue(((J.Literal) finalExtension.getValue()) + .withValue(newExtension) + .withValueSource(delimiter + newExtension + delimiter)); + } + return e; + })); + })); } return m; diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyGroupId.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyGroupId.java index 550b71f1492..ade503f67d1 100755 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyGroupId.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyGroupId.java @@ -25,21 +25,18 @@ import org.openrewrite.gradle.util.ChangeStringLiteral; import org.openrewrite.gradle.util.Dependency; import org.openrewrite.gradle.util.DependencyStringNotationConverter; -import org.openrewrite.groovy.GroovyVisitor; +import org.openrewrite.groovy.GroovyIsoVisitor; import org.openrewrite.groovy.tree.G; import org.openrewrite.internal.ListUtils; import org.openrewrite.internal.StringUtils; -import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; -import org.openrewrite.maven.tree.GroupArtifact; -import org.openrewrite.maven.tree.ResolvedDependency; import org.openrewrite.semver.DependencyMatcher; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; +import java.util.Optional; import static java.util.Objects.requireNonNull; @@ -90,38 +87,42 @@ public Validated validate() { @Override public TreeVisitor getVisitor() { - return Preconditions.check(new IsBuildGradle<>(), new GroovyVisitor() { + return Preconditions.check(new IsBuildGradle<>(), new GroovyIsoVisitor() { final DependencyMatcher depMatcher = requireNonNull(DependencyMatcher.build(groupId + ":" + artifactId).getValue()); - final MethodMatcher dependencyDsl = new MethodMatcher("DependencyHandlerSpec *(..)"); - final Map updatedDependencies = new HashMap<>(); + GradleProject gradleProject; @Override - public G visitCompilationUnit(G.CompilationUnit compilationUnit, ExecutionContext ctx) { - G.CompilationUnit cu = (G.CompilationUnit) super.visitCompilationUnit(compilationUnit, ctx); - if(cu != compilationUnit) { - cu = cu.withMarkers(cu.getMarkers().withMarkers(ListUtils.map(cu.getMarkers().getMarkers(), m -> { - if (m instanceof GradleProject) { - return updateModel((GradleProject) m, updatedDependencies); - } - return m; - }))); + public G.CompilationUnit visitCompilationUnit(G.CompilationUnit cu, ExecutionContext ctx) { + Optional maybeGp = cu.getMarkers().findFirst(GradleProject.class); + if (!maybeGp.isPresent()) { + return cu; + } + + gradleProject = maybeGp.get(); + + G.CompilationUnit g = super.visitCompilationUnit(cu, ctx); + if (g != cu) { + g = g.withMarkers(g.getMarkers().setByType(updateGradleModel(gradleProject))); } - return cu; + return g; } @Override - public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { - J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { + J.MethodInvocation m = super.visitMethodInvocation(method, ctx); - GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); + GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher() + .configuration(configuration) + .groupId(groupId) + .artifactId(artifactId); - if (!((gradleDependencyMatcher.get(getCursor()).isPresent() || dependencyDsl.matches(m)) && (StringUtils.isBlank(configuration) || m.getSimpleName().equals(configuration)))) { + if (!gradleDependencyMatcher.get(getCursor()).isPresent()) { return m; } List depArgs = m.getArguments(); - if (depArgs.get(0) instanceof J.Literal || depArgs.get(0) instanceof G.GString || depArgs.get(0) instanceof G.MapEntry) { + if (depArgs.get(0) instanceof J.Literal || depArgs.get(0) instanceof G.GString || depArgs.get(0) instanceof G.MapEntry || depArgs.get(0) instanceof G.MapLiteral) { m = updateDependency(m); } else if (depArgs.get(0) instanceof J.MethodInvocation && (((J.MethodInvocation) depArgs.get(0)).getSimpleName().equals("platform") || @@ -138,11 +139,8 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m) { String gav = (String) ((J.Literal) depArgs.get(0)).getValue(); if (gav != null) { Dependency dependency = DependencyStringNotationConverter.parse(gav); - if (dependency != null && !newGroupId.equals(dependency.getGroupId()) && - ((dependency.getVersion() == null && depMatcher.matches(dependency.getGroupId(), dependency.getArtifactId())) || - (dependency.getVersion() != null && depMatcher.matches(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion())))) { + if (dependency != null && !newGroupId.equals(dependency.getGroupId())) { Dependency newDependency = dependency.withGroupId(newGroupId); - updatedDependencies.put(dependency.getGav().asGroupArtifact(), newDependency.getGav().asGroupArtifact()); m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> ChangeStringLiteral.withStringValue((J.Literal) arg, newDependency.toStringNotation()))); } } @@ -151,10 +149,8 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m) { if (strings.size() >= 2 && strings.get(0) instanceof J.Literal) { Dependency dependency = DependencyStringNotationConverter.parse((String) requireNonNull(((J.Literal) strings.get(0)).getValue())); - if (dependency != null && !newGroupId.equals(dependency.getGroupId()) && - depMatcher.matches(dependency.getGroupId(), dependency.getArtifactId())) { + if (dependency != null && !newGroupId.equals(dependency.getGroupId())) { Dependency newDependency = dependency.withGroupId(newGroupId); - updatedDependencies.put(dependency.getGav().asGroupArtifact(), newDependency.getGav().asGroupArtifact()); String replacement = newDependency.toStringNotation(); m = m.withArguments(ListUtils.mapFirst(depArgs, arg -> { G.GString gString = (G.GString) arg; @@ -166,7 +162,6 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m) { G.MapEntry groupEntry = null; String groupId = null; String artifactId = null; - String version = null; String versionStringDelimiter = "'"; for (Expression e : depArgs) { @@ -192,13 +187,9 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m) { groupId = valueValue; } else if ("name".equals(keyValue)) { artifactId = valueValue; - } else if ("version".equals(keyValue)) { - version = valueValue; } } - if (groupId == null || artifactId == null || - (version == null && !depMatcher.matches(groupId, artifactId)) || - (version != null && !depMatcher.matches(groupId, artifactId, version))) { + if (groupId == null || artifactId == null) { return m; } String delimiter = versionStringDelimiter; @@ -211,35 +202,86 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m) { } return arg; })); + } else if (depArgs.get(0) instanceof G.MapLiteral) { + G.MapLiteral map = (G.MapLiteral) depArgs.get(0); + G.MapEntry groupEntry = null; + String groupId = null; + String artifactId = null; + + String versionStringDelimiter = "'"; + for (G.MapEntry arg : map.getElements()) { + if (!(arg.getKey() instanceof J.Literal) || !(arg.getValue() instanceof J.Literal)) { + continue; + } + J.Literal key = (J.Literal) arg.getKey(); + J.Literal value = (J.Literal) arg.getValue(); + if (!(key.getValue() instanceof String) || !(value.getValue() instanceof String)) { + continue; + } + String keyValue = (String) key.getValue(); + String valueValue = (String) value.getValue(); + if ("group".equals(keyValue) && !newGroupId.equals(valueValue)) { + if (value.getValueSource() != null) { + versionStringDelimiter = value.getValueSource().substring(0, value.getValueSource().indexOf(valueValue)); + } + groupEntry = arg; + groupId = valueValue; + } else if ("name".equals(keyValue)) { + artifactId = valueValue; + } + } + if (groupId == null || artifactId == null) { + return m; + } + String delimiter = versionStringDelimiter; + G.MapEntry finalGroup = groupEntry; + m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> { + G.MapLiteral mapLiteral = (G.MapLiteral) arg; + return mapLiteral.withElements(ListUtils.map(mapLiteral.getElements(), e -> { + if (e == finalGroup) { + return finalGroup.withValue(((J.Literal) finalGroup.getValue()) + .withValue(newGroupId) + .withValueSource(delimiter + newGroupId + delimiter)); + } + return e; + })); + })); } return m; } - }); - } - private GradleProject updateModel(GradleProject gp, Map updatedDependencies) { - Map nameToConfigurations = gp.getNameToConfiguration(); - Map updatedNameToConfigurations = new HashMap<>(); - for (Map.Entry nameToConfiguration : nameToConfigurations.entrySet()) { - String configurationName = nameToConfiguration.getKey(); - GradleDependencyConfiguration configuration = nameToConfiguration.getValue(); - - List newRequested = configuration.getRequested() - .stream() - .map(requested -> requested.withGav(requested.getGav() - .withGroupArtifact(updatedDependencies.getOrDefault(requested.getGav().asGroupArtifact(), requested.getGav().asGroupArtifact())))) - .collect(Collectors.toList()); - - List newResolved = configuration.getResolved().stream() - .map(resolved -> - resolved.withGav(resolved.getGav() - .withGroupArtifact(updatedDependencies.getOrDefault(resolved.getGav().asGroupArtifact(), resolved.getGav().asGroupArtifact())))) - .collect(Collectors.toList()); - - updatedNameToConfigurations.put(configurationName, configuration.withRequested(newRequested).withDirectResolved(newResolved)); - } - - return gp.withNameToConfiguration(updatedNameToConfigurations); + private GradleProject updateGradleModel(GradleProject gp) { + Map nameToConfiguration = gp.getNameToConfiguration(); + Map newNameToConfiguration = new HashMap<>(nameToConfiguration.size()); + boolean anyChanged = false; + for (GradleDependencyConfiguration gdc : nameToConfiguration.values()) { + if (!StringUtils.isBlank(configuration) && configuration.equals(gdc.getName())) { + newNameToConfiguration.put(gdc.getName(), gdc); + continue; + } + + GradleDependencyConfiguration newGdc = gdc; + newGdc = newGdc.withRequested(ListUtils.map(gdc.getRequested(), requested -> { + if (depMatcher.matches(requested.getGroupId(), requested.getArtifactId())) { + return requested.withGav(requested.getGav().withGroupId(newGroupId)); + } + return requested; + })); + newGdc = newGdc.withDirectResolved(ListUtils.map(gdc.getDirectResolved(), resolved -> { + if (depMatcher.matches(resolved.getGroupId(), resolved.getArtifactId())) { + return resolved.withGav(resolved.getGav().withGroupId(newGroupId)); + } + return resolved; + })); + anyChanged |= newGdc != gdc; + newNameToConfiguration.put(newGdc.getName(), newGdc); + } + if (anyChanged) { + gp = gp.withNameToConfiguration(newNameToConfiguration); + } + return gp; + } + }); } } diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/DependencyUseMapNotation.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/DependencyUseMapNotation.java index 984523ff5d8..301fb375987 100755 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/DependencyUseMapNotation.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/DependencyUseMapNotation.java @@ -25,7 +25,6 @@ import org.openrewrite.groovy.GroovyVisitor; import org.openrewrite.groovy.tree.G; import org.openrewrite.internal.ListUtils; -import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.*; import org.openrewrite.marker.Markers; @@ -53,15 +52,13 @@ public String getDescription() { @Override public TreeVisitor getVisitor() { return Preconditions.check(new IsBuildGradle<>(), new GroovyVisitor() { - final MethodMatcher dependencyDsl = new MethodMatcher("DependencyHandlerSpec *(..)"); - @Override public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); - if (!(gradleDependencyMatcher.get(getCursor()).isPresent() || dependencyDsl.matches(m))) { + if (!gradleDependencyMatcher.get(getCursor()).isPresent()) { return m; } m = forBasicString(m); diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/DependencyUseStringNotation.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/DependencyUseStringNotation.java index b3c17260f90..17f8b300a05 100644 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/DependencyUseStringNotation.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/DependencyUseStringNotation.java @@ -23,7 +23,6 @@ import org.openrewrite.gradle.trait.GradleDependency; import org.openrewrite.groovy.GroovyVisitor; import org.openrewrite.groovy.tree.G; -import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.JavaType; @@ -50,15 +49,13 @@ public String getDescription() { @Override public TreeVisitor getVisitor() { return Preconditions.check(new IsBuildGradle<>(), new GroovyVisitor() { - final MethodMatcher dependencyDsl = new MethodMatcher("DependencyHandlerSpec *(..)"); - @Override public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); - if (!(gradleDependencyMatcher.get(getCursor()).isPresent() || dependencyDsl.matches(m))) { + if (!gradleDependencyMatcher.get(getCursor()).isPresent()) { return m; } diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/RemoveDependency.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/RemoveDependency.java index f38e853fbe6..b05ac29701b 100644 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/RemoveDependency.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/RemoveDependency.java @@ -15,7 +15,6 @@ */ package org.openrewrite.gradle; -import io.micrometer.core.instrument.util.StringUtils; import lombok.EqualsAndHashCode; import lombok.Value; import org.jspecify.annotations.Nullable; @@ -23,17 +22,14 @@ import org.openrewrite.gradle.marker.GradleDependencyConfiguration; import org.openrewrite.gradle.marker.GradleProject; import org.openrewrite.gradle.trait.GradleDependency; -import org.openrewrite.gradle.util.Dependency; -import org.openrewrite.gradle.util.DependencyStringNotationConverter; -import org.openrewrite.groovy.GroovyVisitor; +import org.openrewrite.groovy.GroovyIsoVisitor; import org.openrewrite.groovy.tree.G; import org.openrewrite.internal.ListUtils; -import org.openrewrite.java.MethodMatcher; -import org.openrewrite.java.tree.Expression; +import org.openrewrite.internal.StringUtils; import org.openrewrite.java.tree.J; import org.openrewrite.semver.DependencyMatcher; -import java.util.List; +import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -77,55 +73,35 @@ public String getDescription() { @Override public TreeVisitor getVisitor() { - return Preconditions.check(new IsBuildGradle<>(), new GroovyVisitor() { - final MethodMatcher dependencyDsl = new MethodMatcher("DependencyHandlerSpec *(..)"); - final DependencyMatcher dependencyMatcher = requireNonNull(DependencyMatcher.build(groupId + ":" + artifactId).getValue()); + return Preconditions.check(new IsBuildGradle<>(), new GroovyIsoVisitor() { + final GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher() + .configuration(configuration) + .groupId(groupId) + .artifactId(artifactId); + final DependencyMatcher depMatcher = requireNonNull(DependencyMatcher.build(groupId + ":" + artifactId).getValue()); + + GradleProject gradleProject; @Override - public J visitCompilationUnit(G.CompilationUnit cu, ExecutionContext ctx) { - G.CompilationUnit g = (G.CompilationUnit) super.visitCompilationUnit(cu, ctx); - if (g == cu) { + public G.CompilationUnit visitCompilationUnit(G.CompilationUnit cu, ExecutionContext ctx) { + Optional maybeGp = cu.getMarkers().findFirst(GradleProject.class); + if (!maybeGp.isPresent()) { return cu; } - Optional maybeGp = g.getMarkers().findFirst(GradleProject.class); - if (!maybeGp.isPresent()) { - // Allow modification of freestanding scripts which do not carry a GradleProject marker - return g; - } + gradleProject = maybeGp.get(); - GradleProject gp = maybeGp.get(); - Map nameToConfiguration = gp.getNameToConfiguration(); - boolean anyChanged = false; - for (GradleDependencyConfiguration gdc : nameToConfiguration.values()) { - GradleDependencyConfiguration newGdc = gdc.withRequested(ListUtils.map(gdc.getRequested(), requested -> { - if (requested.getGroupId() != null && dependencyMatcher.matches(requested.getGroupId(), requested.getArtifactId())) { - return null; - } - return requested; - })); - newGdc = newGdc.withDirectResolved(ListUtils.map(newGdc.getDirectResolved(), resolved -> { - if (dependencyMatcher.matches(resolved.getGroupId(), resolved.getArtifactId())) { - return null; - } - return resolved; - })); - nameToConfiguration.put(newGdc.getName(), newGdc); - anyChanged |= newGdc != gdc; - } - - if (!anyChanged) { - // instance was changed, but no marker update is needed - return g; + G.CompilationUnit g = super.visitCompilationUnit(cu, ctx); + if (g != cu) { + g = g.withMarkers(g.getMarkers().setByType(updateGradleModel(gradleProject))); } - - return g.withMarkers(g.getMarkers().setByType(gp.withNameToConfiguration(nameToConfiguration))); + return g; } @Override - public @Nullable J visitReturn(J.Return return_, ExecutionContext ctx) { - boolean dependencyInvocation = return_.getExpression() instanceof J.MethodInvocation && dependencyDsl.matches((J.MethodInvocation) return_.getExpression()); - J.Return r = (J.Return) super.visitReturn(return_, ctx); + public J.@Nullable Return visitReturn(J.Return return_, ExecutionContext ctx) { + boolean dependencyInvocation = return_.getExpression() instanceof J.MethodInvocation && gradleDependencyMatcher.get(return_.getExpression(), getCursor()).isPresent(); + J.Return r = super.visitReturn(return_, ctx); if (dependencyInvocation && r.getExpression() == null) { //noinspection DataFlowIssue return null; @@ -134,86 +110,46 @@ public J visitCompilationUnit(G.CompilationUnit cu, ExecutionContext ctx) { } @Override - public @Nullable J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { - J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); - - GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); - - if ((gradleDependencyMatcher.get(getCursor()).isPresent() || dependencyDsl.matches(m)) && (StringUtils.isEmpty(configuration) || configuration.equals(m.getSimpleName()))) { - Expression firstArgument = m.getArguments().get(0); - if (firstArgument instanceof J.Literal || firstArgument instanceof G.GString || firstArgument instanceof G.MapEntry) { - //noinspection DataFlowIssue - return maybeRemoveDependency(m); - } else if (firstArgument instanceof J.MethodInvocation && - (((J.MethodInvocation) firstArgument).getSimpleName().equals("platform") || - ((J.MethodInvocation) firstArgument).getSimpleName().equals("enforcedPlatform"))) { - J after = maybeRemoveDependency((J.MethodInvocation) firstArgument); - if (after == null) { - //noinspection DataFlowIssue - return null; - } - } + public J.@Nullable MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { + J.MethodInvocation m = super.visitMethodInvocation(method, ctx); + + if (gradleDependencyMatcher.get(getCursor()).isPresent()) { + return null; } return m; } - private @Nullable J maybeRemoveDependency(J.MethodInvocation m) { - if (m.getArguments().get(0) instanceof G.GString) { - G.GString gString = (G.GString) m.getArguments().get(0); - List strings = gString.getStrings(); - if (strings.size() != 2 || !(strings.get(0) instanceof J.Literal) || !(strings.get(1) instanceof G.GString.Value)) { - return m; - } - J.Literal groupArtifact = (J.Literal) strings.get(0); - if (!(groupArtifact.getValue() instanceof String)) { - return m; - } - Dependency dependency = DependencyStringNotationConverter.parse((String) groupArtifact.getValue()); - if (dependency != null && dependencyMatcher.matches(dependency.getGroupId(), dependency.getArtifactId())) { - return null; - } - } else if (m.getArguments().get(0) instanceof J.Literal) { - Object value = ((J.Literal) m.getArguments().get(0)).getValue(); - if(!(value instanceof String)) { - return null; - } - Dependency dependency = DependencyStringNotationConverter.parse((String) value); - if (dependency != null && dependencyMatcher.matches(dependency.getGroupId(), dependency.getArtifactId())) { - return null; + private GradleProject updateGradleModel(GradleProject gp) { + Map nameToConfiguration = gp.getNameToConfiguration(); + Map newNameToConfiguration = new HashMap<>(nameToConfiguration.size()); + boolean anyChanged = false; + for (GradleDependencyConfiguration gdc : nameToConfiguration.values()) { + if (!StringUtils.isBlank(configuration) && configuration.equals(gdc.getName())) { + newNameToConfiguration.put(gdc.getName(), gdc); + continue; } - } else if (m.getArguments().get(0) instanceof G.MapEntry) { - String groupId = null; - String artifactId = null; - for (Expression e : m.getArguments()) { - if (!(e instanceof G.MapEntry)) { - continue; - } - G.MapEntry arg = (G.MapEntry) e; - if (!(arg.getKey() instanceof J.Literal) || !(arg.getValue() instanceof J.Literal)) { - continue; - } - J.Literal key = (J.Literal) arg.getKey(); - J.Literal value = (J.Literal) arg.getValue(); - if (!(key.getValue() instanceof String) || !(value.getValue() instanceof String)) { - continue; + GradleDependencyConfiguration newGdc = gdc; + newGdc = newGdc.withRequested(ListUtils.map(gdc.getRequested(), requested -> { + if (depMatcher.matches(requested.getGroupId(), requested.getArtifactId())) { + return null; } - String keyValue = (String) key.getValue(); - String valueValue = (String) value.getValue(); - if ("group".equals(keyValue)) { - groupId = valueValue; - } else if ("name".equals(keyValue)) { - artifactId = valueValue; + return requested; + })); + newGdc = newGdc.withDirectResolved(ListUtils.map(gdc.getDirectResolved(), resolved -> { + if (depMatcher.matches(resolved.getGroupId(), resolved.getArtifactId())) { + return null; } - } - - if (groupId != null && artifactId != null && dependencyMatcher.matches(groupId, artifactId)) { - return null; - } + return resolved; + })); + anyChanged |= newGdc != gdc; + newNameToConfiguration.put(newGdc.getName(), newGdc); } - - return m; + if (anyChanged) { + gp = gp.withNameToConfiguration(newNameToConfiguration); + } + return gp; } }); } diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/UpgradeDependencyVersion.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/UpgradeDependencyVersion.java index d008c4ae3f1..d8c32b7cd84 100644 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/UpgradeDependencyVersion.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/UpgradeDependencyVersion.java @@ -32,7 +32,6 @@ import org.openrewrite.groovy.tree.G; import org.openrewrite.internal.ListUtils; import org.openrewrite.internal.StringUtils; -import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.JavaSourceFile; @@ -140,8 +139,6 @@ public DependencyVersionState getInitialValue(ExecutionContext ctx) { return new DependencyVersionState(); } - private static final MethodMatcher DEPENDENCY_DSL_MATCHER = new MethodMatcher("DependencyHandlerSpec *(..)"); - @Override public TreeVisitor getScanner(DependencyVersionState acc) { @@ -163,7 +160,7 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); - if (gradleDependencyMatcher.get(getCursor()).isPresent() || DEPENDENCY_DSL_MATCHER.matches(m)) { + if (gradleDependencyMatcher.get(getCursor()).isPresent()) { if (m.getArguments().get(0) instanceof G.MapEntry) { String groupId = null; String artifactId = null; @@ -374,15 +371,10 @@ public J postVisit(J tree, ExecutionContext ctx) { @Override public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) { - if ("constraints".equals(method.getSimpleName()) || "project".equals(method.getSimpleName())) { - // don't mess with anything inside a constraints block, leave that to UpgradeTransitiveDependency version recipe - // `project` dependencies should also be skipped - return method; - } J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx); GradleDependency.Matcher gradleDependencyMatcher = new GradleDependency.Matcher(); - if (gradleDependencyMatcher.get(getCursor()).isPresent() || DEPENDENCY_DSL_MATCHER.matches(m)) { + if (gradleDependencyMatcher.get(getCursor()).isPresent()) { List depArgs = m.getArguments(); if (depArgs.get(0) instanceof J.Literal || depArgs.get(0) instanceof G.GString || depArgs.get(0) instanceof G.MapEntry) { m = updateDependency(m, ctx); diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/trait/GradleDependency.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/trait/GradleDependency.java index 1f20c8e92e2..e4a806cdd25 100644 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/trait/GradleDependency.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/trait/GradleDependency.java @@ -24,10 +24,13 @@ import org.openrewrite.gradle.util.DependencyStringNotationConverter; import org.openrewrite.groovy.tree.G; import org.openrewrite.internal.StringUtils; +import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.Expression; import org.openrewrite.java.tree.J; import org.openrewrite.maven.tree.Dependency; +import org.openrewrite.maven.tree.GroupArtifactVersion; import org.openrewrite.maven.tree.ResolvedDependency; +import org.openrewrite.maven.tree.ResolvedGroupArtifactVersion; import org.openrewrite.trait.Trait; import java.util.List; @@ -43,6 +46,8 @@ public class GradleDependency implements Trait { ResolvedDependency resolvedDependency; public static class Matcher extends GradleTraitMatcher { + private static final MethodMatcher DEPENDENCY_DSL_MATCHER = new MethodMatcher("DependencyHandlerSpec *(..)"); + @Nullable protected String configuration; @@ -77,13 +82,14 @@ public Matcher artifactId(@Nullable String artifactId) { return null; } - GradleProject gradleProject = getGradleProject(cursor); - if (gradleProject == null) { + if (withinDependencyConstraintsBlock(cursor)) { + // A dependency constraint is different from an actual dependency return null; } + GradleProject gradleProject = getGradleProject(cursor); GradleDependencyConfiguration gdc = getConfiguration(gradleProject, methodInvocation); - if (gdc == null) { + if (gdc == null && !(DEPENDENCY_DSL_MATCHER.matches(methodInvocation) && !"project".equals(methodInvocation.getSimpleName()))) { return null; } @@ -95,49 +101,77 @@ public Matcher artifactId(@Nullable String artifactId) { Expression argument = methodInvocation.getArguments().get(0); if (argument instanceof J.Literal || argument instanceof G.GString || argument instanceof G.MapEntry || argument instanceof G.MapLiteral) { dependency = parseDependency(methodInvocation.getArguments()); - } else if (argument instanceof J.MethodInvocation && - (((J.MethodInvocation) argument).getSimpleName().equals("platform") || - ((J.MethodInvocation) argument).getSimpleName().equals("enforcedPlatform"))) { - dependency = parseDependency(((J.MethodInvocation) argument).getArguments()); + } else if (argument instanceof J.MethodInvocation) { + if (((J.MethodInvocation) argument).getSimpleName().equals("platform") || + ((J.MethodInvocation) argument).getSimpleName().equals("enforcedPlatform")) { + dependency = parseDependency(((J.MethodInvocation) argument).getArguments()); + } else if (((J.MethodInvocation) argument).getSimpleName().equals("project")) { + // project dependencies are not yet supported + return null; + } } if (dependency == null) { return null; } - if (gdc.isCanBeResolved()) { - for (ResolvedDependency resolvedDependency : gdc.getResolved()) { - if ((groupId == null || matchesGlob(resolvedDependency.getGroupId(), groupId)) && - (artifactId == null || matchesGlob(resolvedDependency.getArtifactId(), artifactId))) { - Dependency req = resolvedDependency.getRequested(); - if ((req.getGroupId() == null || req.getGroupId().equals(dependency.getGroupId())) && - req.getArtifactId().equals(dependency.getArtifactId())) { - return new GradleDependency(cursor, resolvedDependency); + if (gdc != null) { + if (gdc.isCanBeResolved()) { + for (ResolvedDependency resolvedDependency : gdc.getResolved()) { + if ((groupId == null || matchesGlob(resolvedDependency.getGroupId(), groupId)) && + (artifactId == null || matchesGlob(resolvedDependency.getArtifactId(), artifactId))) { + Dependency req = resolvedDependency.getRequested(); + if ((req.getGroupId() == null || req.getGroupId().equals(dependency.getGroupId())) && + req.getArtifactId().equals(dependency.getArtifactId())) { + return new GradleDependency(cursor, resolvedDependency); + } } } - } - } else { - for (GradleDependencyConfiguration transitiveConfiguration : gradleProject.configurationsExtendingFrom(gdc, true)) { - if (transitiveConfiguration.isCanBeResolved()) { - for (ResolvedDependency resolvedDependency : transitiveConfiguration.getResolved()) { - if ((groupId == null || matchesGlob(resolvedDependency.getGroupId(), groupId)) && - (artifactId == null || matchesGlob(resolvedDependency.getArtifactId(), artifactId))) { - Dependency req = resolvedDependency.getRequested(); - if ((req.getGroupId() == null || req.getGroupId().equals(dependency.getGroupId())) && - req.getArtifactId().equals(dependency.getArtifactId())) { - return new GradleDependency(cursor, resolvedDependency); + } else { + for (GradleDependencyConfiguration transitiveConfiguration : gradleProject.configurationsExtendingFrom(gdc, true)) { + if (transitiveConfiguration.isCanBeResolved()) { + for (ResolvedDependency resolvedDependency : transitiveConfiguration.getResolved()) { + if ((groupId == null || matchesGlob(resolvedDependency.getGroupId(), groupId)) && + (artifactId == null || matchesGlob(resolvedDependency.getArtifactId(), artifactId))) { + Dependency req = resolvedDependency.getRequested(); + if ((req.getGroupId() == null || req.getGroupId().equals(dependency.getGroupId())) && + req.getArtifactId().equals(dependency.getArtifactId())) { + return new GradleDependency(cursor, resolvedDependency); + } } } } } } } + + if ((groupId == null || matchesGlob(dependency.getGroupId(), groupId)) && + (artifactId == null || matchesGlob(dependency.getArtifactId(), artifactId))) { + // Couldn't find the actual resolved dependency, return a virtualized one instead + ResolvedDependency resolvedDependency = ResolvedDependency.builder() + .depth(-1) + .gav(new ResolvedGroupArtifactVersion(null, dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion() != null ? dependency.getVersion() : "", null)) + .classifier(dependency.getClassifier()) + .type(dependency.getExt()) + .requested(Dependency.builder() + .scope(methodInvocation.getSimpleName()) + .type(dependency.getExt()) + .gav(new GroupArtifactVersion(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion())) + .classifier(dependency.getClassifier()) + .build()) + .build(); + return new GradleDependency(cursor, resolvedDependency); + } } return null; } - private static @Nullable GradleDependencyConfiguration getConfiguration(GradleProject gradleProject, J.MethodInvocation methodInvocation) { + private static @Nullable GradleDependencyConfiguration getConfiguration(@Nullable GradleProject gradleProject, J.MethodInvocation methodInvocation) { + if (gradleProject == null) { + return null; + } + String methodName = methodInvocation.getSimpleName(); if (methodName.equals("classpath")) { return gradleProject.getBuildscript().getConfiguration(methodName); @@ -146,12 +180,12 @@ public Matcher artifactId(@Nullable String artifactId) { } } - private boolean withinDependenciesBlock(Cursor cursor) { + private boolean withinBlock(Cursor cursor, String name) { Cursor parentCursor = cursor.getParent(); while (parentCursor != null) { if (parentCursor.getValue() instanceof J.MethodInvocation) { J.MethodInvocation m = parentCursor.getValue(); - if (m.getSimpleName().equals("dependencies")) { + if (m.getSimpleName().equals(name)) { return true; } } @@ -161,6 +195,14 @@ private boolean withinDependenciesBlock(Cursor cursor) { return false; } + private boolean withinDependenciesBlock(Cursor cursor) { + return withinBlock(cursor, "dependencies"); + } + + private boolean withinDependencyConstraintsBlock(Cursor cursor) { + return withinBlock(cursor, "constraints") && withinDependenciesBlock(cursor); + } + private org.openrewrite.gradle.util.@Nullable Dependency parseDependency(List arguments) { Expression argument = arguments.get(0); if (argument instanceof J.Literal) {