Skip to content

Commit

Permalink
Add RelocatedDependencyReport for easier export & analysis (#61)
Browse files Browse the repository at this point in the history
* Add RelocatedDependencyReport for easier export & analysis

* Add missing license
  • Loading branch information
timtebeek authored Jan 20, 2024
1 parent 268d48e commit 6fd1ae4
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.dependencies.oldgroupids.Migration;
import org.openrewrite.java.dependencies.table.RelocatedDependencyReport;
import org.openrewrite.java.tree.Expression;
import org.openrewrite.java.tree.J;
import org.openrewrite.marker.SearchResult;
Expand All @@ -40,6 +41,8 @@
import java.util.Optional;

public class RelocatedDependencyCheck extends ScanningRecipe<RelocatedDependencyCheck.Accumulator> {
transient RelocatedDependencyReport report = new RelocatedDependencyReport(this);

@Override
public String getDisplayName() {
return "Find relocated dependencies";
Expand All @@ -50,7 +53,8 @@ public String getDescription() {
//language=markdown
return "Find Maven and Gradle dependencies and Maven plugins that have relocated to a new `groupId` or `artifactId`. " +
"Relocation information comes from the [oga-maven-plugin](https://github.com/jonathanlermitage/oga-maven-plugin/) " +
"maintained by Jonathan Lermitage, Filipe Roque and others.";
"maintained by Jonathan Lermitage, Filipe Roque and others. " +
"This recipe makes no changes to any source file.";
}

@Value
Expand Down Expand Up @@ -129,32 +133,32 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu
Expression firstMethodArgument = methodArguments.get(0);
if (firstMethodArgument instanceof J.Literal) {
J.Literal literal = (J.Literal) firstMethodArgument;
mi = searchInLiteral(literal, mi);
mi = searchInLiteral(literal, mi, ctx);
} else if (firstMethodArgument instanceof G.GString) {
G.GString gString = (G.GString) firstMethodArgument;
List<J> strings = gString.getStrings();
if (!strings.isEmpty() && strings.get(0) instanceof J.Literal) {
mi = searchInLiteral((J.Literal) strings.get(0), mi);
mi = searchInLiteral((J.Literal) strings.get(0), mi, ctx);
}
} else if (firstMethodArgument instanceof G.MapEntry) {
mi = searchInGMapEntry(methodArguments, mi);
mi = searchInGMapEntry(methodArguments, mi, ctx);
}

}
return mi;
}

private J.MethodInvocation searchInLiteral(J.Literal literal, J.MethodInvocation mi) {
private J.MethodInvocation searchInLiteral(J.Literal literal, J.MethodInvocation mi, ExecutionContext ctx) {
String gav = (String) literal.getValue();
assert gav != null;
String[] parts = gav.split(":");
if (gav.length() >= 2) {
mi = maybeAddComment(acc, mi, parts[0], parts[1]);
mi = maybeAddComment(acc, mi, parts[0], parts[1], ctx);
}
return mi;
}

private J.MethodInvocation searchInGMapEntry(List<Expression> methodArguments, J.MethodInvocation mi) {
private J.MethodInvocation searchInGMapEntry(List<Expression> methodArguments, J.MethodInvocation mi, ExecutionContext ctx) {
String groupId = null;
String artifactId = null;
for (Expression e : methodArguments) {
Expand Down Expand Up @@ -197,15 +201,15 @@ private J.MethodInvocation searchInGMapEntry(List<Expression> methodArguments, J
}
}
if (groupId != null) {
mi = maybeAddComment(acc, mi, groupId, artifactId);
mi = maybeAddComment(acc, mi, groupId, artifactId, ctx);
}
return mi;
}

};
}

private static TreeVisitor<?, ExecutionContext> mavenVisitor(Accumulator acc) {
private TreeVisitor<?, ExecutionContext> mavenVisitor(Accumulator acc) {
final XPathMatcher dependencyMatcher = new XPathMatcher("//dependencies/dependency");
return new MavenIsoVisitor<ExecutionContext>() {
@Override
Expand All @@ -217,13 +221,13 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
if (optionalGroupId.isPresent()) {
String groupId = optionalGroupId.get();
String artifactId = optionalArtifactId.orElse(null);
tag = maybeAddComment(acc, tag, groupId, artifactId);
tag = maybeAddComment(acc, tag, groupId, artifactId, ctx);
}
} else if (isPluginTag()) {
if (optionalArtifactId.isPresent()) {
String groupId = tag.getChildValue("groupId").orElse("org.apache.maven.plugins");
String artifactId = optionalArtifactId.get();
tag = maybeAddComment(acc, tag, groupId, artifactId);
tag = maybeAddComment(acc, tag, groupId, artifactId, ctx);
}
}
return tag;
Expand All @@ -232,20 +236,27 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
};
}

private static <T extends Tree> T maybeAddComment(Accumulator acc, T tree, String groupId, @Nullable String artifactId) {
private <T extends Tree> T maybeAddComment(Accumulator acc, T tree, String groupId, @Nullable String artifactId, ExecutionContext ctx) {
Relocation relocation = acc.getMigrations().get(new GroupArtifact(groupId, artifactId));
if (relocation != null) {
GroupArtifact relocatedGA = relocation.getTo();
String commentText = String.format("Relocated to %s%s%s",
relocation.getTo().getGroupId(),
Optional.ofNullable(relocation.getTo().getArtifactId()).map(a -> ":" + a).orElse(""),
relocatedGA.getGroupId(),
Optional.ofNullable(relocatedGA.getArtifactId()).map(a -> ":" + a).orElse(""),
relocation.getContext() == null ? "" : " as per \"" + relocation.getContext() + "\"");
report.insertRow(ctx, new RelocatedDependencyReport.Row(
groupId,
artifactId,
relocatedGA.getGroupId(),
relocatedGA.getArtifactId(),
relocation.getContext()));
return SearchResult.found(tree, commentText);
}
if (artifactId == null) {
return tree;
}
// Try again without artifactId
return maybeAddComment(acc, tree, groupId, null);
return maybeAddComment(acc, tree, groupId, null, ctx);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
*/
package org.openrewrite.java.dependencies.table;

import com.fasterxml.jackson.annotation.JsonIgnoreType;
import lombok.Value;
import org.openrewrite.Column;
import org.openrewrite.DataTable;
import org.openrewrite.Recipe;

@JsonIgnoreType
public class DependencyListReport extends DataTable<DependencyListReport.Row> {

public DependencyListReport(Recipe recipe) {
super(recipe,
"Dependency report",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@
*/
package org.openrewrite.java.dependencies.table;

import com.fasterxml.jackson.annotation.JsonIgnoreType;
import lombok.Value;
import org.openrewrite.Column;
import org.openrewrite.DataTable;
import org.openrewrite.Recipe;

@JsonIgnoreType
public class GradleDependencyConfigurationErrors extends DataTable<GradleDependencyConfigurationErrors.Row> {


public GradleDependencyConfigurationErrors(Recipe recipe) {
super(recipe, "Gradle dependency configuration errors",
"Records Gradle dependency configurations which failed to resolve during parsing. " +
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openrewrite.java.dependencies.table;

import com.fasterxml.jackson.annotation.JsonIgnoreType;
import lombok.Value;
import org.openrewrite.Column;
import org.openrewrite.DataTable;
import org.openrewrite.Recipe;
import org.openrewrite.internal.lang.Nullable;

@JsonIgnoreType
public class RelocatedDependencyReport extends DataTable<RelocatedDependencyReport.Row> {
public RelocatedDependencyReport(Recipe recipe) {
super(recipe,
"Relocated dependencies",
"A list of dependencies in use that have relocated.");
}

@Value
public static class Row {
@Column(displayName = "Dependency group id",
description = "The Group ID of the dependency in use.")
String dependencyGroupId;
@Column(displayName = "Dependency artifact id",
description = "The Artifact ID of the dependency in use.")
@Nullable
String dependencyArtifactId;

@Column(displayName = "Relocated dependency group id",
description = "The Group ID of the relocated dependency.")
String relocatedGroupId;
@Column(displayName = "Relocated ependency artifact id",
description = "The Artifact ID of the relocated dependency.")
@Nullable
String relocatedArtifactId;

@Column(displayName = "Context",
description = "Context for the relocation, if any.")
@Nullable
String context;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
*/
package org.openrewrite.java.dependencies.table;

import com.fasterxml.jackson.annotation.JsonIgnoreType;
import lombok.Value;
import org.openrewrite.Column;
import org.openrewrite.DataTable;
import org.openrewrite.Recipe;
import org.openrewrite.internal.lang.Nullable;

@JsonIgnoreType
public class RepositoryAccessibilityReport extends DataTable<RepositoryAccessibilityReport.Row> {

public RepositoryAccessibilityReport(Recipe recipe) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.openrewrite.java.dependencies.RelocatedDependencyCheck.Accumulator;
import org.openrewrite.java.dependencies.RelocatedDependencyCheck.GroupArtifact;
import org.openrewrite.java.dependencies.RelocatedDependencyCheck.Relocation;
import org.openrewrite.java.dependencies.table.RelocatedDependencyReport;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

Expand Down Expand Up @@ -54,6 +55,10 @@ class Maven {
@DocumentExample
void findRelocatedMavenDependencies() {
rewriteRun(
recipe -> recipe.dataTable(RelocatedDependencyReport.Row.class, rows -> assertThat(rows).containsExactly(
new RelocatedDependencyReport.Row("commons-lang", "commons-lang", "org.apache.commons", "commons-lang3", null),
new RelocatedDependencyReport.Row("org.codehaus.groovy", null, "org.apache.groovy", null, null)
)),
//language=xml
pomXml(
"""
Expand Down Expand Up @@ -97,7 +102,6 @@ void findRelocatedMavenDependencies() {
</project>
"""
)

);
}

Expand Down Expand Up @@ -207,17 +211,20 @@ class Gradle {
@Test
void findRelocatedGradleDependencies() {
rewriteRun(
recipe -> recipe.dataTable(RelocatedDependencyReport.Row.class, rows -> assertThat(rows).containsExactly(
new RelocatedDependencyReport.Row("commons-lang", "commons-lang", "org.apache.commons", "commons-lang3", null),
new RelocatedDependencyReport.Row("commons-lang", "commons-lang", "org.apache.commons", "commons-lang3", null),
new RelocatedDependencyReport.Row("org.codehaus.groovy", null, "org.apache.groovy", null, null)
)),
//language=groovy
buildGradle(
"""
plugins {
id "java-library"
}
repositories {
mavenCentral()
}
def groovyVersion = "2.5.6"
dependencies {
implementation "commons-lang:commons-lang:2.6"
Expand All @@ -229,11 +236,9 @@ void findRelocatedGradleDependencies() {
plugins {
id "java-library"
}
repositories {
mavenCentral()
}
def groovyVersion = "2.5.6"
dependencies {
/*~~(Relocated to org.apache.commons:commons-lang3)~~>*/implementation "commons-lang:commons-lang:2.6"
Expand Down

0 comments on commit 6fd1ae4

Please sign in to comment.