diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..b927a29 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,23 @@ +# .editorconfig +root = true + +[*.{kt,kts}] +end_of_line = lf +ij_kotlin_packages_to_use_import_on_demand = true +ij_kotlin_allow_trailing_comma = true +ij_kotlin_allow_trailing_comma_on_call_site = true +ij_kotlin_imports_layout = * +ij_kotlin_indent_before_arrow_on_new_line = false +ij_kotlin_line_break_after_multiline_when_entry = true +indent_size = 4 +indent_style = space +insert_final_newline = true +ktlint_argument_list_wrapping_ignore_when_parameter_count_greater_or_equal_than = 8 +ktlint_chain_method_rule_force_multiline_when_chain_operator_count_greater_or_equal_than = 4 +ktlint_code_style = android_studio +ktlint_enum_entry_name_casing = upper_or_camel_cases +ktlint_function_naming_ignore_when_annotated_with = Composable +ktlint_function_signature_body_expression_wrapping = default +ktlint_ignore_back_ticked_identifier = false +max_line_length = 140 +parameter-list-wrapping = true \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 110f01e..fd9fc00 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,21 +24,21 @@ jobs: - name: Validate Gradle Wrapper uses: gradle/wrapper-validation-action@v1 - name: Cache gradle - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} restore-keys: | ${{ runner.os }}-gradle- - name: Cache konan - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.konan key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} restore-keys: | ${{ runner.os }}-gradle- - name: Build - run: ./gradlew build --no-daemon --stacktrace + run: ./gradlew ktlintCheck build --no-daemon --stacktrace env: GRADLE_OPTS: -Dkotlin.incremental=false -Dorg.gradle.jvmargs="-Xmx4g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:MaxMetaspaceSize=512m" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 87eb9c2..ed2421e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -29,7 +29,7 @@ jobs: uses: gradle/wrapper-validation-action@v1 - name: Cache gradle - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} @@ -37,7 +37,7 @@ jobs: ${{ runner.os }}-gradle- - name: Cache konan - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.konan key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c57f597..c16e282 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: - name: Validate Gradle Wrapper uses: gradle/wrapper-validation-action@v1 - name: Cache gradle - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.gradle/caches key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} @@ -32,7 +32,7 @@ jobs: ${{ runner.os }}-gradle- - name: Cache konan - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.konan key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }} diff --git a/bugsnag-ios-link/build.gradle.kts b/bugsnag-ios-link/build.gradle.kts index 282a074..30ca78e 100644 --- a/bugsnag-ios-link/build.gradle.kts +++ b/bugsnag-ios-link/build.gradle.kts @@ -51,7 +51,10 @@ java { } } +@Suppress("ktlint:standard:property-naming") val GROUP: String by project + +@Suppress("ktlint:standard:property-naming") val VERSION_NAME: String by project group = GROUP @@ -63,4 +66,4 @@ mavenPublishing { project.properties["RELEASE_SIGNING_ENABLED"]?.toString()?.equals("false", ignoreCase = true) != true if (releaseSigningEnabled) signAllPublications() pomFromGradleProperties() -} \ No newline at end of file +} diff --git a/bugsnag-ios-link/src/main/kotlin/co/touchlab/crashkios/BugsnagLinkPlugin.kt b/bugsnag-ios-link/src/main/kotlin/co/touchlab/crashkios/BugsnagLinkPlugin.kt index b0742a4..327d532 100644 --- a/bugsnag-ios-link/src/main/kotlin/co/touchlab/crashkios/BugsnagLinkPlugin.kt +++ b/bugsnag-ios-link/src/main/kotlin/co/touchlab/crashkios/BugsnagLinkPlugin.kt @@ -28,7 +28,8 @@ internal val Project.kotlinExtension: KotlinMultiplatformExtension get() = exten @Suppress("unused") class BugsnagLinkPlugin : Plugin { override fun apply(project: Project): Unit = project.withKotlinMultiplatformPlugin { - val linkerArgs = "-U _OBJC_CLASS_\$_BugsnagHandledState " + + val linkerArgs = + "-U _OBJC_CLASS_\$_BugsnagHandledState " + "-U _OBJC_CLASS_\$_Bugsnag " + "-U _OBJC_CLASS_\$_BugsnagStackframe " + "-U _OBJC_CLASS_\$_FIRStackFrame " + diff --git a/bugsnag/build.gradle.kts b/bugsnag/build.gradle.kts index 0bc799d..8a80d15 100644 --- a/bugsnag/build.gradle.kts +++ b/bugsnag/build.gradle.kts @@ -19,7 +19,10 @@ plugins { id("com.vanniktech.maven.publish") } +@Suppress("ktlint:standard:property-naming") val GROUP: String by project + +@Suppress("ktlint:standard:property-naming") val VERSION_NAME: String by project group = GROUP @@ -88,15 +91,20 @@ kotlin { android { namespace = "co.touchlab.crashkios.bugsnag" - compileSdk = libs.versions.compileSdk.get().toInt() + compileSdk = + libs.versions.compileSdk + .get() + .toInt() defaultConfig { - minSdk = libs.versions.minSdk.get().toInt() + minSdk = + libs.versions.minSdk + .get() + .toInt() } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } - } tasks.withType { diff --git a/bugsnag/src/androidMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCallsActual.kt b/bugsnag/src/androidMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCallsActual.kt index 24a5dad..b0e7a52 100644 --- a/bugsnag/src/androidMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCallsActual.kt +++ b/bugsnag/src/androidMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCallsActual.kt @@ -18,4 +18,4 @@ actual class BugsnagCallsActual : BugsnagCalls { override fun setCustomValue(section: String, key: String, value: Any) { Bugsnag.addMetadata(section, key, value) } -} \ No newline at end of file +} diff --git a/bugsnag/src/appleMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCallsActual.kt b/bugsnag/src/appleMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCallsActual.kt index e4012ca..36c9d43 100644 --- a/bugsnag/src/appleMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCallsActual.kt +++ b/bugsnag/src/appleMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCallsActual.kt @@ -6,7 +6,6 @@ import kotlinx.cinterop.ExperimentalForeignApi @OptIn(ExperimentalForeignApi::class) actual class BugsnagCallsActual : BugsnagCalls { - override fun logMessage(message: String) { Bugsnag.leaveBreadcrumbWithMessage(message) } @@ -45,4 +44,4 @@ actual class BugsnagCallsActual : BugsnagCalls { true } } -} \ No newline at end of file +} diff --git a/bugsnag/src/appleMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagConfig.kt b/bugsnag/src/appleMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagConfig.kt index 6de3a94..1278028 100644 --- a/bugsnag/src/appleMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagConfig.kt +++ b/bugsnag/src/appleMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagConfig.kt @@ -8,7 +8,7 @@ import com.rickclephas.kmp.nsexceptionkt.core.wrapUnhandledExceptionHook import kotlinx.cinterop.ExperimentalForeignApi import platform.Foundation.NSException -public fun startBugsnag(config: BugsnagConfiguration){ +public fun startBugsnag(config: BugsnagConfiguration) { configureBugsnag(config) Bugsnag.startWithConfiguration(config) setBugsnagUnhandledExceptionHook() @@ -53,6 +53,7 @@ public fun setBugsnagUnhandledExceptionHook(): Unit = wrapUnhandledExceptionHook /** * Feature flag used to mark the Kotlin termination crash. */ +@Suppress("ktlint:standard:property-naming") private const val kotlinCrashedFeatureFlag = "crashkios.kotlin_crashed" /** diff --git a/bugsnag/src/commonMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCalls.kt b/bugsnag/src/commonMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCalls.kt index fe629c1..c49affa 100644 --- a/bugsnag/src/commonMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCalls.kt +++ b/bugsnag/src/commonMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagCalls.kt @@ -2,9 +2,12 @@ package co.touchlab.crashkios.bugsnag interface BugsnagCalls { fun logMessage(message: String) + fun sendHandledException(throwable: Throwable) + fun sendFatalException(throwable: Throwable) + fun setCustomValue(section: String, key: String, value: Any) } -expect class BugsnagCallsActual() : BugsnagCalls \ No newline at end of file +expect class BugsnagCallsActual() : BugsnagCalls diff --git a/bugsnag/src/commonMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagKotlin.kt b/bugsnag/src/commonMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagKotlin.kt index e0a84da..97ef3b2 100644 --- a/bugsnag/src/commonMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagKotlin.kt +++ b/bugsnag/src/commonMain/kotlin/co/touchlab/crashkios/bugsnag/BugsnagKotlin.kt @@ -26,24 +26,20 @@ object BugsnagKotlin { * Call in startup code in an actual app. Tests should generally skip this. In Kotlin/Native, not calling this * for tests avoids linker issues. */ -fun enableBugsnag(){ +fun enableBugsnag() { BugsnagKotlin.implementation = BugsnagCallsActual() } internal object EmptyCalls : BugsnagCalls { override fun logMessage(message: String) { - } override fun sendHandledException(throwable: Throwable) { - } override fun sendFatalException(throwable: Throwable) { - } override fun setCustomValue(section: String, key: String, value: Any) { - } -} \ No newline at end of file +} diff --git a/build.gradle.kts b/build.gradle.kts index acd9b70..9509351 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ plugins { alias(libs.plugins.android.library) apply false alias(libs.plugins.touchlab.docusaurus.template) alias(libs.plugins.gradle.publish) apply false + id("org.jlleitschuh.gradle.ktlint") version "12.2.0" apply false } allprojects { @@ -11,4 +12,23 @@ allprojects { mavenCentral() google() } +} + +subprojects { + apply(plugin = "org.jlleitschuh.gradle.ktlint") + + configure { + version.set("1.4.0") + enableExperimentalRules.set(true) + verbose.set(true) + filter { + exclude { it.file.path.contains("build/") } + } + } + + afterEvaluate { + tasks.named("check") { + dependsOn(tasks.getByName("ktlintCheck")) + } + } } \ No newline at end of file diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 2285f2e..bcabf0b 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -18,7 +18,10 @@ plugins { kotlin("multiplatform") } +@Suppress("ktlint:standard:property-naming") val GROUP: String by project + +@Suppress("ktlint:standard:property-naming") val VERSION_NAME: String by project group = GROUP @@ -60,9 +63,15 @@ kotlin { android { namespace = "co.touchlab.crashkios.core" - compileSdk = libs.versions.compileSdk.get().toInt() + compileSdk = + libs.versions.compileSdk + .get() + .toInt() defaultConfig { - minSdk = libs.versions.minSdk.get().toInt() + minSdk = + libs.versions.minSdk + .get() + .toInt() } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 diff --git a/core/src/androidMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt b/core/src/androidMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt index 24fe845..6f7543a 100644 --- a/core/src/androidMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt +++ b/core/src/androidMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt @@ -4,6 +4,7 @@ import kotlin.reflect.KProperty actual class ThreadSafeVar actual constructor(@Volatile private var target: T) { actual operator fun getValue(thisRef: Any?, property: KProperty<*>): T = target + actual operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { target = value } diff --git a/core/src/appleMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt b/core/src/appleMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt index 0c2b7d9..7206dfc 100644 --- a/core/src/appleMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt +++ b/core/src/appleMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt @@ -1,14 +1,16 @@ package co.touchlab.crashkios.core -import kotlin.experimental.ExperimentalNativeApi import kotlin.concurrent.AtomicReference +import kotlin.experimental.ExperimentalNativeApi import kotlin.native.concurrent.freeze import kotlin.reflect.KProperty @OptIn(FreezingIsDeprecated::class, ExperimentalNativeApi::class) actual class ThreadSafeVar actual constructor(target: T) { private val atom = AtomicReference(target) + actual operator fun getValue(thisRef: Any?, property: KProperty<*>): T = atom.value + actual operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { if (Platform.memoryModel == MemoryModel.STRICT) { value.freeze() diff --git a/core/src/commonMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt b/core/src/commonMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt index eba4212..160d58b 100644 --- a/core/src/commonMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt +++ b/core/src/commonMain/kotlin/co/touchlab/crashkios/core/ThreadSafeVar.kt @@ -2,7 +2,8 @@ package co.touchlab.crashkios.core import kotlin.reflect.KProperty -expect class ThreadSafeVar(target:T) { +expect class ThreadSafeVar(target: T) { operator fun getValue(thisRef: Any?, property: KProperty<*>): T + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) } diff --git a/crashlytics-ios-link/build.gradle.kts b/crashlytics-ios-link/build.gradle.kts index 413bcd9..4885b4e 100644 --- a/crashlytics-ios-link/build.gradle.kts +++ b/crashlytics-ios-link/build.gradle.kts @@ -50,7 +50,10 @@ java { } } +@Suppress("ktlint:standard:property-naming") val GROUP: String by project + +@Suppress("ktlint:standard:property-naming") val VERSION_NAME: String by project group = GROUP @@ -62,4 +65,4 @@ mavenPublishing { project.properties["RELEASE_SIGNING_ENABLED"]?.toString()?.equals("false", ignoreCase = true) != true if (releaseSigningEnabled) signAllPublications() pomFromGradleProperties() -} \ No newline at end of file +} diff --git a/crashlytics/build.gradle.kts b/crashlytics/build.gradle.kts index d2e383c..cccdeba 100644 --- a/crashlytics/build.gradle.kts +++ b/crashlytics/build.gradle.kts @@ -19,7 +19,10 @@ plugins { id("com.vanniktech.maven.publish") } +@Suppress("ktlint:standard:property-naming") val GROUP: String by project + +@Suppress("ktlint:standard:property-naming") val VERSION_NAME: String by project group = GROUP @@ -49,7 +52,7 @@ kotlin { tvosArm64() tvosSimulatorArm64() tvosX64() - + sourceSets { commonMain { dependencies { @@ -80,15 +83,21 @@ kotlin { compilerOpts("-DNS_FORMAT_ARGUMENT(A)=", "-D_Nullable_result=_Nullable") // extraOpts("-mode", "sourcecode") } - } + } } } android { namespace = "co.touchlab.crashkios.crashlytics" - compileSdk = libs.versions.compileSdk.get().toInt() + compileSdk = + libs.versions.compileSdk + .get() + .toInt() defaultConfig { - minSdk = libs.versions.minSdk.get().toInt() + minSdk = + libs.versions.minSdk + .get() + .toInt() } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 diff --git a/crashlytics/src/androidMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt b/crashlytics/src/androidMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt index 7a603b7..b8a8c4b 100644 --- a/crashlytics/src/androidMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt +++ b/crashlytics/src/androidMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt @@ -16,7 +16,7 @@ actual class CrashlyticsCallsActual : CrashlyticsCalls { } override fun setCustomValue(key: String, value: Any) { - when(value){ + when (value) { is Boolean -> FirebaseCrashlytics.getInstance().setCustomKey(key, value) is Double -> FirebaseCrashlytics.getInstance().setCustomKey(key, value) is Float -> FirebaseCrashlytics.getInstance().setCustomKey(key, value) @@ -32,4 +32,4 @@ actual class CrashlyticsCallsActual : CrashlyticsCalls { override fun setUserId(identifier: String) { FirebaseCrashlytics.getInstance().setUserId(identifier) } -} \ No newline at end of file +} diff --git a/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/Crashlytics.kt b/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/Crashlytics.kt index ef2548d..d771bbb 100644 --- a/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/Crashlytics.kt +++ b/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/Crashlytics.kt @@ -1,11 +1,6 @@ package co.touchlab.crashkios.crashlytics -import com.rickclephas.kmp.nsexceptionkt.core.asNSException -import com.rickclephas.kmp.nsexceptionkt.core.causes import com.rickclephas.kmp.nsexceptionkt.core.wrapUnhandledExceptionHook -import kotlinx.cinterop.UnsafeNumber -import platform.Foundation.NSException -import platform.Foundation.NSNumber /** * Sets the unhandled exception hook such that all unhandled exceptions are logged to Crashlytics as fatal exceptions. diff --git a/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt b/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt index 6e289ef..7e3809b 100644 --- a/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt +++ b/crashlytics/src/appleMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsCallsActual.kt @@ -19,9 +19,13 @@ actual class CrashlyticsCallsActual : CrashlyticsCalls { @OptIn(UnsafeNumber::class) override fun sendHandledException(throwable: Throwable) { val exceptionClassName = throwable::class.qualifiedName ?: throwable::class.simpleName ?: "kotlin.Throwable" - FIRCrashlyticsRecordHandledException(exceptionClassName, throwable.message ?: "", throwable.getFilteredStackTraceAddresses().map { - FIRStackFrameWithAddress(it.convert()) - }) + FIRCrashlyticsRecordHandledException( + exceptionClassName, + throwable.message ?: "", + throwable.getFilteredStackTraceAddresses().map { + FIRStackFrameWithAddress(it.convert()) + }, + ) } override fun sendFatalException(throwable: Throwable) { diff --git a/crashlytics/src/commonMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsKotlin.kt b/crashlytics/src/commonMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsKotlin.kt index 9db53cd..f2f3e79 100644 --- a/crashlytics/src/commonMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsKotlin.kt +++ b/crashlytics/src/commonMain/kotlin/co/touchlab/crashkios/crashlytics/CrashlyticsKotlin.kt @@ -36,22 +36,17 @@ fun enableCrashlytics() { internal object EmptyCalls : CrashlyticsCalls { override fun logMessage(message: String) { - } override fun sendHandledException(throwable: Throwable) { - } override fun sendFatalException(throwable: Throwable) { - } override fun setCustomValue(key: String, value: Any) { - } override fun setUserId(identifier: String) { - } -} \ No newline at end of file +}