Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.1.0 #14

Merged
merged 14 commits into from
Jan 5, 2025
Merged
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
Nek-12 marked this conversation as resolved.
Show resolved Hide resolved
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
Nek-12 marked this conversation as resolved.
Show resolved Hide resolved
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'
Nek-12 marked this conversation as resolved.
Show resolved Hide resolved

- 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
Loading