diff --git a/src/main/java/org/openrewrite/java/dependencies/DependencyList.java b/src/main/java/org/openrewrite/java/dependencies/DependencyList.java index 6f4527fc..1703787b 100644 --- a/src/main/java/org/openrewrite/java/dependencies/DependencyList.java +++ b/src/main/java/org/openrewrite/java/dependencies/DependencyList.java @@ -36,6 +36,7 @@ import java.util.Set; import static java.util.Collections.emptyMap; +import static org.openrewrite.PathUtils.separatorsToUnix; @EqualsAndHashCode(callSuper = false) @Value @@ -89,6 +90,7 @@ public TreeVisitor getVisitor() { if (tree == null) { return null; } + String path = tree instanceof SourceFile ? separatorsToUnix(((SourceFile) tree).getSourcePath().toString()) : ""; Markers m = tree.getMarkers(); Set seen = new HashSet<>(); m.findFirst(GradleProject.class) @@ -100,7 +102,7 @@ public TreeVisitor getVisitor() { if (dep.getDepth() > 0) { continue; } - insertDependency(ctx, gradle, seen, dep, true); + insertDependency(ctx, gradle, path, seen, dep, true); } } }); @@ -109,7 +111,7 @@ public TreeVisitor getVisitor() { if (dep.getDepth() > 0) { continue; } - insertDependency(ctx, maven, seen, dep, true); + insertDependency(ctx, maven, path, seen, dep, true); } }); return tree; @@ -121,14 +123,13 @@ private Scope scope() { return scope == null ? Scope.Compile : scope; } - private void insertDependency(ExecutionContext ctx, GradleProject gradle, Set seen, ResolvedDependency dep, boolean direct) { + private void insertDependency(ExecutionContext ctx, GradleProject gradle, String path, Set seen, ResolvedDependency dep, boolean direct) { if (!seen.add(dep.getGav())) { return; } String resolutionFailure = ""; if (validateResolvable) { try { - //noinspection DataFlowIssue metadataFailures.insertRows(ctx, () -> new MavenPomDownloader( emptyMap(), ctx, null, @@ -140,6 +141,7 @@ private void insertDependency(ExecutionContext ctx, GradleProject gradle, Set seen, ResolvedDependency dep, boolean direct) { + private void insertDependency(ExecutionContext ctx, MavenResolutionResult maven, String path, Set seen, ResolvedDependency dep, boolean direct) { if (!seen.add(dep.getGav())) { return; } @@ -180,6 +182,7 @@ private void insertDependency(ExecutionContext ctx, MavenResolutionResult maven, } report.insertRow(ctx, new DependencyListReport.Row( "Maven", + path, maven.getPom().getGroupId(), maven.getPom().getArtifactId(), maven.getPom().getVersion(), @@ -191,7 +194,7 @@ private void insertDependency(ExecutionContext ctx, MavenResolutionResult maven, )); if (includeTransitive) { for (ResolvedDependency transitive : dep.getDependencies()) { - insertDependency(ctx, maven, seen, transitive, false); + insertDependency(ctx, maven, path, seen, transitive, false); } } } diff --git a/src/main/java/org/openrewrite/java/dependencies/table/DependencyListReport.java b/src/main/java/org/openrewrite/java/dependencies/table/DependencyListReport.java index 4f5e1d3f..8878bf9b 100644 --- a/src/main/java/org/openrewrite/java/dependencies/table/DependencyListReport.java +++ b/src/main/java/org/openrewrite/java/dependencies/table/DependencyListReport.java @@ -36,6 +36,10 @@ public static class Row { description = "The build tool used to manage dependencies (Gradle or Maven).") String buildTool; + @Column(displayName = "Path", + description = "Path to the build file declaring the dependency") + String path; + @Column(displayName = "Group id", description = "The Group ID of the Gradle project or Maven module requesting the dependency.") String groupId; diff --git a/src/test/java/org/openrewrite/java/dependencies/DependencyListTest.java b/src/test/java/org/openrewrite/java/dependencies/DependencyListTest.java index 04dfce69..ef3d9151 100644 --- a/src/test/java/org/openrewrite/java/dependencies/DependencyListTest.java +++ b/src/test/java/org/openrewrite/java/dependencies/DependencyListTest.java @@ -93,12 +93,10 @@ void directOnly() { rewriteRun( spec -> spec.recipe(new DependencyList(DependencyList.Scope.Compile, false, false)) .beforeRecipe(withToolingApi()) - .dataTable(DependencyListReport.Row.class, rows -> { - assertThat(rows) - .containsExactlyInAnyOrder( - new DependencyListReport.Row("Gradle", "com.test", "test", "1.0.0", "io.micrometer.prometheus", "prometheus-rsocket-client", "1.5.3", true, ""), - new DependencyListReport.Row("Maven", "com.test", "test", "1.0.0", "io.micrometer.prometheus", "prometheus-rsocket-client", "1.5.3", true, "")); - }), + .dataTable(DependencyListReport.Row.class, rows -> assertThat(rows) + .containsExactlyInAnyOrder( + new DependencyListReport.Row("Gradle", "build.gradle", "com.test", "test", "1.0.0", "io.micrometer.prometheus", "prometheus-rsocket-client", "1.5.3", true, ""), + new DependencyListReport.Row("Maven", "pom.xml", "com.test", "test", "1.0.0", "io.micrometer.prometheus", "prometheus-rsocket-client", "1.5.3", true, ""))), settingsGradle("rootProject.name = 'test'"), buildGradle( //language=groovy diff --git a/src/test/java/org/openrewrite/java/dependencies/DependencyResolutionDiagnosticTest.java b/src/test/java/org/openrewrite/java/dependencies/DependencyResolutionDiagnosticTest.java index e8c5c1b4..3367eb62 100644 --- a/src/test/java/org/openrewrite/java/dependencies/DependencyResolutionDiagnosticTest.java +++ b/src/test/java/org/openrewrite/java/dependencies/DependencyResolutionDiagnosticTest.java @@ -91,7 +91,7 @@ void gradle() { url "https://nonexistent.moderne.io/maven2" } } - + dependencies { implementation("org.openrewrite.nonexistent:nonexistent:0.0.0") } @@ -107,14 +107,12 @@ void gradleNoDefaultRepos() { spec -> spec.beforeRecipe(withToolingApi()) // It is a limitation of the tooling API which prevents configuration-granularity error information from being collected. // So the GradleDependencyConfigurationErrors table will never be populated in unit tests. - .dataTable(RepositoryAccessibilityReport.Row.class, rows -> { - assertThat(rows) - .hasSize(2) - .contains( - new RepositoryAccessibilityReport.Row("https://plugins.gradle.org/m2", "", "", 200, "", "")) - .contains( - new RepositoryAccessibilityReport.Row("https://nonexistent.moderne.io/maven2", "java.net.UnknownHostException", "nonexistent.moderne.io", null, "", "")); - }), + .dataTable(RepositoryAccessibilityReport.Row.class, rows -> assertThat(rows) + .hasSize(2) + .contains( + new RepositoryAccessibilityReport.Row("https://plugins.gradle.org/m2", "", "", 200, "", "")) + .contains( + new RepositoryAccessibilityReport.Row("https://nonexistent.moderne.io/maven2", "java.net.UnknownHostException", "nonexistent.moderne.io", null, "", ""))), //language=groovy buildGradle( """ @@ -126,7 +124,7 @@ void gradleNoDefaultRepos() { url "https://nonexistent.moderne.io/maven2" } } - + dependencies { implementation("org.openrewrite.nonexistent:nonexistent:0.0.0") } @@ -158,13 +156,11 @@ void mavenSettingsWithMirrors() { """.getBytes())), ctx); ctx.setMavenSettings(settings); spec.beforeRecipe(withToolingApi()) - .dataTable(RepositoryAccessibilityReport.Row.class, rows -> { - assertThat(rows) - .contains( - new RepositoryAccessibilityReport.Row("https://nonexistent.moderne.io/maven2", "java.net.UnknownHostException", "nonexistent.moderne.io", null, "", "") - ) - .noneMatch(repo -> repo.getUri().contains("https://repo.maven.apache.org/maven2")); - }) + .dataTable(RepositoryAccessibilityReport.Row.class, rows -> assertThat(rows) + .contains( + new RepositoryAccessibilityReport.Row("https://nonexistent.moderne.io/maven2", "java.net.UnknownHostException", "nonexistent.moderne.io", null, "", "") + ) + .noneMatch(repo -> repo.getUri().contains("https://repo.maven.apache.org/maven2"))) .executionContext(ctx); }, //language=xml @@ -189,15 +185,9 @@ void maven() { // nor the test's `nonexistent.moderne.io` repo appear in the diagnostic. Force empty settings // here so the recipe sees the pom-declared repositories directly. MavenExecutionContextView ctx = MavenExecutionContextView.view(new InMemoryExecutionContext()); - MavenSettings emptySettings = MavenSettings.parse(new Parser.Input(Path.of("settings.xml"), () -> new ByteArrayInputStream( - //language=xml - """ - - """.getBytes())), ctx); - ctx.setMavenSettings(emptySettings); - spec.beforeRecipe(withToolingApi()) + ctx.setMavenSettings(new MavenSettings(null, null, null, null, null, null)); + spec + .executionContext(ctx) .dataTable(RepositoryAccessibilityReport.Row.class, rows -> { assertThat(rows).contains( new RepositoryAccessibilityReport.Row("https://repo.maven.apache.org/maven2", "", "", 200, "", "")); @@ -205,8 +195,7 @@ void maven() { assertThat(rows).contains( new RepositoryAccessibilityReport.Row("https://nonexistent.moderne.io/maven2", "java.net.UnknownHostException", "nonexistent.moderne.io", null, "", "") ); - }) - .executionContext(ctx); + }); }, //language=xml pomXml( @@ -215,7 +204,7 @@ void maven() { com.example test 0.1.0 - + nonexistent