diff --git a/README.md b/README.md index cd7e794..a8e3dc1 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ template repository for Java projects using Gradle - Automatic code formatting via [Spotless](https://github.com/diffplug/spotless) - Code style analysis via [Checkstyle](https://github.com/checkstyle/checkstyle) - Static analysis via [SpotBugs](https://spotbugs.github.io/) -- Unit and integration test support via JUnit 5 and [TestSets plugin](https://github.com/unbroken-dome/gradle-testsets-plugin) +- Unit and integration test support via [JUnit 5](https://junit.org/junit5/) and [TestSets plugin](https://github.com/unbroken-dome/gradle-testsets-plugin) - Code coverage reporting via [Codecov](https://codecov.io/) - Dependency upgrades via [Renovate bot](https://renovatebot.com) diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 73b9358..0000000 --- a/build.gradle +++ /dev/null @@ -1,142 +0,0 @@ -logger.quiet "Java version: ${System.properties['java.version']}" -logger.quiet "Gradle version: $gradle.gradleVersion" - -buildscript { - repositories { - maven { - url 'https://plugins.gradle.org/m2/' - } - } - dependencies { - classpath group: 'com.diffplug.spotless', name: 'spotless-plugin-gradle', version: '6.19.0' - classpath group: 'com.github.spotbugs.snom', name: 'spotbugs-gradle-plugin', version: '5.0.14' - classpath group: 'com.asarkar.gradle', name: 'build-time-tracker', version: '4.3.0' - classpath group: 'org.unbroken-dome.gradle-plugins', name: 'gradle-testsets-plugin', version: '4.0.0' - } -} - -// Build time tracker -apply plugin: 'com.asarkar.gradle.build-time-tracker' - -allprojects { - group 'com.willmolloy' - repositories { - mavenCentral() - } -} - -subprojects { - apply plugin: 'java' - sourceCompatibility = 19 - targetCompatibility = 19 - - // Spotless (code formatting/linting) - apply plugin: 'com.diffplug.spotless' - spotless { - java { - removeUnusedImports() - googleJavaFormat() - } - } - - // Checkstyle (static analysis - code quality/style) - apply plugin: 'checkstyle' - checkstyle { - toolVersion = '10.12.0' - configFile = rootProject.file('./checkstyle.xml') - maxErrors = 0 - maxWarnings = 0 - ignoreFailures = false - } - - // SpotBugs (static analysis - find possible bugs, performance issues etc.) - apply plugin: 'com.github.spotbugs' - spotbugs { - effort = 'max' - reportLevel = 'low' - ignoreFailures = false - excludeFilter = rootProject.file('./spotbugs-exclude.xml') - } - tasks.withType(com.github.spotbugs.snom.SpotBugsTask) { - reports { - html.enabled = true - xml.enabled = false - } - } - - // Tests - tasks.withType(Test) { - // run tests in parallel, assumes they're threadsafe - maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1 - // use JUnit 5 engine - useJUnitPlatform() - testLogging { - events = ['failed', 'skipped'] - // log the full failure messages - exceptionFormat = 'full' - showExceptions = true - showCauses = true - showStackTraces = true - // log the overall results (based on https://stackoverflow.com/a/36130467/6122976) - afterSuite { desc, result -> - if (!desc.parent) { // will match the outermost suite - println("Results: ${result.resultType} " + - "(${result.testCount} test${result.testCount > 1 ? "s" : ""}, " + - "${result.successfulTestCount} passed, " + - "${result.failedTestCount} failed, " + - "${result.skippedTestCount} skipped)") - } - } - } - } - - // JaCoCo (code coverage reporting) - apply plugin: 'jacoco' - tasks.withType(JacocoReport) { - reports { - xml.enabled = true - html.enabled = true - csv.enabled = false - } - } - test.finalizedBy jacocoTestReport - - // Integration test support - apply plugin: 'org.unbroken-dome.test-sets' - testSets { - integrationTest - } - integrationTest.finalizedBy jacocoIntegrationTestReport - - // pin dependency versions - ext { - // production - log4jVersion = '2.20.0' - guavaVersion = '32.0.1-jre' - - // test - junitVersion = '5.9.3' - truthVersion = '1.1.4' - mockitoVersion = '5.3.1' - } - - dependencies { - implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: "$log4jVersion" - implementation group: 'com.github.spotbugs', name: 'spotbugs-annotations', version: '4.7.3' - implementation group: 'com.google.guava', name: 'guava', version: "$guavaVersion" - - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter', version: "$junitVersion" - testImplementation group: 'com.google.truth', name: 'truth', version: "$truthVersion" - testImplementation group: 'com.google.truth.extensions', name: 'truth-java8-extension', version: "$truthVersion" - testImplementation group: 'org.mockito', name: 'mockito-core', version: "$mockitoVersion" - testImplementation group: 'org.mockito', name: 'mockito-junit-jupiter', version: "$mockitoVersion" - } - - // dependency cleanup, exclusions and resolutions - configurations.all { - exclude group: 'org.assertj' // using truth instead - resolutionStrategy { - force "com.google.guava:guava:$guavaVersion" // so the android version isn't pulled in - } - } -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..d0f9692 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,127 @@ +import com.diffplug.gradle.spotless.SpotlessExtension +import com.github.spotbugs.snom.Confidence +import com.github.spotbugs.snom.Effort +import com.github.spotbugs.snom.SpotBugsExtension +import com.github.spotbugs.snom.SpotBugsTask +import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import org.gradle.api.tasks.testing.logging.TestLogEvent + +logger.quiet("Java version: ${JavaVersion.current()}") +logger.quiet("Gradle version: ${gradle.gradleVersion}") + +plugins { + id("java-library") + id("com.diffplug.gradle.spotless") version "6.19.0" apply (false) + id("com.github.spotbugs") version "5.0.14" apply (false) + id("com.asarkar.gradle.build-time-tracker") version "4.3.0" +} + +allprojects { + group = "com.willmolloy" + repositories { + mavenCentral() + } +} + +subprojects { + apply(plugin = "java") + configure { + sourceCompatibility = JavaVersion.VERSION_19 + targetCompatibility = JavaVersion.VERSION_19 + } + + apply(plugin = "com.diffplug.spotless") + configure { + java { + removeUnusedImports() + googleJavaFormat() + } + } + + apply(plugin = "checkstyle") + configure { + toolVersion = "10.12.0" + configFile = rootProject.file("./checkstyle.xml") + maxErrors = 0 + maxWarnings = 0 + isIgnoreFailures = false + } + + apply(plugin = "com.github.spotbugs") + configure { + effort.set(Effort.MAX) + reportLevel.set(Confidence.LOW) + ignoreFailures.set(false) + excludeFilter.set(rootProject.file("./spotbugs-exclude.xml")) + } + tasks.withType { + reports.create("html").required.set(true) + } + + tasks.withType { + maxParallelForks = Runtime.getRuntime().availableProcessors() + useJUnitPlatform() + testLogging { + events = setOf(TestLogEvent.FAILED, TestLogEvent.SKIPPED) + exceptionFormat = TestExceptionFormat.FULL + showExceptions = true + showCauses = true + showStackTraces = true + afterSuite(KotlinClosure2({ desc: TestDescriptor, result: TestResult -> + if (desc.parent == null) { + println( + "Results: ${result.resultType} " + + "(${result.testCount} test${if (result.testCount > 1) "s" else ""}, " + + "${result.successfulTestCount} passed, " + + "${result.failedTestCount} failed, " + + "${result.skippedTestCount} skipped)" + ) + } + })) + } + finalizedBy(tasks.withType()) + } + + apply(plugin = "jacoco") + tasks.withType { + reports { + xml.required.set(true) + } + } + + val previewFeatures = listOf("--enable-preview") + tasks.withType { + options.compilerArgs = previewFeatures + } + tasks.withType { + jvmArgs = previewFeatures + } + tasks.withType { + jvmArgs = previewFeatures + } + + dependencies { + val log4jVersion = "2.20.0" + val guavaVersion = "32.0.1-jre" + implementation("org.apache.logging.log4j:log4j-core:$log4jVersion") + implementation("com.github.spotbugs:spotbugs-annotations:4.7.3") + implementation("com.google.guava:guava:$guavaVersion") + + val junitVersion = "5.9.3" + val truthVersion = "1.1.4" + val mockitoVersion = "5.3.1" + testImplementation("org.junit.jupiter:junit-jupiter:$junitVersion") + testImplementation("com.google.truth:truth:$truthVersion") + testImplementation("com.google.truth.extensions:truth-java8-extension:$truthVersion") + testImplementation("org.mockito:mockito-core:$mockitoVersion") + testImplementation("org.mockito:mockito-junit-jupiter:$mockitoVersion") + + configurations.all { + exclude("org.assertj") + exclude("junit") + resolutionStrategy { + force("com.google.guava:guava:$guavaVersion") // exclude android version + } + } + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 696eb15..dcc0d6b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ # https://github.com/google/google-java-format/releases/tag/v1.10.0 -org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED +org.gradle.jvmargs=--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 774fae8..31cca49 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/hello-world/build.gradle b/hello-world/build.gradle deleted file mode 100644 index e69de29..0000000 diff --git a/hello-world/build.gradle.kts b/hello-world/build.gradle.kts new file mode 100644 index 0000000..a963759 --- /dev/null +++ b/hello-world/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + id("org.unbroken-dome.test-sets") version "4.0.0" +} + +testSets { + create("integrationTest") +} \ No newline at end of file diff --git a/hello-world/src/main/java/com/willmolloy/HelloWorld.java b/hello-world/src/main/java/com/willmolloy/HelloWorld.java index 50f52de..82a20bc 100644 --- a/hello-world/src/main/java/com/willmolloy/HelloWorld.java +++ b/hello-world/src/main/java/com/willmolloy/HelloWorld.java @@ -8,11 +8,11 @@ * * @author Will Molloy */ -public class HelloWorld { +class HelloWorld { private final Logger log = LogManager.getLogger(); - public String hello(String text) { + String hello(String text) { log.debug("Hello {}!", text); return "Hello %s!".formatted(text); } diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 866e2d5..0000000 --- a/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = 'java-gradle-template' -include 'hello-world' \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..067b92c --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "java-gradle-template" +include("hello-world") \ No newline at end of file diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml index 55c20be..5fd588b 100644 --- a/spotbugs-exclude.xml +++ b/spotbugs-exclude.xml @@ -1,9 +1,4 @@ - - - - -