Skip to content

Commit

Permalink
Remove most logic from root build.gradle file (#247)
Browse files Browse the repository at this point in the history
  • Loading branch information
serpro69 authored Sep 8, 2024
1 parent 22b0f97 commit 41e60fb
Show file tree
Hide file tree
Showing 22 changed files with 383 additions and 294 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
.idea/
.kotlintest/
*.jar
*.log
out/
build/
logs/
!gradle/wrapper/gradle-wrapper.jar
!docs/gradle/wrapper/gradle-wrapper.jar
# kotlin-language-server
kls_database.db

# FIXME remove when Gradle Daemon JVM can be auto-provisioned - see configureGradleDaemonJvm()
gradle/gradle-daemon-jvm.properties
140 changes: 10 additions & 130 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,125 +1,25 @@
import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask
import io.github.serpro69.semverkt.gradle.plugin.tasks.TagTask
import org.gradle.api.tasks.testing.TestResult.ResultType
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
import utils.configureGradleDaemonJvm

plugins {
// NB! some versions are on the classpath from dependency declared in buildSrc/build.gradle.kts
kotlin("jvm") apply false
id("io.github.gradle-nexus.publish-plugin") version "1.3.0"
id("io.github.serpro69.semantic-versioning") apply false
id("com.github.ben-manes.versions") version "0.51.0" apply false
id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.15.0-Beta.1"
alias(libs.plugins.nexus.publish)
alias(libs.plugins.benmanes.versions)
}

group = "io.github.serpro69"

val lib = project.libs

subprojects {
group = rootProject.group.toString()

apply {
plugin("com.github.ben-manes.versions")
}

// don't apply the rest to bom subproject
if (this@subprojects.name == "bom") return@subprojects

apply {
plugin("java")
plugin("org.jetbrains.kotlin.jvm")
}

dependencies {
val implementation by configurations
val testImplementation by configurations
val testRuntimeOnly by configurations
// common-for-all dependencies go here
implementation(platform(lib.kotlin.bom))
implementation(lib.bundles.kotlin)
testImplementation(lib.bundles.test.kotest)
}

configure<JavaPluginExtension> {
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
}

configure<KotlinJvmProjectExtension> {
jvmToolchain {
languageVersion.set(JavaLanguageVersion.of(8))
}
}

tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}

tasks.withType<Test> {
@Suppress("SimpleRedundantLet", "UNNECESSARY_SAFE_CALL")
jvmArgs?.let { it.plus("-ea") }

useJUnitPlatform()
maxParallelForks = 1

testLogging {
// set options for log level LIFECYCLE
events = setOf(
TestLogEvent.FAILED,
TestLogEvent.SKIPPED,
TestLogEvent.STANDARD_OUT
)
exceptionFormat = TestExceptionFormat.FULL
showExceptions = true
showCauses = true
showStackTraces = true
// set options for log level DEBUG and INFO
debug {
events = setOf(
TestLogEvent.STARTED,
TestLogEvent.FAILED,
TestLogEvent.PASSED,
TestLogEvent.SKIPPED,
TestLogEvent.STANDARD_ERROR,
TestLogEvent.STANDARD_OUT
)
exceptionFormat = TestExceptionFormat.FULL
}
info.events = debug.events
info.exceptionFormat = debug.exceptionFormat

afterSuite(KotlinClosure2({ desc: TestDescriptor, result: TestResult ->
if (desc.parent == null) { // will match the outermost suite
val pass = "${Color.GREEN}${result.successfulTestCount} passed${Color.NONE}"
val fail = "${Color.RED}${result.failedTestCount} failed${Color.NONE}"
val skip = "${Color.YELLOW}${result.skippedTestCount} skipped${Color.NONE}"
val type = when (val r: ResultType = result.resultType) {
ResultType.SUCCESS -> "${Color.GREEN}$r${Color.NONE}"
ResultType.FAILURE -> "${Color.RED}$r${Color.NONE}"
ResultType.SKIPPED -> "${Color.YELLOW}$r${Color.NONE}"
}
val output = "Results: $type (${result.testCount} tests, $pass, $fail, $skip)"
val startItem = "| "
val endItem = " |"
val repeatLength = startItem.length + output.length + endItem.length - 36
println("")
println("\n" + ("-" * repeatLength) + "\n" + startItem + output + endItem + "\n" + ("-" * repeatLength))
}
}))
}

onOutput(KotlinClosure2({ _: TestDescriptor, event: TestOutputEvent ->
if (event.destination == TestOutputEvent.Destination.StdOut) {
logger.lifecycle(event.message.replace(Regex("""\s+$"""), ""))
}
}))
}

tasks.withType<DependencyUpdatesTask> {
// disable for cli-bot because the classpath takes forever to resolve
enabled = this@subprojects.name != "cli-bot"
fun isNonStable(version: String): Boolean {
val stableKeyword = listOf("RELEASE", "FINAL", "GA").any { version.uppercase().contains(it) }
val regex = "^[0-9,.v-]+(-r|-jre)?$".toRegex()
Expand All @@ -141,28 +41,6 @@ nexusPublishing {
}
}

operator fun String.times(x: Int): String {
return List(x) { this }.joinToString("")
}

internal enum class Color(ansiCode: Int) {
NONE(0),
BLACK(30),
RED(31),
GREEN(32),
YELLOW(33),
BLUE(34),
PURPLE(35),
CYAN(36),
WHITE(37);

private val ansiString: String = "\u001B[${ansiCode}m"

override fun toString(): String {
return ansiString
}
}

// Run :tag only after we've published artifacts to sonatype
tasks.withType<TagTask>().configureEach {
// don't apply when "dryRun"
Expand All @@ -171,6 +49,8 @@ tasks.withType<TagTask>().configureEach {
}
}

apiValidation {
ignoredProjects += listOf("bom", "cli-bot", /*"docs",*/ "test")
}
configureGradleDaemonJvm(
project = project,
updateDaemonJvm = tasks.updateDaemonJvm,
gradleDaemonJvmVersion = libs.versions.gradleDaemonJvm.map { JavaVersion.toVersion(it) },
)
9 changes: 8 additions & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
plugins {
`kotlin-dsl`
kotlin("jvm") version embeddedKotlinVersion
// kotlin("jvm") version embeddedKotlinVersion
}

dependencies {
//https://github.com/gradle/gradle/issues/15383#issuecomment-779893192
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
implementation(platform(libs.kotlin.bom))
implementation(libs.gradle.plugin.devpublish) // TODO move to plugins bundle
// needed to be able to apply external plugin
// https://docs.gradle.org/current/userguide/custom_plugins.html#applying_external_plugins_in_precompiled_script_plugins
implementation(libs.bundles.gradle.plugins)
Expand All @@ -15,3 +16,9 @@ dependencies {
// use snakeyaml instead of jackson-dataformat-yaml to properly handle yaml anchors and write them as actual values to json
implementation(libs.snakeyaml)
}

tasks.withType<AbstractArchiveTask>().configureEach {
// https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
15 changes: 10 additions & 5 deletions buildSrc/src/main/kotlin/Publishing.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import gradle.kotlin.dsl.accessors._617ff5292df7551646490c1442241820.dokkaJavadoc
import gradle.kotlin.dsl.accessors._617ff5292df7551646490c1442241820.sourceSets
import org.gradle.api.Project
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.bundling.Jar
import org.gradle.configurationcache.extensions.capitalized
import org.gradle.kotlin.dsl.creating
import org.gradle.kotlin.dsl.getByName
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.getValue
import org.jetbrains.dokka.gradle.DokkaTask

//region manually define accessors, because IntelliJ _still_ doesn't index them properly :(
internal val Project.sourceSets: SourceSetContainer get() = extensions.getByType()
//endregion

/**
* For additional providers, use a combination of rootProject and subproject names for artifact name and similar things.
Expand All @@ -30,8 +35,8 @@ private fun createSourcesJarTask(p: Project): Jar {
private fun createJavadocJarTask(p: Project): Jar {
val dokkaJavadocJar by p.tasks.creating(Jar::class) {
archiveClassifier.set("javadoc")
dependsOn(p.tasks.dokkaJavadoc)
from(p.tasks.dokkaJavadoc.get().outputDirectory.orNull)
dependsOn(p.tasks.getByName("dokkaJavadoc", DokkaTask::class))
from(p.tasks.getByName("dokkaJavadoc", DokkaTask::class).outputDirectory.orNull)
}
return dokkaJavadocJar
}
Expand Down
79 changes: 1 addition & 78 deletions buildSrc/src/main/kotlin/faker-base-conventions.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,87 +1,10 @@
import gradle.kotlin.dsl.accessors._617ff5292df7551646490c1442241820.assemble
import gradle.kotlin.dsl.accessors._617ff5292df7551646490c1442241820.jar
import gradle.kotlin.dsl.accessors._617ff5292df7551646490c1442241820.sourceSets
import gradle.kotlin.dsl.accessors._617ff5292df7551646490c1442241820.test
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.creating
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.getValue
import org.gradle.kotlin.dsl.invoke
import org.gradle.kotlin.dsl.withType
import org.jetbrains.dokka.gradle.DokkaTask

/**
* Plugin for base build setup of faker modules with kotlin
*/

plugins {
base
kotlin("jvm")
id("org.jetbrains.dokka")
}

configurations {
create("integrationImplementation") { extendsFrom(configurations.getByName("testImplementation")) }
create("integrationRuntimeOnly") {
if (isShadow) {
extendsFrom(
configurations.getByName("testRuntimeOnly"),
configurations.getByName("shadow"),
)
} else {
extendsFrom(configurations.getByName("testRuntimeOnly"))
}
}
}

// configure sourceSets as extension since it's not available here as `sourceSets` is an extension on `Project`
// https://docs.gradle.org/current/userguide/kotlin_dsl.html#project_extensions_and_conventions
configure<SourceSetContainer> {
create("integration") {
resources.srcDir("src/integration/resources")
compileClasspath += main.get().compileClasspath + test.get().compileClasspath
runtimeClasspath += main.get().runtimeClasspath + test.get().runtimeClasspath
}
main {
resources {
this.srcDir("build/generated/src/main/resources")
}
}
}

val integrationTest: Test by tasks.creating(Test::class) {
testClassesDirs = sourceSets["integration"].output.classesDirs
classpath = sourceSets["integration"].runtimeClasspath
}

tasks.withType<Jar> {
archiveBaseName.set(fullName)

manifest {
attributes(
mapOf(
"Implementation-Title" to fullName,
"Implementation-Version" to project.version,
/*
* We can't add this here because this resolves the configuration,
* after which it effectively becomes read-only and we'll get an error
* Cannot change dependencies of dependency configuration ':core:implementation' after it has been included in dependency resolution
* if we try to add more dependencies in the module's build.gradle file directly
*/
// "Class-Path" to project.configurations.compileClasspath.get().joinToString(" ") { it.name }
)
)
}
}

tasks {
getByName(integrationTest.name).dependsOn(test)
jar { dependsOn(integrationTest) }
}
group = rootProject.group.toString()

tasks.withType<DokkaTask>().configureEach {
onlyIf("Not dev") { !isDev.get() }
onlyIf("Release or snapshot") { isRelease.get() || isSnapshot.get() }
}
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/faker-ext-conventions.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/

plugins {
id("faker-base-conventions")
id("faker-kotlin-conventions")
id("faker-pub-conventions")
}

Expand Down
Loading

0 comments on commit 41e60fb

Please sign in to comment.