Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RelocatedDependencyReport for easier export & analysis #61

Merged
merged 2 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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