Skip to content

Commit

Permalink
Create Temporal Module (#33)
Browse files Browse the repository at this point in the history
* Add broadcast receiver flow

* Make android's plugin match format of other plugins

* Add Android-only temporal module

* Add JVM and JS modules with simple ticker flow

* Write tests for ticker and date time flows

* Readme fix

* Readme cleanups & reduce API surface

* Revert accidentally commented line

* Remove unused imports

* Google above JCenter in repo order
  • Loading branch information
cedrickcooke authored Jan 28, 2021
1 parent 2a13bee commit bca8844
Show file tree
Hide file tree
Showing 30 changed files with 701 additions and 11 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ Toolbox of utilities/helpers for Kotlin development.

# Tuulbox

| Module | Description |
|----------------------------|---------------------------------------------|
| [`coroutines`](coroutines) | Tools/utilities for [Coroutines]. |
| [`logging`](logging) | Multiplatform logging library. |
| [`functional`](functional) | Tools/utilities for manipulating functions. |
| [`test`](test) | Utilities for test suites. |
| Module | Description |
|----------------------------|------------------------------------------------------|
| [`coroutines`](coroutines) | Tools/utilities for [Coroutines]. |
| [`logging`](logging) | Multiplatform logging library. |
| [`functional`](functional) | Tools/utilities for manipulating functions. |
| [`temporal`](temporal) | Tools built on `kotlin.time` and `kotlinx.datetime`. |
| [`test`](test) | Utilities for test suites. |

# License

Expand Down
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import java.net.URI

buildscript {
repositories {
google()
jcenter()
}
}

plugins {
kotlin("multiplatform") version "1.4.10" apply false
id("com.android.library") version "4.0.2" apply false
id("kotlinx-atomicfu") version "0.14.4" apply false
id("org.jmailen.kotlinter") version "3.2.0" apply false
id("binary-compatibility-validator") version "0.2.3"
Expand All @@ -19,7 +21,9 @@ plugins {

subprojects {
repositories {
google()
jcenter()
maven(url = "https://kotlin.bintray.com/kotlinx/")
maven {
url = URI("https://maven.pkg.github.com/juullabs/android-github-packages")
credentials {
Expand Down
11 changes: 11 additions & 0 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,15 @@ object kotlinx {
module: String = "core",
version: String = "1.4.0"
) = "org.jetbrains.kotlinx:kotlinx-coroutines-$module:$version"

fun datetime(
version: String = "0.1.1"
) = "org.jetbrains.kotlinx:kotlinx-datetime:$version"
}

object androidx {

fun startup(
version: String = "1.0.0"
) = "androidx.startup:startup-runtime:$version"
}
1 change: 1 addition & 0 deletions coroutines/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
![badge-android]
![badge-js]
![badge-jvm]
![badge-mac]
Expand Down
38 changes: 37 additions & 1 deletion coroutines/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
plugins {
id("com.android.library")
kotlin("multiplatform")
id("org.jmailen.kotlinter")
jacoco
Expand All @@ -11,9 +12,11 @@ apply(from = rootProject.file("gradle/publish.gradle.kts"))

kotlin {
explicitApi()

jvm()
js().browser()
android {
publishAllLibraryVariants()
}
macosX64()

sourceSets {
Expand All @@ -31,6 +34,19 @@ kotlin {
}
}

val androidMain by getting {
dependencies {
api(kotlinx.coroutines("android"))
implementation(androidx.startup())
}
}

val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
}
}

val jvmTest by getting {
dependencies {
implementation(kotlin("test-junit"))
Expand All @@ -44,3 +60,23 @@ kotlin {
}
}
}

android {
compileSdkVersion(30)

defaultConfig {
minSdkVersion(24)
targetSdkVersion(30)
}

lintOptions {
isAbortOnError = true
isWarningsAsErrors = true
}

sourceSets {
val main by getting {
manifest.srcFile("src/androidMain/AndroidManifest.xml")
}
}
}
20 changes: 20 additions & 0 deletions coroutines/src/androidMain/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.juul.tuulbox.coroutines">

<application>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge"
>

<meta-data
android:name="com.juul.tuulbox.coroutines.TuulboxCoroutinesInitializer"
android:value="androidx.startup"
/>
</provider>
</application>

</manifest>
18 changes: 18 additions & 0 deletions coroutines/src/androidMain/kotlin/TuulboxCoroutinesInitializer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.juul.tuulbox.coroutines

import android.content.Context
import androidx.startup.Initializer

internal lateinit var applicationContext: Context
private set

public object TuulboxCoroutines

public class TuulboxCoroutinesInitializer : Initializer<TuulboxCoroutines> {
override fun create(context: Context): TuulboxCoroutines {
applicationContext = context
return TuulboxCoroutines
}

override fun dependencies(): List<Class<out Initializer<*>>> = emptyList()
}
25 changes: 25 additions & 0 deletions coroutines/src/androidMain/kotlin/flow/BroadcastReceiverFlow.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.juul.tuulbox.coroutines.flow

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import com.juul.tuulbox.coroutines.applicationContext
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow

@Suppress("EXPERIMENTAL_API_USAGE")
public fun broadcastReceiverFlow(
intentFilter: IntentFilter
): Flow<Intent> = callbackFlow {
val broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent != null) {
offer(intent)
}
}
}
applicationContext.registerReceiver(broadcastReceiver, intentFilter)
awaitClose { applicationContext.unregisterReceiver(broadcastReceiver) }
}
7 changes: 7 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m

# Android Configuration
android.useAndroidX=true

# Android Build Features
android.defaults.buildfeatures.buildconfig=false
android.defaults.buildfeatures.resvalues=false

# Publication configuration
# https://github.com/vanniktech/gradle-maven-publish-plugin#setting-properties

Expand Down
16 changes: 12 additions & 4 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
pluginManagement {
repositories {
google()
gradlePluginPortal()
jcenter()
}

resolutionStrategy {
eachPlugin {
if (requested.id.id == "binary-compatibility-validator") {
useModule("org.jetbrains.kotlinx:binary-compatibility-validator:${requested.version}")
} else if (requested.id.id == "kotlinx-atomicfu") {
useModule("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${requested.version}")
when (requested.id.id) {
"binary-compatibility-validator" ->
useModule("org.jetbrains.kotlinx:binary-compatibility-validator:${requested.version}")
"kotlinx-atomicfu" ->
useModule("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${requested.version}")
else -> when (requested.id.namespace) {
"com.android" ->
useModule("com.android.tools.build:gradle:${requested.version}")
}
}
}
}
Expand All @@ -18,5 +25,6 @@ include(
"coroutines",
"logging",
"functional",
"temporal",
"test"
)
78 changes: 78 additions & 0 deletions temporal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
![badge-android]
![badge-js]
![badge-jvm]

# Coroutines

Toolbox of utilities for dates and times, building on [KotlinX DateTime].

## Setup

### Gradle

[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.juul.tuulbox/temporal/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.juul.tuulbox/temporal)

Coroutines toolbox can be configured via Gradle Kotlin DSL as follows:

#### Multiplatform

```kotlin
plugins {
id("com.android.application") // or id("com.android.library")
kotlin("multiplatform")
}

repositories {
jcenter() // or mavenCentral()
}

kotlin {
js().browser() // and/or js().node()
jvm() // or android()

sourceSets {
val commonMain by getting {
dependencies {
implementation("com.juul.tuulbox:temporal:$version")
}
}
}
}

android {
// If this is an application module and your minimum API version is below 26, enable core library
// desugaring. See https://developer.android.com/studio/write/java8-support#library-desugaring
}
```

#### Platform-specific

```kotlin
repositories {
jcenter() // or mavenCentral()
}

dependencies {
implementation("com.juul.tuulbox:temporal-$platform:$version")
}
```

_Where `$platform` represents (should be replaced with) the desired platform dependency (e.g. `jvm`)._

#### Android Notes

Because this is built on top of KotlinX DateTime, [core library desugaring] must be enabled for your project

[core library desugaring]: https://developer.android.com/studio/write/java8-support#library-desugaring
[KotlinX DateTime]: https://github.com/Kotlin/kotlinx-datetime

[badge-android]: http://img.shields.io/badge/platform-android-6EDB8D.svg?style=flat
[badge-ios]: http://img.shields.io/badge/platform-ios-CDCDCD.svg?style=flat
[badge-js]: http://img.shields.io/badge/platform-js-F8DB5D.svg?style=flat
[badge-jvm]: http://img.shields.io/badge/platform-jvm-DB413D.svg?style=flat
[badge-linux]: http://img.shields.io/badge/platform-linux-2D3F6C.svg?style=flat
[badge-windows]: http://img.shields.io/badge/platform-windows-4D76CD.svg?style=flat
[badge-mac]: http://img.shields.io/badge/platform-macos-111111.svg?style=flat
[badge-watchos]: http://img.shields.io/badge/platform-watchos-C0C0C0.svg?style=flat
[badge-tvos]: http://img.shields.io/badge/platform-tvos-808080.svg?style=flat
[badge-wasm]: https://img.shields.io/badge/platform-wasm-624FE8.svg?style=flat
10 changes: 10 additions & 0 deletions temporal/api/temporal.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
public final class com/juul/tuulbox/temporal/DateTimeFlowKt {
public static final fun instantFlow ()Lkotlinx/coroutines/flow/Flow;
public static final fun localDateFlow ()Lkotlinx/coroutines/flow/Flow;
public static final fun localDateTimeFlow ()Lkotlinx/coroutines/flow/Flow;
}

public final class com/juul/tuulbox/temporal/TickerTemporalFlowKt {
public static final fun temporalFlow (Lkotlin/jvm/functions/Function0;)Lkotlinx/coroutines/flow/Flow;
}

Loading

0 comments on commit bca8844

Please sign in to comment.