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) + } +}