From f3f107e510728526f60c011c0245fe59f647befc Mon Sep 17 00:00:00 2001 From: Alex Boyko Date: Tue, 18 Jun 2024 08:53:33 -0400 Subject: [PATCH] Gradle `ChangeDependencyClassifier` supports add and remove classifier (#4268) * Gradle `ChangeDependencyClassifier` supports add and remove classifier * Correction * Minor polish --------- Co-authored-by: Tim te Beek --- .../gradle/ChangeDependencyClassifier.java | 61 +++++-- .../ChangeDependencyClassifierTest.java | 166 ++++++++++++++++-- 2 files changed, 201 insertions(+), 26 deletions(-) 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 baec86def0d..86be691bc61 100644 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyClassifier.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependencyClassifier.java @@ -27,11 +27,12 @@ import org.openrewrite.internal.StringUtils; import org.openrewrite.internal.lang.Nullable; import org.openrewrite.java.MethodMatcher; -import org.openrewrite.java.tree.Expression; -import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.*; +import org.openrewrite.marker.Markers; import org.openrewrite.semver.DependencyMatcher; import java.util.List; +import java.util.Objects; import static java.util.Objects.requireNonNull; @@ -50,7 +51,9 @@ public class ChangeDependencyClassifier extends Recipe { @Option(displayName = "New classifier", description = "A qualification classifier for the dependency.", - example = "sources") + example = "sources", + required = false) + @Nullable String newClassifier; @Option(displayName = "Dependency configuration", @@ -98,7 +101,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 && dependency.getClassifier() != null && !newClassifier.equals(dependency.getClassifier()) && + if (dependency != null && dependency.getVersion() != null && !Objects.equals(newClassifier, dependency.getClassifier()) && depMatcher.matches(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion())) { Dependency newDependency = dependency.withClassifier(newClassifier); m = m.withArguments(ListUtils.mapFirst(m.getArguments(), arg -> ChangeStringLiteral.withStringValue((J.Literal) arg, newDependency.toStringNotation()))); @@ -111,7 +114,10 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) String version = null; String classifier = null; - String classifierStringDelimiter = "'"; + String groupDelimiter = "'"; + G.MapEntry mapEntry = null; + String classifierStringDelimiter = null; + int index = 0; for (Expression e : depArgs) { if (!(e instanceof G.MapEntry)) { continue; @@ -129,38 +135,61 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) 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 ("version".equals(keyValue)) { version = valueValue; - } else if ("classifier".equals(keyValue) && !newClassifier.equals(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 || (version == null && !depMatcher.matches(groupId, artifactId)) || (version != null && !depMatcher.matches(groupId, artifactId, version)) - || classifier == null) { + || Objects.equals(newClassifier, classifier)) { return m; } - String delimiter = classifierStringDelimiter; - G.MapEntry finalClassifier = classifierEntry; - m = m.withArguments(ListUtils.map(m.getArguments(), arg -> { - if (arg == finalClassifier) { - return finalClassifier.withValue(((J.Literal) finalClassifier.getValue()) - .withValue(newClassifier) - .withValueSource(delimiter + newClassifier + delimiter)); + + if (classifier == null) { + String delimiter = groupDelimiter; + List args = m.getArguments(); + 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); + args.add(new G.MapEntry(Tree.randomId(), mapEntry == null ? Space.EMPTY : mapEntry.getPrefix(), Markers.EMPTY, JRightPadded.build(keyLiteral), valueLiteral, null)); + m = m.withArguments(args); + } else { + G.MapEntry finalClassifier = classifierEntry; + if (newClassifier == null) { + m = m.withArguments(ListUtils.map(m.getArguments(), arg -> arg == finalClassifier ? null : arg)); + } else { + String delimiter = classifierStringDelimiter; // `classifierStringDelimiter` cannot be null + m = m.withArguments(ListUtils.map(m.getArguments(), arg -> { + if (arg == finalClassifier) { + return finalClassifier.withValue(((J.Literal) finalClassifier.getValue()) + .withValue(newClassifier) + .withValueSource(delimiter + newClassifier + delimiter)); + } + return arg; + })); } - return arg; - })); + } + } return m; } }); } + } diff --git a/rewrite-gradle/src/test/java/org/openrewrite/gradle/ChangeDependencyClassifierTest.java b/rewrite-gradle/src/test/java/org/openrewrite/gradle/ChangeDependencyClassifierTest.java index ddb1922e5fb..caad9c5bccb 100644 --- a/rewrite-gradle/src/test/java/org/openrewrite/gradle/ChangeDependencyClassifierTest.java +++ b/rewrite-gradle/src/test/java/org/openrewrite/gradle/ChangeDependencyClassifierTest.java @@ -34,7 +34,7 @@ void worksWithEmptyStringConfig() { plugins { id 'java-library' } - + repositories { mavenCentral() } @@ -47,7 +47,7 @@ void worksWithEmptyStringConfig() { plugins { id 'java-library' } - + repositories { mavenCentral() } @@ -108,7 +108,7 @@ void findMapStyleDependency(String group, String artifact) { plugins { id 'java-library' } - + repositories { mavenCentral() } @@ -122,7 +122,7 @@ void findMapStyleDependency(String group, String artifact) { plugins { id 'java-library' } - + repositories { mavenCentral() } @@ -146,7 +146,7 @@ void worksWithoutVersion(String group, String artifact) { plugins { id 'java-library' } - + repositories { mavenCentral() } @@ -160,7 +160,7 @@ void worksWithoutVersion(String group, String artifact) { plugins { id 'java-library' } - + repositories { mavenCentral() } @@ -184,7 +184,7 @@ void worksWithClassifier(String group, String artifact) { plugins { id 'java-library' } - + repositories { mavenCentral() } @@ -200,7 +200,7 @@ void worksWithClassifier(String group, String artifact) { plugins { id 'java-library' } - + repositories { mavenCentral() } @@ -226,7 +226,7 @@ void worksWithExt(String group, String artifact) { plugins { id 'java-library' } - + repositories { mavenCentral() } @@ -246,7 +246,7 @@ void worksWithExt(String group, String artifact) { plugins { id 'java-library' } - + repositories { mavenCentral() } @@ -265,4 +265,150 @@ void worksWithExt(String group, String artifact) { ) ); } + + @Test + void noPreviousClassifier_1() { + rewriteRun( + spec -> spec.recipe(new ChangeDependencyClassifier("org.openrewrite", "*", "classified", "")), + buildGradle( + """ + plugins { + id 'java-library' + } + + repositories { + mavenCentral() + } + + dependencies { + api 'org.openrewrite:rewrite-gradle:latest.release' + } + """, + """ + plugins { + id 'java-library' + } + + repositories { + mavenCentral() + } + + dependencies { + api 'org.openrewrite:rewrite-gradle:latest.release:classified' + } + """ + ) + ); + } + + @ParameterizedTest + @CsvSource(value = {"org.openrewrite:rewrite-core", "*:*"}, delimiterString = ":") + void noPreviousClassifier_2(String group, String artifact) { + rewriteRun( + spec -> spec.recipe(new ChangeDependencyClassifier(group, artifact, "classified", null)), + buildGradle( + """ + plugins { + id 'java-library' + } + + repositories { + mavenCentral() + } + + dependencies { + api(group: 'org.openrewrite', name: 'rewrite-core', version: 'latest.release') + api(group: "org.openrewrite", name: "rewrite-core", version: "latest.release") + } + """, + """ + plugins { + id 'java-library' + } + + repositories { + mavenCentral() + } + + dependencies { + api(group: 'org.openrewrite', name: 'rewrite-core', version: 'latest.release', classifier: 'classified') + api(group: "org.openrewrite", name: "rewrite-core", version: "latest.release", classifier: "classified") + } + """ + ) + ); + } + + @Test + void noNewClassifier_1() { + rewriteRun( + spec -> spec.recipe(new ChangeDependencyClassifier("org.openrewrite", "*", null, "")), + buildGradle( + """ + plugins { + id 'java-library' + } + + repositories { + mavenCentral() + } + + dependencies { + api 'org.openrewrite:rewrite-gradle:latest.release:classified' + } + """, + """ + plugins { + id 'java-library' + } + + repositories { + mavenCentral() + } + + dependencies { + api 'org.openrewrite:rewrite-gradle:latest.release' + } + """ + ) + ); + } + + @ParameterizedTest + @CsvSource(value = {"org.openrewrite:rewrite-core", "*:*"}, delimiterString = ":") + void noNewClassifier_2(String group, String artifact) { + rewriteRun( + spec -> spec.recipe(new ChangeDependencyClassifier(group, artifact, null, null)), + buildGradle( + """ + plugins { + id 'java-library' + } + + repositories { + mavenCentral() + } + + dependencies { + api(group: 'org.openrewrite', name: 'rewrite-core', version: 'latest.release', classifier: 'classified') + api(group: "org.openrewrite", name: "rewrite-core", version: "latest.release", classifier: "classified") + } + """, + """ + plugins { + id 'java-library' + } + + repositories { + mavenCentral() + } + + dependencies { + api(group: 'org.openrewrite', name: 'rewrite-core', version: 'latest.release') + api(group: "org.openrewrite", name: "rewrite-core", version: "latest.release") + } + """ + ) + ); + } }