From 147c7effda5b9ef521ca6d8a341fde69d9881c56 Mon Sep 17 00:00:00 2001 From: Chris Salch Date: Fri, 22 Nov 2024 00:09:06 -0600 Subject: [PATCH] Simplify Plugins approach to adding dependencies so that it no longer uses a hidden detached configuration. (#345) * Attempt to simplify the rewrite deps. * Setup the the dependencies early using withDependencies * Use addAllLater to add dependencies. * Fix version vs newVersion parameter name. * Switch to addLater to continue supporting Gradle 4. * Use `beforeResolve` to allow version setting. With the `addLater` approach that was previously attempted the dependency strings were generated early. This would prevent users from being able to set the rewrite version in their build file. Using `beforeResolve` allows us to delay until just before resolution. --- .../org/openrewrite/gradle/RewritePlugin.java | 81 +++++++++++-------- .../org/openrewrite/gradle/RewriteRunTest.kt | 2 +- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/plugin/src/main/java/org/openrewrite/gradle/RewritePlugin.java b/plugin/src/main/java/org/openrewrite/gradle/RewritePlugin.java index fa20b3d00..4bc74617f 100644 --- a/plugin/src/main/java/org/openrewrite/gradle/RewritePlugin.java +++ b/plugin/src/main/java/org/openrewrite/gradle/RewritePlugin.java @@ -20,6 +20,7 @@ import org.gradle.api.Task; import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Dependency; +import org.gradle.api.artifacts.DependencySet; import org.gradle.api.artifacts.dsl.DependencyHandler; import org.gradle.api.attributes.*; import org.gradle.api.attributes.java.TargetJvmEnvironment; @@ -37,7 +38,9 @@ import java.io.File; import java.util.Comparator; import java.util.HashSet; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import java.util.stream.Stream; import static org.gradle.api.attributes.Bundling.BUNDLING_ATTRIBUTE; @@ -70,8 +73,43 @@ public void apply(Project project) { // Rewrite module dependencies put here will be available to all rewrite tasks Configuration rewriteConf = project.getConfigurations().maybeCreate("rewrite"); + // Defer actually evaluating the dependencies until resolution is triggered. This should allow + // the user to set the rewrite version in the extension. `addLater` doesn't work here because + // it operates on a single dependency at a time. + rewriteConf.getIncoming().beforeResolve(conf -> { + rewriteConf.getDependencies().addAll( + knownRewriteDependencies(extension, project.getDependencies()) + ); + }); + + // Because of how this Gradle has no criteria with which to select between variants of + // dependencies which expose differing capabilities. So those must be manually configured + try { + final ObjectFactory objectFactory = project.getObjects(); + rewriteConf.attributes(attributes -> { + // Adapted from org.gradle.api.plugins.jvm.internal.DefaultJvmEcosystemAttributesDetails + attributes.attribute( + Category.CATEGORY_ATTRIBUTE, objectFactory.named(Category.class, Category.LIBRARY)); + attributes.attribute(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage.class, Usage.JAVA_RUNTIME)); + attributes.attribute( + LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, + objectFactory.named(LibraryElements.class, LibraryElements.JAR)); + attributes.attribute(BUNDLING_ATTRIBUTE, objectFactory.named(Bundling.class, Bundling.EXTERNAL)); + try { + attributes.attribute( + TARGET_JVM_ENVIRONMENT_ATTRIBUTE, + objectFactory.named(TargetJvmEnvironment.class, TargetJvmEnvironment.STANDARD_JVM)); + } catch (final NoClassDefFoundError ex) { + // Old versions of Gradle don't have the class TargetJvmEnvironment and that's OK, we can always + // try this attribute instead + attributes.attribute(Attribute.of("org.gradle.jvm.environment", String.class), "standard-jvm"); + } + }); + } catch (final NoClassDefFoundError ex) { + // Old versions of Gradle don't have all of these attributes and that's OK + } - Provider> resolvedDependenciesProvider = project.provider(() -> getResolvedDependencies(project, extension, rewriteConf)); + Provider> resolvedDependenciesProvider = project.provider(() -> getResolvedDependencies(rewriteConf)); TaskProvider rewriteRun = project.getTasks().register("rewriteRun", RewriteRunTask.class, task -> { task.setExtension(extension); @@ -153,43 +191,16 @@ private static void configureProject(Project project, RewriteExtension extension }); } - private Set getResolvedDependencies(Project project, RewriteExtension extension, Configuration rewriteConf) { - if (resolvedDependencies == null) { - Dependency[] dependencies = Stream.concat( - knownRewriteDependencies(extension, project.getDependencies()), - rewriteConf.getDependencies().stream() - ).toArray(Dependency[]::new); - // By using a detached configuration, we separate this dependency resolution from the rest of the project's - // configuration. This also means that Gradle has no criteria with which to select between variants of - // dependencies which expose differing capabilities. So those must be manually configured - Configuration detachedConf = project.getConfigurations().detachedConfiguration(dependencies); - - try { - ObjectFactory objectFactory = project.getObjects(); - detachedConf.attributes(attributes -> { - // Adapted from org.gradle.api.plugins.jvm.internal.DefaultJvmEcosystemAttributesDetails - attributes.attribute(Category.CATEGORY_ATTRIBUTE, objectFactory.named(Category.class, Category.LIBRARY)); - attributes.attribute(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage.class, Usage.JAVA_RUNTIME)); - attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objectFactory.named(LibraryElements.class, LibraryElements.JAR)); - attributes.attribute(BUNDLING_ATTRIBUTE, objectFactory.named(Bundling.class, Bundling.EXTERNAL)); - try { - attributes.attribute(TARGET_JVM_ENVIRONMENT_ATTRIBUTE, objectFactory.named(TargetJvmEnvironment.class, TargetJvmEnvironment.STANDARD_JVM)); - } catch (NoClassDefFoundError e) { - // Old versions of Gradle don't have the class TargetJvmEnvironment and that's OK, we can always - // try this attribute instead - attributes.attribute(Attribute.of("org.gradle.jvm.environment", String.class), "standard-jvm"); - } - }); - } catch (NoClassDefFoundError e) { - // Old versions of Gradle don't have all of these attributes and that's OK - } - - resolvedDependencies = detachedConf.resolve(); + private Set getResolvedDependencies(Configuration rewriteConf) { + if (resolvedDependencies != null) { + return resolvedDependencies; } + + resolvedDependencies = rewriteConf.resolve(); return resolvedDependencies; } - private static Stream knownRewriteDependencies(RewriteExtension extension, DependencyHandler deps) { + private static List knownRewriteDependencies(RewriteExtension extension, DependencyHandler deps) { String rewriteVersion = extension.getRewriteVersion(); return Stream.of( deps.create("org.openrewrite:rewrite-core:" + rewriteVersion), @@ -212,6 +223,6 @@ private static Stream knownRewriteDependencies(RewriteExtension exte deps.create("org.openrewrite.gradle.tooling:model:" + extension.getRewriteGradleModelVersion()), deps.create("com.fasterxml.jackson.module:jackson-module-kotlin:" + extension.getJacksonModuleKotlinVersion()), deps.create("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:" + extension.getJacksonModuleKotlinVersion()) - ); + ).collect(Collectors.toList()); } } diff --git a/plugin/src/test/kotlin/org/openrewrite/gradle/RewriteRunTest.kt b/plugin/src/test/kotlin/org/openrewrite/gradle/RewriteRunTest.kt index d9f66c3ca..c86b4241a 100644 --- a/plugin/src/test/kotlin/org/openrewrite/gradle/RewriteRunTest.kt +++ b/plugin/src/test/kotlin/org/openrewrite/gradle/RewriteRunTest.kt @@ -1452,7 +1452,7 @@ class RewriteRunTest : RewritePluginTest { - org.openrewrite.gradle.UpgradeDependencyVersion: groupId: com.fasterxml.jackson.core artifactId: jackson-databind - version: 2.18.0 + newVersion: 2.18.0 """) buildGradle(""" plugins {