restructure project to Kotlin Multiplatform

- custom POM location removed (there are now two POMs, one for the 'Kotlin Multiplatform' publication, and another for Kotlin/JVM, and more are on the way, which would lead to a cluttered build dir)
- renamed the directories (the directory name is how Kotlin Multiplatform chooses the published artifact ID, and there's no an easier way to change it.)
- updated README examples, and link to `-jvm` variant guide
This commit is contained in:
Adam 2023-06-06 00:04:26 +02:00
parent 4df6d3f599
commit dce203845e
16 changed files with 59 additions and 243 deletions

View file

@ -63,7 +63,7 @@ dependencies {
``` ```
Instructions for using with Maven, Ivy, etc. can be found Instructions for using with Maven, Ivy, etc. can be found
on [Maven Central](https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik/urlencoder). on [Maven Central](https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik/urlencoder-jvm).
## Standalone usage ## Standalone usage
@ -85,10 +85,10 @@ Encode and decode URL components defensively.
### Running with Gradle ### Running with Gradle
```shell ```shell
./gradlew run --args="-e 'a test &'" # -> a%20test%20%26 ./gradlew run --quiet --args="-e 'a test &'" # -> a%20test%20%26
./gradlew run --args="%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2 ./gradlew run --quiet --args="%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2
./gradlew run --args="-d 'a%20test%20%26'" # -> a test & ./gradlew run --quiet --args="-d 'a%20test%20%26'" # -> a test &
``` ```
### Running with Java ### Running with Java
@ -96,23 +96,23 @@ Encode and decode URL components defensively.
First build the jar file: First build the jar file:
```shell ```shell
./gradlew clean fatJar ./gradlew fatJar
``` ```
Then run it: Then run it:
```shell ```shell
java -jar lib/build/libs/urlencoder-*all.jar -e "a test &" # -> a%20test%20%26 java -jar urlencoder-app/build/libs/urlencoder-*all.jar -e "a test &" # -> a%20test%20%26
java -jar lib/build/libs/urlencoder-*all.jar "%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2 java -jar urlencoder-app/build/libs/urlencoder-*all.jar "%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2
java -jar lib/build/libs/urlencoder-*.all.jar -d "a%20test%20%26" # -> a test & java -jar urlencoder-app/build/libs/urlencoder-*all.jar -d "a%20test%20%26" # -> a test &
``` ```
## Why not simply use `java.net.URLEncoder`? ## Why not simply use `java.net.URLEncoder`?
Apart for being quite inefficient, some URL components encoded with `URLEncoder.encode` might not be able to be properly decoded. Apart for being quite inefficient, some URL components encoded with `URLEncoder.encode` might not be able to be properly decoded.
For example, a simply search query such as: For example, a simple search query such as:
```kotlin ```kotlin
val u = URLEncoder.encode("foo +bar", StandardCharsets.UTF_8) val u = URLEncoder.encode("foo +bar", StandardCharsets.UTF_8)
@ -139,4 +139,3 @@ foo++bar
Unfortunately, decoding with [Uri.decode](https://developer.android.com/reference/android/net/Uri#decode(java.lang.String)) on Android, [decodeURI](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI) in Javascript, etc. would yield the exact same result. Unfortunately, decoding with [Uri.decode](https://developer.android.com/reference/android/net/Uri#decode(java.lang.String)) on Android, [decodeURI](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI) in Javascript, etc. would yield the exact same result.
![URLEncoder](https://live.staticflickr.com/65535/52607534147_6197b42666_z.jpg) ![URLEncoder](https://live.staticflickr.com/65535/52607534147_6197b42666_z.jpg)

View file

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
<!-- that they should prefer consuming it instead. -->
<!-- do_not_remove: published-with-gradle-metadata -->
<modelVersion>4.0.0</modelVersion>
<groupId>net.thauvin.erik</groupId>
<artifactId>urlencoder</artifactId>
<version>1.3.1-SNAPSHOT</version>
<name>UrlEncoder for Kotlin</name>
<description>A simple defensive application to encode/decode URL components</description>
<url>https://github.com/ethauvin/urlencoder</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>gbevin</id>
<name>Geert Bevin</name>
<email>gbevin@uwyn.com</email>
<url>https://github.com/gbevin</url>
</developer>
<developer>
<id>ethauvin</id>
<name>Erik C. Thauvin</name>
<email>erik@thauvin.net</email>
<url>https://erik.thauvin.net/</url>
</developer>
</developers>
<scm>
<connection>scm:git://github.com/ethauvin/urlencoder.git</connection>
<developerConnection>scm:git@github.com:ethauvin/urlencoder.git</developerConnection>
<url>https://github.com/ethauvin/urlencoder</url>
</scm>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/ethauvin/urlencoder/issues</url>
</issueManagement>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>1.8.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.thauvin.erik</groupId>
<artifactId>urlencoder-lib</artifactId>
<version>1.3.1-SNAPSHOT</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>

View file

@ -24,8 +24,8 @@ group = "net.thauvin.erik"
version = "1.4.0-SNAPSHOT" version = "1.4.0-SNAPSHOT"
dependencies { dependencies {
kover(projects.lib) kover(projects.urlencoderLib)
kover(projects.app) kover(projects.urlencoderApp)
} }
sonar { sonar {

View file

@ -1,47 +0,0 @@
package buildsrc.conventions.lang
import buildsrc.utils.Rife2TestListener
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
/**
* Common configuration for Kotlin/JVM projects
*
* (this can be removed after Kotlin Multiplatform migration)
*/
plugins {
id("buildsrc.conventions.base")
kotlin("jvm")
id("io.gitlab.arturbosch.detekt")
id("org.jetbrains.kotlinx.kover")
}
java {
withSourcesJar()
}
kotlin {
jvmToolchain(11)
}
tasks.withType<KotlinCompile>().configureEach {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}
}
tasks.withType<Test>().configureEach {
// useJUnitPlatform()
val testsBadgeApiKey = providers.gradleProperty("testsBadgeApiKey")
addTestListener(Rife2TestListener(testsBadgeApiKey))
testLogging {
exceptionFormat = TestExceptionFormat.FULL
events = setOf(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED)
}
finalizedBy(tasks.matching { it.name == "koverXmlReport" })
}

View file

@ -89,6 +89,7 @@ signing {
!isSnapshotVersion() || gradle.taskGraph.hasTask("publish") !isSnapshotVersion() || gradle.taskGraph.hasTask("publish")
}) })
} }
tasks.withType<Sign>().configureEach { tasks.withType<Sign>().configureEach {
val signingRequiredPredicate = provider { signing.isRequired } val signingRequiredPredicate = provider { signing.isRequired }
onlyIf { signingRequiredPredicate.get() } onlyIf { signingRequiredPredicate.get() }
@ -106,3 +107,9 @@ val javadocJar by tasks.registering(Jar::class) {
from(tasks.dokkaJavadoc) from(tasks.dokkaJavadoc)
archiveClassifier.set("javadoc") archiveClassifier.set("javadoc")
} }
publishing {
publications.withType<MavenPublication>().configureEach {
artifact(javadocJar)
}
}

View file

@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- This module was also published with a richer model, Gradle metadata, -->
<!-- which should be used instead. Do not delete the following line which -->
<!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
<!-- that they should prefer consuming it instead. -->
<!-- do_not_remove: published-with-gradle-metadata -->
<modelVersion>4.0.0</modelVersion>
<groupId>net.thauvin.erik</groupId>
<artifactId>urlencoder</artifactId>
<version>1.4.0-SNAPSHOT</version>
<name>UrlEncoder for Kotlin</name>
<description>A simple defensive library to encode/decode URL components</description>
<url>https://github.com/ethauvin/urlencoder</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>gbevin</id>
<name>Geert Bevin</name>
<email>gbevin@uwyn.com</email>
<url>https://github.com/gbevin</url>
</developer>
<developer>
<id>ethauvin</id>
<name>Erik C. Thauvin</name>
<email>erik@thauvin.net</email>
<url>https://erik.thauvin.net/</url>
</developer>
</developers>
<scm>
<connection>scm:git://github.com/ethauvin/urlencoder.git</connection>
<developerConnection>scm:git@github.com:ethauvin/urlencoder.git</developerConnection>
<url>https://github.com/ethauvin/urlencoder</url>
</scm>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/ethauvin/urlencoder/issues</url>
</issueManagement>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>1.8.21</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View file

@ -1,17 +0,0 @@
-----BEGIN PGP SIGNATURE-----
Version: BCPG v1.68
iQIzBAABCAAdFiEEOckYpvaxKUI3I6Pxd2cCpqLaMw4FAmO46y8ACgkQd2cCpqLa
Mw49qg//YPTr/FbXTVDB2KsPRRRMAMf3tQxvYknuMJsAIOTq9XfkmWM6XY+A1L6+
Up98MLrBMFKckrZ90bypTCZGhIi52yoE6StchFMJiuLGE+OwQIwPxaX0LNN3pLD6
BE5muGYZV762PeTkNU0oXNX+e0ReATnUHiriNvz9mZN/xDQLQ+C54wlu9wTKVC6l
beDezJsNYS4OhQJuJk4bm7w5umEocvbOydzSa/a95hQY9EfsQOUkc4jdGbDRGjKX
ladPDl8B+Y1+peJDkzcgL+A2T0mJ4bxouI32cGyQBXvawfcfz7ksifhoRDyESXrt
YoQMcVb9Bnv/k2r4jPSb92znTwCWY7joXrTE44C3wUk6cg8QoCEmjAdEfxwCM17f
pYIoejBGAMp3xYmzBJg4017e+Tg8hR2SrQHAF65GezEi/d9SOAevEp9aOPPSWOI1
0LgMcBAE9yxCF2r8EHpFyD2dHfaOI9kKsBfGyKn+8ksu75l6bCZRFJu4syYaNLZn
b9kHAHgmfikKMnHBZGr/SqYADnCLr/PwJFOhACDYtbhcXVm4PJT3l6Yep8xG1N84
+qTFA6CuOZjAklonbroHlkgn8ixhuC9ZNtKaIH6zvdG9SoaN4yMu7Itk6GtAAQy6
qCB+3oylZlKjh1mVo9X8iatL8rdgn8dsEwvC+ItsjsnxXtCPhX4=
=amWH
-----END PGP SIGNATURE-----

View file

@ -23,6 +23,6 @@ dependencyResolutionManagement {
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
include( include(
":app", ":urlencoder-app",
":lib", ":urlencoder-lib",
) )

View file

@ -18,7 +18,7 @@
import org.jetbrains.dokka.gradle.DokkaTask import org.jetbrains.dokka.gradle.DokkaTask
plugins { plugins {
buildsrc.conventions.lang.`kotlin-jvm` buildsrc.conventions.lang.`kotlin-multiplatform-jvm`
buildsrc.conventions.publishing buildsrc.conventions.publishing
buildsrc.conventions.sonarqube buildsrc.conventions.sonarqube
id("application") id("application")
@ -30,13 +30,21 @@ description = "A simple defensive application to encode/decode URL components"
val deployDir = project.layout.projectDirectory.dir("deploy") val deployDir = project.layout.projectDirectory.dir("deploy")
val urlEncoderMainClass = "net.thauvin.erik.urlencoder.UrlEncoder" val urlEncoderMainClass = "net.thauvin.erik.urlencoder.UrlEncoder"
dependencies { kotlin {
implementation(projects.lib) sourceSets {
kover(projects.lib) commonMain {
dependencies {
// testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.25") implementation(projects.urlencoderLib)
// testImplementation("org.junit.jupiter:junit-jupiter:5.9.1") }
testImplementation(kotlin("test")) }
jvmTest {
dependencies {
//implementation("com.willowtreeapps.assertk:assertk-jvm:0.25")
//implementation("org.junit.jupiter:junit-jupiter:5.9.1")
implementation(kotlin("test"))
}
}
}
} }
base { base {
@ -48,7 +56,7 @@ application {
} }
tasks { tasks {
jar { jvmJar {
manifest { manifest {
attributes["Main-Class"] = urlEncoderMainClass attributes["Main-Class"] = urlEncoderMainClass
} }
@ -56,13 +64,13 @@ tasks {
val fatJar by registering(Jar::class) { val fatJar by registering(Jar::class) {
group = LifecycleBasePlugin.BUILD_GROUP group = LifecycleBasePlugin.BUILD_GROUP
dependsOn.addAll(listOf("compileJava", "compileKotlin", "processResources")) dependsOn.addAll(listOf("compileJava", "compileKotlinJvm", "processResources"))
archiveClassifier.set("all") archiveClassifier.set("all")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest { attributes(mapOf("Main-Class" to application.mainClass)) } manifest { attributes(mapOf("Main-Class" to application.mainClass)) }
from(sourceSets.main.get().output) from(sourceSets.main.get().output)
dependsOn(configurations.runtimeClasspath) dependsOn(configurations.jvmRuntimeClasspath)
from(configurations.runtimeClasspath.map { classpath -> from(configurations.jvmRuntimeClasspath.map { classpath ->
classpath.incoming.artifacts.artifactFiles.files.filter { it.name.endsWith("jar") }.map { zipTree(it) } classpath.incoming.artifacts.artifactFiles.files.filter { it.name.endsWith("jar") }.map { zipTree(it) }
}) })
} }
@ -71,28 +79,22 @@ tasks {
dependsOn(fatJar) dependsOn(fatJar)
} }
withType<GenerateMavenPom>().configureEach {
destination = file("$projectDir/pom.xml")
}
clean { clean {
delete(deployDir) delete(deployDir)
} }
withType<DokkaTask>().configureEach { withType<DokkaTask>().configureEach {
dokkaSourceSets { dokkaSourceSets.configureEach {
named("main") { moduleName.set("UrlEncoder Application")
moduleName.set("UrlEncoder Application")
}
} }
} }
val copyToDeploy by registering(Sync::class) { val copyToDeploy by registering(Sync::class) {
group = PublishingPlugin.PUBLISH_TASK_GROUP group = PublishingPlugin.PUBLISH_TASK_GROUP
from(configurations.runtimeClasspath) { from(configurations.jvmRuntimeClasspath) {
exclude("annotations-*.jar") exclude("annotations-*.jar")
} }
from(jar) from(jvmJar)
into(deployDir) into(deployDir)
} }
@ -102,13 +104,3 @@ tasks {
dependsOn(build, copyToDeploy) dependsOn(build, copyToDeploy)
} }
} }
publishing {
publications {
create<MavenPublication>("mavenJava") {
from(components["java"])
artifactId = rootProject.name
artifact(tasks.javadocJar)
}
}
}

View file

@ -18,7 +18,7 @@
import org.jetbrains.dokka.gradle.DokkaTask import org.jetbrains.dokka.gradle.DokkaTask
plugins { plugins {
buildsrc.conventions.lang.`kotlin-jvm` buildsrc.conventions.lang.`kotlin-multiplatform-jvm`
buildsrc.conventions.publishing buildsrc.conventions.publishing
buildsrc.conventions.sonarqube buildsrc.conventions.sonarqube
id("com.github.ben-manes.versions") id("com.github.ben-manes.versions")
@ -28,30 +28,32 @@ description = "A simple defensive library to encode/decode URL components"
val deployDir = project.layout.projectDirectory.dir("deploy") val deployDir = project.layout.projectDirectory.dir("deploy")
dependencies { kotlin {
// testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.25") sourceSets {
// testImplementation("org.junit.jupiter:junit-jupiter:5.9.1") jvmTest {
testImplementation(kotlin("test")) dependencies {
//implementation("com.willowtreeapps.assertk:assertk-jvm:0.25")
//implementation("org.junit.jupiter:junit-jupiter:5.9.1")
implementation(kotlin("test"))
}
}
}
} }
base { base {
archivesName.set("${rootProject.name}-lib") archivesName.set("${rootProject.name}-lib")
} }
tasks { tasks {
withType<GenerateMavenPom>().configureEach {
destination = file("$projectDir/pom.xml")
}
clean { clean {
delete(deployDir) delete(deployDir)
} }
withType<DokkaTask>().configureEach { withType<DokkaTask>().configureEach {
dokkaSourceSets { dokkaSourceSets.configureEach {
named("main") { moduleName.set("UrlEncoder Library")
moduleName.set("UrlEncoder Library")
}
} }
} }
@ -60,7 +62,7 @@ tasks {
from(configurations.runtimeClasspath) { from(configurations.runtimeClasspath) {
exclude("annotations-*.jar") exclude("annotations-*.jar")
} }
from(jar) from(jvmJar)
into(deployDir) into(deployDir)
} }
@ -70,13 +72,3 @@ tasks {
dependsOn(build, copyToDeploy) dependsOn(build, copyToDeploy)
} }
} }
publishing {
publications {
create<MavenPublication>("mavenJava") {
from(components["java"])
artifactId = "${rootProject.name}-lib"
artifact(tasks.javadocJar)
}
}
}