Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
4c789cb
Include in Dependency Report the path to the build file declaring the…
sambsnyd Jul 14, 2026
c9b92d0
OpenRewrite recipe best practices
timtebeek May 15, 2026
7126957
Pin empty MavenSettings in DependencyResolutionDiagnosticTest.maven()…
timtebeek May 18, 2026
f06761d
Speed up ModuleHasDependency and RepositoryHasDependency by removing …
steve-aom-elliott May 21, 2026
a90e41c
Match requested dependencies in ModuleHasDependency and RepositoryHas…
Jenson3210 May 28, 2026
29eb6b1
Regenerate recipes.csv (#180)
timtebeek May 28, 2026
4b3f838
Update Gradle wrapper 9.5.1
timtebeek May 28, 2026
824e8f8
Trust resolved version over declared dep in dependency search (#181)
timtebeek May 29, 2026
203fec4
git-ignore .context/
greg-at-moderne Jun 9, 2026
0273348
Fix RemoveDependency.unlessUsing for multi-module Maven projects (#183)
steve-aom-elliott Jun 16, 2026
3df8160
Remove out-of-date OWASP suppressions
timtebeek Jun 17, 2026
0bc54b0
Use GitHub actions/checkout@v7
timtebeek Jun 19, 2026
85ae1d3
Cache delegate recipes per recipe instance to avoid repeated construc…
knutwannheden Jun 21, 2026
b88b73b
Add software.amazon.ion:ion-java -> com.amazon.ion:ion-java relocatio…
timtebeek Jun 23, 2026
731d38f
[Auto] Old GroupId migrations as of 2026-06-23T1723
TeamModerne Jun 23, 2026
6daad4b
Update findRelocatedIonJava test for new relocation context (#186)
timtebeek Jun 24, 2026
a113ca5
Keep direct dependencies whose scope or exclusions differ from the tr…
timtebeek Jul 10, 2026
5dd03f6
Polish
sambsnyd Jul 14, 2026
cba565c
Merge branch 'main' into report-path
sambsnyd Jul 14, 2026
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 @@ -36,6 +36,7 @@
import java.util.Set;

import static java.util.Collections.emptyMap;
import static org.openrewrite.PathUtils.separatorsToUnix;

@EqualsAndHashCode(callSuper = false)
@Value
Expand Down Expand Up @@ -89,6 +90,7 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
if (tree == null) {
return null;
}
String path = tree instanceof SourceFile ? separatorsToUnix(((SourceFile) tree).getSourcePath().toString()) : "";
Markers m = tree.getMarkers();
Set<ResolvedGroupArtifactVersion> seen = new HashSet<>();
m.findFirst(GradleProject.class)
Expand All @@ -100,7 +102,7 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
if (dep.getDepth() > 0) {
continue;
}
insertDependency(ctx, gradle, seen, dep, true);
insertDependency(ctx, gradle, path, seen, dep, true);
}
}
});
Expand All @@ -109,7 +111,7 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
if (dep.getDepth() > 0) {
continue;
}
insertDependency(ctx, maven, seen, dep, true);
insertDependency(ctx, maven, path, seen, dep, true);
}
});
return tree;
Expand All @@ -121,14 +123,13 @@ private Scope scope() {
return scope == null ? Scope.Compile : scope;
}

private void insertDependency(ExecutionContext ctx, GradleProject gradle, Set<ResolvedGroupArtifactVersion> seen, ResolvedDependency dep, boolean direct) {
private void insertDependency(ExecutionContext ctx, GradleProject gradle, String path, Set<ResolvedGroupArtifactVersion> 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,
Expand All @@ -140,6 +141,7 @@ private void insertDependency(ExecutionContext ctx, GradleProject gradle, Set<Re
}
report.insertRow(ctx, new DependencyListReport.Row(
"Gradle",
path,
gradle.getGroup(),
gradle.getName(),
gradle.getVersion(),
Expand All @@ -151,12 +153,12 @@ private void insertDependency(ExecutionContext ctx, GradleProject gradle, Set<Re
));
if (includeTransitive) {
for (ResolvedDependency transitive : dep.getDependencies()) {
insertDependency(ctx, gradle, seen, transitive, false);
insertDependency(ctx, gradle, path, seen, transitive, false);
}
}
}

private void insertDependency(ExecutionContext ctx, MavenResolutionResult maven, Set<ResolvedGroupArtifactVersion> seen, ResolvedDependency dep, boolean direct) {
private void insertDependency(ExecutionContext ctx, MavenResolutionResult maven, String path, Set<ResolvedGroupArtifactVersion> seen, ResolvedDependency dep, boolean direct) {
if (!seen.add(dep.getGav())) {
return;
}
Expand All @@ -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(),
Expand All @@ -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);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void gradle() {
url "https://nonexistent.moderne.io/maven2"
}
}

dependencies {
implementation("org.openrewrite.nonexistent:nonexistent:0.0.0")
}
Expand All @@ -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(
"""
Expand All @@ -126,7 +124,7 @@ void gradleNoDefaultRepos() {
url "https://nonexistent.moderne.io/maven2"
}
}

dependencies {
implementation("org.openrewrite.nonexistent:nonexistent:0.0.0")
}
Expand Down Expand Up @@ -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
Expand All @@ -189,24 +185,17 @@ 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
"""
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd"/>
""".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, "", ""));
assertThat(rows).filteredOn(row -> row.getUri().startsWith("file:/") && "".equals(row.getPingExceptionMessage())).hasSize(1);
assertThat(rows).contains(
new RepositoryAccessibilityReport.Row("https://nonexistent.moderne.io/maven2", "java.net.UnknownHostException", "nonexistent.moderne.io", null, "", "")
);
})
.executionContext(ctx);
});
},
//language=xml
pomXml(
Expand All @@ -215,7 +204,7 @@ void maven() {
<groupId>com.example</groupId>
<artifactId>test</artifactId>
<version>0.1.0</version>

<repositories>
<repository>
<id>nonexistent</id>
Expand Down
Loading