Compare commits

..

34 commits

Author SHA1 Message Date
b882d68d4c
Removed git-cliff configuration and script 2024-10-20 18:24:53 -07:00
9e60b31f9e
Version 1.6.0 2024-10-19 09:01:36 -07:00
c69d7b7076
Added git-cliff configuration and script 2024-10-18 16:23:04 -07:00
742c221a20
Revert "Set Kotlin's language version to Java 8"
This reverts commit 0b6e55b338.
2024-10-16 12:13:00 -07:00
0b6e55b338
Set Kotlin's language version to Java 8 2024-10-16 11:17:34 -07:00
09b44d53e8
Compile public version with Java 21 2024-10-16 11:15:39 -07:00
df7482c3a0
Version 1.6.0-SNAPSHOT 2024-10-15 13:00:33 -07:00
3e36e389fb
Bumped Gradle to version 8.10.2 2024-10-15 12:43:53 -07:00
d66fdb12e6
Updated dependencies
Bumped Detekt to version 1.23.7
Bumped Kover to version 0.8.3
Bumped Kotlin to version 1.9.24
2024-10-15 12:43:01 -07:00
Ronny Bräunlich
6f33f9c2a9
feat: Java 8 compatibility (#19)
Closes #18

Co-authored-by: Ronny Bräunlich <ronny.braeunlich@cbc.de>
2024-10-15 12:03:54 -07:00
dd3d500496
Version 1.5.0 2024-03-27 21:44:29 -07:00
Adam
c801a9703f
Tidy publishing config (#17)
* remove custom POM location (Gradle gets confused)

* - update GitHub actions
- use new `gradle/actions/setup-gradle`
- block cancel-in-progress for publish.yml
2024-03-27 10:54:49 -07:00
1ef2045b32
Reworked GitHub workflows 2024-03-26 22:14:18 -07:00
Adam
d03c61cb92
bump version to 1.5.0-SNAPSHOT (#16) 2024-03-26 21:38:50 -07:00
a689c56e1e
Bumped Gradle to version 8.7 2024-03-26 14:14:08 -07:00
b59d01ec6d
Bumped Dokka to version 1.9.20 2024-03-26 14:13:32 -07:00
Adam
8890fef665
bump Kotlin to 1.9.23, enable additional Kotlin Multiplatform targets (#15)
* bump Kotlin to 1.9.23, enable additional Kotlin Multiplatform targets

* replace soon-to-be-deprecated kotlinOptions with newer compilerOptions
2024-03-26 13:52:11 -07:00
Adam
171570159e
add Java tests for verifying @JvmStatic (#14) 2024-02-25 04:17:08 -08:00
61137e0878 Updated copyright 2024-02-24 22:21:30 -08:00
f3fc266c6f Bumped dependencies 2024-02-24 22:21:17 -08:00
7817198be1 Removed JDK 20 deprecation reference 2023-11-17 08:56:40 -08:00
b9791dc507 Added java.net.URLEncoder deprecation reference 2023-11-01 00:52:22 -07:00
ee35984130 Added pom.xml generation 2023-10-18 21:04:08 -07:00
05d4a52240 Updated dependencies 2023-10-18 20:16:44 -07:00
8ebc178474 Revert "Added codecov"
This reverts commit 404ca93137.
2023-09-29 00:32:01 -07:00
404ca93137 Added codecov 2023-09-29 00:19:35 -07:00
2523b31073 Remove iOS X64 simulator 2023-09-25 01:50:45 -07:00
6acf3417e5 Added iOS simulator target 2023-09-24 21:53:27 -07:00
f711cf719f Try using iOS target shortcut 2023-09-24 13:08:56 -07:00
ebdc9ceef8 Added iOS publish workflow 2023-09-24 12:41:46 -07:00
9f3803bdcd Added iOS publications 2023-09-24 12:12:01 -07:00
5b46ff448c Updated Kotlin badge 2023-09-22 04:41:04 -07:00
d790a02365 Fixed examples 2023-09-21 22:04:34 -07:00
7ea75e30e7 Fixed Kotlin badge 2023-09-21 19:28:03 -07:00
24 changed files with 361 additions and 382 deletions

View file

@ -17,7 +17,7 @@ jobs:
build:
strategy:
matrix:
java-version: [ 11, 17, 20 ]
java-version: [8, 11, 17, 21]
os:
- macos-latest
- ubuntu-latest
@ -28,27 +28,25 @@ jobs:
GRADLE_OPTS: "-Dorg.gradle.jvmargs=-XX:MaxMetaspaceSize=512m"
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'zulu'
distribution: "zulu"
java-version: ${{ matrix.java-version }}
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v1
uses: gradle/wrapper-validation-action@v2
- name: Cache Kotlin Konan
id: cache-kotlin-konan
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: |
~/.konan/**/*
path: ~/.konan/**/*
key: kotlin-konan-${{ runner.os }}
- name: Test with Gradle
uses: gradle/gradle-build-action@v2
with:
gradle-home-cache-cleanup: true
arguments: build check --stacktrace -PtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }}
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Publish
run: ./gradlew check build --stacktrace -PtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }}

View file

@ -4,90 +4,41 @@ on:
workflow_dispatch:
env:
JAVA_VERSION: 11
JAVA_DISTRIBUTION: 'zulu'
ORG_GRADLE_PROJECT_ossrhUsername: ${{ secrets.OSSRH_USERNAME}}
ORG_GRADLE_PROJECT_ossrhPassword: ${{ secrets.OSSRH_PASSWORD}}
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGN_SECRET_KEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGN_SECRET_PWD }}
concurrency:
group: "${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}"
# Don't cancel midway through publishing if another workflow is triggered, it might cause partial publications
cancel-in-progress: false
jobs:
publish-base:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v3
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRIBUTION }}
- uses: gradle/gradle-build-action@v2
- name: Publish Multiplatform release
run: ./gradlew publishKotlinMultiplatformPublicationToOSSRHRepository
- name: Publish JVM release
run: ./gradlew publishJvmPublicationToOSSRHRepository
- name: Publish JS release
run: ./gradlew publishJsPublicationToOSSRHRepository
publish-linux:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v3
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRIBUTION }}
- uses: gradle/gradle-build-action@v2
- name: Publish Linux x64 release
run: ./gradlew publishLinuxX64PublicationToOSSRHRepository
publish-mac:
publish:
runs-on: macos-latest
strategy:
max-parallel: 6
matrix:
target:
- publishMacosArm64PublicationToOSSRHRepository
- publishMacosX64PublicationToOSSRHRepository
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v3
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRIBUTION }}
java-version: "21"
distribution: "zulu"
- uses: gradle/gradle-build-action@v2
- name: Validate Gradle wrapper
uses: gradle/wrapper-validation-action@v2
- name: Cache Kotlin Konan
uses: actions/cache@v4
with:
path: ~/.konan/**/*
key: kotlin-konan-${{ runner.os }}
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v3
- name: Publish
run: ./gradlew ${{ matrix.target }}
publish-windows:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up JDK ${{ env.JAVA_VERSION }}
uses: actions/setup-java@v3
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: ${{ env.JAVA_DISTRIBUTION }}
- uses: gradle/gradle-build-action@v2
- name: Publish MinGW x64 release
run: ./gradlew publishMingwX64PublicationToOSSRHRepository
run: ./gradlew publish --no-parallel --stacktrace

View file

@ -1,5 +1,5 @@
[![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Kotlin](https://img.shields.io/badge/kotlin-1.9.0-blue)](https://kotlinlang.org/)
[![Kotlin](https://img.shields.io/badge/kotlin-1.6%2B-blue)](https://kotlinlang.org/)
[![Nexus Snapshot](https://img.shields.io/nexus/s/net.thauvin.erik.urlencoder/urlencoder-lib?label=snapshot&server=https%3A%2F%2Foss.sonatype.org%2F)](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/urlencoder/)
[![Release](https://img.shields.io/github/release/ethauvin/urlencoder.svg)](https://github.com/ethauvin/urlencoder/releases/latest)
[![Maven Central](https://img.shields.io/maven-central/v/net.thauvin.erik.urlencoder/urlencoder-lib)](https://central.sonatype.com/search?namespace=net.thauvin.erik.urlencoder)
@ -32,18 +32,17 @@ optimizations have a significantly beneficial impact on performance of encoding
compared to other solutions like the standard `URLEncoder` in the JDK or
`UriUtils` in Spring.
## Examples (TL;DR)
```kotlin
UrlEncoder.encode("a test &") // -> a%20test%20%26
UrlEncoder.encode("%#okékÉȢ smile!😁") // -> %25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81
UrlEncoder.encode("?test=a test", allow = "?=") // -> ?test=a%20test
UrlEncoder.endode("foo bar", spaceToPlus = true) // -> foo+bar
UrlEncoderUtil.encode("a test &") // -> a%20test%20%26
UrlEncoderUtil.encode("%#okékÉȢ smile!😁") // -> %25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81
UrlEncoderUtil.encode("?test=a test", allow = "?=") // -> ?test=a%20test
UrlEncoderUtil.endode("foo bar", spaceToPlus = true) // -> foo+bar
UrlEncoder.decode("a%20test%20%26") // -> a test &
UrlEncoder.decode("%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81") // -> %#okékÉȢ smile!😁
UrlEncoder.decode("foo+bar", plusToSpace = true) // -> foo bar
UrlEncoderUtil.decode("a%20test%20%26") // -> a test &
UrlEncoderUtil.decode("%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81") // -> %#okékÉȢ smile!😁
UrlEncoderUtil.decode("foo+bar", plusToSpace = true) // -> foo bar
```
## Gradle, Maven, etc.
@ -61,7 +60,7 @@ repositories {
}
dependencies {
implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.4.0")
implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.6.0")
}
```
@ -72,11 +71,11 @@ to the artifact URL.
<dependency>
<groupId>net.thauvin.erik.urlencoder</groupId>
<artifactId>urlencoder-lib-jvm</artifactId>
<version>1.4.0</version>
<version>1.6.0</version>
</dependency>
```
Instructions for using with Ivy, etc. can be found on
Instructions for using with Ivy, etc. can be found on
[Maven Central](https://central.sonatype.com/search?namespace=net.thauvin.erik.urlencoder).
## Standalone usage
@ -90,7 +89,7 @@ You have two options:
The usage is as follows:
```
```console
Encode and decode URL components defensively.
-e encode (default)
-d decode
@ -98,7 +97,7 @@ Encode and decode URL components defensively.
### Running with Gradle
```shell
```console
./gradlew run --quiet --args="-e 'a test &'" # -> a%20test%20%26
./gradlew run --quiet --args="%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2
@ -109,13 +108,13 @@ Encode and decode URL components defensively.
First build the jar file:
```shell
```console
./gradlew fatJar
```
Then run it:
```shell
```console
java -jar urlencoder-app/build/libs/urlencoder-*all.jar -e "a test &" # -> a%20test%20%26
java -jar urlencoder-app/build/libs/urlencoder-*all.jar "%#okékÉȢ" # -> %25%23ok%C3%A9k%C3%89%C8%A2

View file

@ -4,7 +4,7 @@ plugins {
}
group = "net.thauvin.erik.urlencoder"
version = "1.4.0"
version = "1.6.0"
dependencies {
kover(projects.urlencoderLib)

View file

@ -3,9 +3,10 @@ plugins {
}
dependencies {
implementation("com.github.ben-manes:gradle-versions-plugin:0.48.0")
implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.1")
implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.9.0")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0")
implementation("org.jetbrains.kotlinx:kover-gradle-plugin:0.7.3")
}
implementation("com.github.ben-manes:gradle-versions-plugin:0.51.0")
implementation("io.gitlab.arturbosch.detekt:detekt-gradle-plugin:1.23.7")
implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.9.20")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.24")
implementation("org.jetbrains.kotlinx:kover-gradle-plugin:0.8.3")
implementation("org.apache.httpcomponents:httpclient:4.5.13")
}

View file

@ -3,7 +3,9 @@ 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.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
@ -24,39 +26,31 @@ plugins {
kotlin {
//jvmToolchain(11)
targets.configureEach {
compilations.configureEach {
kotlinOptions {
languageVersion = "1.6"
}
}
applyDefaultHierarchyTemplate()
@OptIn(ExperimentalKotlinGradlePluginApi::class)
compilerOptions {
languageVersion = KotlinVersion.KOTLIN_1_6
}
// configure all Kotlin/JVM Tests to use JUnit
targets.withType<KotlinJvmTarget>().configureEach {
testRuns.configureEach {
executionTask.configure {
// useJUnitPlatform()
useJUnitPlatform()
}
}
}
sourceSets.configureEach {
languageSettings {
// languageVersion =
// apiVersion =
}
}
}
tasks {
withType<JavaCompile>().configureEach {
sourceCompatibility = JavaVersion.VERSION_11.toString()
targetCompatibility = JavaVersion.VERSION_11.toString()
sourceCompatibility = JavaVersion.VERSION_1_8.toString()
targetCompatibility = JavaVersion.VERSION_1_8.toString()
}
withType<KotlinJvmCompile>().configureEach {
compilerOptions.jvmTarget.set(JvmTarget.JVM_11)
compilerOptions.jvmTarget.set(JvmTarget.JVM_1_8)
}
withType<Test>().configureEach {

View file

@ -1,5 +1,7 @@
package buildsrc.conventions.lang
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl
/** conventions for a Kotlin/JS subproject */
plugins {
@ -7,12 +9,38 @@ plugins {
}
kotlin {
targets {
js(IR) {
browser()
nodejs()
}
js(IR) {
browser()
nodejs()
}
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser()
nodejs()
}
@OptIn(ExperimentalWasmDsl::class)
wasmWasi {
nodejs()
}
}
relocateKotlinJsStore()
//region FIXME: WORKAROUND https://youtrack.jetbrains.com/issue/KT-65864
rootProject.plugins.withType<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin> {
rootProject.extensions.configure<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension> {
// Use a Node.js version current enough to support Kotlin/Wasm
nodeVersion = "22.0.0-nightly2024010568c8472ed9"
logger.lifecycle("Using Node.js $nodeVersion to support Kotlin/Wasm")
nodeDownloadBaseUrl = "https://nodejs.org/download/nightly"
}
}
rootProject.tasks.withType<org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask>().configureEach {
// Prevent Yarn from complaining about newer Node.js versions.
args.add("--ignore-engines")
}
//endregion

View file

@ -7,94 +7,26 @@ plugins {
}
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
linuxX64()
mingwX64()
linuxArm64()
macosX64()
macosArm64()
// https://kotlinlang.org/docs/multiplatform-share-on-platforms.html#use-target-shortcuts
ios() // iosArm64, iosX64
watchos() // watchosArm32, watchosArm64, watchosX64
tvos() // tvosArm64, tvosX64
iosArm64()
iosX64()
iosSimulatorArm64()
tvosSimulatorArm64()
watchosArm32()
watchosArm64()
watchosX64()
watchosSimulatorArm64()
watchosDeviceArm64()
@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) }
}
tvosArm64()
tvosX64()
tvosSimulatorArm64()
}

View file

@ -10,9 +10,9 @@ import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension
* version catalog.
*/
internal fun Project.relocateKotlinJsStore() {
afterEvaluate {
rootProject.extensions.configure<YarnRootExtension> {
lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store")
}
}
afterEvaluate {
rootProject.extensions.configure<YarnRootExtension> {
lockFileDirectory = project.rootDir.resolve("gradle/kotlin-js-store")
}
}
}

View file

@ -1,19 +1,3 @@
/*
* 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 {
@ -98,9 +82,11 @@ signing {
})
}
tasks.withType<Sign>().configureEach {
val signingRequiredPredicate = provider { signing.isRequired }
onlyIf { signingRequiredPredicate.get() }
tasks {
withType<Sign>().configureEach {
val signingRequiredPredicate = provider { signing.isRequired }
onlyIf { signingRequiredPredicate.get() }
}
}
// https://youtrack.jetbrains.com/issue/KT-46466

View file

@ -1,12 +1,11 @@
/*
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
* Copyright 2022-2023 Erik C. Thauvin (erik@thauvin.net)
* Copyright 2001-2024 the original author or authors.
*
* 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
* https://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,
@ -17,14 +16,13 @@
package buildsrc.utils
import org.apache.http.client.methods.HttpPost
import org.apache.http.impl.client.HttpClients
import org.apache.http.util.EntityUtils
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
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
class Rife2TestListener(
private val testBadgeApiKey: Provider<String>
@ -42,23 +40,23 @@ class Rife2TestListener(
if (apiKey != null) {
println(apiKey)
val response: HttpResponse<String> = 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())
val url = "https://rife2.com/tests-badge/update/net.thauvin.erik/urlencoder?" +
"apiKey=$apiKey&" +
"passed=$passed&" +
"failed=$failed&" +
"skipped=$skipped"
val client = HttpClients.createDefault()
val post = HttpPost(url)
val response = client.execute(post)
val entity = response.entity
val statusCode = response.statusLine.statusCode
val responseBody = EntityUtils.toString(entity, "UTF-8")
println("RESPONSE: $statusCode")
println(responseBody)
}
}
}

Binary file not shown.

View file

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

21
gradlew vendored
View file

@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@ -84,7 +86,8 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@ -145,7 +148,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@ -153,7 +156,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@ -202,11 +205,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \

22
gradlew.bat vendored
View file

@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail

View file

@ -1,82 +1,90 @@
rootProject.name = "urlencoder"
pluginManagement {
repositories {
mavenCentral()
gradlePluginPortal()
}
repositories {
mavenCentral()
gradlePluginPortal()
}
}
@Suppress("UnstableApiUsage")
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
mavenCentral()
maven("https://oss.sonatype.org/content/repositories/snapshots") {
name = "Sonatype Snapshots"
mavenContent { snapshotsOnly() }
}
// Declare the Node.js & Yarn download repositories
exclusiveContent {
forRepository {
ivy("https://nodejs.org/dist/") {
name = "Node Distributions at $url"
patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") }
metadataSources { artifact() }
content { includeModule("org.nodejs", "node") }
repositories {
mavenCentral()
maven("https://oss.sonatype.org/content/repositories/snapshots") {
name = "Sonatype Snapshots"
mavenContent { snapshotsOnly() }
}
}
filter { includeGroup("org.nodejs") }
}
exclusiveContent {
forRepository {
ivy("https://github.com/yarnpkg/yarn/releases/download") {
name = "Yarn Distributions at $url"
patternLayout { artifact("v[revision]/[artifact](-v[revision]).[ext]") }
metadataSources { artifact() }
content { includeModule("com.yarnpkg", "yarn") }
// Declare the Node.js & Yarn download repositories
exclusiveContent {
forRepositories(
ivy("https://nodejs.org/dist/") {
name = "Node Distributions at $url"
patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") }
metadataSources { artifact() }
},
ivy("https://nodejs.org/download/v8-canary/") {
name = "Node Canary Distributions at $url"
patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") }
metadataSources { artifact() }
},
ivy("https://nodejs.org/download/nightly/") {
name = "Node Nightly Distributions at $url"
patternLayout { artifact("v[revision]/[artifact](-v[revision]-[classifier]).[ext]") }
metadataSources { artifact() }
},
)
filter { includeGroup("org.nodejs") }
}
}
filter { includeGroup("com.yarnpkg") }
}
// workaround for https://youtrack.jetbrains.com/issue/KT-51379
exclusiveContent {
forRepository {
ivy("https://download.jetbrains.com/kotlin/native/builds") {
name = "Kotlin Native"
patternLayout {
// example download URLs:
// https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/linux-x86_64/kotlin-native-prebuilt-linux-x86_64-1.7.20.tar.gz
// https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/windows-x86_64/kotlin-native-prebuilt-windows-x86_64-1.7.20.zip
// https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/macos-x86_64/kotlin-native-prebuilt-macos-x86_64-1.7.20.tar.gz
listOf(
"macos-x86_64",
"macos-aarch64",
"osx-x86_64",
"osx-aarch64",
"linux-x86_64",
"windows-x86_64",
).forEach { os ->
listOf("dev", "releases").forEach { stage ->
artifact("$stage/[revision]/$os/[artifact]-[revision].[ext]")
}
exclusiveContent {
forRepository {
ivy("https://github.com/yarnpkg/yarn/releases/download") {
name = "Yarn Distributions at $url"
patternLayout { artifact("v[revision]/[artifact](-v[revision]).[ext]") }
metadataSources { artifact() }
}
}
}
metadataSources { artifact() }
filter { includeGroup("com.yarnpkg") }
}
// workaround for https://youtrack.jetbrains.com/issue/KT-51379
exclusiveContent {
forRepository {
ivy("https://download.jetbrains.com/kotlin/native/builds") {
name = "Kotlin Native"
patternLayout {
// example download URLs:
// https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/linux-x86_64/kotlin-native-prebuilt-linux-x86_64-1.7.20.tar.gz
// https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/windows-x86_64/kotlin-native-prebuilt-windows-x86_64-1.7.20.zip
// https://download.jetbrains.com/kotlin/native/builds/releases/1.7.20/macos-x86_64/kotlin-native-prebuilt-macos-x86_64-1.7.20.tar.gz
listOf(
"macos-x86_64",
"macos-aarch64",
"osx-x86_64",
"osx-aarch64",
"linux-x86_64",
"windows-x86_64",
).forEach { os ->
listOf("dev", "releases").forEach { stage ->
artifact("$stage/[revision]/$os/[artifact]-[revision].[ext]")
}
}
}
metadataSources { artifact() }
}
}
filter { includeModuleByRegex(".*", ".*kotlin-native-prebuilt.*") }
}
}
filter { includeModuleByRegex(".*", ".*kotlin-native-prebuilt.*") }
}
}
}
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
include(
":urlencoder-app",
":urlencoder-lib",
":urlencoder-app",
":urlencoder-lib",
)

View file

@ -1,17 +1,21 @@
import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
plugins {
buildsrc.conventions.lang.`kotlin-multiplatform-jvm`
// buildsrc.conventions.lang.`kotlin-multiplatform-js`
// buildsrc.conventions.lang.`kotlin-multiplatform-native`
buildsrc.conventions.publishing
id("application")
id("com.github.ben-manes.versions")
}
val urlEncoderMainClass = "net.thauvin.erik.urlencoder.UrlEncoder"
kotlin {
jvm {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
mainRun {
mainClass.set(urlEncoderMainClass)
}
}
sourceSets {
commonMain {
dependencies {
@ -32,10 +36,6 @@ base {
archivesName.set(rootProject.name)
}
application {
mainClass.set(urlEncoderMainClass)
}
tasks {
jvmJar {
manifest {
@ -45,14 +45,13 @@ tasks {
val fatJar by registering(Jar::class) {
group = LifecycleBasePlugin.BUILD_GROUP
dependsOn.addAll(listOf("compileJava", "compileKotlinJvm", "processResources"))
archiveClassifier.set("all")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest { attributes(mapOf("Main-Class" to application.mainClass)) }
from(sourceSets.main.get().output)
manifest { attributes(mapOf("Main-Class" to urlEncoderMainClass)) }
from(sourceSets.main.map { it.output })
dependsOn(configurations.jvmRuntimeClasspath)
from(configurations.jvmRuntimeClasspath.map { classpath ->
classpath.incoming.artifacts.artifactFiles.files.filter { it.name.endsWith("jar") }.map { zipTree(it) }
classpath.filter { it.name.endsWith(".jar") }.map { zipTree(it) }
})
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2001-2023 the original author or authors.
* Copyright 2001-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -1,5 +1,5 @@
/*
* Copyright 2001-2023 the original author or authors.
* Copyright 2001-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,7 +29,7 @@ class UrlEncoderTest {
val validMap = listOf(
"a test &" to "a%20test%20%26",
"!abcdefghijklmnopqrstuvwxyz%%ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~=" to
"%21abcdefghijklmnopqrstuvwxyz%25%25ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.%7E%3D",
"%21abcdefghijklmnopqrstuvwxyz%25%25ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.%7E%3D",
"%#okékÉȢ smile!😁" to "%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81",
"\uD808\uDC00\uD809\uDD00\uD808\uDF00\uD808\uDD00" to "%F0%92%80%80%F0%92%94%80%F0%92%8C%80%F0%92%84%80",
)

View file

@ -1,5 +1,5 @@
/*
* Copyright 2001-2023 the original author or authors.
* Copyright 2001-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -59,15 +59,15 @@ internal object Character {
internal fun lowSurrogateOf(codePoint: Int): Char =
((codePoint and 0x3FF) + MIN_LOW_SURROGATE.code).toChar()
// private const val MIN_CODE_POINT: Int = 0x000000
// private const val MIN_CODE_POINT: Int = 0x000000
private const val MAX_CODE_POINT: Int = 0x10FFFF
private const val MIN_SUPPLEMENTARY_CODE_POINT: Int = 0x10000
private const val SURROGATE_DECODE_OFFSET: Int =
MIN_SUPPLEMENTARY_CODE_POINT -
(MIN_HIGH_SURROGATE.code shl 10) -
MIN_LOW_SURROGATE.code
(MIN_HIGH_SURROGATE.code shl 10) -
MIN_LOW_SURROGATE.code
private const val HIGH_SURROGATE_ENCODE_OFFSET: Char = MIN_HIGH_SURROGATE - (MIN_SUPPLEMENTARY_CODE_POINT ushr 10)
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2001-2023 the original author or authors.
* Copyright 2001-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View file

@ -0,0 +1,43 @@
/*
* Copyright 2001-2024 the original author or authors.
*
* 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
*
* https://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 net.thauvin.erik.urlencoder
import kotlin.jvm.JvmField
const val standardContent = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_."
val invalidContent = listOf("sdkjfh%", "sdkjfh%6", "sdkjfh%xx", "sdfjfh%-1")
/**
* List of unencoded content paired with the encoded content.
*/
val decodedToEncoded = listOf(
TestData("a test &", "a%20test%20%26"),
TestData(
"!abcdefghijklmnopqrstuvwxyz%%ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~=",
"%21abcdefghijklmnopqrstuvwxyz%25%25ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.%7E%3D"
),
TestData("%#okékÉȢ smile!😁", "%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81"),
TestData("\uD808\uDC00\uD809\uDD00\uD808\uDF00\uD808\uDD00", "%F0%92%80%80%F0%92%94%80%F0%92%8C%80%F0%92%84%80"),
)
data class TestData(
@JvmField
val unencoded: String,
@JvmField
val encoded: String,
)

View file

@ -1,5 +1,5 @@
/*
* Copyright 2001-2023 the original author or authors.
* Copyright 2001-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,30 +23,17 @@ import kotlin.test.DefaultAsserter.assertEquals
import kotlin.test.DefaultAsserter.assertSame
class UrlEncoderUtilTest {
private val same = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_."
companion object {
val invalid = listOf("sdkjfh%", "sdkjfh%6", "sdkjfh%xx", "sdfjfh%-1")
val validMap = listOf(
"a test &" to "a%20test%20%26",
"!abcdefghijklmnopqrstuvwxyz%%ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.~=" to
"%21abcdefghijklmnopqrstuvwxyz%25%25ABCDEFGHIJKLMNOPQRSTUVQXYZ0123456789-_.%7E%3D",
"%#okékÉȢ smile!😁" to "%25%23ok%C3%A9k%C3%89%C8%A2%20smile%21%F0%9F%98%81",
"\uD808\uDC00\uD809\uDD00\uD808\uDF00\uD808\uDD00" to "%F0%92%80%80%F0%92%94%80%F0%92%8C%80%F0%92%84%80",
)
}
@Test
fun decodeURL() {
for (m in validMap) {
assertEquals(m.first, decode(m.second))
for ((unencoded, encoded) in decodedToEncoded) {
assertEquals(unencoded, decode(encoded))
}
}
@Test
fun decodeWithException() {
for (source in invalid) {
for (source in invalidContent) {
assertFailsWith<IllegalArgumentException>(
message = "decode($source)",
block = { decode(source) }
@ -56,7 +43,7 @@ class UrlEncoderUtilTest {
@Test
fun decodeWhenNoneNeeded() {
assertSame(same, decode(same))
assertSame(standardContent, decode(standardContent))
assertEquals("decode('')", decode(""), "")
assertEquals("decode(' ')", decode(" "), " ")
}
@ -72,8 +59,8 @@ class UrlEncoderUtilTest {
@Test
fun encodeURL() {
for (m in validMap) {
assertEquals(m.second, encode(m.first))
for ((unencoded, encoded) in decodedToEncoded) {
assertEquals(encoded, encode(unencoded))
}
}
@ -86,8 +73,8 @@ class UrlEncoderUtilTest {
@Test
fun encodeWhenNoneNeeded() {
assertSame(encode(same), same)
assertSame("with empty allow", encode(same, allow = ""), same)
assertSame(encode(standardContent), standardContent)
assertSame("with empty allow", encode(standardContent, allow = ""), standardContent)
}
@Test

View file

@ -0,0 +1,50 @@
/*
* Copyright 2001-2024 the original author or authors.
*
* 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
*
* https://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 net.thauvin.erik.urlencoder;
import org.junit.jupiter.api.Test;
import static net.thauvin.erik.urlencoder.TestDataKt.getDecodedToEncoded;
import static net.thauvin.erik.urlencoder.UrlEncoderUtil.decode;
import static net.thauvin.erik.urlencoder.UrlEncoderUtil.encode;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
class UrlEncoderJavaTest {
@Test
public void decodeURL() {
assertAll(
getDecodedToEncoded()
.stream()
.map(data ->
() -> assertEquals(data.unencoded, decode(data.encoded))
)
);
}
@Test
public void encodeURL() {
assertAll(
getDecodedToEncoded()
.stream()
.map(data ->
() -> assertEquals(data.encoded, encode(data.unencoded))
)
);
}
}