From 1c167dd3f1ce536134659b9fe976d26b4e15d5ac Mon Sep 17 00:00:00 2001 From: Vincent Potucek Date: Tue, 9 Dec 2025 13:40:37 +0100 Subject: [PATCH] Add `com.tngtech.archunit.openrewrite.SanityCheck` Signed-off-by: Vincent Potucek --- .github/workflows/build.yml | 104 ++++++++---------- .gitignore | 1 + .idea/icon.png | Bin 0 -> 5403 bytes .../AbstractArchUnitTestDescriptor.java | 2 +- .../core/importer/ModuleLocationResolver.java | 38 ++++--- .../core/importer/ClassFileSource.java | 2 +- .../importer/JavaClassDescriptorImporter.java | 2 +- .../archunit/core/importer/UrlSource.java | 2 +- .../domain/JavaParameterizedTypeTest.java | 4 +- .../importer/ClassFileImporterSlowTest.java | 4 +- ...eImporterSyntheticPrivateAccessesTest.java | 2 +- .../core/importer/ImportOptionsTest.java | 2 +- .../syntax/elements/GivenMethodsTest.java | 4 +- .../modules/RandomModulesSyntaxTest.java | 4 +- .../modules/syntax/ModulesShouldTest.java | 6 +- .../testutil/syntax/RandomSyntaxTestBase.java | 2 +- build.gradle | 9 +- ...hunit.java-code-quality-conventions.gradle | 26 ++++- .../main/resources/code_quality/rewrite.yml | 14 +++ rewrite.yml | 69 ++++++++++++ 20 files changed, 196 insertions(+), 101 deletions(-) create mode 100644 .idea/icon.png create mode 100644 buildSrc/src/main/resources/code_quality/rewrite.yml create mode 100644 rewrite.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 328b293b1b..da398b9e99 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,138 +1,126 @@ -name: CI - +name: CI ๐Ÿšฆ on: push: branches: - main - release-* pull_request: - env: build_java_version: 21 - jobs: build: + name: Build ๐Ÿ“ฆ runs-on: ubuntu-latest steps: - - name: Checkout + - name: Checkout ๐Ÿ“ฅ uses: actions/checkout@v6 - - name: Set up Java + - name: Setup Java โ˜•๏ธ uses: actions/setup-java@v5.1.0 with: - distribution: 'zulu' + distribution: zulu java-version: ${{ env.build_java_version }} - - name: Set Up Gradle + - name: Setup Gradle ๐Ÿ˜ uses: gradle/actions/setup-gradle@v5 - - name: Build + - name: Spotless โœจ + run: ./gradlew spotlessCheck + - name: Sanity Check ๐Ÿ•Š + run: ./gradlew rewriteDryRun + - name: Build ๐Ÿ—๏ธ run: ./gradlew build - - name: Check project files unmodified + - name: Verify No Modified Files ๐Ÿ“‹ run: | - directoryState="$(git status --porcelain)" + directoryState="$(git.status --porcelain)" if [ -n "$directoryState" ]; then - echo "Some files were modified during build. Please run the build locally before checking in, as it ensures some source file conventions (like copyright header)." - echo "The following files were modified:" + echo "Some files were modified during build. Please run the build locally before checking in." + echo "Modified files:" echo "$directoryState" exit 1 fi - test: + name: Unit Tests ๐Ÿงช (${{ matrix.os }} - JDK ${{ matrix.test_java_version }}) strategy: fail-fast: false matrix: - os: - - ubuntu-latest - - macos-latest - - windows-latest - test_java_version: - - 8 - - 11 - - 17 - - 21 + os: [ubuntu-latest, macos-latest, windows-latest] + test_java_version: [8, 11, 17, 21] runs-on: ${{ matrix.os }} steps: - - name: Checkout + - name: Checkout ๐Ÿ“ฅ uses: actions/checkout@v6 - - name: Set up Build JDK + - name: Setup Build JDK โ˜• uses: actions/setup-java@v5.1.0 with: - distribution: 'zulu' + distribution: zulu java-version: ${{ env.build_java_version }} - - name: Set up Test JDK + - name: Setup Test JDK โ˜• uses: actions/setup-java@v5.1.0 with: - distribution: 'zulu' + distribution: zulu java-version: ${{ matrix.test_java_version }} - - name: Provide installed JDKs - uses: actions/github-script@v8 + - name: Resolve Installed JDK Paths ๐Ÿ” id: provideJdkPaths + uses: actions/github-script@v8 with: script: | - for ( let envVarName in process.env ) { + for (let envVarName in process.env) { if (/JAVA_HOME_\d.*64/.test(envVarName)) { const version = envVarName.match(/JAVA_HOME_(\d+).*64/)[1]; if (version === "${{ matrix.test_java_version }}") { - core.exportVariable('test_jdk_path', process.env[envVarName]); + core.exportVariable("test_jdk_path", process.env[envVarName]); } else if (version === "${{ env.build_java_version }}") { - core.exportVariable('build_jdk_path', process.env[envVarName]); + core.exportVariable("build_jdk_path", process.env[envVarName]); } } } - - name: Set Up Gradle + - name: Setup Gradle ๐Ÿ˜ uses: gradle/actions/setup-gradle@v5 - - name: Test + - name: Run Tests ๐Ÿงช run: ./gradlew test -PallTests -PtestJavaVersion=${{ matrix.test_java_version }} "-Porg.gradle.java.installations.paths=${{ env.test_jdk_path }}" env: JAVA_HOME: ${{ env.build_jdk_path }} - integration-test: + name: Integration Tests ๐Ÿงฉ (${{ matrix.os }} - JDK ${{ matrix.test_java_version }}) strategy: fail-fast: false matrix: - os: - - ubuntu-latest - - macos-latest - - windows-latest - test_java_version: - - 8 - - 11 - - 17 - - 21 + os: [ubuntu-latest, macos-latest, windows-latest] + test_java_version: [8, 11, 17, 21] runs-on: ${{ matrix.os }} steps: - - name: Checkout + - name: Checkout ๐Ÿ“ฅ uses: actions/checkout@v6 - - name: Set up Build JDK + - name: Setup Build JDK โ˜• uses: actions/setup-java@v5.1.0 with: - distribution: 'zulu' + distribution: zulu java-version: ${{ env.build_java_version }} - - name: Set up Test JDK + - name: Setup Test JDK โ˜• uses: actions/setup-java@v5.1.0 with: - distribution: 'zulu' + distribution: zulu java-version: ${{ matrix.test_java_version }} - - name: Provide installed JDKs - uses: actions/github-script@v8 + - name: Resolve Installed JDK Paths ๐Ÿ” id: provideJdkPaths + uses: actions/github-script@v8 with: script: | - for ( let envVarName in process.env ) { + for (let envVarName in process.env) { if (/JAVA_HOME_\d.*64/.test(envVarName)) { const version = envVarName.match(/JAVA_HOME_(\d+).*64/)[1]; if (version === "${{ matrix.test_java_version }}") { - core.exportVariable('test_jdk_path', process.env[envVarName]); + core.exportVariable("test_jdk_path", process.env[envVarName]); } else if (version === "${{ env.build_java_version }}") { - core.exportVariable('build_jdk_path', process.env[envVarName]); + core.exportVariable("build_jdk_path", process.env[envVarName]); } } } - - name: Set Up Gradle + - name: Setup Gradle ๐Ÿ˜ uses: gradle/actions/setup-gradle@v5 - - name: Publish to Maven Local + - name: Publish to Maven Local ๐Ÿ“ฆ run: ./gradlew build -xtest -xspotbugsMain -xjavadoc publishToMavenLocal env: JAVA_HOME: ${{ env.build_jdk_path }} - - name: Integration test + - name: Run Integration Tests ๐Ÿงฉ run: ./gradlew runMavenTest -PtestJavaVersion=${{ matrix.test_java_version }} "-Porg.gradle.java.installations.paths=${{ env.test_jdk_path }}" env: JAVA_HOME: ${{ env.build_jdk_path }} diff --git a/.gitignore b/.gitignore index bbb461d787..b2729f8acb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .gradle .idea +!.idea/icon.png *.iml build out diff --git a/.idea/icon.png b/.idea/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e8d2ce09d058b4df147814b21af3c6f3b61dbba4 GIT binary patch literal 5403 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 getTags() { static String formatWithPath(UniqueId uniqueId, String name) { return Stream.concat( uniqueId.getSegments().stream() - .filter(it -> it.getType().equals(ArchUnitTestDescriptor.CLASS_SEGMENT_TYPE)) + .filter(it -> ArchUnitTestDescriptor.CLASS_SEGMENT_TYPE.equals(it.getType())) .skip(1) .map(UniqueId.Segment::getValue) .map(Formatters::ensureSimpleName), diff --git a/archunit/src/jdk9main/java/com/tngtech/archunit/core/importer/ModuleLocationResolver.java b/archunit/src/jdk9main/java/com/tngtech/archunit/core/importer/ModuleLocationResolver.java index b5fec8a8db..052de6ace4 100644 --- a/archunit/src/jdk9main/java/com/tngtech/archunit/core/importer/ModuleLocationResolver.java +++ b/archunit/src/jdk9main/java/com/tngtech/archunit/core/importer/ModuleLocationResolver.java @@ -15,44 +15,46 @@ */ package com.tngtech.archunit.core.importer; -import java.io.File; +import com.google.common.base.Splitter; + import java.lang.module.ModuleFinder; -import java.lang.module.ModuleReference; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.List; -import java.util.Set; import java.util.stream.Stream; -import com.google.common.base.Splitter; - import static com.google.common.base.Strings.nullToEmpty; import static com.google.common.collect.Iterables.concat; +import static com.tngtech.archunit.core.importer.UrlSource.From.iterable; +import static java.io.File.pathSeparatorChar; +import static java.lang.System.getProperty; import static java.util.stream.Collectors.toList; class ModuleLocationResolver implements LocationResolver { + private static final String JDK_MODULE_PATH = "jdk.module.path"; private final FromClasspathAndUrlClassLoaders standardResolver = new FromClasspathAndUrlClassLoaders(); @Override public UrlSource resolveClassPath() { - Iterable classpath = standardResolver.resolveClassPath(); - Set systemModuleReferences = ModuleFinder.ofSystem().findAll(); - Set configuredModuleReferences = ModuleFinder.of(modulepath()).findAll(); - Iterable modulepath = Stream.concat(systemModuleReferences.stream(), configuredModuleReferences.stream()) - .flatMap(moduleReference -> moduleReference.location().stream()) - .map(this::toUrl) - .collect(toList()); - - return UrlSource.From.iterable(concat(classpath, modulepath)); + return iterable(concat( + standardResolver.resolveClassPath(), + Stream.concat(ModuleFinder.ofSystem().findAll().stream(), + ModuleFinder.of(modulepath()).findAll().stream()) + .flatMap(moduleReference -> moduleReference.location().stream()) + .map(this::toUrl) + .collect(toList()))); } private Path[] modulepath() { - String modulepathProperty = nullToEmpty(System.getProperty("jdk.module.path")); - List modulepath = Splitter.on(File.pathSeparatorChar).omitEmptyStrings().splitToList(modulepathProperty); - return modulepath.stream().map(Paths::get).toArray(Path[]::new); + return Splitter + .on(pathSeparatorChar) + .omitEmptyStrings() + .splitToList(nullToEmpty(getProperty(JDK_MODULE_PATH))) + .stream() + .map(Paths::get) + .toArray(Path[]::new); } private URL toUrl(URI uri) { diff --git a/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileSource.java b/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileSource.java index befbdc0718..1ca0e36def 100644 --- a/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileSource.java +++ b/archunit/src/main/java/com/tngtech/archunit/core/importer/ClassFileSource.java @@ -207,7 +207,7 @@ public InputStream get() { @Internal class FileToImport { static boolean isRelevant(String simpleFileName) { - return simpleFileName.endsWith(".class") && !simpleFileName.equals("module-info.class"); + return simpleFileName.endsWith(".class") && !"module-info.class".equals(simpleFileName); } } } diff --git a/archunit/src/main/java/com/tngtech/archunit/core/importer/JavaClassDescriptorImporter.java b/archunit/src/main/java/com/tngtech/archunit/core/importer/JavaClassDescriptorImporter.java index 0a6ffa0030..3bd5dfedfe 100644 --- a/archunit/src/main/java/com/tngtech/archunit/core/importer/JavaClassDescriptorImporter.java +++ b/archunit/src/main/java/com/tngtech/archunit/core/importer/JavaClassDescriptorImporter.java @@ -60,7 +60,7 @@ private static boolean isAsmMethodHandle(Handle handle) { } static boolean isLambdaMetafactory(String asmObjectTypeName) { - return asmObjectTypeName.equals(LAMBDA_METAFACTORY_ASM_OBJECT_TYPE_NAME); + return LAMBDA_METAFACTORY_ASM_OBJECT_TYPE_NAME.equals(asmObjectTypeName); } static boolean isLambdaMethod(Handle methodHandle) { diff --git a/archunit/src/main/java/com/tngtech/archunit/core/importer/UrlSource.java b/archunit/src/main/java/com/tngtech/archunit/core/importer/UrlSource.java index 2f593b5d01..914a90d0d6 100644 --- a/archunit/src/main/java/com/tngtech/archunit/core/importer/UrlSource.java +++ b/archunit/src/main/java/com/tngtech/archunit/core/importer/UrlSource.java @@ -98,7 +98,7 @@ private static Iterable readClasspathEntriesFromManifests(List urls) { // Use URI because of better equals / hashcode private static void readClasspathUriEntriesFromManifests(Set result, Set uris) { - uris.stream().filter(url -> url.getScheme().equals("jar")) + uris.stream().filter(url -> "jar".equals(url.getScheme())) .map(From::readClasspathEntriesFromManifest) .map(manifestUris -> ImmutableSet.copyOf(difference(manifestUris, result))) // difference returns a dynamic SetView -> safe-copy .forEach(unknownSoFar -> { diff --git a/archunit/src/test/java/com/tngtech/archunit/core/domain/JavaParameterizedTypeTest.java b/archunit/src/test/java/com/tngtech/archunit/core/domain/JavaParameterizedTypeTest.java index 05b77742a7..47ae37e107 100644 --- a/archunit/src/test/java/com/tngtech/archunit/core/domain/JavaParameterizedTypeTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/core/domain/JavaParameterizedTypeTest.java @@ -48,11 +48,11 @@ class WithWildcards, ? super Map testClass) { Type reflectionType = Arrays.stream(testClass.getTypeParameters()) - .filter(v -> v.getName().equals("TEST")) + .filter(v -> "TEST".equals(v.getName())) .map(v -> v.getBounds()[0]) .findFirst().get(); JavaType javaType = new ClassFileImporter().importClass(testClass).getTypeParameters().stream() - .filter(v -> v.getName().equals("TEST")) + .filter(v -> "TEST".equals(v.getName())) .map(v -> v.getBounds().get(0)) .findFirst().get(); diff --git a/archunit/src/test/java/com/tngtech/archunit/core/importer/ClassFileImporterSlowTest.java b/archunit/src/test/java/com/tngtech/archunit/core/importer/ClassFileImporterSlowTest.java index 3285b03938..9b9c56d8d5 100644 --- a/archunit/src/test/java/com/tngtech/archunit/core/importer/ClassFileImporterSlowTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/core/importer/ClassFileImporterSlowTest.java @@ -183,7 +183,7 @@ private JavaClasses importJavaBase() { // before Java 9 packages like java.lang were in rt.jar; location.contains("rt.jar") || // from Java 9 on those packages were in a JRT with name 'java.base' - (location.asURI().getScheme().equals("jrt") && location.contains("java.base")) + ("jrt".equals(location.asURI().getScheme()) && location.contains("java.base")) )).importClasspath(); } @@ -198,7 +198,7 @@ private ImportOption importJavaBaseOrRtAndJUnitJarAndFilesOnTheClasspath() { if (location.isJar() && (location.contains("junit") || location.contains("/rt.jar"))) { return true; } - return location.asURI().getScheme().equals("jrt") && location.contains("java.base"); + return "jrt".equals(location.asURI().getScheme()) && location.contains("java.base"); }; } diff --git a/archunit/src/test/java/com/tngtech/archunit/core/importer/ClassFileImporterSyntheticPrivateAccessesTest.java b/archunit/src/test/java/com/tngtech/archunit/core/importer/ClassFileImporterSyntheticPrivateAccessesTest.java index 781e53bd7e..6aa035884b 100644 --- a/archunit/src/test/java/com/tngtech/archunit/core/importer/ClassFileImporterSyntheticPrivateAccessesTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/core/importer/ClassFileImporterSyntheticPrivateAccessesTest.java @@ -461,7 +461,7 @@ private void stringConcat() { @SuppressWarnings("OptionalGetWithoutIsPresent") private Set> importRelevantAccesses(Class origin, Class target) { return new ClassFileImporter().importClasses(origin, target).get(origin).getMethods().stream() - .filter(m -> m.getName().equals("access")) + .filter(m -> "access".equals(m.getName())) .findFirst() .get() .getAccessesFromSelf() diff --git a/archunit/src/test/java/com/tngtech/archunit/core/importer/ImportOptionsTest.java b/archunit/src/test/java/com/tngtech/archunit/core/importer/ImportOptionsTest.java index 5fe9cad65b..8c3e466c78 100644 --- a/archunit/src/test/java/com/tngtech/archunit/core/importer/ImportOptionsTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/core/importer/ImportOptionsTest.java @@ -207,7 +207,7 @@ private static Location locationOf(Class clazz) { } private static boolean comesFromJarArchive(Class clazz) { - return LocationTest.urlOfClass(clazz).getProtocol().equals("jar"); + return "jar".equals(LocationTest.urlOfClass(clazz).getProtocol()); } private static class FolderPattern { diff --git a/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenMethodsTest.java b/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenMethodsTest.java index b14b43206a..4232164e3d 100644 --- a/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenMethodsTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/lang/syntax/elements/GivenMethodsTest.java @@ -12,7 +12,9 @@ import static com.tngtech.archunit.core.domain.TestUtils.importClasses; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods; -import static com.tngtech.archunit.lang.syntax.elements.GivenMembersTest.*; +import static com.tngtech.archunit.lang.syntax.elements.GivenMembersTest.DescribedRuleStart; +import static com.tngtech.archunit.lang.syntax.elements.GivenMembersTest.described; +import static com.tngtech.archunit.lang.syntax.elements.GivenMembersTest.everythingViolationPrintMemberName; import static com.tngtech.java.junit.dataprovider.DataProviders.$; import static com.tngtech.java.junit.dataprovider.DataProviders.$$; import static org.assertj.core.api.Assertions.assertThat; diff --git a/archunit/src/test/java/com/tngtech/archunit/library/modules/RandomModulesSyntaxTest.java b/archunit/src/test/java/com/tngtech/archunit/library/modules/RandomModulesSyntaxTest.java index 4a6265e495..4ce35507ab 100644 --- a/archunit/src/test/java/com/tngtech/archunit/library/modules/RandomModulesSyntaxTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/library/modules/RandomModulesSyntaxTest.java @@ -92,7 +92,7 @@ public Parameter get(String methodName, TypeToken type) { new SingleParameterProvider(String.class) { @Override protected boolean canHandle(String methodName, Class type) { - return methodName.equals("respectTheirAllowedDependenciesDeclaredIn") && super.canHandle(methodName, type); + return "respectTheirAllowedDependenciesDeclaredIn".equals(methodName) && super.canHandle(methodName, type); } @Override @@ -104,7 +104,7 @@ public Parameter get(String methodName, TypeToken type) { @Override protected boolean canHandle(String methodName, Class type) { - return methodName.equals("onlyDependOnEachOtherThroughPackagesDeclaredIn") && super.canHandle(methodName, type); + return "onlyDependOnEachOtherThroughPackagesDeclaredIn".equals(methodName) && super.canHandle(methodName, type); } @Override diff --git a/archunit/src/test/java/com/tngtech/archunit/library/modules/syntax/ModulesShouldTest.java b/archunit/src/test/java/com/tngtech/archunit/library/modules/syntax/ModulesShouldTest.java index 93e6ce1887..ec7b2a5e21 100644 --- a/archunit/src/test/java/com/tngtech/archunit/library/modules/syntax/ModulesShouldTest.java +++ b/archunit/src/test/java/com/tngtech/archunit/library/modules/syntax/ModulesShouldTest.java @@ -79,9 +79,9 @@ public void respectTheirAllowedDependenciesDeclaredIn_takes_allowed_dependencies @Test public void respectTheirAllowedDependenciesDeclaredIn_works_together_with_filtering_by_predicate() { assertThatRule(modules().definedByAnnotation(TestModule.class) - .that(DescribedPredicate.describe("are not Module 1", it -> !it.getName().equals("Module 1"))) - .and(DescribedPredicate.describe("are not Module 2", it -> !it.getName().equals("Module 2"))) - .or(DescribedPredicate.describe("are Module 3", it -> it.getName().equals("Module 3"))) + .that(DescribedPredicate.describe("are not Module 1", it -> !"Module 1".equals(it.getName()))) + .and(DescribedPredicate.describe("are not Module 2", it -> !"Module 2".equals(it.getName()))) + .or(DescribedPredicate.describe("are Module 3", it -> "Module 3".equals(it.getName()))) .should().respectTheirAllowedDependenciesDeclaredIn("allowedDependencies", consideringOnlyDependenciesBetweenModules())) .checking(new ClassFileImporter().importPackagesOf(ClassInModule1.class, InternalClassInModule2.class, ClassInModule3.class)) .hasNoViolation(); diff --git a/archunit/src/test/java/com/tngtech/archunit/testutil/syntax/RandomSyntaxTestBase.java b/archunit/src/test/java/com/tngtech/archunit/testutil/syntax/RandomSyntaxTestBase.java index 7e2626c098..bc395797bd 100644 --- a/archunit/src/test/java/com/tngtech/archunit/testutil/syntax/RandomSyntaxTestBase.java +++ b/archunit/src/test/java/com/tngtech/archunit/testutil/syntax/RandomSyntaxTestBase.java @@ -350,7 +350,7 @@ public Parameter get(String methodName, TypeToken type) { || methodName.toLowerCase().contains("declared") || methodName.toLowerCase().contains("type")) { return new Parameter("some.Type", "some.Type"); - } else if (methodName.equals("be") || methodName.equals("notBe")) { + } else if ("be".equals(methodName) || "notBe".equals(methodName)) { return new Parameter("some.Type", "some.Type"); } else { return new Parameter("string", "'string'"); diff --git a/build.gradle b/build.gradle index 4b7e162f55..cdbf6e4d9b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,11 @@ plugins { id 'archunit.base-conventions' - id 'com.gradleup.shadow' version '8.3.9' apply false - id 'com.github.spotbugs' version '6.4.7' apply false - id "io.github.gradle-nexus.publish-plugin" version "2.0.0" apply false - id "com.diffplug.spotless" version "8.1.0" apply false + id 'com.diffplug.spotless' version '8.1.0' apply false id 'com.github.ben-manes.versions' version '0.53.0' apply false + id 'com.github.spotbugs' version '6.4.7' apply false + id 'com.gradleup.shadow' version '8.3.9' apply false + id 'io.github.gradle-nexus.publish-plugin' version '2.0.0' apply false + id 'org.openrewrite.rewrite' version '7.21.0' apply false } def appAndSourceUrl = 'https://github.com/TNG/ArchUnit' diff --git a/buildSrc/src/main/groovy/archunit.java-code-quality-conventions.gradle b/buildSrc/src/main/groovy/archunit.java-code-quality-conventions.gradle index 6fee7b4725..c914f1f896 100644 --- a/buildSrc/src/main/groovy/archunit.java-code-quality-conventions.gradle +++ b/buildSrc/src/main/groovy/archunit.java-code-quality-conventions.gradle @@ -1,23 +1,41 @@ plugins { id 'com.github.spotbugs' id 'com.diffplug.spotless' + id 'org.openrewrite.rewrite' +} +dependencies { + rewrite('org.openrewrite.recipe:rewrite-java-security:3.22.0') + rewrite('org.openrewrite.recipe:rewrite-migrate-java:3.22.0') + rewrite('org.openrewrite.recipe:rewrite-rewrite:0.16.0') + rewrite('org.openrewrite.recipe:rewrite-static-analysis:2.22.0') + rewrite('org.openrewrite.recipe:rewrite-testing-frameworks:3.22.0') + rewrite('org.openrewrite.recipe:rewrite-third-party:0.31.2') +} +rewrite { + activeRecipe('com.tngtech.archunit.openrewrite.SanityCheck') + configFile = project.getRootProject().file('buildSrc/src/main/resources/code_quality/rewrite.yml') + exclusions.addAll( + '**special-tests.gradle', + '**testlib/src/main/resources**' + ) + exportDatatables = true + failOnDryRunResults = true } - spotbugs { excludeFilter = rootProject.file('buildSrc/src/main/resources/code_quality/spotbugs-excludes.xml') } - spotbugsMain { reports { xml.enabled false html.enabled true } } - spotbugsTest.enabled = false - spotless { java { + // palantirJavaFormat() // might consider. + forbidWildcardImports() removeUnusedImports() + trimTrailingWhitespace() } } diff --git a/buildSrc/src/main/resources/code_quality/rewrite.yml b/buildSrc/src/main/resources/code_quality/rewrite.yml new file mode 100644 index 0000000000..c227f18e18 --- /dev/null +++ b/buildSrc/src/main/resources/code_quality/rewrite.yml @@ -0,0 +1,14 @@ +--- +type: specs.openrewrite.org/v1beta/recipe +name: com.tngtech.archunit.openrewrite.SanityCheck +displayName: Apply all common best practices +description: Comprehensive code quality recipe combining modernization, security, and best practices. +recipeList: + - org.openrewrite.staticanalysis.EqualsAvoidsNull + - tech.picnic.errorprone.refasterrules.TimeRulesRecipes +# - org.openrewrite.java.testing.assertj.Assertj +# - org.openrewrite.java.testing.junit.JupiterBestPractices +# - tech.picnic.errorprone.refasterrules.JUnitRulesRecipes +# - tech.picnic.errorprone.refasterrules.JUnitToAssertJRulesRecipes +# - tech.picnic.errorprone.refasterrules.StreamRulesRecipes +--- diff --git a/rewrite.yml b/rewrite.yml new file mode 100644 index 0000000000..371d838682 --- /dev/null +++ b/rewrite.yml @@ -0,0 +1,69 @@ +--- +type: specs.openrewrite.org/v1beta/recipe +name: com.tngtech.archunit.openrewrite.SanityCheck +displayName: Apply all common best practices +description: Comprehensive code quality recipe combining modernization, security, and best practices. +recipeList: + - org.openrewrite.gradle.EnableGradleBuildCache + - org.openrewrite.gradle.EnableGradleParallelExecution + - org.openrewrite.gradle.GradleBestPractices + - org.openrewrite.java.RemoveUnusedImports + - org.openrewrite.java.format.NormalizeFormat + - org.openrewrite.java.format.NormalizeLineBreaks + - org.openrewrite.java.format.RemoveTrailingWhitespace + - org.openrewrite.java.migrate.UpgradeToJava21 + - org.openrewrite.java.migrate.lang.StringRulesRecipes + - org.openrewrite.java.migrate.util.JavaLangAPIs + - org.openrewrite.java.migrate.util.JavaUtilAPIs + - org.openrewrite.java.migrate.util.MigrateInflaterDeflaterToClose + - org.openrewrite.java.migrate.util.ReplaceStreamCollectWithToList + - org.openrewrite.java.migrate.util.SequencedCollection + - org.openrewrite.java.recipes.JavaRecipeBestPractices + - org.openrewrite.java.recipes.RecipeTestingBestPractices + - org.openrewrite.java.security.JavaSecurityBestPractices + - org.openrewrite.java.testing.archunit.ArchUnit0to1Migration + - org.openrewrite.java.testing.assertj.Assertj + - org.openrewrite.java.testing.cleanup.BestPractices + - org.openrewrite.java.testing.junit.JupiterBestPractices + - org.openrewrite.java.testing.junit5.CleanupAssertions + - org.openrewrite.java.testing.junit5.JUnit5BestPractices + - org.openrewrite.staticanalysis.BufferedWriterCreationRecipes + - org.openrewrite.staticanalysis.CodeCleanup + - org.openrewrite.staticanalysis.CommonStaticAnalysis + - org.openrewrite.staticanalysis.EqualsAvoidsNull + - org.openrewrite.staticanalysis.JavaApiBestPractices + - org.openrewrite.staticanalysis.LowercasePackage + - org.openrewrite.staticanalysis.MissingOverrideAnnotation + - org.openrewrite.staticanalysis.ModifierOrder + - org.openrewrite.staticanalysis.NoFinalizer + - org.openrewrite.staticanalysis.NoToStringOnStringType + - org.openrewrite.staticanalysis.NoValueOfOnStringType + - org.openrewrite.staticanalysis.RemoveUnusedLocalVariables + - org.openrewrite.staticanalysis.RemoveUnusedPrivateFields + - org.openrewrite.staticanalysis.RemoveUnusedPrivateMethods + - org.openrewrite.staticanalysis.SimplifyTernaryRecipes + - org.openrewrite.staticanalysis.URLEqualsHashCodeRecipes + - org.openrewrite.staticanalysis.UnnecessaryCloseInTryWithResources + - org.openrewrite.staticanalysis.UnnecessaryExplicitTypeArguments + - org.openrewrite.staticanalysis.UnnecessaryParentheses + - org.openrewrite.staticanalysis.UnnecessaryReturnAsLastStatement + - tech.picnic.errorprone.refasterrules.BigDecimalRulesRecipes + - tech.picnic.errorprone.refasterrules.CharSequenceRulesRecipes + - tech.picnic.errorprone.refasterrules.ClassRulesRecipes + - tech.picnic.errorprone.refasterrules.CollectionRulesRecipes + - tech.picnic.errorprone.refasterrules.ComparatorRulesRecipes + - tech.picnic.errorprone.refasterrules.EqualityRulesRecipes + - tech.picnic.errorprone.refasterrules.FileRulesRecipes + - tech.picnic.errorprone.refasterrules.JUnitRulesRecipes + - tech.picnic.errorprone.refasterrules.MapRulesRecipes + - tech.picnic.errorprone.refasterrules.MicrometerRulesRecipes + - tech.picnic.errorprone.refasterrules.MockitoRulesRecipes + - tech.picnic.errorprone.refasterrules.NullRulesRecipes + - tech.picnic.errorprone.refasterrules.OptionalRulesRecipes + - tech.picnic.errorprone.refasterrules.PatternRulesRecipes + - tech.picnic.errorprone.refasterrules.PreconditionsRulesRecipes + - tech.picnic.errorprone.refasterrules.PrimitiveRulesRecipes + - tech.picnic.errorprone.refasterrules.StreamRulesRecipes + - tech.picnic.errorprone.refasterrules.StringRulesRecipes + - tech.picnic.errorprone.refasterrules.TimeRulesRecipes +---