Skip to content

Commit

Permalink
2.1.0 (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nek-12 authored Jan 5, 2025
2 parents 9d7ff03 + 9dbc435 commit 90d102a
Show file tree
Hide file tree
Showing 31 changed files with 434 additions and 161 deletions.
2 changes: 1 addition & 1 deletion .github/changelog_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
],
"label_extractor" : [
{
"pattern" : "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\\([\\w\\-\\.]+\\))?(!)?: ([\\w ])+([\\s\\S]*)",
"pattern" : "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test|feat!|breaking|api){1}(\\([\\w\\-\\.]+\\))?(!)?: ([\\w ])+([\\s\\S]*)",
"target" : "$1"
}
]
Expand Down
33 changes: 25 additions & 8 deletions .github/ci-gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
org.gradle.jvmargs=-Xmx3g -Xms1g -XX:+UseParallelGC -XX:+UseStringDeduplication -Dfile.encoding=UTF-8
kotlin.daemon.jvmargs=-Xmx3g -Xms1g -XX:+UseParallelGC -XX:+UseStringDeduplication -XX:MaxMetaspaceSize=1g
# suppress inspection "UnusedProperty" for whole file
org.gradle.jvmargs=-Xmx6g -Xms1g -XX:+UseParallelGC -XX:+UseStringDeduplication -Dfile.encoding=UTF-8
kotlin.daemon.jvmargs=-Xmx6g -Xms1g -XX:+UseParallelGC -XX:+UseStringDeduplication -XX:MaxMetaspaceSize=2g
android.useAndroidX=true
kotlin.code.style=official
org.gradle.caching=true
Expand All @@ -8,21 +9,37 @@ android.enableR8.fullMode=true
org.gradle.configureondemand=true
android.enableJetifier=false
kotlin.incremental.usePreciseJavaTracking=true
org.gradle.configuration-cache.problems=warn
android.nonTransitiveRClass=true
android.experimental.enableSourceSetPathsMap=true
android.experimental.cacheCompileLibResources=true
kotlin.mpp.enableCInteropCommonization=true
kotlin.mpp.stability.nowarn=true
kotlin.mpp.androidGradlePluginCompatibility.nowarn=true
org.gradle.unsafe.configuration-cache=true
kotlin.mpp.androidSourceSetLayoutVersion=2
android.disableResourceValidation=false
org.gradle.daemon=true
org.gradle.daemon=false
android.nonFinalResIds=true
kotlin.native.ignoreIncorrectDependencies=true
kotlinx.atomicfu.enableJvmIrTransformation=true
org.jetbrains.compose.experimental.macos.enabled=true
org.gradle.configuration-cache.problems=warn
android.lint.useK2Uast=true
nl.littlerobots.vcu.resolver=true
org.gradle.console=plain
org.jetbrains.compose.experimental.jscanvas.enabled=true
org.jetbrains.compose.experimental.wasm.enabled=true
org.jetbrains.compose.experimental.macos.enabled=true
# Do not garbage collect on timeout on native when appExtensions are used and app is in bacground
kotlin.native.binary.appStateTracking=enabled
# Lift main thread suspending function invocation restriction
kotlin.native.binary.objcExportSuspendFunctionLaunchThreadRestriction=none
# Native incremental compilation
kotlin.incremental.native=true
android.experimental.additionalArtifactsInModel=true
kotlin.apple.xcodeCompatibility.nowarn=true
# Enable new k/n GC
kotlin.native.binary.gc=cms
org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true
org.gradle.configuration-cache.parallel=true
release=true
#kotlin.kmp.isolated-projects.support=enable
kotlin.incremental.wasm=true
#org.gradle.unsafe.isolated-projects=true
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
with:
distribution: 'zulu'
check-latest: true
java-version: 22
java-version: 23
cache: 'gradle'

- name: Validate gradle wrapper
Expand Down
9 changes: 6 additions & 3 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
with:
distribution: 'zulu'
check-latest: true
java-version: 22
java-version: 23
cache: 'gradle'

- name: Validate gradle wrapper
Expand All @@ -39,10 +39,13 @@ jobs:
run: cp ./README.md ./docs/README.md

- name: Generate docs
run: ./gradlew :dokkaHtmlMultiModule --no-configuration-cache
run: ./gradlew dokkaGenerate

- name: Make javadoc dir
run: mkdir -p ./docs/javadocs

- name: Move docs to the parent docs dir
run: cp -r ./build/dokka/htmlMultiModule/ ./docs/javadocs/
run: cp -r ./build/dokka/html/ ./docs/javadocs

- name: Setup Pages
uses: actions/configure-pages@v5
Expand Down
24 changes: 21 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@ jobs:
environment: publishing

steps:
- uses: actions/checkout@v4
- name: Checkout
uses: actions/checkout@v4

- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

- name: set up JDK
- name: Set up JDK
uses: actions/setup-java@v4
with:
distribution: 'zulu'
check-latest: true
java-version: 22
java-version: 23
cache: 'gradle'

- name: Validate gradle wrapper
Expand All @@ -41,6 +42,22 @@ jobs:
with:
xcode-version: latest

- name: Create local properties
env:
LOCAL_PROPERTIES: ${{ secrets.LOCAL_PROPERTIES }}
run: echo "$LOCAL_PROPERTIES" | base64 --decode > local.properties

- name: Cache konan directory
uses: actions/cache@v4
with:
path: ~/.konan
key: ${{ runner.os }}-konan-${{ hashFiles('*.gradle.kts', 'buildSrc/*') }}
restore-keys: |
${{ runner.os }}-konan-
- name: Assemble android sample
run: ./gradlew :app:assembleRelease

- name: Publish to sonatype
env:
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USERNAME }}
Expand All @@ -64,6 +81,7 @@ jobs:
draft: true
artifactErrorsFailBuild: true
prerelease: false
artifacts: app/build/outputs/apk/release/*
body: ${{steps.build_changelog.outputs.changelog}}
tag: ${{ inputs.tag != '' && inputs.tag || github.ref_name }}
env:
Expand Down
6 changes: 6 additions & 0 deletions .idea/AndroidProjectSystem.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions .idea/runConfigurations.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,40 @@ ApiResult is [Railway Programming](https://proandroiddev.com/railway-oriented-pr
functional
error handling **on steroids**.

## Features
## Why use a library instead of try/catch?

* ApiResult is **lightweight**. The library creates no objects, makes no allocations or virtual function resolutions.
Most of the code is inlined.
* ApiResult offers 90+ operators covering most of possible use cases to turn your
Exceptions in Kotlin are **unchecked**.
Each time you call a function, it can throw and crash you app.
With ApiResult, you will never have this problem again.

* ApiResult **forces** your code users to handle errors. Forget about unhandled exceptions and unexpected crashes.
* ApiResult is **lightweight**. The library creates no objects and has ~0 performance impact.
* Use 90+ operators covering most of possible use cases to turn your
code from imperative and procedural to declarative and functional, which is more readable and extensible.
* ApiResult defines a contract that you can use in your code. No one will be able to obtain the result of a computation
without being forced to handle errors at compilation time.
* The library has 129 tests for 92% operator coverage.
* Core library has **no dependencies**. No need to worry about unexpected junk in your codebase.
* This isn't like Arrow, where with a monad you get a bunch of extra black magic. This framework focuses on **error handling** only.
* ApiResult is fully compatible with Exceptions and Coroutines. Just wrap a call and it will work.
* The library has 140+ tests for 92% operator coverage. Expect long-term support and stability.

## Preview
## How do I use it?

```kotlin
// wrap a result of a computation and expose the result
// wrap a result of any computation and expose the result
class BillingRepository(private val api: RestApi) {

suspend fun getSubscriptions() = ApiResult {
api.getSubscriptions()
} // -> ApiResult<List<Subscription>?>
}

// -----

// obtain and handle the result in the client code
val repo = BillingRepository( /* ... */)

fun onClickVerify() {
val state: SubscriptionState = repo.getSubscriptions()
val state: SubscriptionState = billingRepository.getSubscriptions()
.errorOnNull() // map nulls to error states with compile-time safety
.recover<NotSignedInException, _> { emptyList() } // recover from some or all errors
.require { securityRepository.isDeviceTrusted() } // conditionally fail the chain
.mapValues(::SubscriptionModel) // map list items
.filter { it.isPurchased } // filter values
.filter { it.isPurchased } // filter
.mapError<NetworkException, _, _> { e -> BillingException(cause = e) } // map exceptions
.then { validateSubscriptions(it) } // execute a computation and continue with its result, propagating errors
.chain { updateGracePeriod(it) } // execute another computation, and if it fails, stop the chain
Expand Down Expand Up @@ -92,7 +93,7 @@ Ready to try? Start with reading the [Quickstart Guide](https://opensource.respa
## License

```
Copyright 2022-2024 Respawn Team and contributors
Copyright 2022-2025 Respawn Team and contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
64 changes: 34 additions & 30 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
import com.vanniktech.maven.publish.JavadocJar
import com.vanniktech.maven.publish.KotlinMultiplatform
import com.vanniktech.maven.publish.MavenPublishBaseExtension
import com.vanniktech.maven.publish.MavenPublishBasePlugin
import com.vanniktech.maven.publish.SonatypeHost
import nl.littlerobots.vcu.plugin.versionCatalogUpdate
import nl.littlerobots.vcu.plugin.versionSelector
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradleSubplugin
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnLockMismatchReport
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin
import org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
alias(libs.plugins.detekt)
alias(libs.plugins.gradleDoctor)
alias(libs.plugins.version.catalog.update)
alias(libs.plugins.dokka)
alias(libs.plugins.atomicfu)
// alias(libs.plugins.atomicfu)
alias(libs.plugins.compose.compiler) apply false
alias(libs.plugins.maven.publish) apply false
dokkaDocumentation
// plugins already on a classpath (conventions)
// alias(libs.plugins.dokka) apply false
// alias(libs.plugins.androidApplication) apply false
// alias(libs.plugins.androidLibrary) apply false
// alias(libs.plugins.kotlinMultiplatform) apply false
Expand All @@ -31,20 +36,25 @@ allprojects {
subprojects {
plugins.withType<ComposeCompilerGradleSubplugin>().configureEach {
the<ComposeCompilerGradlePluginExtension>().apply {
enableIntrinsicRemember = true
enableNonSkippingGroupOptimization = true
enableStrongSkippingMode = true
stabilityConfigurationFile = rootProject.layout.projectDirectory.file("stability_definitions.txt")
featureFlags.addAll(ComposeFeatureFlag.OptimizeNonSkippingGroups)
stabilityConfigurationFiles.add(rootProject.layout.projectDirectory.file("stability_definitions.txt"))
if (properties["enableComposeCompilerReports"] == "true") {
val metricsDir = layout.buildDirectory.dir("compose_metrics")
metricsDestination = metricsDir
reportsDestination = metricsDir
}
}
}
afterEvaluate {
extensions.findByType<MavenPublishBaseExtension>()?.run {
plugins.withType<MavenPublishBasePlugin> {
the<MavenPublishBaseExtension>().apply {
val isReleaseBuild = properties["release"]?.toString().toBoolean()
configure(
KotlinMultiplatform(
javadocJar = JavadocJar.Empty(),
sourcesJar = true,
androidVariantsToPublish = listOf("release"),
)
)
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL, false)
if (isReleaseBuild) signAllPublications()
coordinates(Config.artifactId, name, Config.version(isReleaseBuild))
Expand Down Expand Up @@ -79,21 +89,6 @@ subprojects {
useJUnitPlatform()
filter { isFailOnNoMatchingTests = true }
}
withType<KotlinCompile>().configureEach {
compilerOptions {
jvmTarget.set(Config.jvmTarget)
freeCompilerArgs.apply { addAll(Config.jvmCompilerArgs) }
optIn.addAll(Config.optIns.map { "-opt-in=$it" })
}
}
}

if (name == "app") return@subprojects

apply(plugin = rootProject.libs.plugins.dokka.id)

dependencies {
dokkaPlugin(rootProject.libs.dokka.android)
}
}

Expand Down Expand Up @@ -121,12 +116,10 @@ versionCatalogUpdate {
}
}

atomicfu {
dependenciesVersion = libs.versions.atomicfu.get()
transformJvm = false
jvmVariant = "VH"
transformJs = false
}
// atomicfu {
// dependenciesVersion = libs.versions.atomicfu.get()
// jvmVariant = "VH"
// }

tasks {
withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
Expand Down Expand Up @@ -165,3 +158,14 @@ rootProject.plugins.withType<YarnPlugin>().configureEach {
yarnLockAutoReplace = true
}
}

dependencies {
detektPlugins(rootProject.libs.detekt.formatting)
detektPlugins(rootProject.libs.detekt.compose)
detektPlugins(rootProject.libs.detekt.libraries)
projects.run {
listOf(
core,
).forEach { dokka(it) }
}
}
1 change: 1 addition & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ plugins {
dependencies {
implementation(libs.android.gradle)
implementation(libs.kotlin.gradle)
implementation(libs.dokka.gradle)
}
Loading

0 comments on commit 90d102a

Please sign in to comment.