diff --git a/src/main/java/org/openrewrite/java/dependencies/UpgradeDependencyVersion.java b/src/main/java/org/openrewrite/java/dependencies/UpgradeDependencyVersion.java index 7ad3f59..baf99fd 100644 --- a/src/main/java/org/openrewrite/java/dependencies/UpgradeDependencyVersion.java +++ b/src/main/java/org/openrewrite/java/dependencies/UpgradeDependencyVersion.java @@ -24,7 +24,7 @@ import java.util.Arrays; import java.util.List; - +import java.util.Objects; @Getter @@ -88,14 +88,20 @@ public String getDescription() { } @Nullable - private org.openrewrite.gradle.UpgradeDependencyVersion upgradeGradleDependencyVersion; + private transient org.openrewrite.gradle.UpgradeDependencyVersion upgradeGradleDependencyVersion; @Nullable - private org.openrewrite.maven.UpgradeDependencyVersion upgradeMavenDependencyVersion; + private transient org.openrewrite.maven.UpgradeDependencyVersion upgradeMavenDependencyVersion; @Override public List getRecipeList() { - if (upgradeGradleDependencyVersion == null && upgradeMavenDependencyVersion == null) { + // Checking if the fields have been updated externally via reflection, so we need to update the child recipes + if (upgradeGradleDependencyVersion == null || + !Objects.equals(upgradeGradleDependencyVersion.getGroupId(), groupId) || + !Objects.equals(upgradeGradleDependencyVersion.getArtifactId(), artifactId) || + !Objects.equals(upgradeGradleDependencyVersion.getNewVersion(), newVersion) || + !Objects.equals(upgradeGradleDependencyVersion.getVersionPattern(), versionPattern) + ) { upgradeGradleDependencyVersion = new org.openrewrite.gradle.UpgradeDependencyVersion(groupId, artifactId, newVersion, versionPattern); upgradeMavenDependencyVersion = new org.openrewrite.maven.UpgradeDependencyVersion(groupId, artifactId, newVersion, versionPattern, overrideManagedVersion, retainVersions); } diff --git a/src/test/java/org/openrewrite/java/dependencies/UpgradeDependencyVersionTest.java b/src/test/java/org/openrewrite/java/dependencies/UpgradeDependencyVersionTest.java index 38430e7..9557023 100644 --- a/src/test/java/org/openrewrite/java/dependencies/UpgradeDependencyVersionTest.java +++ b/src/test/java/org/openrewrite/java/dependencies/UpgradeDependencyVersionTest.java @@ -16,13 +16,22 @@ package org.openrewrite.java.dependencies; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; import org.junit.jupiter.api.Test; import org.openrewrite.DocumentExample; +import org.openrewrite.config.RecipeDescriptor; import org.openrewrite.gradle.marker.GradleDependencyConfiguration; import org.openrewrite.gradle.marker.GradleProject; -import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; @@ -138,4 +147,106 @@ void updateManagedDependencyVersion() { ) ); } + + /** + * This test emulates how recipes are instantiated from the SaaS, build plugins or the CLI using Jackson and later on their parameters populated via reflection with + * jackson. This causes that some care has to be taken in this recipe when instantiating the child recipes, since the + * constructor parameters and fields of the class might not be correct (or final) when some methods are called during + * instantiation or validation. + */ + @Test + void testRecipeInstantiation() throws JsonMappingException { + // We instantiate the recipe with default values. + UpgradeDependencyVersion recipe = new UpgradeDependencyVersion("", "", "", null, null, null); + + // We get the RecipeDescriptor (internally calls getRecipeList). + RecipeDescriptor recipeDescriptor = recipe.getDescriptor(); + assertThat(recipeDescriptor.getRecipeList().size()).isEqualTo(2); + + // This is a similar ObjectMapper than the one used to set up recipes + ObjectMapper mapper = JsonMapper.builder() + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT) + .build() + .registerModule(new ParameterNamesModule()) + .registerModule(new JavaTimeModule()); + + // New parameters to update the recipe + Map parameters = new HashMap<>(); + parameters.put("groupId", "org.openrewrite.recipe"); + parameters.put("artifactId", "rewrite-java-dependencies"); + parameters.put("newVersion", "1.0.4"); + + UpgradeDependencyVersion updatedRecipe = mapper.updateValue(recipe, parameters); + + // We check that it's the same instance that is being updated + assertThat(updatedRecipe).isSameAs(recipe); + + // We then run the recipe with maven and gradle projects. + rewriteRun( + spec -> { + spec.recipe(updatedRecipe); + spec.beforeRecipe(withToolingApi()); + }, + pomXml( + """ + + com.mycompany.app + my-app + 1 + + + org.openrewrite.recipe + rewrite-java-dependencies + 1.0.0 + + + + """, + """ + + com.mycompany.app + my-app + 1 + + + org.openrewrite.recipe + rewrite-java-dependencies + 1.0.4 + + + + """ + ), + buildGradle( + """ + plugins { + id 'java-library' + } + + repositories { + mavenCentral() + } + + dependencies { + compileOnly 'org.openrewrite.recipe:rewrite-java-dependencies:1.0.0' + } + """, + """ + plugins { + id 'java-library' + } + + repositories { + mavenCentral() + } + + dependencies { + compileOnly 'org.openrewrite.recipe:rewrite-java-dependencies:1.0.4' + } + """ + ) + ); + } }