From a3d973100aee3b95cba4e3b26db9295742d94f01 Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Wed, 31 May 2023 20:51:03 +0200
Subject: [PATCH 01/10] tidy up the .gitignore
---
.gitignore | 152 ++++++++++++++++++++++++-----------------------------
1 file changed, 70 insertions(+), 82 deletions(-)
diff --git a/.gitignore b/.gitignore
index 13a066e..cd21c82 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,85 +1,73 @@
-!.vscode/extensions.json
-!.vscode/launch.json
-!.vscode/settings.json
-!.vscode/tasks.json
-*.class
-*.code-workspace
-*.ctxt
-*.iws
-*.log
-*.nar
-*.rar
-*.sublime-*
-*.tar.gz
-*.zip
-.DS_Store
-.classpath
+### Gradle ###
.gradle
-.history
-.kobalt
-.mtj.tmp/
-.mvn/timing.properties
-.mvn/wrapper/maven-wrapper.jar
-.nb-gradle
-.project
-.scannerwork
-.settings
-.vscode/*
-/**/.idea/$CACHE_FILE$
-/**/.idea/$PRODUCT_WORKSPACE_FILE$
-/**/.idea/**/caches/build_file_checksums.ser
-/**/.idea/**/contentModel.xml
-/**/.idea/**/dataSources.ids
-/**/.idea/**/dataSources.local.xml
-/**/.idea/**/dataSources/
-/**/.idea/**/dbnavigator.xml
-/**/.idea/**/dictionaries
-/**/.idea/**/dynamic.xml
-/**/.idea/**/gradle.xml
-/**/.idea/**/httpRequests
-/**/.idea/**/libraries
-/**/.idea/**/mongoSettings.xml
-/**/.idea/**/replstate.xml
-/**/.idea/**/shelf
-/**/.idea/**/shelf/
-/**/.idea/**/sqlDataSources.xml
-/**/.idea/**/tasks.xml
-/**/.idea/**/uiDesigner.xml
-/**/.idea/**/usage.statistics.xml
-/**/.idea/**/workspace.xml
-/**/.idea/sonarlint*
-/**/.idea_modules/
-Thumbs.db
-__pycache__
-atlassian-ide-plugin.xml
-bin/
build/
-cmake-build-*/
-com_crashlytics_export_strings.xml
-crashlytics-build.properties
-crashlytics.properties
-dependency-reduced-pom.xml
-deploy/
-dist/
-ehthumbs.db
-fabric.properties
-gen/
-gradle.properties
+
+!gradle/wrapper/gradle-wrapper.jar
+!gradle/wrapper/gradle-wrapper.properties
+
+
+### Kotlin/JVM ###
+*.class
+*.log
+
hs_err_pid*
-kobaltBuild
-kobaltw*-test
-lib/kotlin*
-libs/
-local.properties
-out/
-pom.xml.asc
-pom.xml.next
-pom.xml.releaseBackup
-pom.xml.tag
-pom.xml.versionsBackup
-proguard-project.txt
-project.properties
-release.properties
-target/
-test-output
-venv
+replay_pid*
+*.hprof
+
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+
+### IntelliJ ###
+.idea/**/*
+!.idea/copyright/
+!.idea/copyright/**
+!.idea/inspectionProfiles/
+!.idea/inspectionProfiles/**
+
+
+### Eclipse ###
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+.settings/
+.loadpath
+.recommenders
+.classpath
+
+.apt_generated/
+.apt_generated_test/
+.project
+
+
+### Linux ###
+*~
+.fuse_hidden*
+.Trash-*
+.nfs*
+
+
+### Windows ###
+[Dd]esktop.ini
+$RECYCLE.BIN/
+*.lnk
+
+
+### macOS ###
+.DS_Store
+._*
+
+# Icon must end with two \r
+Icon
+
+
+###########################
From 425e79eb383ea3ed2b14e4671c38ca97d8d86ddc Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Wed, 31 May 2023 20:58:41 +0200
Subject: [PATCH 02/10] rm .idea files
---
.idea/.gitignore | 3 ---
.idea/compiler.xml | 6 -----
.idea/inspectionProfiles/Project_Default.xml | 8 -------
.idea/jarRepositories.xml | 25 --------------------
.idea/kotlinc.xml | 6 -----
.idea/misc.xml | 8 -------
.idea/vcs.xml | 6 -----
7 files changed, 62 deletions(-)
delete mode 100644 .idea/.gitignore
delete mode 100644 .idea/compiler.xml
delete mode 100644 .idea/inspectionProfiles/Project_Default.xml
delete mode 100644 .idea/jarRepositories.xml
delete mode 100644 .idea/kotlinc.xml
delete mode 100644 .idea/misc.xml
delete mode 100644 .idea/vcs.xml
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 26d3352..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index fb7f4a8..0000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 1e01b48..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
deleted file mode 100644
index cfd3ca8..0000000
--- a/.idea/jarRepositories.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
deleted file mode 100644
index 2b8a50f..0000000
--- a/.idea/kotlinc.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 2540c68..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
From c9bbe70fbba38832f32c68e27fbc8fe91d389fb6 Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Wed, 31 May 2023 20:58:52 +0200
Subject: [PATCH 03/10] put git overrides last
---
.gitignore | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/.gitignore b/.gitignore
index cd21c82..b63b9be 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,10 +2,6 @@
.gradle
build/
-!gradle/wrapper/gradle-wrapper.jar
-!gradle/wrapper/gradle-wrapper.properties
-
-
### Kotlin/JVM ###
*.class
*.log
@@ -25,11 +21,6 @@ replay_pid*
### IntelliJ ###
.idea/**/*
-!.idea/copyright/
-!.idea/copyright/**
-!.idea/inspectionProfiles/
-!.idea/inspectionProfiles/**
-
### Eclipse ###
.metadata
@@ -71,3 +62,10 @@ Icon
###########################
+
+# place overrides last, so they're not themselves overridden
+
+!gradle/wrapper/gradle-wrapper.jar
+!gradle/wrapper/gradle-wrapper.properties
+
+!.idea/copyright/**
From 93e113fa69d4895be38035b9840fd641ce0e1564 Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Wed, 31 May 2023 21:10:57 +0200
Subject: [PATCH 04/10] set up convention plugins
- tidy up build scripts to use convention plugins
- use centralised repo definition
- tidy up some of the build config
---
build.gradle.kts | 24 +++
buildSrc/build.gradle.kts | 9 ++
buildSrc/settings.gradle.kts | 16 ++
.../buildsrc/conventions/base.gradle.kts | 18 +++
.../lang/kotlin-multiplatform-base.gradle.kts | 45 ++++++
.../lang/kotlin-multiplatform-js.gradle.kts | 18 +++
.../lang/kotlin-multiplatform-jvm.gradle.kts | 11 ++
.../kotlin-multiplatform-native.gradle.kts | 102 ++++++++++++
.../conventions/lang/kotlinJsExtensions.kt | 18 +++
.../conventions/publishing.gradle.kts | 102 ++++++++++++
.../buildsrc/conventions/sonarqube.gradle.kts | 33 ++++
.../buildsrc/utils/Rife2TestListener.kt | 62 ++++++++
lib/build.gradle.kts | 146 ++----------------
settings.gradle.kts | 35 +++--
14 files changed, 498 insertions(+), 141 deletions(-)
create mode 100644 build.gradle.kts
create mode 100644 buildSrc/build.gradle.kts
create mode 100644 buildSrc/settings.gradle.kts
create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-base.gradle.kts
create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-js.gradle.kts
create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-jvm.gradle.kts
create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-native.gradle.kts
create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlinJsExtensions.kt
create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts
create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/sonarqube.gradle.kts
create mode 100644 buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000..7b93509
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+plugins {
+ buildsrc.conventions.base
+}
+
+description = "A simple defensive library to encode/decode URL components"
+group = "net.thauvin.erik"
+version = "1.3.1-SNAPSHOT"
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
new file mode 100644
index 0000000..be67fdf
--- /dev/null
+++ b/buildSrc/build.gradle.kts
@@ -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")
+}
diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts
new file mode 100644
index 0000000..bf6ac65
--- /dev/null
+++ b/buildSrc/settings.gradle.kts
@@ -0,0 +1,16 @@
+rootProject.name = "buildSrc"
+
+pluginManagement {
+ repositories {
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+@Suppress("UnstableApiUsage")
+dependencyResolutionManagement {
+ repositories {
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
new file mode 100644
index 0000000..0ef8540
--- /dev/null
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
@@ -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().configureEach {
+ // https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives
+ isPreserveFileTimestamps = false
+ isReproducibleFileOrder = true
+}
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-base.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-base.gradle.kts
new file mode 100644
index 0000000..4af978b
--- /dev/null
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-base.gradle.kts
@@ -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().configureEach {
+ testRuns.configureEach {
+ executionTask.configure {
+ useJUnitPlatform()
+ }
+ }
+ }
+
+ sourceSets.configureEach {
+ languageSettings {
+// languageVersion =
+// apiVersion =
+ }
+ }
+}
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-js.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-js.gradle.kts
new file mode 100644
index 0000000..2a0034a
--- /dev/null
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-js.gradle.kts
@@ -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()
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-jvm.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-jvm.gradle.kts
new file mode 100644
index 0000000..6bbef24
--- /dev/null
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-jvm.gradle.kts
@@ -0,0 +1,11 @@
+package buildsrc.conventions.lang
+
+plugins {
+ id("buildsrc.conventions.lang.kotlin-multiplatform-base")
+}
+
+kotlin {
+ jvm {
+ withJava()
+ }
+}
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-native.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-native.gradle.kts
new file mode 100644
index 0000000..7e8bb2a
--- /dev/null
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-multiplatform-native.gradle.kts
@@ -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) }
+ }
+}
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlinJsExtensions.kt b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlinJsExtensions.kt
new file mode 100644
index 0000000..eefdc94
--- /dev/null
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlinJsExtensions.kt
@@ -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 {
+ lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store")
+ }
+ }
+}
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts
new file mode 100644
index 0000000..4c26d99
--- /dev/null
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts
@@ -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().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()
+tasks.withType().configureEach {
+ dependsOn(signingTasks)
+}
+
+val javadocJar by tasks.registering(Jar::class) {
+ dependsOn(tasks.dokkaJavadoc)
+ from(tasks.dokkaJavadoc)
+ archiveClassifier.set("javadoc")
+}
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/sonarqube.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/sonarqube.gradle.kts
new file mode 100644
index 0000000..80ce521
--- /dev/null
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/sonarqube.gradle.kts
@@ -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")
+ }
+}
diff --git a/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt b/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt
new file mode 100644
index 0000000..2fe062f
--- /dev/null
+++ b/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt
@@ -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 = 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())
+ }
+ }
+ }
+}
diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts
index 5b12abf..9b81aef 100644
--- a/lib/build.gradle.kts
+++ b/lib/build.gradle.kts
@@ -1,11 +1,8 @@
+import buildsrc.utils.Rife2TestListener
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-import java.net.URI
-import java.net.http.HttpClient
-import java.net.http.HttpRequest
-import java.net.http.HttpResponse
plugins {
@@ -14,30 +11,20 @@ plugins {
id("io.gitlab.arturbosch.detekt") version "1.22.0"
id("java-library")
id("maven-publish")
- id("org.jetbrains.dokka") version "1.7.20"
- id("org.jetbrains.kotlin.jvm") version "1.8.0"
+ id("org.jetbrains.kotlin.jvm")
id("org.jetbrains.kotlinx.kover") version "0.6.1"
- id("org.sonarqube") version "3.5.0.2730"
- id("signing")
+
+ buildsrc.conventions.publishing
+ buildsrc.conventions.sonarqube
}
-description = "A simple defensive library to encode/decode URL components"
-group = "net.thauvin.erik"
-version = "1.3.1-SNAPSHOT"
-
-
val mavenName = "UrlEncoder"
-val deployDir = "deploy"
+val deployDir = project.layout.projectDirectory.dir("deploy")
val gitHub = "ethauvin/${rootProject.name}"
val mavenUrl = "https://github.com/$gitHub"
val publicationName = "mavenJava"
val myClassName = "$group.${rootProject.name}.$mavenName"
-repositories {
- mavenCentral()
- maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots") }
-}
-
dependencies {
// testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.25")
testImplementation("org.junit.jupiter:junit-jupiter:5.9.1")
@@ -57,23 +44,6 @@ application {
mainClass.set(myClassName)
}
-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")
- }
-}
-
-val javadocJar by tasks.creating(Jar::class) {
- dependsOn(tasks.dokkaJavadoc)
- from(tasks.dokkaJavadoc)
- archiveClassifier.set("javadoc")
-}
-
tasks {
jar {
manifest {
@@ -102,58 +72,23 @@ tasks {
}
test {
- useJUnitPlatform()
- addTestListener(object : 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 (project.properties["testsBadgeApiKey"] != null) {
- val apiKey = project.properties["testsBadgeApiKey"]
- println(apiKey)
- val response: HttpResponse = HttpClient.newHttpClient()
- .send(
- HttpRequest.newBuilder()
- .uri(
- URI(
- "https://rife2.com/tests-badge/update/net.thauvin.erik/urlencoder?" +
- "apiKey=$apiKey&" +
- "passed=$passed&" +
- "failed=$failed&" +
- "skipped=$skipped"
- )
- )
- .POST(HttpRequest.BodyPublishers.noBody())
- .build(), HttpResponse.BodyHandlers.ofString()
- )
- println("RESPONSE: ${response.statusCode()}")
- println(response.body())
- }
- }
- }
- })
+ addTestListener(Rife2TestListener(project.properties["testsBadgeApiKey"]?.toString()))
}
withType {
+ useJUnitPlatform()
testLogging {
exceptionFormat = TestExceptionFormat.FULL
events = setOf(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
}
}
- withType {
+ withType().configureEach {
destination = file("$projectDir/pom.xml")
}
clean {
- doLast {
- project.delete(fileTree(deployDir))
- }
+ delete(deployDir)
}
withType().configureEach {
@@ -164,7 +99,7 @@ tasks {
}
}
- val copyToDeploy by registering(Copy::class) {
+ val copyToDeploy by registering(Sync::class) {
from(configurations.runtimeClasspath) {
exclude("annotations-*.jar")
}
@@ -173,12 +108,11 @@ tasks {
}
register("deploy") {
- description = "Copies all needed files to the $deployDir directory."
+ description = "Copies all needed files to the 'deploy' directory."
group = PublishingPlugin.PUBLISH_TASK_GROUP
- dependsOn(clean, build, jar)
+ dependsOn(build, jar)
outputs.dir(deployDir)
inputs.files(copyToDeploy)
- mustRunAfter(clean)
}
"sonar" {
@@ -188,58 +122,10 @@ tasks {
publishing {
publications {
- create(publicationName) {
+ create("mavenJava") {
from(components["java"])
- artifactId = rootProject.name
- artifact(javadocJar)
- pom {
- name.set("$mavenName 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 {
- name = "ossrh"
- url = 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/")
- credentials(PasswordCredentials::class)
+ artifactId = "${rootProject.name}-lib"
+ artifact(tasks.javadocJar)
}
}
}
-
-signing {
- useGpgCmd()
- sign(publishing.publications[publicationName])
-}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 0cb10ee..e75db1d 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,12 +1,25 @@
-/*
- * This file was generated by the Gradle 'init' task.
- *
- * The settings file is used to specify which projects to include in your build.
- *
- * Detailed information about configuring a multi-project build in Gradle can be found
- * in the user manual at https://docs.gradle.org/7.6/userguide/multi_project_builds.html
- * This project uses @Incubating APIs which are subject to change.
- */
-
rootProject.name = "urlencoder"
-include("lib")
+
+pluginManagement {
+ repositories {
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+@Suppress("UnstableApiUsage")
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
+
+ repositories {
+ mavenCentral()
+ maven("https://oss.sonatype.org/content/repositories/snapshots") {
+ name = "Sonatype Snapshots"
+ mavenContent { snapshotsOnly() }
+ }
+ }
+}
+
+include(
+ ":lib",
+)
From 4d294bfee8cd5d269a1e58c85b6b0281bec4461c Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Wed, 31 May 2023 21:18:10 +0200
Subject: [PATCH 05/10] tidy up build config
---
build.gradle.kts | 1 -
lib/build.gradle.kts | 24 +++++++++++-------------
2 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/build.gradle.kts b/build.gradle.kts
index 7b93509..3dd9d03 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -19,6 +19,5 @@ plugins {
buildsrc.conventions.base
}
-description = "A simple defensive library to encode/decode URL components"
group = "net.thauvin.erik"
version = "1.3.1-SNAPSHOT"
diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts
index 9b81aef..13e8a6a 100644
--- a/lib/build.gradle.kts
+++ b/lib/build.gradle.kts
@@ -18,12 +18,10 @@ plugins {
buildsrc.conventions.sonarqube
}
-val mavenName = "UrlEncoder"
+description = "A simple defensive library to encode/decode URL components"
+
val deployDir = project.layout.projectDirectory.dir("deploy")
-val gitHub = "ethauvin/${rootProject.name}"
-val mavenUrl = "https://github.com/$gitHub"
-val publicationName = "mavenJava"
-val myClassName = "$group.${rootProject.name}.$mavenName"
+val mainClassName = "net.thauvin.erik.urlencoder.UrlEncoder"
dependencies {
// testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.25")
@@ -41,18 +39,18 @@ java {
}
application {
- mainClass.set(myClassName)
+ mainClass.set(mainClassName)
}
tasks {
jar {
manifest {
- attributes["Main-Class"] = myClassName
+ attributes["Main-Class"] = mainClassName
}
}
- val fatJar = register("fatJar") {
- group = "build"
+ val fatJar by registering(Jar::class) {
+ group = LifecycleBasePlugin.BUILD_GROUP
dependsOn.addAll(listOf("compileJava", "compileKotlin", "processResources"))
archiveClassifier.set("all")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
@@ -75,7 +73,7 @@ tasks {
addTestListener(Rife2TestListener(project.properties["testsBadgeApiKey"]?.toString()))
}
- withType {
+ withType().configureEach {
useJUnitPlatform()
testLogging {
exceptionFormat = TestExceptionFormat.FULL
@@ -100,6 +98,8 @@ tasks {
}
val copyToDeploy by registering(Sync::class) {
+ description = "Copies all needed files to the 'deploy' directory."
+ group = PublishingPlugin.PUBLISH_TASK_GROUP
from(configurations.runtimeClasspath) {
exclude("annotations-*.jar")
}
@@ -110,9 +110,7 @@ tasks {
register("deploy") {
description = "Copies all needed files to the 'deploy' directory."
group = PublishingPlugin.PUBLISH_TASK_GROUP
- dependsOn(build, jar)
- outputs.dir(deployDir)
- inputs.files(copyToDeploy)
+ dependsOn(build, copyToDeploy)
}
"sonar" {
From 61b51824fd098ace4f255aadbfddf42a5b6eafd6 Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Wed, 31 May 2023 21:27:52 +0200
Subject: [PATCH 06/10] define all plugins in `buildSrc/build.gradle.kts`, and
bump Kover version
---
buildSrc/build.gradle.kts | 11 +++++++----
lib/build.gradle.kts | 6 +++---
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index be67fdf..788b119 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -1,9 +1,12 @@
plugins {
- `kotlin-dsl`
+ `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")
+ implementation("com.github.ben-manes:gradle-versions-plugin:0.44.0")
+ implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.22.0")
+ implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.7.20")
+ implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.0")
+ implementation("org.jetbrains.kotlinx:kover-gradle-plugin:0.7.0")
+ implementation("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.5.0.2730")
}
diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts
index 13e8a6a..6ebdf1d 100644
--- a/lib/build.gradle.kts
+++ b/lib/build.gradle.kts
@@ -7,12 +7,12 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("application")
- id("com.github.ben-manes.versions") version "0.44.0"
- id("io.gitlab.arturbosch.detekt") version "1.22.0"
+ id("com.github.ben-manes.versions")
+ id("io.gitlab.arturbosch.detekt")
id("java-library")
id("maven-publish")
id("org.jetbrains.kotlin.jvm")
- id("org.jetbrains.kotlinx.kover") version "0.6.1"
+ id("org.jetbrains.kotlinx.kover")
buildsrc.conventions.publishing
buildsrc.conventions.sonarqube
From b2d20e93ed24e0a4bb14813d71f16a99d547b23b Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Wed, 31 May 2023 21:33:33 +0200
Subject: [PATCH 07/10] add `deploy/` dir
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index b63b9be..2a8f5da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
### Gradle ###
.gradle
build/
+deploy/
### Kotlin/JVM ###
*.class
From 6670346890c751429f1f0ea1cbfe2e6239597122 Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Wed, 31 May 2023 22:48:49 +0200
Subject: [PATCH 08/10] tweaks and fixes
- introduce kotlin-jvm convention
- tidy up code-quality build config
---
.../buildsrc/conventions/base.gradle.kts | 25 ++++++--
...ube.gradle.kts => code-quality.gradle.kts} | 26 +++++---
.../conventions/lang/kotlin-jvm.gradle.kts | 42 +++++++++++++
.../buildsrc/utils/Rife2TestListener.kt | 63 ++++++++++---------
lib/build.gradle.kts | 52 +++------------
5 files changed, 119 insertions(+), 89 deletions(-)
rename buildSrc/src/main/kotlin/buildsrc/conventions/{sonarqube.gradle.kts => code-quality.gradle.kts} (52%)
create mode 100644 buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-jvm.gradle.kts
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
index 0ef8540..7404066 100644
--- a/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
@@ -1,18 +1,31 @@
package buildsrc.conventions
+import buildsrc.utils.Rife2TestListener
+import org.gradle.api.tasks.testing.logging.TestExceptionFormat
+import org.gradle.api.tasks.testing.logging.TestLogEvent
+
/** common config for all subprojects */
plugins {
- base
+ base
}
if (project != rootProject) {
- project.version = rootProject.version
- project.group = rootProject.group
+ project.version = rootProject.version
+ project.group = rootProject.group
}
tasks.withType().configureEach {
- // https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives
- isPreserveFileTimestamps = false
- isReproducibleFileOrder = true
+ // https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives
+ isPreserveFileTimestamps = false
+ isReproducibleFileOrder = true
+}
+
+tasks.withType().configureEach {
+ val testsBadgeApiKey = providers.gradleProperty("testsBadgeApiKey")
+ addTestListener(Rife2TestListener(testsBadgeApiKey))
+ testLogging {
+ exceptionFormat = TestExceptionFormat.FULL
+ events = setOf(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
+ }
}
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/sonarqube.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/code-quality.gradle.kts
similarity index 52%
rename from buildSrc/src/main/kotlin/buildsrc/conventions/sonarqube.gradle.kts
rename to buildSrc/src/main/kotlin/buildsrc/conventions/code-quality.gradle.kts
index 80ce521..a81b982 100644
--- a/buildSrc/src/main/kotlin/buildsrc/conventions/sonarqube.gradle.kts
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/code-quality.gradle.kts
@@ -17,17 +17,25 @@
package buildsrc.conventions
+import org.sonarqube.gradle.SonarTask
+
plugins {
- id("org.sonarqube")
+ id("org.sonarqube")
+ id("io.gitlab.arturbosch.detekt")
+ id("org.jetbrains.kotlinx.kover")
}
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")
- }
+ 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/report.xml")
+ }
+}
+
+tasks.withType().configureEach {
+ dependsOn(tasks.matching { it.name == "koverXmlReport" })
}
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-jvm.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-jvm.gradle.kts
new file mode 100644
index 0000000..790e694
--- /dev/null
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/lang/kotlin-jvm.gradle.kts
@@ -0,0 +1,42 @@
+package buildsrc.conventions.lang
+
+import buildsrc.utils.Rife2TestListener
+import org.gradle.api.JavaVersion
+import org.gradle.api.tasks.testing.Test
+import org.gradle.api.tasks.testing.logging.TestExceptionFormat
+import org.gradle.api.tasks.testing.logging.TestLogEvent
+import org.gradle.kotlin.dsl.withType
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+import org.sonarqube.gradle.SonarTask
+
+/**
+ * Common configuration for Kotlin/JVM projects
+ *
+ * (this can be removed after Kotlin Multiplatform migration)
+ */
+
+plugins {
+ id("buildsrc.conventions.base")
+ kotlin("jvm")
+ id("buildsrc.conventions.code-quality")
+}
+
+java {
+ withSourcesJar()
+}
+
+kotlin {
+ jvmToolchain(11)
+}
+
+tasks.withType().configureEach {
+ compilerOptions {
+ jvmTarget.set(JvmTarget.JVM_11)
+ }
+}
+
+tasks.withType().configureEach {
+ useJUnitPlatform()
+}
diff --git a/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt b/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt
index 2fe062f..748b064 100644
--- a/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt
+++ b/buildSrc/src/main/kotlin/buildsrc/utils/Rife2TestListener.kt
@@ -17,6 +17,7 @@
package buildsrc.utils
+import org.gradle.api.provider.Provider
import org.gradle.api.tasks.testing.TestDescriptor
import org.gradle.api.tasks.testing.TestListener
import org.gradle.api.tasks.testing.TestResult
@@ -26,37 +27,39 @@ import java.net.http.HttpRequest
import java.net.http.HttpResponse
class Rife2TestListener(
- private val testBadgeApiKey: String?
+ private val testBadgeApiKey: Provider
) : 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
+ 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 = 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())
- }
+ val apiKey = testBadgeApiKey.orNull
+
+ if (apiKey != null) {
+ println(apiKey)
+ val response: HttpResponse = HttpClient.newHttpClient()
+ .send(
+ HttpRequest.newBuilder()
+ .uri(
+ URI(
+ "https://rife2.com/tests-badge/update/net.thauvin.erik/urlencoder?" +
+ "apiKey=$apiKey&" +
+ "passed=$passed&" +
+ "failed=$failed&" +
+ "skipped=$skipped"
+ )
+ )
+ .POST(HttpRequest.BodyPublishers.noBody())
+ .build(), HttpResponse.BodyHandlers.ofString()
+ )
+ println("RESPONSE: ${response.statusCode()}")
+ println(response.body())
+ }
+ }
}
- }
}
diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts
index 6ebdf1d..eb0edae 100644
--- a/lib/build.gradle.kts
+++ b/lib/build.gradle.kts
@@ -1,27 +1,17 @@
-import buildsrc.utils.Rife2TestListener
-import org.gradle.api.tasks.testing.logging.TestExceptionFormat
-import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.dokka.gradle.DokkaTask
-import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
+ buildsrc.conventions.lang.`kotlin-jvm`
+ buildsrc.conventions.publishing
id("application")
id("com.github.ben-manes.versions")
- id("io.gitlab.arturbosch.detekt")
- id("java-library")
- id("maven-publish")
- id("org.jetbrains.kotlin.jvm")
- id("org.jetbrains.kotlinx.kover")
-
- buildsrc.conventions.publishing
- buildsrc.conventions.sonarqube
}
description = "A simple defensive library to encode/decode URL components"
val deployDir = project.layout.projectDirectory.dir("deploy")
-val mainClassName = "net.thauvin.erik.urlencoder.UrlEncoder"
+val urlEncoderMainClass = "net.thauvin.erik.urlencoder.UrlEncoder"
dependencies {
// testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.25")
@@ -32,20 +22,14 @@ base {
archivesName.set(rootProject.name)
}
-java {
- sourceCompatibility = JavaVersion.VERSION_11
- targetCompatibility = JavaVersion.VERSION_11
- withSourcesJar()
-}
-
application {
- mainClass.set(mainClassName)
+ mainClass.set(urlEncoderMainClass)
}
tasks {
jar {
manifest {
- attributes["Main-Class"] = mainClassName
+ attributes["Main-Class"] = urlEncoderMainClass
}
}
@@ -65,30 +49,10 @@ tasks {
dependsOn(fatJar)
}
- withType().configureEach {
- kotlinOptions.jvmTarget = java.targetCompatibility.toString()
- }
-
- test {
- addTestListener(Rife2TestListener(project.properties["testsBadgeApiKey"]?.toString()))
- }
-
- withType().configureEach {
- useJUnitPlatform()
- testLogging {
- exceptionFormat = TestExceptionFormat.FULL
- events = setOf(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
- }
- }
-
withType().configureEach {
destination = file("$projectDir/pom.xml")
}
- clean {
- delete(deployDir)
- }
-
withType().configureEach {
dokkaSourceSets {
named("main") {
@@ -113,8 +77,8 @@ tasks {
dependsOn(build, copyToDeploy)
}
- "sonar" {
- dependsOn(koverReport)
+ clean {
+ delete(deployDir)
}
}
@@ -122,7 +86,7 @@ publishing {
publications {
create("mavenJava") {
from(components["java"])
- artifactId = "${rootProject.name}-lib"
+ artifactId = rootProject.name
artifact(tasks.javadocJar)
}
}
From acfaaec7544541b4dabed61afea5b2dcbfb51a48 Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Wed, 31 May 2023 23:07:13 +0200
Subject: [PATCH 09/10] only enable signing if not snapshot OR running
'publish' task
---
.../conventions/publishing.gradle.kts | 127 +++++++++---------
1 file changed, 65 insertions(+), 62 deletions(-)
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts
index 4c26d99..2390479 100644
--- a/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/publishing.gradle.kts
@@ -16,87 +16,90 @@
*/
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")
+ id("maven-publish")
+ id("signing")
+ id("org.jetbrains.dokka")
}
val gitHub = "ethauvin/${rootProject.name}"
val mavenUrl = "https://github.com/$gitHub"
+val isSnapshotVersion = { project.version.toString().contains("SNAPSHOT") }
publishing {
- publications {
- withType().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")
- }
+ publications {
+ withType().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")
+ }
+ }
}
- 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)
+ repositories {
+ maven(
+ if (isSnapshotVersion()) {
+ 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)
-}
+ useGpgCmd()
+ sign(publishing.publications)
+ setRequired({
+ !isSnapshotVersion() || gradle.taskGraph.hasTask("publish")
+ })
+}
+tasks.withType().configureEach {
+ val signingRequiredPredicate = provider { signing.isRequired }
+ onlyIf { signingRequiredPredicate.get() }
+}
// https://youtrack.jetbrains.com/issue/KT-46466
val signingTasks = tasks.withType()
tasks.withType().configureEach {
- dependsOn(signingTasks)
+ dependsOn(signingTasks)
}
val javadocJar by tasks.registering(Jar::class) {
- dependsOn(tasks.dokkaJavadoc)
- from(tasks.dokkaJavadoc)
- archiveClassifier.set("javadoc")
+ dependsOn(tasks.dokkaJavadoc)
+ from(tasks.dokkaJavadoc)
+ archiveClassifier.set("javadoc")
}
From 671e4c68106905f1cc288091b3a6cd874c488db7 Mon Sep 17 00:00:00 2001
From: Adam <897017+aSemy@users.noreply.github.com>
Date: Wed, 31 May 2023 23:10:23 +0200
Subject: [PATCH 10/10] move test config to `code-quality` convention plugin
---
.../kotlin/buildsrc/conventions/base.gradle.kts | 13 -------------
.../buildsrc/conventions/code-quality.gradle.kts | 12 ++++++++++++
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
index 7404066..59e3a56 100644
--- a/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/base.gradle.kts
@@ -1,9 +1,5 @@
package buildsrc.conventions
-import buildsrc.utils.Rife2TestListener
-import org.gradle.api.tasks.testing.logging.TestExceptionFormat
-import org.gradle.api.tasks.testing.logging.TestLogEvent
-
/** common config for all subprojects */
plugins {
@@ -20,12 +16,3 @@ tasks.withType().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
-
-tasks.withType().configureEach {
- val testsBadgeApiKey = providers.gradleProperty("testsBadgeApiKey")
- addTestListener(Rife2TestListener(testsBadgeApiKey))
- testLogging {
- exceptionFormat = TestExceptionFormat.FULL
- events = setOf(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
- }
-}
diff --git a/buildSrc/src/main/kotlin/buildsrc/conventions/code-quality.gradle.kts b/buildSrc/src/main/kotlin/buildsrc/conventions/code-quality.gradle.kts
index a81b982..f9c3d13 100644
--- a/buildSrc/src/main/kotlin/buildsrc/conventions/code-quality.gradle.kts
+++ b/buildSrc/src/main/kotlin/buildsrc/conventions/code-quality.gradle.kts
@@ -17,6 +17,9 @@
package buildsrc.conventions
+import buildsrc.utils.Rife2TestListener
+import org.gradle.api.tasks.testing.logging.TestExceptionFormat
+import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.sonarqube.gradle.SonarTask
plugins {
@@ -39,3 +42,12 @@ sonarqube {
tasks.withType().configureEach {
dependsOn(tasks.matching { it.name == "koverXmlReport" })
}
+
+tasks.withType().configureEach {
+ val testsBadgeApiKey = providers.gradleProperty("testsBadgeApiKey")
+ addTestListener(Rife2TestListener(testsBadgeApiKey))
+ testLogging {
+ exceptionFormat = TestExceptionFormat.FULL
+ events = setOf(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
+ }
+}