From 598d7cd340efdb83310832b9cad53e606773a372 Mon Sep 17 00:00:00 2001 From: Simon Verhoeven Date: Fri, 24 Nov 2023 16:25:22 +0100 Subject: [PATCH] feature: ArchUnit 0.x to 1.x migration (#432) * feature: ArchUnit 0.x to 1.x migration Resolves #431 * feat: add testcases for ArchUnit 0 to 1 migration * Minor test fixes * Upgrade any ArchUnit dependency --------- Co-authored-by: Tim te Beek --- build.gradle.kts | 2 + .../resources/META-INF/rewrite/archunit.yml | 49 +++ .../archunit/ArchUnit0To1MigrationTest.java | 327 ++++++++++++++++++ 3 files changed, 378 insertions(+) create mode 100644 src/main/resources/META-INF/rewrite/archunit.yml create mode 100644 src/test/java/org/openrewrite/java/testing/archunit/ArchUnit0To1MigrationTest.java diff --git a/build.gradle.kts b/build.gradle.kts index 5c9e144b4..946c1a97f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -44,6 +44,8 @@ dependencies { testRuntimeOnly("org.gradle:gradle-tooling-api:latest.release") + testRuntimeOnly("com.tngtech.archunit:archunit:0.23.1") + // testImplementation("org.hamcrest:hamcrest:latest.release") // testImplementation("org.assertj:assertj-core:latest.release") } diff --git a/src/main/resources/META-INF/rewrite/archunit.yml b/src/main/resources/META-INF/rewrite/archunit.yml new file mode 100644 index 000000000..0fe3dc14e --- /dev/null +++ b/src/main/resources/META-INF/rewrite/archunit.yml @@ -0,0 +1,49 @@ +# +# Copyright 2023 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. +# +--- +type: specs.openrewrite.org/v1beta/recipe +name: org.openrewrite.java.testing.archunit.ArchUnit0to1Migration +displayName: ArchUnit 0.x upgrade +description: Upgrade ArchUnit from 0.x to 1.x. +recipeList: + - org.openrewrite.java.dependencies.UpgradeDependencyVersion: + groupId: com.tngtech.archunit + artifactId: archunit* + newVersion: 1.x + - org.openrewrite.java.ChangeMethodName: + methodPattern: com.tngtech.archunit.core.domain.JavaPackage getAllClasses() + newMethodName: getClassesInPackageTree + - org.openrewrite.java.ChangeMethodName: + methodPattern: com.tngtech.archunit.core.domain.JavaPackage getAllSubpackages() + newMethodName: getSubpackagesInTree + - org.openrewrite.java.ChangeMethodName: + methodPattern: com.tngtech.archunit.core.domain.JavaPackage getClassDependenciesFromSelf() + newMethodName: getClassDependenciesFromThisPackageTree + - org.openrewrite.java.ChangeMethodName: + methodPattern: com.tngtech.archunit.core.domain.JavaPackage getClassDependenciesToSelf() + newMethodName: getClassDependenciesToThisPackageTree + - org.openrewrite.java.ChangeMethodName: + methodPattern: com.tngtech.archunit.core.domain.JavaPackage getPackageDependenciesFromSelf() + newMethodName: getPackageDependenciesFromThisPackageTree + - org.openrewrite.java.ChangeMethodName: + methodPattern: com.tngtech.archunit.core.domain.JavaPackage getPackageDependenciesToSelf() + newMethodName: getPackageDependenciesToThisPackageTree + - org.openrewrite.java.ChangeMethodName: + methodPattern: com.tngtech.archunit.core.domain.JavaPackage accept(..) + newMethodName: traversePackageTree + - org.openrewrite.java.ChangePackage: + oldPackageName: com.tngtech.archunit.library.plantuml + newPackageName: com.tngtech.archunit.library.plantuml.rules diff --git a/src/test/java/org/openrewrite/java/testing/archunit/ArchUnit0To1MigrationTest.java b/src/test/java/org/openrewrite/java/testing/archunit/ArchUnit0To1MigrationTest.java new file mode 100644 index 000000000..726993091 --- /dev/null +++ b/src/test/java/org/openrewrite/java/testing/archunit/ArchUnit0To1MigrationTest.java @@ -0,0 +1,327 @@ +/* + * Copyright 2023 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.java.testing.archunit; + +import org.junit.jupiter.api.Test; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.openrewrite.java.Assertions.java; +import static org.openrewrite.java.Assertions.mavenProject; +import static org.openrewrite.maven.Assertions.pomXml; + +class ArchUnit0To1MigrationTest implements RewriteTest { + @Override + public void defaults(RecipeSpec spec) { + spec + .parser(JavaParser.fromJavaVersion().classpath("archunit-0.23.1")) + .recipeFromResource("/META-INF/rewrite/archunit.yml", "org.openrewrite.java.testing.archunit.ArchUnit0to1Migration"); + } + + @Test + void shouldMigrateMavenDependency() { + rewriteRun( + mavenProject("project", + //language=xml + pomXml( + """ + + 4.0.0 + com.example + demo + 0.0.1-SNAPSHOT + + + com.tngtech.archunit + archunit-junit5 + 0.23.1 + test + + + + """, + spec -> spec.after(pom -> { + Matcher matcher = Pattern.compile("(1\\..+)").matcher(pom); + matcher.find(); + String version = matcher.group(1); + return """ + + 4.0.0 + com.example + demo + 0.0.1-SNAPSHOT + + + com.tngtech.archunit + archunit-junit5 + %s + test + + + + """.formatted(version); + }) + ) + ) + ); + } + + @Test + void shouldUseGetClassesInPackageTree() { + //language=java + rewriteRun( + java( + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.JavaClass; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getAllClasses(); + } + } + """, + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.JavaClass; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getClassesInPackageTree(); + } + } + """ + ) + ); + } + + @Test + void shouldUseGetSubpackagesInTree() { + //language=java + rewriteRun( + java( + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.JavaClass; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getAllSubpackages(); + } + } + """, + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.JavaClass; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getSubpackagesInTree(); + } + } + """ + ) + ); + } + + @Test + void shouldUseGetClassDependenciesFromThisPackageTree() { + //language=java + rewriteRun( + java( + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.Dependency; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getClassDependenciesFromSelf(); + } + } + """, + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.Dependency; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getClassDependenciesFromThisPackageTree(); + } + } + """ + ) + ); + } + + @Test + void shouldUseGetClassDependenciesToThisPackageTree() { + //language=java + rewriteRun( + java( + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.Dependency; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getClassDependenciesToSelf(); + } + } + """, + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.Dependency; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getClassDependenciesToThisPackageTree(); + } + } + """ + ) + ); + } + + @Test + void shouldUseGetPackageDependenciesFromThisPackageTree() { + //language=java + rewriteRun( + java( + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.JavaPackage; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getPackageDependenciesFromSelf(); + } + } + """, + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.JavaPackage; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getPackageDependenciesFromThisPackageTree(); + } + } + """ + ) + ); + } + + @Test + void shouldUseGetPackageDependenciesToThisPackageTree() { + //language=java + rewriteRun( + java( + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.JavaPackage; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getPackageDependenciesToSelf(); + } + } + """, + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import java.util.Set; + import com.tngtech.archunit.core.domain.JavaPackage; + + public class ArchUnitTest { + public Set sample(JavaPackage javaPackage) { + return javaPackage.getPackageDependenciesToThisPackageTree(); + } + } + """ + ) + ); + } + + @Test + void shouldUseTraversePackageTree() { + //language=java + rewriteRun( + java( + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import static com.tngtech.archunit.core.domain.JavaPackage.ClassVisitor; + + public class ArchUnitTest { + public void sample(JavaPackage javaPackage, ClassVisitor visitor) { + javaPackage.accept(null, visitor); + } + } + """, + """ + import com.tngtech.archunit.core.domain.JavaPackage; + import static com.tngtech.archunit.core.domain.JavaPackage.ClassVisitor; + + public class ArchUnitTest { + public void sample(JavaPackage javaPackage, ClassVisitor visitor) { + javaPackage.traversePackageTree(null, visitor); + } + } + """ + ) + ); + } + + @Test + void shouldUsePlantUmlRulesPackage() { + //language=java + rewriteRun( + java( + """ + import com.tngtech.archunit.library.plantuml.PlantUmlArchCondition; + + public class ArchUnitTest { + public void sample(PlantUmlArchCondition condition) { + condition.ignoreDependencies("origin", ""); + } + } + """, + """ + import com.tngtech.archunit.library.plantuml.rules.PlantUmlArchCondition; + + public class ArchUnitTest { + public void sample(PlantUmlArchCondition condition) { + condition.ignoreDependencies("origin", ""); + } + } + """ + ) + ); + } +}