From c5cea33e18207abcef7d64af961fd23f230129ef Mon Sep 17 00:00:00 2001 From: Steven Jeuris Date: Sat, 25 Jun 2022 19:29:14 +0200 Subject: [PATCH 1/6] Build: make `kotlinx.interval` a module part of a multi-project setup --- build.gradle.kts | 129 +---------------- buildSrc/build.gradle.kts | 13 ++ buildSrc/settings.gradle.kts | 0 .../interval.library-conventions.gradle.kts | 134 ++++++++++++++++++ kotlinx.interval/build.gradle.kts | 12 ++ .../commonMain/kotlin/BasicTypeIntervals.kt | 0 .../commonMain/kotlin/BasicTypeOperations.kt | 0 .../src}/commonMain/kotlin/Interval.kt | 0 .../kotlin/IntervalTypeOperations.kt | 0 .../src}/commonMain/kotlin/TypeOperations.kt | 0 .../kotlin/BasicTypeIntervalsTest.kt | 0 .../kotlin/BasicTypeOperationsTest.kt | 0 .../src}/commonTest/kotlin/IntervalTest.kt | 0 .../src}/commonTest/kotlin/Readme.kt | 0 .../commonTest/kotlin/TypeOperationsTest.kt | 0 settings.gradle.kts | 2 + 16 files changed, 163 insertions(+), 127 deletions(-) create mode 100644 buildSrc/build.gradle.kts create mode 100644 buildSrc/settings.gradle.kts create mode 100644 buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts create mode 100644 kotlinx.interval/build.gradle.kts rename {src => kotlinx.interval/src}/commonMain/kotlin/BasicTypeIntervals.kt (100%) rename {src => kotlinx.interval/src}/commonMain/kotlin/BasicTypeOperations.kt (100%) rename {src => kotlinx.interval/src}/commonMain/kotlin/Interval.kt (100%) rename {src => kotlinx.interval/src}/commonMain/kotlin/IntervalTypeOperations.kt (100%) rename {src => kotlinx.interval/src}/commonMain/kotlin/TypeOperations.kt (100%) rename {src => kotlinx.interval/src}/commonTest/kotlin/BasicTypeIntervalsTest.kt (100%) rename {src => kotlinx.interval/src}/commonTest/kotlin/BasicTypeOperationsTest.kt (100%) rename {src => kotlinx.interval/src}/commonTest/kotlin/IntervalTest.kt (100%) rename {src => kotlinx.interval/src}/commonTest/kotlin/Readme.kt (100%) rename {src => kotlinx.interval/src}/commonTest/kotlin/TypeOperationsTest.kt (100%) diff --git a/build.gradle.kts b/build.gradle.kts index 3707c71..0fd615f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,66 +1,7 @@ -import java.io.FileInputStream -import java.util.Properties -import org.gradle.jvm.tasks.Jar -import org.jetbrains.dokka.Platform -import org.jetbrains.dokka.gradle.DokkaTask - - plugins { - kotlin("multiplatform") version "1.6.20" - `maven-publish` - signing - id("org.jetbrains.dokka") version "1.6.21" id("io.github.gradle-nexus.publish-plugin") version "1.1.0" } -group = "io.github.whathecode.kotlinx.interval" -version = "1.0.0-alpha.2" - -repositories { - mavenCentral() - gradlePluginPortal() -} - -kotlin { - jvm { - compilations.all { - kotlinOptions.jvmTarget = "1.8" - } - withJava() - testRuns["test"].executionTask.configure { - useJUnitPlatform() - } - } - js(BOTH) { - browser { } - } - val hostOs = System.getProperty("os.name") - val isMingwX64 = hostOs.startsWith("Windows") - val nativeTarget = when { - hostOs == "Mac OS X" -> macosX64("native") - hostOs == "Linux" -> linuxX64("native") - isMingwX64 -> mingwX64("native") - else -> throw GradleException("Host OS is not supported in Kotlin/Native.") - } - - - sourceSets { - val commonMain by getting - val commonTest by getting { - dependencies { - implementation(kotlin("test")) - } - } - val jvmMain by getting - val jvmTest by getting - val jsMain by getting - val jsTest by getting - val nativeMain by getting - val nativeTest by getting - } -} - - // Publish configuration. // For signing and publishing to work, a 'publish.properties' file needs to be added to the root containing: // The OpenPGP credentials to sign all artifacts: @@ -69,69 +10,10 @@ kotlin { // A username and password to upload artifacts to the Sonatype repository: // > repository.username= // > repository.password= -val publishProperties = Properties() +val publishProperties = java.util.Properties() val publishPropertiesFile = File("publish.properties") if (publishPropertiesFile.exists()) { - publishProperties.load(FileInputStream(publishPropertiesFile)) -} -val dokkaJvmJavadoc by tasks.creating(DokkaTask::class) { - dokkaSourceSets { - register("jvm") { - platform.set(Platform.jvm) - sourceRoots.from(kotlin.sourceSets.getByName("jvmMain").kotlin.srcDirs) - } - } -} -val javadocJar by tasks.creating(Jar::class) { - group = JavaBasePlugin.DOCUMENTATION_GROUP - description = "Create javadoc jar using Dokka" - archiveClassifier.set("javadoc") - from(dokkaJvmJavadoc) -} -publishing { - repositories { - maven { - name = "local" - url = uri("$buildDir/repo") - } - } - publications.filterIsInstance().forEach { - if (it.name == "jvm") { - it.artifact(javadocJar) - } - it.pom { - name.set("kotlinx.interval") - description.set("Kotlin multiplatform bounded open/closed generic intervals.") - url.set("https://github.com/Whathecode/kotlinx.interval") - licenses { - license { - name.set("The Apache Licence, Version 2.0") - url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("Whathecode") - name.set("Steven Jeuris") - email.set("steven.jeuris@gmail.com") - } - } - scm { - connection.set("scm:git:git://github.com/Whathecode/kotlinx.interval.git") - developerConnection.set("scm:git:ssh://github.com/Whathecode/carp.core-kotlin.git") - url.set("https://github.com/Whathecode/kotlinx.interval") - } - } - } -} -signing { - val signingKeyFile = publishProperties["signing.keyFile"] as? String - if (signingKeyFile != null) { - val signingKey = File(signingKeyFile).readText() - val signingPassword = publishProperties["signing.password"] as? String - useInMemoryPgpKeys(signingKey, signingPassword) - sign(publishing.publications) - } + publishProperties.load(java.io.FileInputStream(publishPropertiesFile)) } nexusPublishing { repositories { @@ -143,10 +25,3 @@ nexusPublishing { } } } -val setSnapshotVersion by tasks.creating { - doFirst { - val versionSplit = version.toString().split("-") - val snapshotVersion = "${versionSplit[0]}-SNAPSHOT" - version = snapshotVersion - } -} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000..5f40a73 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() + gradlePluginPortal() +} + +dependencies { + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.20") + implementation("org.jetbrains.dokka:dokka-gradle-plugin:1.6.21") +} diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts new file mode 100644 index 0000000..e69de29 diff --git a/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts b/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts new file mode 100644 index 0000000..87d077a --- /dev/null +++ b/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts @@ -0,0 +1,134 @@ +import java.io.FileInputStream +import java.util.Properties +import org.jetbrains.dokka.Platform +import org.jetbrains.dokka.gradle.DokkaTask + + +plugins { + kotlin("multiplatform") + id("org.jetbrains.dokka") + `maven-publish` + signing +} + +repositories { + mavenCentral() +} + +group = "io.github.whathecode.kotlinx.interval" +version = "1.0.0-alpha.2" + + +kotlin { + jvm { + compilations.all { + kotlinOptions.jvmTarget = "1.8" + } + withJava() + testRuns["test"].executionTask.configure { + useJUnitPlatform() + } + } + js(BOTH) { + browser { } + } + val hostOs = System.getProperty("os.name") + val isMingwX64 = hostOs.startsWith("Windows") + val nativeTarget = when { + hostOs == "Mac OS X" -> macosX64("native") + hostOs == "Linux" -> linuxX64("native") + isMingwX64 -> mingwX64("native") + else -> throw GradleException("Host OS is not supported in Kotlin/Native.") + } + + + sourceSets { + val commonMain by getting + val commonTest by getting { + dependencies { + implementation(kotlin("test")) + } + } + val jvmMain by getting + val jvmTest by getting + val jsMain by getting + val jsTest by getting + val nativeMain by getting + val nativeTest by getting + } +} + + +// Documentation. +val dokkaJvmJavadoc by tasks.creating(DokkaTask::class) { + dokkaSourceSets { + register("jvm") { + platform.set(Platform.jvm) + sourceRoots.from(kotlin.sourceSets.getByName("jvmMain").kotlin.srcDirs) + } + } +} +val javadocJar by tasks.creating(Jar::class) { + group = JavaBasePlugin.DOCUMENTATION_GROUP + description = "Create javadoc jar using Dokka" + archiveClassifier.set("javadoc") + from(dokkaJvmJavadoc) +} + + +// Publish configuration. +val publishProperties = Properties() +val publishPropertiesFile = File("publish.properties") +if (publishPropertiesFile.exists()) { + publishProperties.load(FileInputStream(publishPropertiesFile)) +} +publishing { + repositories { + maven { + name = "local" + url = uri("$buildDir/repo") + } + } + publications.filterIsInstance().forEach { + if (it.name == "jvm") { + it.artifact(javadocJar) + } + it.pom { + url.set("https://github.com/Whathecode/kotlinx.interval") + licenses { + license { + name.set("The Apache Licence, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("Whathecode") + name.set("Steven Jeuris") + email.set("steven.jeuris@gmail.com") + } + } + scm { + connection.set("scm:git:git://github.com/Whathecode/kotlinx.interval.git") + developerConnection.set("scm:git:ssh://github.com/Whathecode/carp.core-kotlin.git") + url.set("https://github.com/Whathecode/kotlinx.interval") + } + } + } +} +signing { + val signingKeyFile = publishProperties["signing.keyFile"] as? String + if (signingKeyFile != null) { + val signingKey = File(signingKeyFile).readText() + val signingPassword = publishProperties["signing.password"] as? String + useInMemoryPgpKeys(signingKey, signingPassword) + sign(publishing.publications) + } +} +val setSnapshotVersion by tasks.creating { + doFirst { + val versionSplit = version.toString().split("-") + val snapshotVersion = "${versionSplit[0]}-SNAPSHOT" + version = snapshotVersion + } +} diff --git a/kotlinx.interval/build.gradle.kts b/kotlinx.interval/build.gradle.kts new file mode 100644 index 0000000..c9efc27 --- /dev/null +++ b/kotlinx.interval/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id( "interval.library-conventions" ) +} + +publishing { + publications.filterIsInstance().forEach { + it.pom { + name.set("kotlinx.interval") + description.set("Kotlin multiplatform bounded open/closed generic intervals.") + } + } +} diff --git a/src/commonMain/kotlin/BasicTypeIntervals.kt b/kotlinx.interval/src/commonMain/kotlin/BasicTypeIntervals.kt similarity index 100% rename from src/commonMain/kotlin/BasicTypeIntervals.kt rename to kotlinx.interval/src/commonMain/kotlin/BasicTypeIntervals.kt diff --git a/src/commonMain/kotlin/BasicTypeOperations.kt b/kotlinx.interval/src/commonMain/kotlin/BasicTypeOperations.kt similarity index 100% rename from src/commonMain/kotlin/BasicTypeOperations.kt rename to kotlinx.interval/src/commonMain/kotlin/BasicTypeOperations.kt diff --git a/src/commonMain/kotlin/Interval.kt b/kotlinx.interval/src/commonMain/kotlin/Interval.kt similarity index 100% rename from src/commonMain/kotlin/Interval.kt rename to kotlinx.interval/src/commonMain/kotlin/Interval.kt diff --git a/src/commonMain/kotlin/IntervalTypeOperations.kt b/kotlinx.interval/src/commonMain/kotlin/IntervalTypeOperations.kt similarity index 100% rename from src/commonMain/kotlin/IntervalTypeOperations.kt rename to kotlinx.interval/src/commonMain/kotlin/IntervalTypeOperations.kt diff --git a/src/commonMain/kotlin/TypeOperations.kt b/kotlinx.interval/src/commonMain/kotlin/TypeOperations.kt similarity index 100% rename from src/commonMain/kotlin/TypeOperations.kt rename to kotlinx.interval/src/commonMain/kotlin/TypeOperations.kt diff --git a/src/commonTest/kotlin/BasicTypeIntervalsTest.kt b/kotlinx.interval/src/commonTest/kotlin/BasicTypeIntervalsTest.kt similarity index 100% rename from src/commonTest/kotlin/BasicTypeIntervalsTest.kt rename to kotlinx.interval/src/commonTest/kotlin/BasicTypeIntervalsTest.kt diff --git a/src/commonTest/kotlin/BasicTypeOperationsTest.kt b/kotlinx.interval/src/commonTest/kotlin/BasicTypeOperationsTest.kt similarity index 100% rename from src/commonTest/kotlin/BasicTypeOperationsTest.kt rename to kotlinx.interval/src/commonTest/kotlin/BasicTypeOperationsTest.kt diff --git a/src/commonTest/kotlin/IntervalTest.kt b/kotlinx.interval/src/commonTest/kotlin/IntervalTest.kt similarity index 100% rename from src/commonTest/kotlin/IntervalTest.kt rename to kotlinx.interval/src/commonTest/kotlin/IntervalTest.kt diff --git a/src/commonTest/kotlin/Readme.kt b/kotlinx.interval/src/commonTest/kotlin/Readme.kt similarity index 100% rename from src/commonTest/kotlin/Readme.kt rename to kotlinx.interval/src/commonTest/kotlin/Readme.kt diff --git a/src/commonTest/kotlin/TypeOperationsTest.kt b/kotlinx.interval/src/commonTest/kotlin/TypeOperationsTest.kt similarity index 100% rename from src/commonTest/kotlin/TypeOperationsTest.kt rename to kotlinx.interval/src/commonTest/kotlin/TypeOperationsTest.kt diff --git a/settings.gradle.kts b/settings.gradle.kts index 8224f7b..b504937 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1 +1,3 @@ rootProject.name = "kotlinx-interval" + +include( "kotlinx.interval" ) \ No newline at end of file From 26f19fe642ca2f3fcb84cd58a01601d8501ceb79 Mon Sep 17 00:00:00 2001 From: Steven Jeuris Date: Tue, 26 Jul 2022 11:11:39 +0200 Subject: [PATCH 2/6] Move base test classes to separate module: `kotlinx.interval.test` Currently, this is the only way these test sources can be reused by `kotlinx.interval` extensions (https://stackoverflow.com/q/58956010/590790), such as the upcoming `kotlinx.interval.datetime` module. --- kotlinx.interval.test/build.gradle.kts | 28 +++++++++++++++++++ .../src/commonMain}/kotlin/IntervalTest.kt | 4 ++- .../commonMain}/kotlin/TypeOperationsTest.kt | 3 +- kotlinx.interval/build.gradle.kts | 10 +++++++ .../kotlin/BasicTypeIntervalsTest.kt | 2 ++ .../kotlin/BasicTypeOperationsTest.kt | 1 + settings.gradle.kts | 3 +- 7 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 kotlinx.interval.test/build.gradle.kts rename {kotlinx.interval/src/commonTest => kotlinx.interval.test/src/commonMain}/kotlin/IntervalTest.kt (96%) rename {kotlinx.interval/src/commonTest => kotlinx.interval.test/src/commonMain}/kotlin/TypeOperationsTest.kt (94%) diff --git a/kotlinx.interval.test/build.gradle.kts b/kotlinx.interval.test/build.gradle.kts new file mode 100644 index 0000000..e531158 --- /dev/null +++ b/kotlinx.interval.test/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + id( "interval.library-conventions" ) +} + +publishing { + publications.filterIsInstance().forEach { + it.pom { + name.set("kotlinx.interval.test") + description.set("Base test classes for extensions of kotlinx.interval.") + } + } +} + +kotlin { + sourceSets { + commonMain { + dependencies { + api(project(":kotlinx.interval")) + implementation(kotlin("test")) + } + } + jvmMain { + dependencies { + implementation(kotlin("test-junit5")) + } + } + } +} diff --git a/kotlinx.interval/src/commonTest/kotlin/IntervalTest.kt b/kotlinx.interval.test/src/commonMain/kotlin/IntervalTest.kt similarity index 96% rename from kotlinx.interval/src/commonTest/kotlin/IntervalTest.kt rename to kotlinx.interval.test/src/commonMain/kotlin/IntervalTest.kt index 789d090..1d380a3 100644 --- a/kotlinx.interval/src/commonTest/kotlin/IntervalTest.kt +++ b/kotlinx.interval.test/src/commonMain/kotlin/IntervalTest.kt @@ -1,5 +1,7 @@ -package io.github.whathecode.kotlinx.interval +package io.github.whathecode.kotlinx.interval.test +import io.github.whathecode.kotlinx.interval.Interval +import io.github.whathecode.kotlinx.interval.IntervalTypeOperations import kotlin.test.* diff --git a/kotlinx.interval/src/commonTest/kotlin/TypeOperationsTest.kt b/kotlinx.interval.test/src/commonMain/kotlin/TypeOperationsTest.kt similarity index 94% rename from kotlinx.interval/src/commonTest/kotlin/TypeOperationsTest.kt rename to kotlinx.interval.test/src/commonMain/kotlin/TypeOperationsTest.kt index 5007ebc..83bffa8 100644 --- a/kotlinx.interval/src/commonTest/kotlin/TypeOperationsTest.kt +++ b/kotlinx.interval.test/src/commonMain/kotlin/TypeOperationsTest.kt @@ -1,5 +1,6 @@ -package io.github.whathecode.kotlinx.interval +package io.github.whathecode.kotlinx.interval.test +import io.github.whathecode.kotlinx.interval.TypeOperations import kotlin.test.* diff --git a/kotlinx.interval/build.gradle.kts b/kotlinx.interval/build.gradle.kts index c9efc27..62996f6 100644 --- a/kotlinx.interval/build.gradle.kts +++ b/kotlinx.interval/build.gradle.kts @@ -10,3 +10,13 @@ publishing { } } } + +kotlin { + sourceSets { + commonTest { + dependencies { + implementation(project(":kotlinx.interval.test")) + } + } + } +} diff --git a/kotlinx.interval/src/commonTest/kotlin/BasicTypeIntervalsTest.kt b/kotlinx.interval/src/commonTest/kotlin/BasicTypeIntervalsTest.kt index 0a05894..e7c055d 100644 --- a/kotlinx.interval/src/commonTest/kotlin/BasicTypeIntervalsTest.kt +++ b/kotlinx.interval/src/commonTest/kotlin/BasicTypeIntervalsTest.kt @@ -1,5 +1,7 @@ package io.github.whathecode.kotlinx.interval +import io.github.whathecode.kotlinx.interval.test.IntervalTest + object ByteIntervalTest : IntervalTest( 0, 5, 10, 5.toUByte(), ByteInterval.Operations ) object ShortIntervalTest : IntervalTest( 0, 5, 10, 5.toUShort(), ShortInterval.Operations ) diff --git a/kotlinx.interval/src/commonTest/kotlin/BasicTypeOperationsTest.kt b/kotlinx.interval/src/commonTest/kotlin/BasicTypeOperationsTest.kt index 5b3be57..1bca7c4 100644 --- a/kotlinx.interval/src/commonTest/kotlin/BasicTypeOperationsTest.kt +++ b/kotlinx.interval/src/commonTest/kotlin/BasicTypeOperationsTest.kt @@ -1,5 +1,6 @@ package io.github.whathecode.kotlinx.interval +import io.github.whathecode.kotlinx.interval.test.TypeOperationsTest import kotlin.test.* diff --git a/settings.gradle.kts b/settings.gradle.kts index b504937..7ebac27 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,4 @@ rootProject.name = "kotlinx-interval" -include( "kotlinx.interval" ) \ No newline at end of file +include( "kotlinx.interval" ) +include( "kotlinx.interval.test" ) From aaaa539c2e4f93e1d16d20dbe67e99b5a03d9b65 Mon Sep 17 00:00:00 2001 From: Steven Jeuris Date: Mon, 1 Aug 2022 18:08:52 +0200 Subject: [PATCH 3/6] Add `DateTimeTypeOperations` Provide access to `TypeOperations` for `Instant` and `Duration`. --- kotlin-js-store/yarn.lock | 5 +++ kotlinx.interval.datetime/build.gradle.kts | 28 ++++++++++++++ .../kotlin/DateTimeTypeOperations.kt | 37 +++++++++++++++++++ .../kotlin/DateTimeOperationsTest.kt | 17 +++++++++ settings.gradle.kts | 1 + 5 files changed, 88 insertions(+) create mode 100644 kotlinx.interval.datetime/build.gradle.kts create mode 100644 kotlinx.interval.datetime/src/commonMain/kotlin/DateTimeTypeOperations.kt create mode 100644 kotlinx.interval.datetime/src/commonTest/kotlin/DateTimeOperationsTest.kt diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 7a554ce..4c90fc0 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -7,6 +7,11 @@ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== +"@js-joda/core@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273" + integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg== + "@types/component-emitter@^1.2.10": version "1.2.11" resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506" diff --git a/kotlinx.interval.datetime/build.gradle.kts b/kotlinx.interval.datetime/build.gradle.kts new file mode 100644 index 0000000..5db8f0d --- /dev/null +++ b/kotlinx.interval.datetime/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + id( "interval.library-conventions" ) +} + +publishing { + publications.filterIsInstance().forEach { + it.pom { + name.set("kotlinx.interval.datetime") + description.set("Kotlin multiplatform bounded open/closed date/time intervals.") + } + } +} + +kotlin { + sourceSets { + commonMain { + dependencies { + api(project(":kotlinx.interval")) + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.3.2") + } + } + commonTest { + dependencies { + implementation(project(":kotlinx.interval.test")) + } + } + } +} diff --git a/kotlinx.interval.datetime/src/commonMain/kotlin/DateTimeTypeOperations.kt b/kotlinx.interval.datetime/src/commonMain/kotlin/DateTimeTypeOperations.kt new file mode 100644 index 0000000..98dc63b --- /dev/null +++ b/kotlinx.interval.datetime/src/commonMain/kotlin/DateTimeTypeOperations.kt @@ -0,0 +1,37 @@ +package io.github.whathecode.kotlinx.interval.datetime + +import io.github.whathecode.kotlinx.interval.TypeOperations +import kotlinx.datetime.Instant +import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds + + +internal object InstantOperations : TypeOperations +{ + override val additiveIdentity: Instant = Instant.fromEpochMilliseconds( 0 ) + override val minValue: Instant = Instant.fromEpochSeconds( Long.MIN_VALUE, Long.MIN_VALUE ) + override val maxValue: Instant = Instant.fromEpochSeconds( Long.MAX_VALUE, Long.MAX_VALUE ) + + override fun unsafeAdd( a: Instant, b: Instant ): Instant = Instant.fromEpochSeconds( + a.epochSeconds + b.epochSeconds, + a.nanosecondsOfSecond + b.nanosecondsOfSecond + ) + + override fun unsafeSubtract( a: Instant, b: Instant ): Instant = Instant.fromEpochSeconds( + a.epochSeconds - b.epochSeconds, + a.nanosecondsOfSecond - b.nanosecondsOfSecond + ) +} + + +internal object DurationOperations : TypeOperations +{ + override val additiveIdentity: Duration = Duration.ZERO + + private const val MAX_MILLIS = Long.MAX_VALUE / 2 + override val minValue: Duration = -MAX_MILLIS.milliseconds + override val maxValue: Duration = MAX_MILLIS.milliseconds + + override fun unsafeAdd( a: Duration, b: Duration ): Duration = a + b + override fun unsafeSubtract( a: Duration, b: Duration ): Duration = a - b +} diff --git a/kotlinx.interval.datetime/src/commonTest/kotlin/DateTimeOperationsTest.kt b/kotlinx.interval.datetime/src/commonTest/kotlin/DateTimeOperationsTest.kt new file mode 100644 index 0000000..4aff0ec --- /dev/null +++ b/kotlinx.interval.datetime/src/commonTest/kotlin/DateTimeOperationsTest.kt @@ -0,0 +1,17 @@ +package io.github.whathecode.kotlinx.interval.datetime + +import io.github.whathecode.kotlinx.interval.test.TypeOperationsTest +import kotlinx.datetime.Instant +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds + + +object InstantOperationsTest : TypeOperationsTest( + InstantOperations, + a = Instant.fromEpochSeconds( 10, 10 ), + b = Instant.fromEpochSeconds( 5, 15 ), + aMinusB = Instant.fromEpochSeconds( 4, 1_000_000_000 - 5 ) +) + + +object DurationOperationsTest : TypeOperationsTest( DurationOperations, 10.seconds, 5.seconds, 5.seconds ) diff --git a/settings.gradle.kts b/settings.gradle.kts index 7ebac27..4f0954d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,3 +2,4 @@ rootProject.name = "kotlinx-interval" include( "kotlinx.interval" ) include( "kotlinx.interval.test" ) +include( "kotlinx.interval.datetime" ) From 637bcb69a302f54a12045d5ffd79a882e4cac6c8 Mon Sep 17 00:00:00 2001 From: Steven Jeuris Date: Mon, 1 Aug 2022 21:59:36 +0200 Subject: [PATCH 4/6] Add `InstantInterval` --- README.md | 17 +++++++++-- .../src/commonMain/kotlin/InstantInterval.kt | 30 +++++++++++++++++++ .../commonTest/kotlin/InstantIntervalTest.kt | 12 ++++++++ .../src/commonTest/kotlin/Readme.kt | 19 ++++++++++++ .../src/commonTest/kotlin/Readme.kt | 2 +- 5 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 kotlinx.interval.datetime/src/commonMain/kotlin/InstantInterval.kt create mode 100644 kotlinx.interval.datetime/src/commonTest/kotlin/InstantIntervalTest.kt create mode 100644 kotlinx.interval.datetime/src/commonTest/kotlin/Readme.kt diff --git a/README.md b/README.md index 8c7cfee..b1d8aae 100644 --- a/README.md +++ b/README.md @@ -17,14 +17,21 @@ val size: UInt = interval.size // 10 ``` This protects against overflows (e.g. if `size > Int.MAX_VALUE`) but also offers better semantics. -For example, you can create intervals for [kotlinx datetime](https://github.com/Kotlin/kotlinx-datetime) `Instant` values which are a `Duration` apart. +For example, this library supports [kotlinx datetime](https://github.com/Kotlin/kotlinx-datetime) `Instant` values which are a `Duration` apart. + +```kotlin +val now = Clock.System.now() +val interval: InstantInterval = interval( now, now + 100.seconds ) +val areIncluded = now + 50.seconds in interval // true +val size: Duration = interval.size // 100 seconds +``` ## Interval Types This library includes a generic base class `Interval` which can be used to create intervals for any type. To achieve this, it directs type operations to `IntervalTypeOperations` which the constructor takes as a parameter. -The following interval types are included by default: +The following interval types are included in `io.github.whathecode.kotlinx.interval:kotlinx.interval` on Maven: | Type | Values (`T`) | Distances (`TSize`) | |:----------------:|:------------:|:-------------------:| @@ -38,4 +45,8 @@ The following interval types are included by default: | `UShortInterval` | `UShort` | `UShort` | | `UIntInterval` | `UInt` | `UInt` | | `ULongInterval` | `ULong` | `ULong` | -| `CharInterval` | `Char` | `UShort` | \ No newline at end of file +| `CharInterval` | `Char` | `UShort` | + +### Date/time intervals +Date/time intervals are implemented as `InstantInterval` using the [kotlinx datetime](https://github.com/Kotlin/kotlinx-datetime) library. +Since you may not always want to pull in this dependency, this class is published separately in `io.github.whathecode.kotlinx.interval:kotlinx.interval.datetime`. \ No newline at end of file diff --git a/kotlinx.interval.datetime/src/commonMain/kotlin/InstantInterval.kt b/kotlinx.interval.datetime/src/commonMain/kotlin/InstantInterval.kt new file mode 100644 index 0000000..2d74655 --- /dev/null +++ b/kotlinx.interval.datetime/src/commonMain/kotlin/InstantInterval.kt @@ -0,0 +1,30 @@ +package io.github.whathecode.kotlinx.interval.datetime + +import io.github.whathecode.kotlinx.interval.Interval +import io.github.whathecode.kotlinx.interval.IntervalTypeOperations +import kotlinx.datetime.Instant +import kotlin.time.Duration +import kotlin.time.Duration.Companion.nanoseconds +import kotlin.time.Duration.Companion.seconds + + +/** + * An [Interval] representing the set of all [Instant] values lying between a provided [start] and [end] value. + * The interval can be closed, open, or half-open, as determined by [isStartIncluded] and [isEndIncluded]. + */ +class InstantInterval( start: Instant, isStartIncluded: Boolean, end: Instant, isEndIncluded: Boolean ) + : Interval( start, isStartIncluded, end, isEndIncluded, Operations ) +{ + companion object + { + internal val Operations = IntervalTypeOperations( InstantOperations, DurationOperations ) + { time: Instant -> (time.epochSeconds.seconds + time.nanosecondsOfSecond.nanoseconds).absoluteValue } + } +} + +/** + * Create an [InstantInterval] representing the set of all [Instant] values lying between [start] and [end]. + * To exclude endpoints, set [isStartIncluded] or [isEndIncluded] to false; a closed interval is created by default. + */ +fun interval( start: Instant, end: Instant, isStartIncluded: Boolean = true, isEndIncluded: Boolean = true ) = + InstantInterval( start, isStartIncluded, end, isEndIncluded ) diff --git a/kotlinx.interval.datetime/src/commonTest/kotlin/InstantIntervalTest.kt b/kotlinx.interval.datetime/src/commonTest/kotlin/InstantIntervalTest.kt new file mode 100644 index 0000000..9dbde3c --- /dev/null +++ b/kotlinx.interval.datetime/src/commonTest/kotlin/InstantIntervalTest.kt @@ -0,0 +1,12 @@ +package io.github.whathecode.kotlinx.interval.datetime + +import io.github.whathecode.kotlinx.interval.test.IntervalTest +import kotlinx.datetime.Instant +import kotlin.time.Duration + + +private val a = Instant.fromEpochSeconds( 0, 50 ) +private val b = Instant.fromEpochSeconds( 0, 100 ) +private val c = Instant.fromEpochSeconds( 100, 50 ) + +object InstantIntervalTest : IntervalTest( a, b, c, b - a, InstantInterval.Operations ) diff --git a/kotlinx.interval.datetime/src/commonTest/kotlin/Readme.kt b/kotlinx.interval.datetime/src/commonTest/kotlin/Readme.kt new file mode 100644 index 0000000..86b4c67 --- /dev/null +++ b/kotlinx.interval.datetime/src/commonTest/kotlin/Readme.kt @@ -0,0 +1,19 @@ +package io.github.whathecode.kotlinx.interval.datetime + +import kotlinx.datetime.Clock +import kotlin.test.* +import kotlin.time.Duration +import kotlin.time.Duration.Companion.seconds + + +class Readme +{ + @Test + fun introduction_instant_interval_example() + { + val now = Clock.System.now() + val interval: InstantInterval = interval( now, now + 100.seconds ) + val areIncluded = now + 50.seconds in interval // true + val size: Duration = interval.size // 100 seconds + } +} diff --git a/kotlinx.interval/src/commonTest/kotlin/Readme.kt b/kotlinx.interval/src/commonTest/kotlin/Readme.kt index 6c798e8..29ab726 100644 --- a/kotlinx.interval/src/commonTest/kotlin/Readme.kt +++ b/kotlinx.interval/src/commonTest/kotlin/Readme.kt @@ -6,7 +6,7 @@ import kotlin.test.* class Readme { @Test - fun introduction_example() + fun introduction_int_interval_example() { val interval: IntInterval = interval( 0, 10, isEndIncluded = false ) val areIncluded = 0 in interval && 5 in interval // true From 5a1f4548c9867d2d9bb8bbbce396b6b4b56ea3e6 Mon Sep 17 00:00:00 2001 From: Steven Jeuris Date: Mon, 1 Aug 2022 22:06:19 +0200 Subject: [PATCH 5/6] Build: bump to version 1.0.0-alpha.3 --- .../src/main/kotlin/interval.library-conventions.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts b/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts index 87d077a..bf4def6 100644 --- a/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts @@ -16,7 +16,7 @@ repositories { } group = "io.github.whathecode.kotlinx.interval" -version = "1.0.0-alpha.2" +version = "1.0.0-alpha.3" kotlin { From 2e062f59cb5504aaafcb251f00e85eae81f9f9c3 Mon Sep 17 00:00:00 2001 From: Steven Jeuris Date: Mon, 1 Aug 2022 22:47:09 +0200 Subject: [PATCH 6/6] Fix: Sonatype Nexus publishing There seems to be a problem with `group` and `version` set on the root project conflicting with the same set on the subprojects when trying to use the Nexus publishing plugin: https://github.com/gradle-nexus/publish-plugin/issues/150 These changes resolve this by aligning all of them. Once this needs to deviate we may have to revisit. --- README.md | 4 ++-- build.gradle.kts | 11 +++++++++++ .../kotlin/interval.library-conventions.gradle.kts | 10 ---------- kotlinx.interval.datetime/build.gradle.kts | 9 ++++++--- kotlinx.interval.test/build.gradle.kts | 7 +++++-- kotlinx.interval/build.gradle.kts | 7 +++++-- settings.gradle.kts | 11 +++++++---- 7 files changed, 36 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index b1d8aae..a613589 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ val size: Duration = interval.size // 100 seconds This library includes a generic base class `Interval` which can be used to create intervals for any type. To achieve this, it directs type operations to `IntervalTypeOperations` which the constructor takes as a parameter. -The following interval types are included in `io.github.whathecode.kotlinx.interval:kotlinx.interval` on Maven: +The following interval types are included in `io.github.whathecode.kotlinx.interval:kotlinx-interval` on Maven: | Type | Values (`T`) | Distances (`TSize`) | |:----------------:|:------------:|:-------------------:| @@ -49,4 +49,4 @@ The following interval types are included in `io.github.whathecode.kotlinx.inter ### Date/time intervals Date/time intervals are implemented as `InstantInterval` using the [kotlinx datetime](https://github.com/Kotlin/kotlinx-datetime) library. -Since you may not always want to pull in this dependency, this class is published separately in `io.github.whathecode.kotlinx.interval:kotlinx.interval.datetime`. \ No newline at end of file +Since you may not always want to pull in this dependency, this class is published separately in `io.github.whathecode.kotlinx.interval:kotlinx-interval-datetime`. diff --git a/build.gradle.kts b/build.gradle.kts index 0fd615f..f71f761 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,6 +15,8 @@ val publishPropertiesFile = File("publish.properties") if (publishPropertiesFile.exists()) { publishProperties.load(java.io.FileInputStream(publishPropertiesFile)) } +group = "io.github.whathecode.kotlinx.interval" +version = "1.0.0-alpha.3" nexusPublishing { repositories { sonatype { @@ -25,3 +27,12 @@ nexusPublishing { } } } +val setSnapshotVersion: Task by tasks.creating { + doFirst { + val versionSplit = version.toString().split("-") + val snapshotVersion = "${versionSplit[0]}-SNAPSHOT" + version = snapshotVersion + + rootProject.subprojects.forEach { it.version = snapshotVersion } + } +} diff --git a/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts b/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts index bf4def6..c631114 100644 --- a/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/interval.library-conventions.gradle.kts @@ -15,9 +15,6 @@ repositories { mavenCentral() } -group = "io.github.whathecode.kotlinx.interval" -version = "1.0.0-alpha.3" - kotlin { jvm { @@ -125,10 +122,3 @@ signing { sign(publishing.publications) } } -val setSnapshotVersion by tasks.creating { - doFirst { - val versionSplit = version.toString().split("-") - val snapshotVersion = "${versionSplit[0]}-SNAPSHOT" - version = snapshotVersion - } -} diff --git a/kotlinx.interval.datetime/build.gradle.kts b/kotlinx.interval.datetime/build.gradle.kts index 5db8f0d..0992cf1 100644 --- a/kotlinx.interval.datetime/build.gradle.kts +++ b/kotlinx.interval.datetime/build.gradle.kts @@ -1,3 +1,6 @@ +group = rootProject.group +version = rootProject.version + plugins { id( "interval.library-conventions" ) } @@ -5,7 +8,7 @@ plugins { publishing { publications.filterIsInstance().forEach { it.pom { - name.set("kotlinx.interval.datetime") + name.set("kotlinx-interval-datetime") description.set("Kotlin multiplatform bounded open/closed date/time intervals.") } } @@ -15,13 +18,13 @@ kotlin { sourceSets { commonMain { dependencies { - api(project(":kotlinx.interval")) + api(project(":kotlinx-interval")) implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.3.2") } } commonTest { dependencies { - implementation(project(":kotlinx.interval.test")) + implementation(project(":kotlinx-interval-test")) } } } diff --git a/kotlinx.interval.test/build.gradle.kts b/kotlinx.interval.test/build.gradle.kts index e531158..d31cc93 100644 --- a/kotlinx.interval.test/build.gradle.kts +++ b/kotlinx.interval.test/build.gradle.kts @@ -1,3 +1,6 @@ +group = rootProject.group +version = rootProject.version + plugins { id( "interval.library-conventions" ) } @@ -5,7 +8,7 @@ plugins { publishing { publications.filterIsInstance().forEach { it.pom { - name.set("kotlinx.interval.test") + name.set("kotlinx-interval-test") description.set("Base test classes for extensions of kotlinx.interval.") } } @@ -15,7 +18,7 @@ kotlin { sourceSets { commonMain { dependencies { - api(project(":kotlinx.interval")) + api(project(":kotlinx-interval")) implementation(kotlin("test")) } } diff --git a/kotlinx.interval/build.gradle.kts b/kotlinx.interval/build.gradle.kts index 62996f6..082d3b8 100644 --- a/kotlinx.interval/build.gradle.kts +++ b/kotlinx.interval/build.gradle.kts @@ -1,3 +1,6 @@ +group = rootProject.group +version = rootProject.version + plugins { id( "interval.library-conventions" ) } @@ -5,7 +8,7 @@ plugins { publishing { publications.filterIsInstance().forEach { it.pom { - name.set("kotlinx.interval") + name.set("kotlinx-interval") description.set("Kotlin multiplatform bounded open/closed generic intervals.") } } @@ -15,7 +18,7 @@ kotlin { sourceSets { commonTest { dependencies { - implementation(project(":kotlinx.interval.test")) + implementation(project(":kotlinx-interval-test")) } } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 4f0954d..f336af0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,8 @@ -rootProject.name = "kotlinx-interval" +include("kotlinx.interval") +project(":kotlinx.interval").name = "kotlinx-interval" -include( "kotlinx.interval" ) -include( "kotlinx.interval.test" ) -include( "kotlinx.interval.datetime" ) +include("kotlinx.interval.test") +project(":kotlinx.interval.test").name = "kotlinx-interval-test" + +include("kotlinx.interval.datetime") +project(":kotlinx.interval.datetime").name = "kotlinx-interval-datetime"