From df16f0ae2f1ed3b03e5b219543031eb02b1bded8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Merlin=20B=C3=B6gershausen?= Date: Thu, 30 Apr 2026 13:18:22 +0200 Subject: [PATCH 1/2] Maven, Gradle: emit DependenciesDeclared data table from FindDependency Adds a new shared DependenciesDeclared data table in org.openrewrite.maven.table. Both rewrite-maven and rewrite-gradle FindDependency recipes populate it alongside the existing SearchResult markers, one row per declared dependency match. Schema mirrors DependenciesInUse minus the count column (every row is direct by construction). Single shared class follows the existing precedent: rewrite-gradle already imports org.openrewrite.maven.table.DependenciesInUse from rewrite-maven. --- .../gradle/search/FindDependency.java | 35 ++++- .../resources/META-INF/rewrite/recipes.csv | 10 +- .../gradle/search/FindDependencyTest.java | 80 ++++++++++ .../maven/search/FindDependency.java | 35 ++++- .../maven/table/DependenciesDeclared.java | 66 ++++++++ .../resources/META-INF/rewrite/recipes.csv | 8 +- .../maven/search/FindDependencyTest.java | 145 ++++++++++++++++++ 7 files changed, 367 insertions(+), 12 deletions(-) create mode 100644 rewrite-maven/src/main/java/org/openrewrite/maven/table/DependenciesDeclared.java diff --git a/rewrite-gradle/src/main/java/org/openrewrite/gradle/search/FindDependency.java b/rewrite-gradle/src/main/java/org/openrewrite/gradle/search/FindDependency.java index 6edd64c3e7e..55ab2dda283 100755 --- a/rewrite-gradle/src/main/java/org/openrewrite/gradle/search/FindDependency.java +++ b/rewrite-gradle/src/main/java/org/openrewrite/gradle/search/FindDependency.java @@ -21,9 +21,13 @@ import org.openrewrite.ExecutionContext; import org.openrewrite.Option; import org.openrewrite.Recipe; +import org.openrewrite.SourceFile; import org.openrewrite.TreeVisitor; import org.openrewrite.gradle.trait.GradleDependency; +import org.openrewrite.java.marker.JavaProject; +import org.openrewrite.java.marker.JavaSourceSet; import org.openrewrite.marker.SearchResult; +import org.openrewrite.maven.table.DependenciesDeclared; import org.openrewrite.semver.Semver; import org.openrewrite.semver.VersionComparator; import org.openrewrite.Validated; @@ -31,6 +35,8 @@ @Value @EqualsAndHashCode(callSuper = false) public class FindDependency extends Recipe { + transient DependenciesDeclared dependenciesDeclared = new DependenciesDeclared(this); + @Option(displayName = "Group", description = "The first part of a dependency coordinate identifying its publisher.", example = "com.google.guava") @@ -71,7 +77,9 @@ public String getInstanceNameSuffix() { return String.format("`%s:%s%s`", groupId, artifactId, maybeVersionSuffix); } - String description = "Finds dependencies declared in gradle build files. See the [reference](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph) on Gradle configurations or the diagram below for a description of what configuration to use. " + + String description = "Finds dependencies declared in gradle build files. " + + "Each match is also recorded as a row in the `DependenciesDeclared` data table. " + + "See the [reference](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph) on Gradle configurations or the diagram below for a description of what configuration to use. " + "A project's compile and runtime classpath is based on these configurations.\n\n\"Gradle\n" + "A project's test classpath is based on these configurations.\n\n\"Gradle."; @@ -81,7 +89,30 @@ public TreeVisitor getVisitor() { .groupId(groupId) .artifactId(artifactId) .configuration(configuration) - .asVisitor(gd -> versionIsValid(version, versionPattern, gd) ? SearchResult.found(gd.getTree()) : gd.getTree()); + .asVisitor((gd, ctx) -> { + if (!versionIsValid(version, versionPattern, gd)) { + return gd.getTree(); + } + SourceFile sourceFile = gd.getCursor().firstEnclosing(SourceFile.class); + String projectName = sourceFile == null ? "" : sourceFile.getMarkers() + .findFirst(JavaProject.class) + .map(JavaProject::getProjectName) + .orElse(""); + String sourceSetName = sourceFile == null ? "main" : sourceFile.getMarkers() + .findFirst(JavaSourceSet.class) + .map(JavaSourceSet::getName) + .orElse("main"); + dependenciesDeclared.insertRow(ctx, new DependenciesDeclared.Row( + projectName, + sourceSetName, + gd.getGroupId(), + gd.getArtifactId(), + gd.getVersion(), + null, + gd.getConfigurationName() + )); + return SearchResult.found(gd.getTree()); + }); } private static boolean versionIsValid(@Nullable String desiredVersion, @Nullable String versionPattern, diff --git a/rewrite-gradle/src/main/resources/META-INF/rewrite/recipes.csv b/rewrite-gradle/src/main/resources/META-INF/rewrite/recipes.csv index be02db45aa3..485cb2df460 100644 --- a/rewrite-gradle/src/main/resources/META-INF/rewrite/recipes.csv +++ b/rewrite-gradle/src/main/resources/META-INF/rewrite/recipes.csv @@ -50,12 +50,12 @@ maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.MigrateToGradle7,Mig maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.MigrateToGradle8,Migrate to Gradle 8 from Gradle 7,Migrate to version 8.x. See the Gradle upgrade guide from [version 7.x to 8.0](https://docs.gradle.org/current/userguide/upgrading_version_7.html) and [version 8.x to latest](https://docs.gradle.org/current/userguide/upgrading_version_8.html) for more information.,35,,Gradle,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.UseAssignmentForPropertySyntax,Use `=` assignment syntax for well-known Gradle properties,"Converts deprecated Groovy DSL property assignment syntax from space/method-call form (e.g., `description 'text'` or `description('text')`) to assignment form (`description = 'text'`) for well-known Gradle project and task properties. See the [Gradle 8.14 upgrade guide](https://docs.gradle.org/8.14/userguide/upgrading_version_8.html#groovy_space_assignment_syntax) for more information.",14,,Gradle,, maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.AddJUnitPlatformLauncher,Add JUnit Platform Launcher,Add the JUnit Platform Launcher to the buildscript dependencies.,2,,Gradle,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" -maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.MigrateToGradle9,Migrate to Gradle 9 from Gradle 8,Migrate to version 9.x. See the Gradle upgrade guide from [version 8.x to 9.0](https://docs.gradle.org/9.0.0/userguide/upgrading_major_version_9.html) for more information.,38,,Gradle,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" -maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.GradleBestPractices,Apply Gradle best practices,"Apply a set of [Gradle best practices](https://docs.gradle.org/current/userguide/best_practices_general.html) to the build files, for more efficient and ideomatic builds.",44,,Gradle,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" +maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.MigrateToGradle9,Migrate to Gradle 9 from Gradle 8,Migrate to version 9.x. See the Gradle upgrade guide from [version 8.x to 9.0](https://docs.gradle.org/9.0.0/userguide/upgrading_major_version_9.html) for more information.,39,,Gradle,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" +maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.GradleBestPractices,Apply Gradle best practices,"Apply a set of [Gradle best practices](https://docs.gradle.org/current/userguide/best_practices_general.html) to the build files, for more efficient and idiomatic builds.",49,,Gradle,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.EnableGradleBuildCache,Enable Gradle build cache,"Enable the Gradle build cache. By enabling build cache the build outputs are stored externally and fetched from the cache when it is determined that those inputs have no changed, avoiding the expensive work of regenerating them. See the [Gradle Build Cache](https://docs.gradle.org/current/userguide/build_cache.html) for more information.",2,,Gradle,, maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.EnableGradleParallelExecution,Enable Gradle parallel execution,"Most builds consist of more than one project and some of those projects are usually independent of one another. Yet Gradle will only run one task at a time by default, regardless of the project structure. By using the `--parallel` switch, you can force Gradle to execute tasks in parallel as long as those tasks are in different projects. See the [Gradle performance documentation](https://docs.gradle.org/current/userguide/performance.html#parallel_execution) for more information.",2,,Gradle,, maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.gradle8.JacocoReportDeprecations,Replace Gradle 8 introduced deprecations in JaCoCo report task,Set the `enabled` to `required` and the `destination` to `outputLocation` for Reports deprecations that were removed in gradle 8. See [the gradle docs on this topic](https://docs.gradle.org/current/userguide/upgrading_version_7.html#report_and_testreport_api_cleanup).,1,Gradle8,Gradle,, -maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.gradle9.UseMainClassProperty,Use `mainClass` instead of `main` for `JavaExec` tasks,The `main` property on `JavaExec` tasks was deprecated in Gradle 7.1 and removed in Gradle 9.0. Use the `mainClass` property instead.,1,Gradle9,Gradle,, +maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.gradle9.UseMainClassProperty,Use `mainClass` instead of `main` for `JavaExec` tasks,The `main` property on `JavaExec` tasks was deprecated in Gradle 7.1 and removed in Gradle 9.0. Use the `mainClass` property instead. See the [Gradle upgrade guide](https://docs.gradle.org/9.0.0/userguide/upgrading_major_version_9.html) for more information.,1,Gradle9,Gradle,, maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.plugins.AddBuildPlugin,Add Gradle plugin,Add a build plugin to a Gradle build file's `plugins` block.,1,Plugins,Gradle,"[{""name"":""pluginId"",""type"":""String"",""displayName"":""Plugin id"",""description"":""The plugin id to apply."",""example"":""com.jfrog.bintray"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Plugin version"",""description"":""An exact version number or node-style semver selector used to select the version number. You can also use `latest.release` for the latest available version and `latest.patch` if the current version is a valid semantic version. For more details, you can look at the documentation page of [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors)."",""example"":""3.x""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""},{""name"":""apply"",""type"":""Boolean"",""displayName"":""Apply plugin"",""description"":""Immediate apply the plugin. Defaults to `true`."",""valid"":[""true"",""false""]},{""name"":""acceptTransitive"",""type"":""Boolean"",""displayName"":""Accept transitive"",""description"":""Some plugins apply other plugins. When this is set to true no plugin declaration will be added if the plugin is already applied transitively. When this is set to false the plugin will be added explicitly even if it is already applied transitively. Defaults to `true`."",""valid"":[""true"",""false""]}]", maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.plugins.AddDevelocityGradlePlugin,Add the Develocity Gradle plugin,Add the Develocity Gradle plugin to settings.gradle files.,1,Plugins,Gradle,"[{""name"":""version"",""type"":""String"",""displayName"":""Plugin version"",""description"":""An exact version number or node-style semver selector used to select the version number. You can also use `latest.release` for the latest available version and `latest.patch` if the current version is a valid semantic version. For more details, you can look at the documentation page of [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors). Defaults to `latest.release`."",""example"":""3.x""},{""name"":""server"",""type"":""String"",""displayName"":""Server URL"",""description"":""The URL of the Develocity server. If omitted the recipe will set no URL and Gradle will direct scans to https://scans.gradle.com/"",""example"":""https://scans.gradle.com/""},{""name"":""allowUntrustedServer"",""type"":""Boolean"",""displayName"":""Allow untrusted server"",""description"":""When set to `true` the plugin will be configured to allow unencrypted http connections with the server. If set to `false` or omitted, the plugin will refuse to communicate without transport layer security enabled."",""example"":""true""},{""name"":""captureTaskInputFiles"",""type"":""Boolean"",""displayName"":""Capture task input files"",""description"":""When set to `true` the plugin will capture additional information about the inputs to Gradle tasks. This increases the size of build scans, but is useful for diagnosing issues with task caching. "",""example"":""true""},{""name"":""uploadInBackground"",""type"":""Boolean"",""displayName"":""Upload in background"",""description"":""When set to `true` the plugin will capture additional information about the outputs of Gradle tasks. This increases the size of build scans, but is useful for diagnosing issues with task caching. "",""example"":""true""},{""name"":""publishCriteria"",""type"":""PublishCriteria"",""displayName"":""Publish criteria"",""description"":""When set to `Always` the plugin will publish build scans of every single build. When set to `Failure` the plugin will only publish build scans when the build fails. When omitted scans will be published only when the `--scan` option is passed to the build."",""example"":""Always"",""valid"":[""Always"",""Failure""]}]","[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.plugins.AddSettingsPlugin,Add Gradle settings plugin,Add plugin to Gradle settings file `plugins` block by id.,1,Plugins,Gradle,"[{""name"":""pluginId"",""type"":""String"",""displayName"":""Plugin id"",""description"":""The plugin id to apply."",""example"":""com.jfrog.bintray"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Plugin version"",""description"":""An exact version number or node-style semver selector used to select the version number. You can also use `latest.release` for the latest available version and `latest.patch` if the current version is a valid semantic version. For more details, you can look at the documentation page of [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors). Defaults to `latest.release`."",""example"":""3.x""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""},{""name"":""apply"",""type"":""Boolean"",""displayName"":""Apply plugin"",""description"":""Immediate apply the plugin. Defaults to `true`."",""valid"":[""true"",""false""]},{""name"":""acceptTransitive"",""type"":""Boolean"",""displayName"":""Accept transitive"",""description"":""Some plugins apply other plugins. When this is set to true no plugin declaration will be added if the plugin is already applied transitively. When this is set to false the plugin will be added explicitly even if it is already applied transitively. Defaults to `true`."",""valid"":[""true"",""false""]}]", @@ -72,12 +72,12 @@ maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.DependencyIns maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.DoesNotIncludeDependency,Does not include Gradle dependency,"A precondition which returns false if visiting a Gradle file which includes the specified dependency in the classpath of some scope. For compatibility with multimodule projects, this should most often be applied as a precondition.",1,Search,Gradle,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""guava"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""Match only dependencies with the specified resolved version. Node-style [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors) may be used. All versions are searched by default."",""example"":""1.x""},{""name"":""configuration"",""type"":""String"",""displayName"":""Scope"",""description"":""Match dependencies with the specified scope. If not specified, all configurations will be searched."",""example"":""compileClasspath""}]", maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.EffectiveGradlePluginRepositories,List effective Gradle plugin repositories,"Lists the Gradle plugin repositories that would be used for plugin resolution, in order of precedence. This includes Maven repositories defined in the settings.gradle pluginManagement section and build.gradle buildscript repositories as determined when the LST was produced.",1,Search,Gradle,"[{""name"":""useMarkers"",""type"":""Boolean"",""displayName"":""Use markers"",""description"":""Whether to add markers for each effective Gradle plugin repository to the build or settings file. Default `false`.""}]","[{""name"":""org.openrewrite.maven.search.EffectiveMavenRepositoriesTable"",""displayName"":""Effective Maven repositories"",""instanceName"":""Effective Maven repositories"",""description"":""Table showing which Maven repositories were used in dependency resolution for this POM."",""columns"":[{""name"":""pomPath"",""type"":""String"",""displayName"":""POM path"",""description"":""The path to the POM file.""},{""name"":""repositoryUri"",""type"":""String"",""displayName"":""Repository URI"",""description"":""The URI of the Maven repository.""}]}]" maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.EffectiveGradleRepositories,List effective Gradle project repositories,"Lists the Gradle project repositories that would be used for dependency resolution, in order of precedence. This includes Maven repositories defined in the Gradle build files and settings as determined when the LST was produced.",1,Search,Gradle,"[{""name"":""useMarkers"",""type"":""Boolean"",""displayName"":""Use markers"",""description"":""Whether to add markers for each effective Gradle repository to the build file. Default `false`.""}]","[{""name"":""org.openrewrite.maven.search.EffectiveMavenRepositoriesTable"",""displayName"":""Effective Maven repositories"",""instanceName"":""Effective Maven repositories"",""description"":""Table showing which Maven repositories were used in dependency resolution for this POM."",""columns"":[{""name"":""pomPath"",""type"":""String"",""displayName"":""POM path"",""description"":""The path to the POM file.""},{""name"":""repositoryUri"",""type"":""String"",""displayName"":""Repository URI"",""description"":""The URI of the Maven repository.""}]}]" -maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindDependency,Find Gradle dependency,"Finds dependencies declared in gradle build files. See the [reference](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph) on Gradle configurations or the diagram below for a description of what configuration to use. A project's compile and runtime classpath is based on these configurations. +maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindDependency,Find Gradle dependency,"Finds dependencies declared in gradle build files. Each match is also recorded as a row in the `DependenciesDeclared` data table. See the [reference](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph) on Gradle configurations or the diagram below for a description of what configuration to use. A project's compile and runtime classpath is based on these configurations. A project's test classpath is based on these configurations. -.",1,Search,Gradle,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate identifying its publisher."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate uniquely identifying it among artifacts from the same publisher."",""example"":""guava"",""required"":true},{""name"":""configuration"",""type"":""String"",""displayName"":""Dependency configuration"",""description"":""The dependency configuration to search for dependencies in. If omitted then all configurations will be searched."",""example"":""api""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""3.0.0""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""}]", +.",1,Search,Gradle,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate identifying its publisher."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate uniquely identifying it among artifacts from the same publisher."",""example"":""guava"",""required"":true},{""name"":""configuration"",""type"":""String"",""displayName"":""Dependency configuration"",""description"":""The dependency configuration to search for dependencies in. If omitted then all configurations will be searched."",""example"":""api""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""3.0.0""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""}]","[{""name"":""org.openrewrite.maven.table.DependenciesDeclared"",""displayName"":""Dependencies declared"",""instanceName"":""Dependencies declared"",""description"":""Direct (first-order) dependencies declared by the project."",""columns"":[{""name"":""projectName"",""type"":""String"",""displayName"":""Project name"",""description"":""The name of the project that contains the dependency.""},{""name"":""sourceSet"",""type"":""String"",""displayName"":""Source set"",""description"":""The source set that contains the dependency.""},{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The resolved version.""},{""name"":""datedSnapshotVersion"",""type"":""String"",""displayName"":""Dated snapshot version"",""description"":""The resolved dated snapshot version or `null` if this dependency is not a snapshot.""},{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""Maven scope (e.g. `compile`, `test`) or Gradle configuration name (e.g. `implementation`, `testImplementation`). For Maven, defaults to `compile` when no scope is declared.""}]}]" maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindDependencyHandler,Find Gradle `dependencies` blocks,Find the dependency handler containing any number of dependency definitions.,1,Search,Gradle,, maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindGradleProject,Find Gradle projects,Gradle projects are those with `build.gradle` or `build.gradle.kts` files.,1,Search,Gradle,"[{""name"":""searchCriteria"",""type"":""SearchCriteria"",""displayName"":""Search criteria"",""description"":""Whether to identify gradle projects by source file name or the presence of a marker"",""example"":""Marker"",""valid"":[""File"",""Marker""],""required"":true}]", maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindGradleWrapper,Find Gradle wrappers,Find Gradle wrappers.,1,Search,Gradle,"[{""name"":""version"",""type"":""String"",""displayName"":""Version expression"",""description"":""A version expression representing the versions to search for"",""example"":""7.x""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""},{""name"":""distribution"",""type"":""String"",""displayName"":""Distribution type"",""description"":""The distribution of Gradle to find. \""bin\"" includes Gradle binaries. \""all\"" includes Gradle binaries, source code, and documentation."",""valid"":[""bin"",""all""]}]","[{""name"":""org.openrewrite.gradle.table.GradleWrappersInUse"",""displayName"":""Gradle wrappers in use"",""instanceName"":""Gradle wrappers in use"",""description"":""Gradle wrappers in use."",""columns"":[{""name"":""version"",""type"":""String"",""displayName"":""Wrapper version"",""description"":""The version of the Gradle wrapper in use.""},{""name"":""distribution"",""type"":""String"",""displayName"":""Wrapper distribution"",""description"":""The distribution type of the Gradle wrapper in use.""}]}]" diff --git a/rewrite-gradle/src/test/java/org/openrewrite/gradle/search/FindDependencyTest.java b/rewrite-gradle/src/test/java/org/openrewrite/gradle/search/FindDependencyTest.java index 9d0919f649d..f73d11010bd 100755 --- a/rewrite-gradle/src/test/java/org/openrewrite/gradle/search/FindDependencyTest.java +++ b/rewrite-gradle/src/test/java/org/openrewrite/gradle/search/FindDependencyTest.java @@ -19,8 +19,10 @@ import org.junit.jupiter.api.Test; import org.openrewrite.DocumentExample; import org.openrewrite.Issue; +import org.openrewrite.maven.table.DependenciesDeclared; import org.openrewrite.test.RewriteTest; +import static org.assertj.core.api.Assertions.assertThat; import static org.openrewrite.gradle.Assertions.buildGradle; import static org.openrewrite.gradle.Assertions.buildGradleKts; import static org.openrewrite.gradle.toolingapi.Assertions.withToolingApi; @@ -376,6 +378,84 @@ void findDependencyByVersionPatternNoMatch() { ); } + @Test + void emitsDataTableRow() { + rewriteRun( + spec -> spec.recipe(new FindDependency("org.openrewrite", "rewrite-core", "api", null, null)) + .dataTable(DependenciesDeclared.Row.class, rows -> { + assertThat(rows).hasSize(1); + DependenciesDeclared.Row row = rows.get(0); + assertThat(row.getGroupId()).isEqualTo("org.openrewrite"); + assertThat(row.getArtifactId()).isEqualTo("rewrite-core"); + assertThat(row.getScope()).isEqualTo("api"); + assertThat(row.getDatedSnapshotVersion()).isNull(); + }), + buildGradle( + //language=gradle + """ + plugins { + id 'java-library' + } + repositories { + mavenCentral() + } + dependencies { + api "org.openrewrite:rewrite-core:latest.release" + } + """, + """ + plugins { + id 'java-library' + } + repositories { + mavenCentral() + } + dependencies { + /*~~>*/api "org.openrewrite:rewrite-core:latest.release" + } + """ + ) + ); + } + + @Test + void emitsDataTableRowKotlinDsl() { + rewriteRun(spec -> spec + .beforeRecipe(withToolingApi()) + .recipe(new FindDependency("org.openrewrite", "rewrite-core", "api", null, null)) + .dataTable(DependenciesDeclared.Row.class, rows -> { + assertThat(rows).hasSize(1); + assertThat(rows.get(0).getArtifactId()).isEqualTo("rewrite-core"); + assertThat(rows.get(0).getScope()).isEqualTo("api"); + }), + buildGradleKts( + //language=gradle + """ + plugins { + `java-library` + } + repositories { + mavenCentral() + } + dependencies { + api("org.openrewrite:rewrite-core:latest.release") + } + """, + """ + plugins { + `java-library` + } + repositories { + mavenCentral() + } + dependencies { + /*~~>*/api("org.openrewrite:rewrite-core:latest.release") + } + """ + ) + ); + } + @Issue("https://github.com/openrewrite/rewrite/issues/5599") @Test void constraintsVsRegularDependencies() { diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/search/FindDependency.java b/rewrite-maven/src/main/java/org/openrewrite/maven/search/FindDependency.java index 7388dcfae8d..18bb4921c16 100644 --- a/rewrite-maven/src/main/java/org/openrewrite/maven/search/FindDependency.java +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/search/FindDependency.java @@ -19,8 +19,11 @@ import lombok.Value; import org.jspecify.annotations.Nullable; import org.openrewrite.*; +import org.openrewrite.java.marker.JavaProject; +import org.openrewrite.java.marker.JavaSourceSet; import org.openrewrite.marker.SearchResult; import org.openrewrite.maven.MavenIsoVisitor; +import org.openrewrite.maven.table.DependenciesDeclared; import org.openrewrite.maven.tree.ResolvedDependency; import org.openrewrite.semver.Semver; import org.openrewrite.semver.VersionComparator; @@ -33,6 +36,7 @@ @EqualsAndHashCode(callSuper = false) @Value public class FindDependency extends Recipe { + transient DependenciesDeclared dependenciesDeclared = new DependenciesDeclared(this); @Option(displayName = "Group", description = "The first part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob.", @@ -87,15 +91,44 @@ public String getInstanceNameSuffix() { return String.format("`%s:%s%s`", groupId, artifactId, maybeVersionSuffix); } - String description = "Finds first-order dependency uses, i.e. dependencies that are defined directly in a project."; + String description = "Finds first-order dependency uses, i.e. dependencies that are defined directly in a project. " + + "Each match is also recorded as a row in the `DependenciesDeclared` data table."; @Override public TreeVisitor getVisitor() { return new MavenIsoVisitor() { + String projectName = ""; + String sourceSetName = "main"; + + @Override + public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) { + projectName = document.getMarkers() + .findFirst(JavaProject.class) + .map(JavaProject::getProjectName) + .orElse(""); + sourceSetName = document.getMarkers() + .findFirst(JavaSourceSet.class) + .map(JavaSourceSet::getName) + .orElse("main"); + return super.visitDocument(document, ctx); + } + @Override public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) { if (isDependencyTag(groupId, artifactId) && versionIsValid(version, versionPattern, () -> findDependency(tag))) { + ResolvedDependency resolved = findDependency(tag); + if (resolved != null) { + dependenciesDeclared.insertRow(ctx, new DependenciesDeclared.Row( + projectName, + sourceSetName, + resolved.getGroupId(), + resolved.getArtifactId(), + resolved.getVersion(), + resolved.getDatedSnapshotVersion(), + tag.getChildValue("scope").orElse("compile") + )); + } return SearchResult.found(tag); } return super.visitTag(tag, ctx); diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/table/DependenciesDeclared.java b/rewrite-maven/src/main/java/org/openrewrite/maven/table/DependenciesDeclared.java new file mode 100644 index 00000000000..77ed70c5701 --- /dev/null +++ b/rewrite-maven/src/main/java/org/openrewrite/maven/table/DependenciesDeclared.java @@ -0,0 +1,66 @@ +/* + * Copyright 2026 the original author or authors. + *

+ * 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 + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.maven.table; + +import com.fasterxml.jackson.annotation.JsonIgnoreType; +import lombok.NonNull; +import lombok.Value; +import org.jspecify.annotations.Nullable; +import org.openrewrite.Column; +import org.openrewrite.DataTable; +import org.openrewrite.Recipe; + +@JsonIgnoreType +public class DependenciesDeclared extends DataTable { + + public DependenciesDeclared(Recipe recipe) { + super(recipe, "Dependencies declared", + "Direct (first-order) dependencies declared by the project."); + } + + @Value + public static class Row { + @Column(displayName = "Project name", + description = "The name of the project that contains the dependency.") + String projectName; + + @Column(displayName = "Source set", + description = "The source set that contains the dependency.") + String sourceSet; + + @Column(displayName = "Group", + description = "The first part of a dependency coordinate `com.google.guava:guava:VERSION`.") + String groupId; + + @Column(displayName = "Artifact", + description = "The second part of a dependency coordinate `com.google.guava:guava:VERSION`.") + String artifactId; + + @Column(displayName = "Version", + description = "The resolved version.") + String version; + + @Column(displayName = "Dated snapshot version", + description = "The resolved dated snapshot version or `null` if this dependency is not a snapshot.") + @Nullable + String datedSnapshotVersion; + + @Column(displayName = "Scope", + description = "Maven scope (e.g. `compile`, `test`) or Gradle configuration name (e.g. `implementation`, " + + "`testImplementation`). For Maven, defaults to `compile` when no scope is declared.") + String scope; + } +} diff --git a/rewrite-maven/src/main/resources/META-INF/rewrite/recipes.csv b/rewrite-maven/src/main/resources/META-INF/rewrite/recipes.csv index efad66c17b2..89a6f02380f 100644 --- a/rewrite-maven/src/main/resources/META-INF/rewrite/recipes.csv +++ b/rewrite-maven/src/main/resources/META-INF/rewrite/recipes.csv @@ -48,9 +48,8 @@ maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UpdateMavenProjectProp * `release.version` If none of these properties are in use and the maven compiler plugin is not otherwise configured, adds the `maven.compiler.release` property.",1,,Maven,"[{""name"":""version"",""type"":""Integer"",""displayName"":""Java version"",""description"":""The Java version to upgrade to."",""example"":""11"",""required"":true}]", -maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UpdateScmFromGitOrigin,Update SCM with Git origin,"Updates or adds the Maven `` tag based on the Git remote origin. By default, only existing Source Control Management (SCM) sections are updated. Set `addIfMissing` to `true` to also add missing SCM sections.",1,,Maven,"[{""name"":""addIfMissing"",""type"":""Boolean"",""displayName"":""Add if missing"",""description"":""If set to `true`, the recipe will add a `` section if it is missing. If set to `false` (default), the recipe will only update existing `` sections.""}]", +maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UpdateScmFromGitOrigin,Update SCM with Git origin,"Updates or adds the Maven `` tag based on the Git remote origin. By default, only existing Source Control Management (SCM) sections are updated. Set `addIfMissing` to `true` to also add missing SCM sections to root POMs (POMs without a parent element).",1,,Maven,"[{""name"":""addIfMissing"",""type"":""Boolean"",""displayName"":""Add if missing"",""description"":""If set to `true`, the recipe will add a `` section if it is missing. If set to `false` (default), the recipe will only update existing `` sections.""}]", maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UpgradePluginVersion,Upgrade Maven plugin version,"Upgrade the version of a plugin using Node Semver advanced range selectors, allowing more precise control over version updates to patch or minor releases.",1,,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate 'org.openrewrite.maven:rewrite-maven-plugin:VERSION'. Supports globs."",""example"":""org.openrewrite.maven"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate 'org.openrewrite.maven:rewrite-maven-plugin:VERSION'. Supports globs."",""example"":""rewrite-maven-plugin"",""required"":true},{""name"":""newVersion"",""type"":""String"",""displayName"":""New version"",""description"":""An exact version number or node-style semver selector used to select the version number. You can also use `latest.release` for the latest available version and `latest.patch` if the current version is a valid semantic version. For more details, you can look at the documentation page of [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors)"",""example"":""29.X"",""required"":true},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""},{""name"":""trustParent"",""type"":""Boolean"",""displayName"":""Trust parent POM"",""description"":""Even if the parent suggests a version that is older than what we are trying to upgrade to, trust it anyway. Useful when you want to wait for the parent to catch up before upgrading. The parent is not trusted by default.""},{""name"":""addVersionIfMissing"",""type"":""Boolean"",""displayName"":""Add version if missing"",""description"":""If the plugin is missing a version, add the latest release. Defaults to false.""}]","[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" -maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UseMavenCompilerPluginReleaseConfiguration,Use Maven compiler plugin release configuration,"Replaces any explicit `source` or `target` configuration (if present) on the `maven-compiler-plugin` with `release`, and updates the `release` value if needed. Will not downgrade the Java version if the current version is higher.",1,,Maven,"[{""name"":""releaseVersion"",""type"":""Integer"",""displayName"":""Release version"",""description"":""The new value for the release configuration. This recipe prefers ${java.version} if defined."",""example"":""11"",""required"":true}]", maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UseParentInference,Use Maven 4 parent inference,"Maven 4.1.0 supports automatic parent version inference when using a relative path. This recipe simplifies parent declarations by using the shorthand `` form when the parent is in the default location (`..`), removing the explicit ``, ``, ``, and `` elements. Maven automatically infers these values from the parent POM.",1,,Maven,, maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.AddAnnotationProcessor,Add an annotation processor to `maven-compiler-plugin`,"Add an annotation processor path to the `maven-compiler-plugin` configuration. For modules with an in-reactor parent, adds to the parent's `build/pluginManagement/plugins` section. For modules without a parent or with a parent outside the reactor, adds directly to `build/plugins`. Updates the annotation processor version if a newer version is specified.",1,,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of the coordinate 'org.projectlombok:lombok-mapstruct-binding:0.2.0' of the processor to add."",""example"":""org.projectlombok"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a coordinate 'org.projectlombok:lombok-mapstruct-binding:0.2.0' of the processor to add."",""example"":""lombok-mapstruct-binding"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The third part of a coordinate 'org.projectlombok:lombok-mapstruct-binding:0.2.0' of the processor to add. Note that an exact version is expected"",""example"":""0.2.0"",""required"":true}]", maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.AddDependency,Add Maven dependency,Add a Maven dependency to a `pom.xml` file in the correct scope based on where it is used.,1,,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`."",""example"":""guava"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""29.X"",""required"":true},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""},{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""A scope to use when it is not what can be inferred from usage. Most of the time this will be left empty, but is used when adding a runtime, provided, or test dependency."",""example"":""runtime"",""valid"":[""compile"",""runtime"",""provided"",""test""]},{""name"":""releasesOnly"",""type"":""Boolean"",""displayName"":""Releases only"",""description"":""Whether to exclude snapshots from consideration when using a semver selector""},{""name"":""onlyIfUsing"",""type"":""String"",""displayName"":""Only if using"",""description"":""Used to determine if the dependency will be added and in which scope it should be placed. Required for multi-module projects to avoid adding dependencies unnecessarily."",""example"":""org.junit.jupiter.api.*""},{""name"":""type"",""type"":""String"",""displayName"":""Type"",""description"":""The type of dependency to add. If omitted Maven defaults to assuming the type is \""jar\""."",""example"":""jar"",""valid"":[""jar"",""pom"",""war""]},{""name"":""classifier"",""type"":""String"",""displayName"":""Classifier"",""description"":""A Maven classifier to add. Most commonly used to select shaded or test variants of a library"",""example"":""test""},{""name"":""optional"",""type"":""Boolean"",""displayName"":""Optional"",""description"":""Set the value of the `` tag. No `` tag will be added when this is `null`.""},{""name"":""familyPattern"",""type"":""String"",""displayName"":""Family pattern"",""description"":""A pattern, applied to groupIds, used to determine which other dependencies should have aligned version numbers. Accepts '*' as a wildcard character."",""example"":""com.fasterxml.jackson*""},{""name"":""acceptTransitive"",""type"":""Boolean"",""displayName"":""Accept transitive"",""description"":""Default false. If enabled, the dependency will not be added if it is already on the classpath as a transitive dependency."",""example"":""true""}]","[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" @@ -66,7 +65,8 @@ maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UpdateMavenWrapper,Upd maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UpgradeDependencyVersion,Upgrade Maven dependency version,"Upgrade the version of a dependency by specifying a group and (optionally) an artifact using Node Semver advanced range selectors, allowing more precise control over version updates to patch or minor releases.",1,,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`. This can be a glob expression."",""example"":""com.fasterxml.jackson*"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`. This can be a glob expression."",""example"":""jackson-module*"",""required"":true},{""name"":""newVersion"",""type"":""String"",""displayName"":""New version"",""description"":""An exact version number or node-style semver selector used to select the version number. You can also use `latest.release` for the latest available version and `latest.patch` if the current version is a valid semantic version. For more details, you can look at the documentation page of [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors)"",""example"":""29.X"",""required"":true},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'newVersion' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""},{""name"":""overrideManagedVersion"",""type"":""Boolean"",""displayName"":""Override managed version"",""description"":""This flag can be set to explicitly override a managed dependency's version. If the dependency has its version managed by a Bill of Materials (BOM), enabling this flag will attempt to upgrade the BOM. The default for this flag is `false`.""},{""name"":""retainVersions"",""type"":""List"",""displayName"":""Retain versions"",""description"":""Accepts a list of GAVs. For each GAV, if it is a project direct dependency, and it is removed from dependency management after the changes from this recipe, then it will be retained with an explicit version. The version can be omitted from the GAV to use the old value from dependency management"",""example"":""com.jcraft:jsch""}]","[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UpgradeParentVersion,Upgrade Maven parent project version,Set the parent pom version number according to a [version selector](https://docs.openrewrite.org/reference/dependency-version-selectors) or to a specific version number.,1,,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate 'org.springframework.boot:spring-boot-parent:VERSION'."",""example"":""org.springframework.boot"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate 'org.springframework.boot:spring-boot-parent:VERSION'."",""example"":""spring-boot-parent"",""required"":true},{""name"":""newVersion"",""type"":""String"",""displayName"":""New version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""29.X"",""required"":true},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""},{""name"":""onlyExternal"",""type"":""Boolean"",""displayName"":""Only external"",""description"":""Only upgrade `` if external to the project, i.e. it has an empty ``. Defaults to `false`.""}]", maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UpgradeTransitiveDependencyVersion,Upgrade transitive Maven dependencies,"Upgrades the version of a transitive dependency in a Maven pom file. Leaves direct dependencies unmodified. Can be paired with the regular Upgrade Dependency Version recipe to upgrade a dependency everywhere, regardless of whether it is direct or transitive.",1,,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate 'org.apache.logging.log4j:ARTIFACT_ID:VERSION'."",""example"":""org.apache.logging.log4j"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate 'org.apache.logging.log4j:log4j-bom:VERSION'."",""example"":""log4j-bom"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""latest.release"",""required"":true},{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""An optional scope to use for the dependency management tag."",""example"":""import"",""valid"":[""import"",""runtime"",""provided"",""test""]},{""name"":""type"",""type"":""String"",""displayName"":""Type"",""description"":""An optional type to use for the dependency management tag."",""example"":""pom"",""valid"":[""jar"",""pom"",""war""]},{""name"":""classifier"",""type"":""String"",""displayName"":""Classifier"",""description"":""An optional classifier to use for the dependency management tag"",""example"":""test""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select 29.0-jre"",""example"":""-jre""},{""name"":""releasesOnly"",""type"":""Boolean"",""displayName"":""Releases only"",""description"":""Whether to exclude snapshots from consideration when using a semver selector""},{""name"":""onlyIfUsing"",""type"":""String"",""displayName"":""Only if using glob expression for group:artifact"",""description"":""Only add managed dependencies to projects having a dependency matching the expression."",""example"":""org.apache.logging.log4j:log4j*""},{""name"":""addToRootPom"",""type"":""Boolean"",""displayName"":""Add to the root pom"",""description"":""Add to the root pom where root is the eldest parent of the pom within the source set.""},{""name"":""because"",""type"":""String"",""displayName"":""Because"",""description"":""The reason for upgrading the transitive dependency. This will be added as an XML comment preceding the managed dependency."",""example"":""CVE-2021-1234""}]","[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" -maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.BestPractices,Apache Maven best practices,Applies best practices to Maven POMs.,18,,Maven,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" +maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.UseMavenCompilerPluginReleaseConfiguration,Use Maven compiler plugin release configuration,"Replaces any explicit `source` or `target` configuration (if present) on the `maven-compiler-plugin` with `release`, and updates the `release` value if needed. When `testSource` or `testTarget` differ from the main version, introduces `testRelease`. Will not downgrade the Java version if the current version is higher. Also removes stale `maven.compiler.source`, `maven.compiler.target`, `maven.compiler.testSource`, and `maven.compiler.testTarget` properties that are no longer referenced.",1,,Maven,"[{""name"":""releaseVersion"",""type"":""Integer"",""displayName"":""Release version"",""description"":""The new value for the release configuration. This recipe prefers ${java.version} if defined."",""example"":""11"",""required"":true}]", +maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.BestPractices,Apache Maven best practices,Applies best practices to Maven POMs.,21,,Maven,,"[{""name"":""org.openrewrite.maven.table.MavenMetadataFailures"",""displayName"":""Maven metadata failures"",""instanceName"":""Maven metadata failures"",""description"":""Attempts to resolve maven metadata that failed."",""columns"":[{""name"":""group"",""type"":""String"",""displayName"":""Group id"",""description"":""The groupId of the artifact for which the metadata download failed.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact id"",""description"":""The artifactId of the artifact for which the metadata download failed.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The version of the artifact for which the metadata download failed.""},{""name"":""mavenRepositoryUri"",""type"":""String"",""displayName"":""Maven repository"",""description"":""The URL of the Maven repository that the metadata download failed on.""},{""name"":""snapshots"",""type"":""String"",""displayName"":""Snapshots"",""description"":""Does the repository support snapshots.""},{""name"":""releases"",""type"":""String"",""displayName"":""Releases"",""description"":""Does the repository support releases.""},{""name"":""failure"",""type"":""String"",""displayName"":""Failure"",""description"":""The reason the metadata download failed.""}]}]" maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.MigrateToMaven4,Migrate to Maven 4,"Migrates Maven POMs from Maven 3 to Maven 4, addressing breaking changes and deprecations. This recipe updates property expressions, lifecycle phases, removes duplicate plugin declarations, and replaces removed properties to ensure compatibility with Maven 4.",27,,Maven,, maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.ReplaceRemovedRootDirectoryProperties,Replace removed root directory properties,Maven 4 removed support for deprecated root directory properties. This recipe replaces `${executionRootDirectory}` with `${session.rootDirectory}` and `${multiModuleProjectDirectory}` with `${project.rootDirectory}`.,3,,Maven,, maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.ReplaceDeprecatedLifecyclePhases,Replace deprecated lifecycle phases,"Maven 4 deprecated all `pre-*` and `post-*` lifecycle phases in favor of the `before:` and `after:` syntax. This recipe updates plugin phase declarations to use the new syntax, including `pre-clean` → `before:clean`, `pre-site` → `before:site`, `pre-integration-test` → `before:integration-test`, and their `post-*` equivalents.",7,,Maven,, @@ -85,7 +85,7 @@ maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.DoesNotIncludeD maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.EffectiveDependencies,Effective dependencies,Emit the data of binary dependency relationships.,1,Search,Maven,"[{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""Match dependencies with the specified scope"",""example"":""compile"",""valid"":[""compile"",""test"",""runtime"",""provided""],""required"":true}]","[{""name"":""org.openrewrite.maven.table.DependencyGraph"",""displayName"":""Dependency graph"",""instanceName"":""Dependency graph"",""description"":""Relationships between dependencies."",""columns"":[{""name"":""projectName"",""type"":""String"",""displayName"":""Project name"",""description"":""The name of the project that contains the dependency.""},{""name"":""sourceSet"",""type"":""String"",""displayName"":""Source set"",""description"":""The source set that contains the dependency.""},{""name"":""from"",""type"":""String"",""displayName"":""From dependency"",""description"":""What depends on the 'to' dependency.""},{""name"":""to"",""type"":""String"",""displayName"":""From dependency"",""description"":""A dependency.""}]}]" maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.EffectiveManagedDependencies,Effective managed dependencies,Emit the data of binary dependency relationships.,1,Search,Maven,,"[{""name"":""org.openrewrite.maven.table.ManagedDependencyGraph"",""displayName"":""Managed dependency graph"",""instanceName"":""Managed dependency graph"",""description"":""Relationships between POMs and their ancestors that define managed dependencies."",""columns"":[{""name"":""from"",""type"":""String"",""displayName"":""From dependency"",""description"":""What depends on the 'to' dependency.""},{""name"":""to"",""type"":""String"",""displayName"":""From dependency"",""description"":""A dependency.""}]}]" maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.EffectiveMavenRepositories,List effective Maven repositories,"Lists the Maven repositories that would be used for dependency resolution, in order of precedence. This includes Maven repositories defined in the Maven settings file (and those contributed by active profiles) as determined when the LST was produced.",1,Search,Maven,"[{""name"":""useMarkers"",""type"":""Boolean"",""displayName"":""Use markers"",""description"":""Whether to add markers for each effective Maven repository to the POM. Default `false`.""}]","[{""name"":""org.openrewrite.maven.search.EffectiveMavenRepositoriesTable"",""displayName"":""Effective Maven repositories"",""instanceName"":""Effective Maven repositories"",""description"":""Table showing which Maven repositories were used in dependency resolution for this POM."",""columns"":[{""name"":""pomPath"",""type"":""String"",""displayName"":""POM path"",""description"":""The path to the POM file.""},{""name"":""repositoryUri"",""type"":""String"",""displayName"":""Repository URI"",""description"":""The URI of the Maven repository.""}]}]" -maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.FindDependency,Find Maven dependency,"Finds first-order dependency uses, i.e. dependencies that are defined directly in a project.",1,Search,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""guava"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""3.0.0""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""}]", +maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.FindDependency,Find Maven dependency,"Finds first-order dependency uses, i.e. dependencies that are defined directly in a project. Each match is also recorded as a row in the `DependenciesDeclared` data table.",1,Search,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""guava"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""3.0.0""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""}]","[{""name"":""org.openrewrite.maven.table.DependenciesDeclared"",""displayName"":""Dependencies declared"",""instanceName"":""Dependencies declared"",""description"":""Direct (first-order) dependencies declared by the project."",""columns"":[{""name"":""projectName"",""type"":""String"",""displayName"":""Project name"",""description"":""The name of the project that contains the dependency.""},{""name"":""sourceSet"",""type"":""String"",""displayName"":""Source set"",""description"":""The source set that contains the dependency.""},{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The resolved version.""},{""name"":""datedSnapshotVersion"",""type"":""String"",""displayName"":""Dated snapshot version"",""description"":""The resolved dated snapshot version or `null` if this dependency is not a snapshot.""},{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""Maven scope (e.g. `compile`, `test`) or Gradle configuration name (e.g. `implementation`, `testImplementation`). For Maven, defaults to `compile` when no scope is declared.""}]}]" maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.FindManagedDependency,Find Maven dependency management entry,"Finds first-order dependency management entries, i.e. dependencies that are defined directly in a project.",1,Search,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""guava"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""3.0.0""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""}]", maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.FindMavenProject,Find Maven projects,Maven projects are `pom.xml` files with a `MavenResolutionResult` marker.,1,Search,Maven,, maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.FindMavenSettings,Find effective maven settings,List the effective maven settings file for the current project.,1,Search,Maven,"[{""name"":""existenceCheckOnly"",""type"":""Boolean"",""displayName"":""Existence check only"",""description"":""Only record that a maven settings file exists; do not include its contents.""}]","[{""name"":""org.openrewrite.maven.table.EffectiveMavenSettings"",""displayName"":""Effective maven settings"",""instanceName"":""Effective maven settings"",""description"":""The maven settings file used by each pom."",""columns"":[{""name"":""pom"",""type"":""String"",""displayName"":""POM"",""description"":""The location of the `pom.xml`.""},{""name"":""mavenSettings"",""type"":""String"",""displayName"":""Maven settings"",""description"":""Effective maven settings.""}]}]" diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/search/FindDependencyTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/search/FindDependencyTest.java index 16aa57fe398..a7ec7f568a5 100644 --- a/rewrite-maven/src/test/java/org/openrewrite/maven/search/FindDependencyTest.java +++ b/rewrite-maven/src/test/java/org/openrewrite/maven/search/FindDependencyTest.java @@ -17,8 +17,10 @@ import org.junit.jupiter.api.Test; import org.openrewrite.DocumentExample; +import org.openrewrite.maven.table.DependenciesDeclared; import org.openrewrite.test.RewriteTest; +import static org.assertj.core.api.Assertions.assertThat; import static org.openrewrite.maven.Assertions.pomXml; class FindDependencyTest implements RewriteTest { @@ -334,4 +336,147 @@ void versionInProperties() { ) ); } + + @Test + void emitsDataTableRow() { + rewriteRun(spec -> spec.recipe(new FindDependency("jakarta.activation", "jakarta.activation-api", null, null)) + .dataTable(DependenciesDeclared.Row.class, rows -> { + assertThat(rows).hasSize(1); + DependenciesDeclared.Row row = rows.get(0); + assertThat(row.getGroupId()).isEqualTo("jakarta.activation"); + assertThat(row.getArtifactId()).isEqualTo("jakarta.activation-api"); + assertThat(row.getVersion()).isEqualTo("2.1.2"); + assertThat(row.getScope()).isEqualTo("compile"); + assertThat(row.getSourceSet()).isEqualTo("main"); + }), + pomXml( + """ + + 4.0.0 + org.sample + sample + 1.0.0 + + + jakarta.activation + jakarta.activation-api + 2.1.2 + + + + """, + """ + + 4.0.0 + org.sample + sample + 1.0.0 + + + jakarta.activation + jakarta.activation-api + 2.1.2 + + + + """ + ) + ); + } + + @Test + void declaredScopeRecordedInTable() { + rewriteRun(spec -> spec.recipe(new FindDependency("jakarta.activation", "jakarta.activation-api", null, null)) + .dataTable(DependenciesDeclared.Row.class, rows -> { + assertThat(rows).hasSize(1); + assertThat(rows.get(0).getScope()).isEqualTo("test"); + }), + pomXml( + """ + + 4.0.0 + org.sample + sample + 1.0.0 + + + jakarta.activation + jakarta.activation-api + 2.1.2 + test + + + + """, + """ + + 4.0.0 + org.sample + sample + 1.0.0 + + + jakarta.activation + jakarta.activation-api + 2.1.2 + test + + + + """ + ) + ); + } + + @Test + void rowOnlyEmittedForDeclaredCoordinate() { + rewriteRun(spec -> spec.recipe(new FindDependency("jakarta.activation", "jakarta.activation-api", null, null)) + .dataTable(DependenciesDeclared.Row.class, rows -> { + assertThat(rows).hasSize(1); + assertThat(rows.get(0).getArtifactId()).isEqualTo("jakarta.activation-api"); + }), + pomXml( + """ + + 4.0.0 + org.sample + sample + 1.0.0 + + + jakarta.activation + jakarta.activation-api + 2.1.2 + + + jakarta.servlet + jakarta.servlet-api + 6.0.0 + + + + """, + """ + + 4.0.0 + org.sample + sample + 1.0.0 + + + jakarta.activation + jakarta.activation-api + 2.1.2 + + + jakarta.servlet + jakarta.servlet-api + 6.0.0 + + + + """ + ) + ); + } } From a569cdcbb22ce41badcccfc38505f372242834a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Merlin=20B=C3=B6gershausen?= Date: Tue, 5 May 2026 09:38:44 +0200 Subject: [PATCH 2/2] Maven, Gradle: regenerate recipes.csv for FindDependency data table Re-applies the recipes.csv updates that were lost during the merge from main, so the catalog reflects the DependenciesDeclared data table now emitted by both FindDependency recipes. --- .../src/main/resources/META-INF/rewrite/recipes.csv | 4 ++-- rewrite-maven/src/main/resources/META-INF/rewrite/recipes.csv | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rewrite-gradle/src/main/resources/META-INF/rewrite/recipes.csv b/rewrite-gradle/src/main/resources/META-INF/rewrite/recipes.csv index 17e33567b8a..783eff21cd0 100644 --- a/rewrite-gradle/src/main/resources/META-INF/rewrite/recipes.csv +++ b/rewrite-gradle/src/main/resources/META-INF/rewrite/recipes.csv @@ -78,12 +78,12 @@ maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindGradlePro maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.EffectiveGradlePluginRepositories,List effective Gradle plugin repositories,"Lists the Gradle plugin repositories that would be used for plugin resolution, in order of precedence. This includes Maven repositories defined in the settings.gradle pluginManagement section and build.gradle buildscript repositories as determined when the LST was produced.",1,Search,Gradle,"[{""name"":""useMarkers"",""type"":""Boolean"",""displayName"":""Use markers"",""description"":""Whether to add markers for each effective Gradle plugin repository to the build or settings file. Default `false`.""}]","[{""name"":""org.openrewrite.maven.search.EffectiveMavenRepositoriesTable"",""displayName"":""Effective Maven repositories"",""instanceName"":""Effective Maven repositories"",""description"":""Table showing which Maven repositories were used in dependency resolution for this POM."",""columns"":[{""name"":""pomPath"",""type"":""String"",""displayName"":""POM path"",""description"":""The path to the POM file.""},{""name"":""repositoryUri"",""type"":""String"",""displayName"":""Repository URI"",""description"":""The URI of the Maven repository.""}]}]" maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindRepositoryOrder,Gradle repository order,Determine the order in which dependencies will be resolved for each `build.gradle` based on its defined repositories as determined when the LST was produced.,1,Search,Gradle,,"[{""name"":""org.openrewrite.maven.table.MavenRepositoryOrder"",""displayName"":""Maven repository order"",""instanceName"":""Maven repository order"",""description"":""The order in which dependencies will be resolved for each `pom.xml` based on its defined repositories and effective `settings.xml`."",""columns"":[{""name"":""id"",""type"":""String"",""displayName"":""Repository ID"",""description"":""The ID of the repository. Note that projects may define the same physical repository with different IDs.""},{""name"":""uri"",""type"":""String"",""displayName"":""Repository URI"",""description"":""The URI of the repository.""},{""name"":""knownToExist"",""type"":""boolean"",""displayName"":""Known to exist"",""description"":""If the repository is provably reachable. If false, does not guarantee that the repository does not exist.""},{""name"":""rank"",""type"":""int"",""displayName"":""Rank"",""description"":""The index order of this repository in the repository list.""}]}]" maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindRepository,Find Gradle repository,Find a Gradle repository by url.,1,Search,Gradle,"[{""name"":""type"",""type"":""String"",""displayName"":""Type"",""description"":""The type of the artifact repository"",""example"":""maven""},{""name"":""url"",""type"":""String"",""displayName"":""URL"",""description"":""The url of the artifact repository"",""example"":""https://repo.spring.io""},{""name"":""purpose"",""type"":""Purpose"",""displayName"":""Purpose"",""description"":""The purpose of this repository in terms of resolving project or plugin dependencies"",""valid"":[""Project"",""Plugin""]}]", -maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindDependency,Find Gradle dependency,"Finds dependencies declared in gradle build files. See the [reference](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph) on Gradle configurations or the diagram below for a description of what configuration to use. A project's compile and runtime classpath is based on these configurations. +maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindDependency,Find Gradle dependency,"Finds dependencies declared in gradle build files. Each match is also recorded as a row in the `DependenciesDeclared` data table. See the [reference](https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_configurations_graph) on Gradle configurations or the diagram below for a description of what configuration to use. A project's compile and runtime classpath is based on these configurations. A project's test classpath is based on these configurations. -.",1,Search,Gradle,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate identifying its publisher."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate uniquely identifying it among artifacts from the same publisher."",""example"":""guava"",""required"":true},{""name"":""configuration"",""type"":""String"",""displayName"":""Dependency configuration"",""description"":""The dependency configuration to search for dependencies in. If omitted then all configurations will be searched."",""example"":""api""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""3.0.0""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""}]", +.",1,Search,Gradle,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate identifying its publisher."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate uniquely identifying it among artifacts from the same publisher."",""example"":""guava"",""required"":true},{""name"":""configuration"",""type"":""String"",""displayName"":""Dependency configuration"",""description"":""The dependency configuration to search for dependencies in. If omitted then all configurations will be searched."",""example"":""api""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""3.0.0""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""}]","[{""name"":""org.openrewrite.maven.table.DependenciesDeclared"",""displayName"":""Dependencies declared"",""instanceName"":""Dependencies declared"",""description"":""Direct (first-order) dependencies declared by the project."",""columns"":[{""name"":""projectName"",""type"":""String"",""displayName"":""Project name"",""description"":""The name of the project that contains the dependency.""},{""name"":""sourceSet"",""type"":""String"",""displayName"":""Source set"",""description"":""The source set that contains the dependency.""},{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The resolved version.""},{""name"":""datedSnapshotVersion"",""type"":""String"",""displayName"":""Dated snapshot version"",""description"":""The resolved dated snapshot version or `null` if this dependency is not a snapshot.""},{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""Maven scope (e.g. `compile`, `test`) or Gradle configuration name (e.g. `implementation`, `testImplementation`). For Maven, defaults to `compile` when no scope is declared.""}]}]" maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.DependencyInsight,Gradle dependency insight,"Find direct and transitive dependencies matching a group, artifact, resolved version, and optionally a configuration name. Results include dependencies that either directly match or transitively include a matching dependency.",1,Search,Gradle,"[{""name"":""groupIdPattern"",""type"":""String"",""displayName"":""Group pattern"",""description"":""Group glob pattern used to match dependencies."",""example"":""com.fasterxml.jackson.module"",""required"":true},{""name"":""artifactIdPattern"",""type"":""String"",""displayName"":""Artifact pattern"",""description"":""Artifact glob pattern used to match dependencies."",""example"":""jackson-module-*"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""Match only dependencies with the specified resolved version. Node-style [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors) may be used.All versions are searched by default."",""example"":""1.x""},{""name"":""configuration"",""type"":""String"",""displayName"":""Scope"",""description"":""Match dependencies with the specified scope. If not specified, all configurations will be searched."",""example"":""compileClasspath""}]","[{""name"":""org.openrewrite.maven.table.DependenciesInUse"",""displayName"":""Dependencies in use"",""instanceName"":""Dependencies in use"",""description"":""Direct and transitive dependencies in use."",""columns"":[{""name"":""projectName"",""type"":""String"",""displayName"":""Project name"",""description"":""The name of the project that contains the dependency.""},{""name"":""sourceSet"",""type"":""String"",""displayName"":""Source set"",""description"":""The source set that contains the dependency.""},{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The resolved version.""},{""name"":""datedSnapshotVersion"",""type"":""String"",""displayName"":""Dated snapshot version"",""description"":""The resolved dated snapshot version or `null` if this dependency is not a snapshot.""},{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""Dependency scope. This will be `compile` if the dependency is direct and a scope is not explicitly specified in the POM.""},{""name"":""count"",""type"":""Integer"",""displayName"":""Count"",""description"":""How many times does this dependency appear.""}]},{""name"":""org.openrewrite.maven.table.ExplainDependenciesInUse"",""displayName"":""Explain dependencies in use"",""instanceName"":""Explain dependencies in use"",""description"":""A dependency graph explainer similar to that shown by `gradle dependencyInsight` for each matching dependency. This table will contain a row per matching dependency per configuration per (sub)project."",""columns"":[{""name"":""projectName"",""type"":""String"",""displayName"":""Project name"",""description"":""The name of the project that contains the dependency.""},{""name"":""sourceSet"",""type"":""String"",""displayName"":""Source set"",""description"":""The source set that contains the dependency.""},{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The resolved version.""},{""name"":""datedSnapshotVersion"",""type"":""String"",""displayName"":""Dated snapshot version"",""description"":""The resolved dated snapshot version or `null` if this dependency is not a snapshot.""},{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""Dependency scope. This will be `compile` if the dependency is direct and a scope is not explicitly specified in the POM.""},{""name"":""count"",""type"":""Integer"",""displayName"":""Count"",""description"":""How many times does this dependency appear.""},{""name"":""dependencyGraph"",""type"":""String"",""displayName"":""Dependency graph"",""description"":""The dependency paths that requested the dependency.""}]}]" maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.ModuleHasPlugin,Module has plugin,"Searches for Gradle Projects (modules) that have a plugin matching the specified id or implementing class. Places a `SearchResult` marker on all sources within a project with a matching plugin. This recipe is intended to be used as a precondition for other recipes. For example this could be used to limit the application of a spring boot migration to only projects that apply the spring dependency management plugin, limiting unnecessary upgrading. If the search result you want is instead just the build.gradle(.kts) file applying the plugin, use the `FindPlugins` recipe instead.",1,Search,Gradle,"[{""name"":""pluginId"",""type"":""String"",""displayName"":""Plugin id"",""description"":""The unique identifier used to apply a plugin in the `plugins` block. Note that this alone is insufficient to search for plugins applied by fully qualified class name and the `buildscript` block."",""example"":""`com.jfrog.bintray`"",""required"":true},{""name"":""pluginClass"",""type"":""String"",""displayName"":""Plugin class"",""description"":""The fully qualified name of a class implementing a Gradle plugin. "",""example"":""com.jfrog.bintray.gradle.BintrayPlugin""}]", maven,org.openrewrite:rewrite-gradle,org.openrewrite.gradle.search.FindGradleWrapper,Find Gradle wrappers,Find Gradle wrappers.,1,Search,Gradle,"[{""name"":""version"",""type"":""String"",""displayName"":""Version expression"",""description"":""A version expression representing the versions to search for"",""example"":""7.x""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""},{""name"":""distribution"",""type"":""String"",""displayName"":""Distribution type"",""description"":""The distribution of Gradle to find. \""bin\"" includes Gradle binaries. \""all\"" includes Gradle binaries, source code, and documentation."",""valid"":[""bin"",""all""]}]","[{""name"":""org.openrewrite.gradle.table.GradleWrappersInUse"",""displayName"":""Gradle wrappers in use"",""instanceName"":""Gradle wrappers in use"",""description"":""Gradle wrappers in use."",""columns"":[{""name"":""version"",""type"":""String"",""displayName"":""Wrapper version"",""description"":""The version of the Gradle wrapper in use.""},{""name"":""distribution"",""type"":""String"",""displayName"":""Wrapper distribution"",""description"":""The distribution type of the Gradle wrapper in use.""}]}]" diff --git a/rewrite-maven/src/main/resources/META-INF/rewrite/recipes.csv b/rewrite-maven/src/main/resources/META-INF/rewrite/recipes.csv index 356f75c729e..416220af27f 100644 --- a/rewrite-maven/src/main/resources/META-INF/rewrite/recipes.csv +++ b/rewrite-maven/src/main/resources/META-INF/rewrite/recipes.csv @@ -82,7 +82,7 @@ maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.cleanup.ExplicitPlugin maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.cleanup.AddProjectBuildOutputTimestamp,Add `project.build.outputTimestamp` for reproducible builds,"Adds the `project.build.outputTimestamp` property, which Maven uses to make build outputs reproducible by stamping archive entries with a fixed timestamp instead of the current time. An existing value is preserved. See [Configuring for Reproducible Builds](https://maven.apache.org/guides/mini/guide-reproducible-builds.html).",2,Cleanup,Maven,"[{""name"":""timestamp"",""type"":""String"",""displayName"":""Timestamp"",""description"":""ISO 8601 timestamp, integer seconds since the epoch, or property reference such as `${git.commit.author.time}`. Defaults to `1980-01-01T00:00:00Z`, the earliest value the ZIP format can represent."",""example"":""2024-01-01T00:00:00Z""}]", maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.cleanup.PrefixlessExpressions,Drop prefixless expressions in POM,MNG-7404 drops support for prefixless in POMs. This recipe will add the `project.` prefix where missing.,7,Cleanup,Maven,, maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.plugin.DependencyPluginGoalResolveSources,Migrate to `maven-dependency-plugin` goal `resolve-sources`,Migrate from `sources` to `resolve-sources` for the `maven-dependency-plugin`.,1,Plugin,Maven,, -maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.FindDependency,Find Maven dependency,"Finds first-order dependency uses, i.e. dependencies that are defined directly in a project.",1,Search,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""guava"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""3.0.0""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""}]", +maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.FindDependency,Find Maven dependency,"Finds first-order dependency uses, i.e. dependencies that are defined directly in a project. Each match is also recorded as a row in the `DependenciesDeclared` data table.",1,Search,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""guava"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""An exact version number or node-style semver selector used to select the version number."",""example"":""3.0.0""},{""name"":""versionPattern"",""type"":""String"",""displayName"":""Version pattern"",""description"":""Allows version selection to be extended beyond the original Node Semver semantics. So for example,Setting 'version' to \""25-29\"" can be paired with a metadata pattern of \""-jre\"" to select Guava 29.0-jre"",""example"":""-jre""}]","[{""name"":""org.openrewrite.maven.table.DependenciesDeclared"",""displayName"":""Dependencies declared"",""instanceName"":""Dependencies declared"",""description"":""Direct (first-order) dependencies declared by the project."",""columns"":[{""name"":""projectName"",""type"":""String"",""displayName"":""Project name"",""description"":""The name of the project that contains the dependency.""},{""name"":""sourceSet"",""type"":""String"",""displayName"":""Source set"",""description"":""The source set that contains the dependency.""},{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`.""},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""The resolved version.""},{""name"":""datedSnapshotVersion"",""type"":""String"",""displayName"":""Dated snapshot version"",""description"":""The resolved dated snapshot version or `null` if this dependency is not a snapshot.""},{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""Maven scope (e.g. `compile`, `test`) or Gradle configuration name (e.g. `implementation`, `testImplementation`). For Maven, defaults to `compile` when no scope is declared.""}]}]" maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.FindMavenProject,Find Maven projects,Maven projects are `pom.xml` files with a `MavenResolutionResult` marker.,1,Search,Maven,, maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.EffectiveDependencies,Effective dependencies,Emit the data of binary dependency relationships.,1,Search,Maven,"[{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""Match dependencies with the specified scope"",""example"":""compile"",""valid"":[""compile"",""test"",""runtime"",""provided""],""required"":true}]","[{""name"":""org.openrewrite.maven.table.DependencyGraph"",""displayName"":""Dependency graph"",""instanceName"":""Dependency graph"",""description"":""Relationships between dependencies."",""columns"":[{""name"":""projectName"",""type"":""String"",""displayName"":""Project name"",""description"":""The name of the project that contains the dependency.""},{""name"":""sourceSet"",""type"":""String"",""displayName"":""Source set"",""description"":""The source set that contains the dependency.""},{""name"":""from"",""type"":""String"",""displayName"":""From dependency"",""description"":""What depends on the 'to' dependency.""},{""name"":""to"",""type"":""String"",""displayName"":""From dependency"",""description"":""A dependency.""}]}]" maven,org.openrewrite:rewrite-maven,org.openrewrite.maven.search.DoesNotIncludeDependency,Does not include Maven dependency,"A precondition which returns false if visiting a Maven pom which includes the specified dependency in the classpath of some scope. For compatibility with multimodule projects, this should most often be applied as a precondition.",1,Search,Maven,"[{""name"":""groupId"",""type"":""String"",""displayName"":""Group"",""description"":""The first part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""com.google.guava"",""required"":true},{""name"":""artifactId"",""type"":""String"",""displayName"":""Artifact"",""description"":""The second part of a dependency coordinate `com.google.guava:guava:VERSION`. Supports glob."",""example"":""guava"",""required"":true},{""name"":""version"",""type"":""String"",""displayName"":""Version"",""description"":""Match only dependencies with the specified version. Node-style [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors) may be used. All versions are searched by default."",""example"":""1.x""},{""name"":""onlyDirect"",""type"":""Boolean"",""displayName"":""Only direct dependencies"",""description"":""Default false. If enabled, transitive dependencies will not be considered."",""example"":""true""},{""name"":""scope"",""type"":""String"",""displayName"":""Scope"",""description"":""Default any. If specified, only the requested scope's classpaths will be checked."",""example"":""compile"",""valid"":[""compile"",""test"",""runtime"",""provided""]}]",