Skip to content

Commit

Permalink
Upgrade to modern kotlin multiplatform project structure (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
noheltcj authored Oct 30, 2019
1 parent a377b14 commit 10515b7
Show file tree
Hide file tree
Showing 90 changed files with 961 additions and 1,022 deletions.
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
*.iml
.gradle
.gradle/
/local.properties
/gradle.properties
/.idea
.DS_Store
/**/build
/**/out
out/
build/
/captures
/local
*.orig
Expand Down
117 changes: 49 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# RxCommon
A multi-platform (Native, JVM, iOS, macOS, and JS) ReactiveX implementation.
A multi-platform ReactiveX implementation targetting JVM, iOS, Android, and JS.

More targets can be added upon request.

## Documentation
Please refer to <https://reactivex.io> for documentation.
Expand All @@ -15,7 +17,7 @@ retain and emit the latest element.
* [BehaviorSubject](http://reactivex.io/documentation/subject.html) - Similar to the BehaviorRelay, but acknowledges
notifications
* [PublishSubject](http://reactivex.io/documentation/subject.html)
* More coming, _I would gladly accept new collaborators / contributions_.
* More coming, _new collaborators / contributions are greatly appreciated_.

### Operators
More operators are coming quickly, but not all have been implemented.
Expand Down Expand Up @@ -67,93 +69,72 @@ val disposable = Observable<String>(createWithEmitter = { emitter ->
```

## Installing
There are several places requiring imports to utilize this library.

### Common Module
```groovy
implementation "com.noheltcj:rx-common:0.5.2"
```
Please ensure you're using gradle 5.3+.

Installing has recently become significantly easier. Now it's as simple as including
the following:

### Kotlin Build Script

### JVM Module
```groovy
implementation "com.noheltcj:rx-common-jvm:0.5.2"
```kotlin
kotlin {
sourceSets {
val commonMain by getting {
dependencies {
api("com.noheltcj:rxcommon:0.6.0")
}
}
}
}
```

### JavaScript Module
```groovy
implementation "com.noheltcj:rx-common-js:0.5.2"
### Groovy Build Script

```kotlin
kotlin {
sourceSets {
commonMain {
dependencies {
api 'com.noheltcj:rxcommon:0.6.0'
}
}
}
}
```

### Native Module
Slightly more complicated. See the [Native Distribution Limitation](#native-library-distribution)
### Kotlin Support Map (For Native)

Since native modules require dependencies to be compiled with the same kotlin version,
we will be keeping up with this support map going forward.

**RxCommon to Kotlin Stdlib Version Support Map**:
```
0.4.2 -> 1.3.20
0.5.0 -> 1.3.21
0.5.1 -> 1.3.21
0.5.2 -> 1.3.30
0.5.3 -> 1.3.31
0.6.0 -> 1.3.50
```

## Temporary Limitations
As this is a new project with only a couple of contributors, we haven't had time
to implement many of the things many have come to expect from a complete Rx
implementation, but open up a pull request to solve any issues and we'll work through it.

### Native Library Distribution
Distribution via maven central for the native kotlin library in kotlin/native
projects hasn't been implemented yet, but you can still use this in native projects.

_You can find the pre-built kotlin libraries zipped in the release tag for each
version._

To install this and successfully produce a framework which can be
distributed for use in XCode projects, you'll need to manually install
the .klib files for your target architectures.

For example, the following gradle script looks for the files in in the
lib directory of the kotlin/native project.

```groovy
apply plugin: 'konan'
konanArtifacts {
framework('Example', targets: ['ios_x64', 'ios_arm64']) {
extraOpts '-module_name', 'EX'
enableMultiplatform true
### Objective-C Generics
Objective-c only has partial generics support, so we lose a bit of
information when this library is imported as a framework in XCode.

target('ios_x64') {
libraries {
useRepo 'lib/ios_x64'
noStdLib true // Avoids linker issues
klib 'RxCommon'
}
}
To help with this, when you produce an Objective-C framework, be sure to
enable generics support.

target('ios_arm64') {
libraries {
useRepo 'lib/ios_arm64'
noStdLib true
klib 'RxCommon'
}
}
}
```^groovy
components.main {
outputKinds("framework")
extraOpts "-Xobjc-generics"
}
```

### Objective-C Generics
Objective-c only has partial generics support, so we lose a bit of
information when this library is imported as a framework in XCode.

### Concurrency
There is absolutely no thread safety or scheduling in the library yet,
but it's on the to-do list. In the meantime, it's best to keep any
application state and logic that utilizes this library on one thread.
This doesn't mean you can't still operate on different threads, just
transfer any data back to a single designated thread. I personally use the
existing platform specific implementations of Rx (RxSwift, RxJava, etc)
combined with platform scheduling (ExecutorService, DispatchQueue, etc) to do this.
This library doesn't support concurrency. In the majority of cases, concurrency is
a side effect that can be handled on the platform. If you are doing anything that
requires a significant amount of time to operate, it's important to do this work
off the main thread (Especially if your application has a user interface). Of course
do that using other resources such as RxSwift, RxJava, or basic platform concurrency
frameworks, but ensure you've returned to the main thread before re-entering the common code.
31 changes: 0 additions & 31 deletions build.gradle

This file was deleted.

22 changes: 22 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
buildscript {
repositories {
jcenter()
google()
}

dependencies {
classpath(Dependencies.Classpath.kotlinGradle)
classpath(Dependencies.Classpath.androidTools)
classpath(Dependencies.Classpath.dokkaPlugin)
}
}

subprojects {
group = "com.noheltcj"
version = Versions.rxcommon

repositories {
jcenter()
google()
}
}
6 changes: 0 additions & 6 deletions build.sh

This file was deleted.

7 changes: 7 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
plugins {
`kotlin-dsl`
}

repositories {
jcenter()
}
7 changes: 7 additions & 0 deletions buildSrc/src/main/java/Dependencies.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
object Dependencies {
object Classpath {
const val kotlinGradle = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}"
const val androidTools = "com.android.tools.build:gradle:${Versions.Android.gradleTools}"
const val dokkaPlugin = "org.jetbrains.dokka:dokka-gradle-plugin:${Versions.dokka}"
}
}
15 changes: 15 additions & 0 deletions buildSrc/src/main/java/Properties.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import org.gradle.api.Project

object Properties {
val isRelease by lazy {
System.getenv("release") == "true"
}

fun Project.requiredForReleaseProperty(name: String) =
properties[name] as String?
?: let {
if (isRelease)
throw RuntimeException("Missing property $name")
return ""
}
}
64 changes: 64 additions & 0 deletions buildSrc/src/main/java/Publishing.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
@file:Suppress("UnstableApiUsage")

import Properties.requiredForReleaseProperty
import org.gradle.api.Project
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import java.net.URI

object Publishing {
fun PublishingExtension.addRepositories(project: Project) {
repositories {
maven {
val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2"
val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots"

url = URI(
if (Properties.isRelease) {
releasesRepoUrl
} else {
snapshotsRepoUrl
}
)

authentication {
credentials {
username = project.requiredForReleaseProperty("ossrhUsername")
password = project.requiredForReleaseProperty("ossrhPassword")
}
}
}
}
}

fun MavenPublication.mutatePublicationPom(projectName: String) {
pom {
name.set(projectName)
inceptionYear.set("2018")

description.set("A multiplatform ReactiveX implementation.")
url.set("https://github.com/noheltcj/RxCommon")

scm {
connection.set("scm:git:https://github.com/noheltcj/RxCommon")
developerConnection.set("scm:git:https://github.com/noheltcj/RxCommon")
url.set("https://github.com/noheltcj/RxCommon")
}

licenses {
license {
name.set("MIT")
url.set("https://github.com/noheltcj/RxCommon/blob/master/LICENSE")
}
}

developers {
developer {
id.set("noheltcj")
name.set("Colton Nohelty")
email.set("noheltycolton@gmail.com")
}
}
}
}
}
9 changes: 9 additions & 0 deletions buildSrc/src/main/java/Versions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
object Versions {
const val rxcommon = "0.6.0"
const val kotlin = "1.3.50"
const val dokka = "0.10.0"

object Android {
const val gradleTools = "3.5.0"
}
}
Loading

0 comments on commit 10515b7

Please sign in to comment.