set up convention plugins

- tidy up build scripts to use convention plugins
- use centralised repo definition
- tidy up some of the build config
This commit is contained in:
Adam 2023-05-31 21:10:57 +02:00
parent 34b69a7d1f
commit 93e113fa69
14 changed files with 498 additions and 141 deletions

View file

@ -0,0 +1,9 @@
plugins {
`kotlin-dsl`
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0")
implementation("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.5.0.2730")
implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.7.20")
}

View file

@ -0,0 +1,16 @@
rootProject.name = "buildSrc"
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
}
@Suppress("UnstableApiUsage")
dependencyResolutionManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
}

View file

@ -0,0 +1,18 @@
package buildsrc.conventions
/** common config for all subprojects */
plugins {
base
}
if (project != rootProject) {
project.version = rootProject.version
project.group = rootProject.group
}
tasks.withType<AbstractArchiveTask>().configureEach {
// https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}

View file

@ -0,0 +1,45 @@
package buildsrc.conventions.lang
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
/**
* Base configuration for all Kotlin/Multiplatform conventions.
*
* This plugin does not enable any Kotlin target. To enable a target in a subproject, prefer applying specific Kotlin
* target convention plugins.
*/
plugins {
id("buildsrc.conventions.base")
kotlin("multiplatform")
}
kotlin {
jvmToolchain(11)
targets.configureEach {
compilations.configureEach {
kotlinOptions {
// nothin' yet
}
}
}
// configure all Kotlin/JVM Tests to use JUnit
targets.withType<KotlinJvmTarget>().configureEach {
testRuns.configureEach {
executionTask.configure {
useJUnitPlatform()
}
}
}
sourceSets.configureEach {
languageSettings {
// languageVersion =
// apiVersion =
}
}
}

View file

@ -0,0 +1,18 @@
package buildsrc.conventions.lang
/** conventions for a Kotlin/JS subproject */
plugins {
id("buildsrc.conventions.lang.kotlin-multiplatform-base")
}
kotlin {
targets {
js(IR) {
browser()
nodejs()
}
}
}
relocateKotlinJsStore()

View file

@ -0,0 +1,11 @@
package buildsrc.conventions.lang
plugins {
id("buildsrc.conventions.lang.kotlin-multiplatform-base")
}
kotlin {
jvm {
withJava()
}
}

View file

@ -0,0 +1,102 @@
package buildsrc.conventions.lang
/** conventions for a Kotlin/Native subproject */
plugins {
id("buildsrc.conventions.lang.kotlin-multiplatform-base")
}
kotlin {
// Native targets all extend commonMain and commonTest.
//
// Some targets (ios, tvos, watchos) are shortcuts provided by the Kotlin DSL, that
// provide additional targets, except for 'simulators' which must be defined manually.
// https://kotlinlang.org/docs/multiplatform-share-on-platforms.html#use-target-shortcuts
//
// common/
// └── native/
// ├── linuxX64
// ├── mingwX64
// ├── macosX64
// ├── macosArm64
// ├── ios/ (shortcut)
// │ ├── iosArm64
// │ ├── iosX64
// │ └── iosSimulatorArm64
// ├── tvos/ (shortcut)
// │ ├── tvosArm64
// │ ├── tvosX64
// │ └── tvosSimulatorArm64Main
// └── watchos/ (shortcut)
// ├── watchosArm32
// ├── watchosArm64
// ├── watchosX64
// └── watchosSimulatorArm64Main
targets {
linuxX64()
mingwX64()
macosX64()
macosArm64()
// https://kotlinlang.org/docs/multiplatform-share-on-platforms.html#use-target-shortcuts
ios() // iosArm64, iosX64
watchos() // watchosArm32, watchosArm64, watchosX64
tvos() // tvosArm64, tvosX64
iosSimulatorArm64()
tvosSimulatorArm64()
watchosSimulatorArm64()
}
@Suppress("UNUSED_VARIABLE")
sourceSets {
val commonMain by getting {}
val commonTest by getting {}
val nativeMain by creating { dependsOn(commonMain) }
val nativeTest by creating { dependsOn(commonTest) }
// Linux
val linuxX64Main by getting { dependsOn(nativeMain) }
val linuxX64Test by getting { dependsOn(nativeTest) }
// Windows - MinGW
val mingwX64Main by getting { dependsOn(nativeMain) }
val mingwX64Test by getting { dependsOn(nativeTest) }
// Apple - macOS
val macosArm64Main by getting { dependsOn(nativeMain) }
val macosArm64Test by getting { dependsOn(nativeTest) }
val macosX64Main by getting { dependsOn(nativeMain) }
val macosX64Test by getting { dependsOn(nativeTest) }
// Apple - iOS
val iosMain by getting { dependsOn(nativeMain) }
val iosTest by getting { dependsOn(nativeTest) }
// val iosSimulatorArm64Main by getting { dependsOn(iosMain) }
// val iosSimulatorArm64Test by getting { dependsOn(iosTest) }
// // Apple - tvOS
// val tvosMain by getting { dependsOn(nativeMain) }
// val tvosTest by getting { dependsOn(nativeTest) }
//
// val tvosSimulatorArm64Main by getting { dependsOn(tvosMain) }
// val tvosSimulatorArm64Test by getting { dependsOn(tvosTest) }
//
// // Apple - watchOS
// val watchosMain by getting { dependsOn(nativeMain) }
// val watchosTest by getting { dependsOn(nativeTest) }
//
// val watchosSimulatorArm64Main by getting { dependsOn(watchosMain) }
// val watchosSimulatorArm64Test by getting { dependsOn(watchosTest) }
// val iosArm32Main by getting { dependsOn(desktopMain) }
// val iosArm32Test by getting { dependsOn(nativeTest) }
}
}

View file

@ -0,0 +1,18 @@
package buildsrc.conventions.lang
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension
/**
* `kotlin-js` and `kotlin-multiplatform` plugins adds a directory in the root-dir for the Yarn
* lockfile. That's a bit annoying. It's a little neater if it's in the Gradle dir, next to the
* version catalog.
*/
internal fun Project.relocateKotlinJsStore() {
afterEvaluate {
rootProject.extensions.configure<YarnRootExtension> {
lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store")
}
}
}

View file

@ -0,0 +1,102 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Copyright 2022-2023 Erik C. Thauvin (erik@thauvin.net)
*
* 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
*
* http://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 buildsrc.conventions
import org.gradle.api.tasks.bundling.Jar
import org.gradle.kotlin.dsl.creating
import org.gradle.kotlin.dsl.getValue
import org.gradle.kotlin.dsl.version
plugins {
id("maven-publish")
id("signing")
id("org.jetbrains.dokka")
}
val gitHub = "ethauvin/${rootProject.name}"
val mavenUrl = "https://github.com/$gitHub"
publishing {
publications {
withType<MavenPublication>().configureEach {
pom {
name.set("UrlEncoder for Kotlin")
description.set(project.description)
url.set(mavenUrl)
licenses {
license {
name.set("The Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
developers {
developer {
id.set("gbevin")
name.set("Geert Bevin")
email.set("gbevin@uwyn.com")
url.set("https://github.com/gbevin")
}
developer {
id.set("ethauvin")
name.set("Erik C. Thauvin")
email.set("erik@thauvin.net")
url.set("https://erik.thauvin.net/")
}
}
scm {
connection.set("scm:git://github.com/$gitHub.git")
developerConnection.set("scm:git@github.com:$gitHub.git")
url.set(mavenUrl)
}
issueManagement {
system.set("GitHub")
url.set("$mavenUrl/issues")
}
}
}
}
repositories {
maven(
if (project.version.toString().contains("SNAPSHOT")) {
uri("https://oss.sonatype.org/content/repositories/snapshots/")
} else {
uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
}
) {
name = "ossrh"
credentials(PasswordCredentials::class)
}
}
}
signing {
useGpgCmd()
sign(publishing.publications)
}
// https://youtrack.jetbrains.com/issue/KT-46466
val signingTasks = tasks.withType<Sign>()
tasks.withType<AbstractPublishToMaven>().configureEach {
dependsOn(signingTasks)
}
val javadocJar by tasks.registering(Jar::class) {
dependsOn(tasks.dokkaJavadoc)
from(tasks.dokkaJavadoc)
archiveClassifier.set("javadoc")
}

View file

@ -0,0 +1,33 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Copyright 2022-2023 Erik C. Thauvin (erik@thauvin.net)
*
* 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
*
* http://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 buildsrc.conventions
plugins {
id("org.sonarqube")
}
sonarqube {
properties {
property("sonar.projectName", rootProject.name)
property("sonar.projectKey", "ethauvin_${rootProject.name}")
property("sonar.organization", "ethauvin-github")
property("sonar.host.url", "https://sonarcloud.io")
property("sonar.sourceEncoding", "UTF-8")
property("sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/kover/xml/report.xml")
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Copyright 2022-2023 Erik C. Thauvin (erik@thauvin.net)
*
* 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
*
* http://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 buildsrc.utils
import org.gradle.api.tasks.testing.TestDescriptor
import org.gradle.api.tasks.testing.TestListener
import org.gradle.api.tasks.testing.TestResult
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
class Rife2TestListener(
private val testBadgeApiKey: String?
) : TestListener {
override fun beforeTest(p0: TestDescriptor?) = Unit
override fun beforeSuite(p0: TestDescriptor?) = Unit
override fun afterTest(desc: TestDescriptor, result: TestResult) = Unit
override fun afterSuite(desc: TestDescriptor, result: TestResult) {
if (desc.parent == null) {
val passed = result.successfulTestCount
val failed = result.failedTestCount
val skipped = result.skippedTestCount
if (testBadgeApiKey != null) {
println(testBadgeApiKey)
val response: HttpResponse<String> = HttpClient.newHttpClient()
.send(
HttpRequest.newBuilder()
.uri(
URI(
"https://rife2.com/tests-badge/update/net.thauvin.erik/urlencoder?" +
"apiKey=$testBadgeApiKey&" +
"passed=$passed&" +
"failed=$failed&" +
"skipped=$skipped"
)
)
.POST(HttpRequest.BodyPublishers.noBody())
.build(), HttpResponse.BodyHandlers.ofString()
)
println("RESPONSE: ${response.statusCode()}")
println(response.body())
}
}
}
}