From 960f3722cbb59a8ad7e4d009848ac482e806a462 Mon Sep 17 00:00:00 2001 From: Giancarlo Buenaflor Date: Wed, 10 Jun 2026 14:48:40 +0200 Subject: [PATCH] style: Migrate to ktlint_official code style Remove the intellij_idea style pin introduced with the Spotless 7 / ktlint 1.x upgrade and adopt ktlint's default ktlint_official code style: run spotlessApply across the repo, add the explicit Unit return type that explicit-api mode requires after the expression-body conversion in SentryKMP, and regenerate the detekt baseline for the reformat-induced MaxLineLength findings. Also wire DetektCreateBaselineTask to the same sources/excludes as the Detekt tasks so ./gradlew detektBaseline actually regenerates the shared baseline. No functional change. Co-Authored-By: Claude Fable 5 --- .editorconfig | 11 +- build.gradle.kts | 39 ++- buildSrc/src/main/java/Publication.kt | 50 ++-- config/detekt/baseline.xml | 6 + .../build.gradle.kts | 6 +- .../gradle/AutoInstallExtension.kt | 40 ++-- .../gradle/CocoaFrameworkLinker.kt | 46 ++-- .../gradle/CocoapodsAutoInstallExtension.kt | 42 ++-- .../gradle/DerivedDataPathValueSource.kt | 31 +-- .../multiplatform/gradle/FrameworkLinker.kt | 37 ++- .../gradle/FrameworkPathResolver.kt | 101 ++++---- .../multiplatform/gradle/LinkerExtension.kt | 66 +++--- .../ManualFrameworkPathSearchValueSource.kt | 39 +-- .../multiplatform/gradle/SentryExtension.kt | 28 ++- .../multiplatform/gradle/SentryPlugin.kt | 67 +++--- .../gradle/SourceSetAutoInstallExtension.kt | 42 ++-- .../gradle/Spm4KmpAutoInstallExtension.kt | 46 ++-- .../CocoaFrameworkLinkerIntegrationTest.kt | 45 ++-- .../gradle/CocoaFrameworkLinkerTest.kt | 86 +++---- .../gradle/CustomPathStrategyTest.kt | 15 +- .../gradle/DerivedDataPathTest.kt | 29 ++- .../gradle/DerivedDataStrategyTest.kt | 59 +++-- .../gradle/FrameworkPathResolverTest.kt | 7 +- .../gradle/ManualSearchStrategyTest.kt | 13 +- .../gradle/SentryFrameworkArchitectureTest.kt | 64 ++--- .../multiplatform/gradle/SentryPluginTest.kt | 9 +- sentry-kotlin-multiplatform/build.gradle.kts | 6 +- .../kotlin/multiplatform/Context.android.kt | 15 +- .../SentryPlatformInstance.android.kt | 9 +- .../SentryPlatformOptions.android.kt | 3 +- .../SentryOptionsExtensions.android.kt | 51 ++-- .../kotlin/multiplatform/BaseSentryTest.kt | 1 + .../multiplatform/PlatformOptions.android.kt | 25 +- .../multiplatform/SentryAndroidBridgeTest.kt | 11 +- .../kotlin/multiplatform/Attachment.apple.kt | 6 +- .../multiplatform/CocoaScopeProvider.kt | 54 ++++- .../multiplatform/SentryBridge.apple.kt | 65 ++--- .../kotlin/multiplatform/SentryEvent.apple.kt | 14 +- .../extensions/BreadcrumbExtensions.apple.kt | 38 +-- .../extensions/FoundationExtensions.kt | 22 +- .../extensions/MessageExtensions.apple.kt | 11 +- .../SentryExceptionExtensions.apple.kt | 13 +- .../SentryOptionsExtensions.apple.kt | 35 +-- .../extensions/UserExtensions.apple.kt | 30 +-- .../log/CocoaSentryLoggerAdapter.kt | 7 +- .../log/SentryLogConverters.apple.kt | 76 +++--- .../multiplatform/nsexception/NSException.kt | 24 +- .../nsexception/SentryUnhandledExceptions.kt | 117 ++++----- .../multiplatform/nsexception/Throwable.kt | 35 +-- .../multiplatform/protocol/SentryId.apple.kt | 20 +- .../kotlin/multiplatform/AppleSentryIdTest.kt | 1 - .../kotlin/multiplatform/ApplyKmpEventTest.kt | 56 +++-- .../kotlin/multiplatform/BaseSentryTest.kt | 1 + .../multiplatform/BreadcrumbTestConverter.kt | 25 +- .../multiplatform/PlatformOptions.apple.kt | 14 +- .../SentryAttributesConversionTest.kt | 3 +- .../multiplatform/SentryBridgeTest.apple.kt | 34 ++- .../multiplatform/SentryExceptionTest.kt | 37 +-- .../multiplatform/SentryLevelTestConverter.kt | 4 +- .../UserFeedbackExtensionsTest.kt | 33 +-- .../nsexception/InitAddressesTests.kt | 18 +- .../nsexception/ThrowableCausesTests.kt | 5 +- .../nsexception/ThrowableNameTests.kt | 1 - .../nsexception/ThrowableReasonTests.kt | 14 +- .../kotlin/multiplatform/Attachment.jvm.kt | 6 +- .../kotlin/multiplatform/JvmScopeProvider.kt | 58 +++-- .../multiplatform/SentryBridge.commonJvm.kt | 36 +-- .../extensions/BreadcrumbExtensions.jvm.kt | 36 +-- .../extensions/MessageExtensions.jvm.kt | 24 +- .../SentryExceptionExtensions.jvm.kt | 13 +- .../extensions/SentryLevelExtensions.jvm.kt | 10 +- .../extensions/SentryOptionsExtensions.jvm.kt | 11 +- .../extensions/UserExtensions.jvm.kt | 38 +-- .../log/JvmSentryLoggerAdapter.kt | 7 +- .../log/SentryLogConverters.jvm.kt | 69 +++--- .../multiplatform/protocol/SentryId.jvm.kt | 20 +- .../multiplatform/BreadcrumbTestConverter.kt | 25 +- .../kotlin/multiplatform/JvmSentryIdTest.kt | 1 - .../SentryAttributesConversionTest.kt | 3 +- .../SentryBridgeTest.commonJvm.kt | 42 ++-- .../multiplatform/SentryLevelTestConverter.kt | 4 +- .../sentry/kotlin/multiplatform/Attachment.kt | 1 - .../multiplatform/HttpStatusCodeRange.kt | 10 +- .../io/sentry/kotlin/multiplatform/Scope.kt | 46 +++- .../multiplatform/SentryAttributeValue.kt | 18 +- .../kotlin/multiplatform/SentryAttributes.kt | 36 ++- .../kotlin/multiplatform/SentryBaseEvent.kt | 7 +- .../kotlin/multiplatform/SentryBridge.kt | 19 +- .../sentry/kotlin/multiplatform/SentryKMP.kt | 45 ++-- .../kotlin/multiplatform/SentryLevel.kt | 16 +- .../multiplatform/SentryReplayOptions.kt | 10 +- .../multiplatform/log/BaseSentryLogger.kt | 191 ++++++++++----- .../log/DefaultSentryLogBuilder.kt | 14 +- .../kotlin/multiplatform/log/SentryLog.kt | 6 +- .../multiplatform/log/SentryLogBuilder.kt | 7 +- .../multiplatform/log/SentryLogLevel.kt | 2 +- .../kotlin/multiplatform/log/SentryLogger.kt | 109 +++++++-- .../multiplatform/protocol/Breadcrumb.kt | 101 ++++---- .../kotlin/multiplatform/protocol/Message.kt | 2 +- .../multiplatform/protocol/SdkVersion.kt | 10 +- .../multiplatform/protocol/SentryException.kt | 2 +- .../kotlin/multiplatform/protocol/SentryId.kt | 5 +- .../kotlin/multiplatform/protocol/User.kt | 10 +- .../multiplatform/protocol/UserFeedback.kt | 2 +- .../multiplatform/Attachment.commonStub.kt | 1 - .../kotlin/multiplatform/NoOpSentryLogger.kt | 109 +++++++-- .../multiplatform/SentryBridge.commonStub.kt | 41 ++-- .../protocol/SentryId.commonStub.kt | 4 +- .../kotlin/multiplatform/AttachmentTest.kt | 1 - .../multiplatform/BaseSentryScopeTest.kt | 1 - .../kotlin/multiplatform/BaseSentryTest.kt | 2 + .../BeforeBreadcrumbIntegrationTest.kt | 125 +++++----- .../BeforeSendIntegrationTest.kt | 222 ++++++++++-------- .../kotlin/multiplatform/BeforeSendTest.kt | 34 +-- .../multiplatform/BreadcrumbConfigurator.kt | 2 + .../kotlin/multiplatform/BreadcrumbTest.kt | 1 - .../multiplatform/BreadcrumbTestConverter.kt | 8 +- .../sentry/kotlin/multiplatform/ScopeTest.kt | 6 +- .../multiplatform/SentryAttributeValueTest.kt | 1 - .../multiplatform/SentryAttributesTest.kt | 10 +- .../kotlin/multiplatform/SentryBridgeTest.kt | 5 + .../kotlin/multiplatform/SentryE2ETest.kt | 92 ++++---- .../multiplatform/SentryEventConfigurator.kt | 2 + .../kotlin/multiplatform/SentryEventTest.kt | 1 - .../kotlin/multiplatform/SentryIdTest.kt | 1 - .../multiplatform/SentryIntegrationTest.kt | 129 +++++----- .../SentryLevelConversionTest.kt | 1 - .../multiplatform/SentryLevelTestConverter.kt | 1 - .../kotlin/multiplatform/SentryOptionsTest.kt | 87 +++---- .../kotlin/multiplatform/UserFeedbackTest.kt | 1 - .../sentry/kotlin/multiplatform/UserTest.kt | 5 +- .../multiplatform/log/BaseSentryLoggerTest.kt | 22 +- .../multiplatform/log/SentryLogBuilderTest.kt | 1 - .../multiplatform/log/SentryLogOptionsTest.kt | 3 +- .../SentryPlatformOptions.tvwatchmacos.kt | 3 +- .../PlatformOptions.tvwatchmacos.kt | 5 +- .../SentryPlatformOptions.ios.kt | 3 +- .../extensions/SentryOptionsExtensions.ios.kt | 58 +++-- .../multiplatform/PlatformOptions.ios.kt | 11 +- .../SentryPlatformOptions.jvm.kt | 3 +- .../kotlin/multiplatform/BaseSentryTest.kt | 1 + .../multiplatform/PlatformOptions.jvm.kt | 11 +- .../kotlin/sample.kmp.app.desktop/Main.kt | 29 +-- .../kmp-app-spm/shared/build.gradle.kts | 2 +- .../kotlin/sample.kmp.app/LoginImpl.kt | 41 ++-- .../kotlin/sample.kmp.app/SentrySetup.kt | 9 +- .../kotlin/sample.kmp.app/HttpClient.kt | 19 +- 147 files changed, 2344 insertions(+), 1800 deletions(-) diff --git a/.editorconfig b/.editorconfig index 6a262a5fa..bf8a6582d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,16 +1,7 @@ root = true [*.{kt,kts}] -# ktlint 1.x defaults to the new ktlint_official code style, which would reformat -# most of the codebase (multiline expression wrapping, trailing commas, signature -# wrapping). Pin the pre-1.x style until a dedicated style-migration PR adopts -# ktlint_official deliberately. -ktlint_code_style = intellij_idea -# ktlint 1.x adds trailing commas by default regardless of code style; the -# codebase doesn't use them. -ij_kotlin_allow_trailing_comma = false -ij_kotlin_allow_trailing_comma_on_call_site = false -# ktlint 1.x also enables stricter naming rules by default. The codebase relies on +# ktlint enables strict naming rules by default. The codebase relies on # backtick-wrapped test function names and constant-style vals that predate # these rules, so keep them disabled to match existing conventions. ktlint_standard_function-naming = disabled diff --git a/build.gradle.kts b/build.gradle.kts index 7ce024a29..f6f8075d5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,7 @@ import com.diffplug.spotless.LineEnding import com.vanniktech.maven.publish.MavenPublishPlugin import io.gitlab.arturbosch.detekt.Detekt +import io.gitlab.arturbosch.detekt.DetektCreateBaselineTask import org.jetbrains.dokka.gradle.DokkaTask import java.util.zip.ZipFile @@ -113,7 +114,7 @@ private fun Project.validateKotlinMultiplatformCoreArtifacts() { "wasm-js", "linuxx64", "linuxarm64", - "mingwx64" + "mingwx64", ) val artifactPaths = @@ -122,7 +123,7 @@ private fun Project.validateKotlinMultiplatformCoreArtifacts() { addAll( platforms.map { platform -> distributionDir.resolve("$baseFileName-$platform-$version.zip") - } + }, ) } @@ -131,7 +132,7 @@ private fun Project.validateKotlinMultiplatformCoreArtifacts() { "javadoc", "sources", "module", - "pom-default.xml" + "pom-default.xml", ) artifactPaths.forEach { artifactFile -> @@ -167,7 +168,7 @@ private fun Project.validateKotlinMultiplatformCoreArtifacts() { val actualKlibFiles = entries.count { it.contains("klib") } if (actualKlibFiles != expectedNumOfKlibFiles) { throw GradleException( - "❌ Expected $expectedNumOfKlibFiles klib files in ${artifactFile.name}, but found $actualKlibFiles" + "❌ Expected $expectedNumOfKlibFiles klib files in ${artifactFile.name}, but found $actualKlibFiles", ) } else { println("✅ Found $expectedNumOfKlibFiles klib files in ${artifactFile.name}") @@ -199,37 +200,18 @@ subprojects { } } -// Keep ktlint 1.x on the pre-1.0 formatting conventions (see .editorconfig for the -// rationale). Spotless does not reliably forward the ij_* properties from -// .editorconfig to ktlint, so pass them explicitly. -val ktlintEditorConfigOverride = - mapOf( - "ktlint_code_style" to "intellij_idea", - "ij_kotlin_allow_trailing_comma" to "false", - "ij_kotlin_allow_trailing_comma_on_call_site" to "false", - "ktlint_standard_argument-list-wrapping" to "disabled", - "ktlint_standard_chain-method-continuation" to "disabled", - "ktlint_standard_class-signature" to "disabled", - "ktlint_standard_condition-wrapping" to "disabled", - "ktlint_standard_function-expression-body" to "disabled", - "ktlint_standard_function-signature" to "disabled", - "ktlint_standard_multiline-expression-wrapping" to "disabled", - "ktlint_standard_function-naming" to "disabled", - "ktlint_standard_property-naming" to "disabled" - ) - spotless { lineEndings = LineEnding.UNIX kotlin { target("**/*.kt") targetExclude("**/generated/**/*.kt") - ktlint().editorConfigOverride(ktlintEditorConfigOverride) + ktlint() } kotlinGradle { target("**/*.kts") targetExclude("**/generated/**/*.kts") - ktlint().editorConfigOverride(ktlintEditorConfigOverride) + ktlint() } } @@ -244,6 +226,8 @@ detekt { fun SourceTask.detektExcludes() { exclude("**/build/**") + exclude("**/.kotlin/**") + exclude("**/.gradle/**") exclude("**/*.kts") exclude("**/buildSrc/**") exclude("**/*Test*/**") @@ -259,6 +243,11 @@ tasks.withType().configureEach { detektExcludes() } +tasks.withType().configureEach { + setSource(files(project.projectDir)) + detektExcludes() +} + /** Task for generating a Detekt baseline.xml */ val detektProjectBaseline by tasks.registering(io.gitlab.arturbosch.detekt.DetektCreateBaselineTask::class) { buildUponDefaultConfig.set(true) diff --git a/buildSrc/src/main/java/Publication.kt b/buildSrc/src/main/java/Publication.kt index 96bb9f884..749024baf 100644 --- a/buildSrc/src/main/java/Publication.kt +++ b/buildSrc/src/main/java/Publication.kt @@ -5,34 +5,38 @@ import java.io.File private val sep: String = File.separator -fun DistributionContainer.configureForMultiplatform(project: Project, buildPublishDir: String) { +fun DistributionContainer.configureForMultiplatform( + project: Project, + buildPublishDir: String, +) { val version = project.property("versionName").toString() if (version.isEmpty()) { throw GradleException("DistZip: version name is empty") } val projectName = project.name - val platforms = mapOf( - "main" to projectName, - "android" to "$projectName-android", - "jvm" to "$projectName-jvm", - "iosarm64" to "$projectName-iosarm64", - "iossimulatorarm64" to "$projectName-iossimulatorarm64", - "iosx64" to "$projectName-iosx64", - "macosarm64" to "$projectName-macosarm64", - "macosx64" to "$projectName-macosx64", - "tvosarm64" to "$projectName-tvosarm64", - "tvossimulatorarm64" to "$projectName-tvossimulatorarm64", - "tvosx64" to "$projectName-tvosx64", - "watchosarm32" to "$projectName-watchosarm32", - "watchosarm64" to "$projectName-watchosarm64", - "watchossimulatorarm64" to "$projectName-watchossimulatorarm64", - "watchosx64" to "$projectName-watchosx64", - "js" to "$projectName-js", - "wasm-js" to "$projectName-wasm-js", - "mingwx64" to "$projectName-mingwx64", - "linuxarm64" to "$projectName-linuxarm64", - "linuxx64" to "$projectName-linuxx64" - ) + val platforms = + mapOf( + "main" to projectName, + "android" to "$projectName-android", + "jvm" to "$projectName-jvm", + "iosarm64" to "$projectName-iosarm64", + "iossimulatorarm64" to "$projectName-iossimulatorarm64", + "iosx64" to "$projectName-iosx64", + "macosarm64" to "$projectName-macosarm64", + "macosx64" to "$projectName-macosx64", + "tvosarm64" to "$projectName-tvosarm64", + "tvossimulatorarm64" to "$projectName-tvossimulatorarm64", + "tvosx64" to "$projectName-tvosx64", + "watchosarm32" to "$projectName-watchosarm32", + "watchosarm64" to "$projectName-watchosarm64", + "watchossimulatorarm64" to "$projectName-watchossimulatorarm64", + "watchosx64" to "$projectName-watchosx64", + "js" to "$projectName-js", + "wasm-js" to "$projectName-wasm-js", + "mingwx64" to "$projectName-mingwx64", + "linuxarm64" to "$projectName-linuxarm64", + "linuxx64" to "$projectName-linuxx64", + ) platforms.forEach { (distName, projectName) -> val distribution = maybeCreate(distName) diff --git a/config/detekt/baseline.xml b/config/detekt/baseline.xml index 46dc74477..b1bd6b1d5 100644 --- a/config/detekt/baseline.xml +++ b/config/detekt/baseline.xml @@ -2,7 +2,13 @@ + MaxLineLength:ManualFrameworkPathSearchValueSource.kt$ManualFrameworkPathSearchValueSource$abstract MaxLineLength:SentryAttributes.kt$SentryAttributes.Companion$public + MaxLineLength:SentryLogConverters.apple.kt$is SentryAttributeValue.BooleanValue -> SentryStructuredLogAttribute(boolean = attrValue.value as Boolean) + MaxLineLength:SentryPlatformOptions.android.kt$internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration + MaxLineLength:SentryPlatformOptions.ios.kt$internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration + MaxLineLength:SentryPlatformOptions.jvm.kt$internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration + MaxLineLength:SentryPlatformOptions.tvwatchmacos.kt$internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration SwallowedException:CocoaScopeProvider.kt$CocoaScopeProvider$e: Throwable SwallowedException:SentryLevel.kt$SentryLevel.Companion$throwable: Throwable TooGenericExceptionCaught:CocoaScopeProvider.kt$CocoaScopeProvider$e: Throwable diff --git a/sentry-kotlin-multiplatform-gradle-plugin/build.gradle.kts b/sentry-kotlin-multiplatform-gradle-plugin/build.gradle.kts index 62f0785ab..700bdd92e 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/build.gradle.kts +++ b/sentry-kotlin-multiplatform-gradle-plugin/build.gradle.kts @@ -52,7 +52,7 @@ listOf("compileClasspath", "testCompileClasspath", "testRuntimeClasspath").forEa attributes { attribute( TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, - JavaVersion.VERSION_17.majorVersion.toInt() + JavaVersion.VERSION_17.majorVersion.toInt(), ) } } @@ -114,12 +114,12 @@ buildConfig { buildConfigField( "String", "SentryCocoaVersion", - provider { "\"${project.property("sentryCocoaVersion")}\"" } + provider { "\"${project.property("sentryCocoaVersion")}\"" }, ) buildConfigField( "String", "SentryKmpVersion", - provider { "\"${project.property("versionName")}\"" } + provider { "\"${project.property("versionName")}\"" }, ) } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/AutoInstallExtension.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/AutoInstallExtension.kt index 4a4ea5325..bc960fb58 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/AutoInstallExtension.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/AutoInstallExtension.kt @@ -5,25 +5,29 @@ import org.gradle.api.provider.Property import javax.inject.Inject @Suppress("UnnecessaryAbstractClass") -abstract class AutoInstallExtension @Inject constructor(project: Project) { - private val objects = project.objects +abstract class AutoInstallExtension + @Inject + constructor( + project: Project, + ) { + private val objects = project.objects - /** - * Enable auto-installation of the Sentry dependencies through [CocoapodsAutoInstallExtension], - * [Spm4KmpAutoInstallExtension] and [SourceSetAutoInstallExtension]. - * - * Disabling this will prevent the plugin from auto installing any dependency. - * - * Defaults to true. - */ - val enabled: Property = objects.property(Boolean::class.java).convention(true) + /** + * Enable auto-installation of the Sentry dependencies through [CocoapodsAutoInstallExtension], + * [Spm4KmpAutoInstallExtension] and [SourceSetAutoInstallExtension]. + * + * Disabling this will prevent the plugin from auto installing any dependency. + * + * Defaults to true. + */ + val enabled: Property = objects.property(Boolean::class.java).convention(true) - val cocoapods: CocoapodsAutoInstallExtension = - objects.newInstance(CocoapodsAutoInstallExtension::class.java, project) + val cocoapods: CocoapodsAutoInstallExtension = + objects.newInstance(CocoapodsAutoInstallExtension::class.java, project) - val spm: Spm4KmpAutoInstallExtension = - objects.newInstance(Spm4KmpAutoInstallExtension::class.java, project) + val spm: Spm4KmpAutoInstallExtension = + objects.newInstance(Spm4KmpAutoInstallExtension::class.java, project) - val commonMain: SourceSetAutoInstallExtension = - objects.newInstance(SourceSetAutoInstallExtension::class.java, project) -} + val commonMain: SourceSetAutoInstallExtension = + objects.newInstance(SourceSetAutoInstallExtension::class.java, project) + } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinker.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinker.kt index ee47e83fe..68908d635 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinker.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinker.kt @@ -13,13 +13,13 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget class CocoaFrameworkLinker( private val logger: Logger, private val pathResolver: FrameworkPathResolver, - private val binaryLinker: FrameworkLinker + private val binaryLinker: FrameworkLinker, ) { fun configure(appleTargets: List) { appleTargets.forEach { target -> try { logger.info( - "Start resolving Sentry Cocoa framework paths for target: ${target.name}" + "Start resolving Sentry Cocoa framework paths for target: ${target.name}", ) processTarget(target) logger.lifecycle("Successfully configured Sentry Cocoa framework linking for target: ${target.name}") @@ -42,7 +42,7 @@ class CocoaFrameworkLinker( internal class FrameworkLinkingException( message: String, - cause: Throwable? = null + cause: Throwable? = null, ) : GradleException(message, cause) /** @@ -56,17 +56,18 @@ internal class FrameworkLinkingException( * @return Set of possible architecture folder names for the given target. * Returns empty set if target is not supported. */ -internal fun KotlinNativeTarget.toSentryFrameworkArchitecture(): Set = buildSet { - when (name) { - "iosSimulatorArm64", "iosX64" -> addAll(SentryCocoaFrameworkArchitectures.IOS_SIMULATOR_AND_X64) - "iosArm64" -> addAll(SentryCocoaFrameworkArchitectures.IOS_ARM64) - "macosArm64", "macosX64" -> addAll(SentryCocoaFrameworkArchitectures.MACOS_ARM64_AND_X64) - "tvosSimulatorArm64", "tvosX64" -> addAll(SentryCocoaFrameworkArchitectures.TVOS_SIMULATOR_AND_X64) - "tvosArm64" -> addAll(SentryCocoaFrameworkArchitectures.TVOS_ARM64) - "watchosArm32", "watchosArm64" -> addAll(SentryCocoaFrameworkArchitectures.WATCHOS_ARM) - "watchosSimulatorArm64", "watchosX64" -> addAll(SentryCocoaFrameworkArchitectures.WATCHOS_SIMULATOR_AND_X64) +internal fun KotlinNativeTarget.toSentryFrameworkArchitecture(): Set = + buildSet { + when (name) { + "iosSimulatorArm64", "iosX64" -> addAll(SentryCocoaFrameworkArchitectures.IOS_SIMULATOR_AND_X64) + "iosArm64" -> addAll(SentryCocoaFrameworkArchitectures.IOS_ARM64) + "macosArm64", "macosX64" -> addAll(SentryCocoaFrameworkArchitectures.MACOS_ARM64_AND_X64) + "tvosSimulatorArm64", "tvosX64" -> addAll(SentryCocoaFrameworkArchitectures.TVOS_SIMULATOR_AND_X64) + "tvosArm64" -> addAll(SentryCocoaFrameworkArchitectures.TVOS_ARM64) + "watchosArm32", "watchosArm64" -> addAll(SentryCocoaFrameworkArchitectures.WATCHOS_ARM) + "watchosSimulatorArm64", "watchosX64" -> addAll(SentryCocoaFrameworkArchitectures.WATCHOS_SIMULATOR_AND_X64) + } } -} internal object SentryCocoaFrameworkArchitectures { val IOS_SIMULATOR_AND_X64 = setOf("ios-arm64_x86_64-simulator") @@ -78,15 +79,16 @@ internal object SentryCocoaFrameworkArchitectures { val WATCHOS_SIMULATOR_AND_X64 = setOf("watchos-arm64_i386_x86_64-simulator") // Used for tests - val all = setOf( - IOS_SIMULATOR_AND_X64, - IOS_ARM64, - MACOS_ARM64_AND_X64, - TVOS_SIMULATOR_AND_X64, - TVOS_ARM64, - WATCHOS_ARM, - WATCHOS_SIMULATOR_AND_X64 - ) + val all = + setOf( + IOS_SIMULATOR_AND_X64, + IOS_ARM64, + MACOS_ARM64_AND_X64, + TVOS_SIMULATOR_AND_X64, + TVOS_ARM64, + WATCHOS_ARM, + WATCHOS_SIMULATOR_AND_X64, + ) } internal fun KotlinMultiplatformExtension.appleTargets() = diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/CocoapodsAutoInstallExtension.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/CocoapodsAutoInstallExtension.kt index e38772113..3021782ff 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/CocoapodsAutoInstallExtension.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/CocoapodsAutoInstallExtension.kt @@ -6,24 +6,28 @@ import org.gradle.api.provider.Property import javax.inject.Inject @Suppress("UnnecessaryAbstractClass") -abstract class CocoapodsAutoInstallExtension @Inject constructor(project: Project) { - private val objects = project.objects +abstract class CocoapodsAutoInstallExtension + @Inject + constructor( + project: Project, + ) { + private val objects = project.objects - /** - * Enable auto-installation of the Sentry Cocoa SDK pod. - * - * If the cocoapods plugin is applied and no existing Sentry pod configuration exists, the - * Sentry-Cocoa SDK pod will be installed. - * - * Defaults to true. - */ - val enabled: Property = objects.property(Boolean::class.java).convention(true) + /** + * Enable auto-installation of the Sentry Cocoa SDK pod. + * + * If the cocoapods plugin is applied and no existing Sentry pod configuration exists, the + * Sentry-Cocoa SDK pod will be installed. + * + * Defaults to true. + */ + val enabled: Property = objects.property(Boolean::class.java).convention(true) - /** - * Overrides default Sentry Cocoa version. - * - * Defaults to the version used in the latest KMP SDK. - */ - val sentryCocoaVersion: Property = - objects.property(String::class.java).convention("~> ${BuildConfig.SentryCocoaVersion}") -} + /** + * Overrides default Sentry Cocoa version. + * + * Defaults to the version used in the latest KMP SDK. + */ + val sentryCocoaVersion: Property = + objects.property(String::class.java).convention("~> ${BuildConfig.SentryCocoaVersion}") + } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataPathValueSource.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataPathValueSource.kt index a529412d7..c680088d9 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataPathValueSource.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataPathValueSource.kt @@ -14,8 +14,7 @@ import javax.inject.Inject * * e.g /Users/theusername/Library/Developer/Xcode/DerivedData/iosApp-ddefikekigqzzgcnpfkkdallksmlfpln/ */ -abstract class DerivedDataPathValueSource : - ValueSource { +abstract class DerivedDataPathValueSource : ValueSource { interface Parameters : ValueSourceParameters { @get:Input val xcodeprojPath: Property @@ -32,17 +31,19 @@ abstract class DerivedDataPathValueSource : val buildDirOutput = ByteArrayOutputStream() val errOutput = ByteArrayOutputStream() - val execOperations = execOperations.exec { - it.commandLine = listOf( - "xcodebuild", - "-project", - parameters.xcodeprojPath.get(), - "-showBuildSettings" - ) - it.standardOutput = buildDirOutput - it.errorOutput = errOutput - it.isIgnoreExitValue = true - } + val execOperations = + execOperations.exec { + it.commandLine = + listOf( + "xcodebuild", + "-project", + parameters.xcodeprojPath.get(), + "-showBuildSettings", + ) + it.standardOutput = buildDirOutput + it.errorOutput = errOutput + it.isIgnoreExitValue = true + } if (execOperations.exitValue == 0) { val buildSettings = buildDirOutput.toString("UTF-8") @@ -56,9 +57,9 @@ abstract class DerivedDataPathValueSource : logger.warn( "Failed to retrieve derived data path. xcodebuild command failed. Error output: ${ errOutput.toString( - Charsets.UTF_8 + Charsets.UTF_8, ) - }" + }", ) return null } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/FrameworkLinker.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/FrameworkLinker.kt index 135f077e7..9d2d6de0e 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/FrameworkLinker.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/FrameworkLinker.kt @@ -10,12 +10,12 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.TestExecutable * This involves configuring and linking binaries to the Sentry Cocoa framework. */ class FrameworkLinker( - private val logger: Logger + private val logger: Logger, ) { fun configureBinaries( binaries: KotlinNativeBinaryContainer, dynamicPath: String?, - staticPath: String? + staticPath: String?, ) { binaries.all { binary -> when (binary) { @@ -26,27 +26,38 @@ class FrameworkLinker( } } - private fun chooseTestPath(dynamic: String?, static: String?) = when { + private fun chooseTestPath( + dynamic: String?, + static: String?, + ) = when { dynamic != null -> dynamic static != null -> static else -> throw FrameworkLinkingException("No valid framework path found for tests") } - private fun linkTestBinary(binary: TestExecutable, path: String) { + private fun linkTestBinary( + binary: TestExecutable, + path: String, + ) { // Linking in test binaries works with both dynamic and static framework binary.linkerOpts("-rpath", path, "-F$path") logger.info("Linked Sentry Cocoa framework to test binary ${binary.name}") } - private fun linkFrameworkBinary(binary: Framework, dynamicPath: String?, staticPath: String?) { - val (path, type) = when { - binary.isStatic && staticPath != null -> staticPath to "static" - !binary.isStatic && dynamicPath != null -> dynamicPath to "dynamic" - else -> throw FrameworkLinkingException( - "Framework mismatch for ${binary.name}. " + - "Required ${if (binary.isStatic) "static" else "dynamic"} Sentry Cocoa framework not found." - ) - } + private fun linkFrameworkBinary( + binary: Framework, + dynamicPath: String?, + staticPath: String?, + ) { + val (path, type) = + when { + binary.isStatic && staticPath != null -> staticPath to "static" + !binary.isStatic && dynamicPath != null -> dynamicPath to "dynamic" + else -> throw FrameworkLinkingException( + "Framework mismatch for ${binary.name}. " + + "Required ${if (binary.isStatic) "static" else "dynamic"} Sentry Cocoa framework not found.", + ) + } binary.linkerOpts("-F$path") logger.info("Linked $type Sentry Cocoa framework to ${binary.name}") diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/FrameworkPathResolver.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/FrameworkPathResolver.kt index ec405e7cf..1ee4064de 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/FrameworkPathResolver.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/FrameworkPathResolver.kt @@ -11,12 +11,12 @@ import kotlin.io.path.absolutePathString enum class FrameworkType { STATIC, - DYNAMIC + DYNAMIC, } data class FrameworkPaths( val dynamic: String? = null, - val static: String? = null + val static: String? = null, ) { companion object { val NONE = FrameworkPaths(null, null) @@ -25,15 +25,17 @@ data class FrameworkPaths( dynamicBasePath: String? = null, staticBasePath: String? = null, architectures: Set, - pathExists: (String) -> Boolean = { path -> File(path).exists() } + pathExists: (String) -> Boolean = { path -> File(path).exists() }, ): FrameworkPaths { - val dynamicPath = dynamicBasePath?.let { basePath -> - architectures.map { arch -> "$basePath/$arch" }.firstOrNull { pathExists(it) } - } + val dynamicPath = + dynamicBasePath?.let { basePath -> + architectures.map { arch -> "$basePath/$arch" }.firstOrNull { pathExists(it) } + } - val staticPath = staticBasePath?.let { basePath -> - architectures.map { arch -> "$basePath/$arch" }.firstOrNull { pathExists(it) } - } + val staticPath = + staticBasePath?.let { basePath -> + architectures.map { arch -> "$basePath/$arch" }.firstOrNull { pathExists(it) } + } return when { dynamicPath != null && staticPath != null -> @@ -61,32 +63,35 @@ interface FrameworkResolutionStrategy { * This should generally be executed first. */ class CustomPathStrategy( - private val project: Project + private val project: Project, ) : FrameworkResolutionStrategy { private val linker: LinkerExtension = project.extensions.getByType(LinkerExtension::class.java) // In this function we don't distinguish between static and dynamic frameworks // We trust that the user knows the distinction if they purposefully override the framework path override fun resolvePaths(architectures: Set): FrameworkPaths { - val result = linker.frameworkPath.orNull?.takeIf { it.isNotEmpty() }?.let { basePath -> - when { - basePath.endsWith("Sentry.xcframework") -> FrameworkPaths.createValidated( - staticBasePath = basePath, - architectures = architectures - ) + val result = + linker.frameworkPath.orNull?.takeIf { it.isNotEmpty() }?.let { basePath -> + when { + basePath.endsWith("Sentry.xcframework") -> + FrameworkPaths.createValidated( + staticBasePath = basePath, + architectures = architectures, + ) - basePath.endsWith("Sentry-Dynamic.xcframework") -> FrameworkPaths.createValidated( - dynamicBasePath = basePath, - architectures = architectures - ) + basePath.endsWith("Sentry-Dynamic.xcframework") -> + FrameworkPaths.createValidated( + dynamicBasePath = basePath, + architectures = architectures, + ) - else -> FrameworkPaths.NONE - } - } ?: FrameworkPaths.NONE + else -> FrameworkPaths.NONE + } + } ?: FrameworkPaths.NONE if (linker.frameworkPath.orNull != null && result == FrameworkPaths.NONE) { project.logger.warn( "Custom framework path has been set manually but could not be found. " + - "Trying to resolve framework paths using other strategies." + "Trying to resolve framework paths using other strategies.", ) } return result @@ -103,10 +108,11 @@ class CustomPathStrategy( class DerivedDataStrategy( private val project: Project, private val derivedDataProvider: (String) -> String? = { xcodeprojPath -> - project.providers.of(DerivedDataPathValueSource::class.java) { - it.parameters.xcodeprojPath.set(xcodeprojPath) - }.orNull - } + project.providers + .of(DerivedDataPathValueSource::class.java) { + it.parameters.xcodeprojPath.set(xcodeprojPath) + }.orNull + }, ) : FrameworkResolutionStrategy { private val linker: LinkerExtension = project.extensions.getByType(LinkerExtension::class.java) @@ -126,7 +132,7 @@ class DerivedDataStrategy( return FrameworkPaths.createValidated( dynamicBasePath = dynamicBasePath, staticBasePath = staticBasePath, - architectures = architectures + architectures = architectures, ) } @@ -143,9 +149,9 @@ class DerivedDataStrategy( object : SimpleFileVisitor() { override fun preVisitDirectory( dir: Path, - attrs: BasicFileAttributes - ): FileVisitResult { - return when { + attrs: BasicFileAttributes, + ): FileVisitResult = + when { // Check if current directory is a xcodeproj before checking ignored dirs dir.toString().endsWith(".xcodeproj") -> { foundXcodeprojPath = dir.absolutePathString() @@ -155,8 +161,7 @@ class DerivedDataStrategy( ignoredDirectories.contains(dir.fileName.toString()) -> FileVisitResult.SKIP_SUBTREE else -> FileVisitResult.CONTINUE } - } - } + }, ) if (foundXcodeprojPath != null) { @@ -179,7 +184,7 @@ class DerivedDataStrategy( */ class ManualSearchStrategy( private val project: Project, - private val basePathToSearch: String? = null + private val basePathToSearch: String? = null, ) : FrameworkResolutionStrategy { // TODO: currently the search doesnt differentiate between Cocoa versions // we can improve this by checking the info.plist and prefer the ones that are the version we are looking for @@ -202,28 +207,26 @@ class ManualSearchStrategy( return FrameworkPaths.createValidated( dynamicBasePath = dynamicValueSource.orNull, staticBasePath = staticValueSource.orNull, - architectures = architectures + architectures = architectures, ) } } class FrameworkPathResolver( private val project: Project, - private val strategies: List = defaultStrategies(project) + private val strategies: List = defaultStrategies(project), ) { - fun resolvePaths( - architectures: Set - ): FrameworkPaths { + fun resolvePaths(architectures: Set): FrameworkPaths { strategies.forEach { strategy -> try { project.logger.info( - "Attempt to resolve Sentry Cocoa framework paths using ${strategy::class.simpleName}" + "Attempt to resolve Sentry Cocoa framework paths using ${strategy::class.simpleName}", ) val result = strategy.resolvePaths(architectures) if (result != FrameworkPaths.NONE) { val path = result.dynamic ?: result.static project.logger.lifecycle( - "Found Sentry Cocoa framework path using ${strategy::class.simpleName} at $path" + "Found Sentry Cocoa framework path using ${strategy::class.simpleName} at $path", ) return result } else { @@ -231,7 +234,7 @@ class FrameworkPathResolver( } } catch (e: FrameworkLinkingException) { project.logger.warn( - "Strategy ${strategy::class.simpleName} failed due to error: ${e.message}" + "Strategy ${strategy::class.simpleName} failed due to error: ${e.message}", ) } } @@ -240,7 +243,8 @@ class FrameworkPathResolver( throw FrameworkLinkingException(frameworkNotFoundMessage) } - private val frameworkNotFoundMessage = """ + private val frameworkNotFoundMessage = + """ Failed to find Sentry Cocoa framework. Steps to resolve: 1. Install Sentry Cocoa via SPM in Xcode @@ -254,7 +258,7 @@ class FrameworkPathResolver( frameworkPath.set("path/to/Sentry.xcframework") } } - """.trimIndent() + """.trimIndent() companion object { /** @@ -264,14 +268,13 @@ class FrameworkPathResolver( * resolved by the first successful strategy. Specifically here Custom Path will be checked first, * if that fails then it is followed by the Derived Data strategy etc... */ - fun defaultStrategies(project: Project): List { - return listOf( + fun defaultStrategies(project: Project): List = + listOf( CustomPathStrategy(project), DerivedDataStrategy(project), - ManualSearchStrategy(project) + ManualSearchStrategy(project), // TODO: add DownloadStrategy -> downloads the framework and stores it in build dir // this is especially useful for users who dont have a monorepo setup ) - } } } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/LinkerExtension.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/LinkerExtension.kt index f9f0114e5..1d1951520 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/LinkerExtension.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/LinkerExtension.kt @@ -5,36 +5,40 @@ import org.gradle.api.provider.Property import javax.inject.Inject @Suppress("UnnecessaryAbstractClass") -abstract class LinkerExtension @Inject constructor(project: Project) { - private val objects = project.objects +abstract class LinkerExtension + @Inject + constructor( + project: Project, + ) { + private val objects = project.objects - /** - * Path to the Xcode project that will be used to link the framework. - * This is used to find the derived data path in which the framework is stored for SPM. - */ - val xcodeprojPath: Property = objects.property(String::class.java) + /** + * Path to the Xcode project that will be used to link the framework. + * This is used to find the derived data path in which the framework is stored for SPM. + */ + val xcodeprojPath: Property = objects.property(String::class.java) - /** - * Path to the framework that will be linked. - * Takes precedence over [xcodeprojPath] if both are set. - * - * The path must: - * 1. Point directly to the .xcframework folder - * 2. The .xcframework folder needs to be either `Sentry.xcframework` or `Sentry-Dynamic.xcframework` - * - * ### Usage Example: - * ```kotlin - * sentryKmp { - * frameworkPath.set( - * "path/to/Sentry.xcframework" // Static framework - * // or - * "path/to/Sentry-Dynamic.xcframework" // Dynamic framework - * ) - * } - * ``` - * - * ### Typical Locations: - * `~/Library/Developer/Xcode/DerivedData/{PROJECT}/SourcePackages/artifacts/sentry-cocoa` - */ - val frameworkPath: Property = objects.property(String::class.java) -} + /** + * Path to the framework that will be linked. + * Takes precedence over [xcodeprojPath] if both are set. + * + * The path must: + * 1. Point directly to the .xcframework folder + * 2. The .xcframework folder needs to be either `Sentry.xcframework` or `Sentry-Dynamic.xcframework` + * + * ### Usage Example: + * ```kotlin + * sentryKmp { + * frameworkPath.set( + * "path/to/Sentry.xcframework" // Static framework + * // or + * "path/to/Sentry-Dynamic.xcframework" // Dynamic framework + * ) + * } + * ``` + * + * ### Typical Locations: + * `~/Library/Developer/Xcode/DerivedData/{PROJECT}/SourcePackages/artifacts/sentry-cocoa` + */ + val frameworkPath: Property = objects.property(String::class.java) + } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/ManualFrameworkPathSearchValueSource.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/ManualFrameworkPathSearchValueSource.kt index 06f92471f..d05a2d428 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/ManualFrameworkPathSearchValueSource.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/ManualFrameworkPathSearchValueSource.kt @@ -7,8 +7,7 @@ import org.gradle.api.provider.ValueSourceParameters import org.gradle.process.ExecOperations import java.io.ByteArrayOutputStream -abstract class ManualFrameworkPathSearchValueSource : - ValueSource { +abstract class ManualFrameworkPathSearchValueSource : ValueSource { interface Parameters : ValueSourceParameters { val frameworkType: Property val basePathToSearch: Property @@ -31,40 +30,42 @@ abstract class ManualFrameworkPathSearchValueSource : */ private fun findFrameworkWithFindCommand( frameworkType: FrameworkType, - basePathToSearch: String + basePathToSearch: String, ): String? { val stdOutput = ByteArrayOutputStream() val errOutput = ByteArrayOutputStream() val xcFrameworkName = if (frameworkType == FrameworkType.STATIC) "Sentry.xcframework" else "Sentry-Dynamic.xcframework" - val execResult = execOperations.exec { - it.commandLine( - "bash", - "-c", - "find $basePathToSearch " + - "-name $xcFrameworkName " + - "-exec stat -f \"%m %N\" {} \\; | " + - "sort -nr | " + - "cut -d' ' -f2-" - ) - it.standardOutput = stdOutput - it.errorOutput = errOutput - it.isIgnoreExitValue = true - } + val execResult = + execOperations.exec { + it.commandLine( + "bash", + "-c", + "find $basePathToSearch " + + "-name $xcFrameworkName " + + "-exec stat -f \"%m %N\" {} \\; | " + + "sort -nr | " + + "cut -d' ' -f2-", + ) + it.standardOutput = stdOutput + it.errorOutput = errOutput + it.isIgnoreExitValue = true + } val stringOutput = stdOutput.toString("UTF-8") return if (execResult.exitValue == 0) { if (stringOutput.lineSequence().firstOrNull().isNullOrEmpty()) { null } else { - stringOutput.lineSequence() + stringOutput + .lineSequence() .first() } } else { logger.warn( "Manual search failed to find $xcFrameworkName in $basePathToSearch. " + - "Error output: ${errOutput.toString(Charsets.UTF_8)}" + "Error output: ${errOutput.toString(Charsets.UTF_8)}", ) null } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SentryExtension.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SentryExtension.kt index 38baf8749..616628c62 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SentryExtension.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SentryExtension.kt @@ -4,17 +4,21 @@ import org.gradle.api.Project import javax.inject.Inject @Suppress("UnnecessaryAbstractClass") -abstract class SentryExtension @Inject constructor(project: Project) { - private val objects = project.objects +abstract class SentryExtension + @Inject + constructor( + project: Project, + ) { + private val objects = project.objects - /** - * Linker configuration. - * - * If you use SPM this configuration is necessary for setting up linking the framework and test - * executable. - */ - val linker: LinkerExtension = objects.newInstance(LinkerExtension::class.java, project) + /** + * Linker configuration. + * + * If you use SPM this configuration is necessary for setting up linking the framework and test + * executable. + */ + val linker: LinkerExtension = objects.newInstance(LinkerExtension::class.java, project) - val autoInstall: AutoInstallExtension = - objects.newInstance(AutoInstallExtension::class.java, project) -} + val autoInstall: AutoInstallExtension = + objects.newInstance(AutoInstallExtension::class.java, project) + } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SentryPlugin.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SentryPlugin.kt index 9104de665..2d71d6e77 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SentryPlugin.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SentryPlugin.kt @@ -31,21 +31,21 @@ class SentryPlugin : Plugin { project.extensions.create( SENTRY_EXTENSION_NAME, SentryExtension::class.java, - project + project, ) project.extensions.add(LINKER_EXTENSION_NAME, sentryExtension.linker) project.extensions.add(AUTO_INSTALL_EXTENSION_NAME, sentryExtension.autoInstall) project.extensions.add( COCOAPODS_AUTO_INSTALL_EXTENSION_NAME, - sentryExtension.autoInstall.cocoapods + sentryExtension.autoInstall.cocoapods, ) project.extensions.add( SPM4KMP_AUTO_INSTALL_EXTENSION_NAME, - sentryExtension.autoInstall.spm + sentryExtension.autoInstall.spm, ) project.extensions.add( COMMON_MAIN_AUTO_INSTALL_EXTENSION_NAME, - sentryExtension.autoInstall.commonMain + sentryExtension.autoInstall.commonMain, ) // spm4Kmp consumes its swiftPackageConfig during the configuration phase (before @@ -62,7 +62,7 @@ class SentryPlugin : Plugin { internal fun executeConfiguration( project: Project, - hostIsMac: Boolean = HostManager.hostIsMac + hostIsMac: Boolean = HostManager.hostIsMac, ) { val sentryExtension = project.extensions.getByType(SentryExtension::class.java) val hasCocoapodsPlugin = @@ -90,7 +90,7 @@ class SentryPlugin : Plugin { maybeLinkCocoaFramework( project, frameworkProvidedExternally = hasCocoapodsPlugin || hasSpm4KmpPlugin, - hostIsMac + hostIsMac, ) } @@ -104,7 +104,7 @@ class SentryPlugin : Plugin { private fun maybeLinkCocoaFramework( project: Project, frameworkProvidedExternally: Boolean, - hostIsMac: Boolean + hostIsMac: Boolean, ) { if (hostIsMac && !frameworkProvidedExternally) { // Register a task graph listener so that we only configure Cocoa framework linking @@ -130,7 +130,7 @@ private fun maybeLinkCocoaFramework( if (activeTargets.isEmpty()) { project.logger.lifecycle( "No Apple compile task scheduled for this build " + - "- skipping Sentry Cocoa framework linking" + "- skipping Sentry Cocoa framework linking", ) return@whenReady } @@ -140,7 +140,7 @@ private fun maybeLinkCocoaFramework( CocoaFrameworkLinker( logger = project.logger, pathResolver = FrameworkPathResolver(project), - binaryLinker = FrameworkLinker(project.logger) + binaryLinker = FrameworkLinker(project.logger), ).configure(appleTargets = activeTargets) } } @@ -149,26 +149,27 @@ private fun maybeLinkCocoaFramework( private fun getActiveTargets( project: Project, appleTargets: List, - graph: TaskExecutionGraph -): List = appleTargets.filter { target -> - val targetName = target.name.replaceFirstChar { - it.uppercase() - } - val path = if (project.path == ":") { - ":compileKotlin$targetName" - } else { - "${project.path}:compileKotlin$targetName" - } - try { - graph.hasTask(path) - } catch (_: Exception) { - false + graph: TaskExecutionGraph, +): List = + appleTargets.filter { target -> + val targetName = + target.name.replaceFirstChar { + it.uppercase() + } + val path = + if (project.path == ":") { + ":compileKotlin$targetName" + } else { + "${project.path}:compileKotlin$targetName" + } + try { + graph.hasTask(path) + } catch (_: Exception) { + false + } } -} -internal fun Project.installSentryForKmp( - commonMainAutoInstallExtension: SourceSetAutoInstallExtension -) { +internal fun Project.installSentryForKmp(commonMainAutoInstallExtension: SourceSetAutoInstallExtension) { val kmpExtension = extensions.findByName(KOTLIN_EXTENSION_NAME) if (kmpExtension !is KotlinMultiplatformExtension) { logger.info("Kotlin Multiplatform plugin not found. Skipping Sentry installation.") @@ -182,7 +183,7 @@ internal fun Project.installSentryForKmp( "Unsupported target: ${target.name}. " + "Cannot auto install in commonMain. " + "Please create an intermediate sourceSet with targets that the Sentry SDK " + - "supports and add the dependency manually." + "supports and add the dependency manually.", ) } } @@ -193,9 +194,7 @@ internal fun Project.installSentryForKmp( commonMain?.dependencies { api("io.sentry:sentry-kotlin-multiplatform:$sentryVersion") } } -internal fun Project.installSentryForCocoapods( - cocoapodsAutoInstallExtension: CocoapodsAutoInstallExtension -) { +internal fun Project.installSentryForCocoapods(cocoapodsAutoInstallExtension: CocoapodsAutoInstallExtension) { val kmpExtension = extensions.findByName(KOTLIN_EXTENSION_NAME) if (kmpExtension !is KotlinMultiplatformExtension || kmpExtension.targets.isEmpty() || !HostManager.hostIsMac) { logger.info("Skipping Cocoapods installation.") @@ -225,7 +224,7 @@ private const val SENTRY_COCOA_GIT_URL = "https://github.com/getsentry/sentry-co */ internal fun Project.installSentryForSpm4Kmp( autoInstall: AutoInstallExtension, - hostIsMac: Boolean = HostManager.hostIsMac + hostIsMac: Boolean = HostManager.hostIsMac, ) { val kmpExtension = extensions.findByName(KOTLIN_EXTENSION_NAME) if (kmpExtension !is KotlinMultiplatformExtension || !hostIsMac) { @@ -242,7 +241,7 @@ internal fun Project.installSentryForSpm4Kmp( if (mainCompilation?.cinterops?.findByName(SENTRY_COCOA_CINTEROP_NAME) != null) { logger.info( "Sentry Cocoa Swift package already configured for ${target.name}. " + - "Skipping spm4Kmp auto installation." + "Skipping spm4Kmp auto installation.", ) return@configureEach } @@ -257,7 +256,7 @@ internal fun Project.installSentryForSpm4Kmp( // already contains the Sentry cinterop bindings, so consumers only need the // framework available at link time. add("Sentry") - } + }, ) } } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SourceSetAutoInstallExtension.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SourceSetAutoInstallExtension.kt index 6e4ec17c2..3e4f0eede 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SourceSetAutoInstallExtension.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/SourceSetAutoInstallExtension.kt @@ -6,24 +6,28 @@ import org.gradle.api.provider.Property import javax.inject.Inject @Suppress("UnnecessaryAbstractClass") -abstract class SourceSetAutoInstallExtension @Inject constructor(project: Project) { - private val objects = project.objects +abstract class SourceSetAutoInstallExtension + @Inject + constructor( + project: Project, + ) { + private val objects = project.objects - /** - * Enable auto-installation of the Sentry Kotlin Multiplatform SDK dependency in the commonMain - * source set. - * - * Defaults to true. - */ - val enabled: Property = objects.property(Boolean::class.java).convention(true) + /** + * Enable auto-installation of the Sentry Kotlin Multiplatform SDK dependency in the commonMain + * source set. + * + * Defaults to true. + */ + val enabled: Property = objects.property(Boolean::class.java).convention(true) - /** - * Overrides the default Sentry Kotlin Multiplatform SDK dependency version. - * - * Defaults to the version of this plugin which is synchronized with the KMP SDK version. - */ - val sentryKmpVersion: Property = - objects - .property(String::class.java) - .convention(BuildConfig.SentryKmpVersion) -} + /** + * Overrides the default Sentry Kotlin Multiplatform SDK dependency version. + * + * Defaults to the version of this plugin which is synchronized with the KMP SDK version. + */ + val sentryKmpVersion: Property = + objects + .property(String::class.java) + .convention(BuildConfig.SentryKmpVersion) + } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/Spm4KmpAutoInstallExtension.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/Spm4KmpAutoInstallExtension.kt index 645793feb..02400bb97 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/Spm4KmpAutoInstallExtension.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/main/java/io/sentry/kotlin/multiplatform/gradle/Spm4KmpAutoInstallExtension.kt @@ -7,28 +7,28 @@ import javax.inject.Inject @Suppress("UnnecessaryAbstractClass") abstract class Spm4KmpAutoInstallExtension -@Inject -constructor( - project: Project -) { - private val objects = project.objects + @Inject + constructor( + project: Project, + ) { + private val objects = project.objects - /** - * Enable auto-installation of the Sentry Cocoa SDK Swift package via spm4Kmp. - * - * If the spm4Kmp plugin (io.github.frankois944.spmForKmp) is applied and no existing Sentry - * Swift package configuration exists, the Sentry-Cocoa SDK will be added to every Apple target. - * - * Defaults to true. - */ - val enabled: Property = objects.property(Boolean::class.java).convention(true) + /** + * Enable auto-installation of the Sentry Cocoa SDK Swift package via spm4Kmp. + * + * If the spm4Kmp plugin (io.github.frankois944.spmForKmp) is applied and no existing Sentry + * Swift package configuration exists, the Sentry-Cocoa SDK will be added to every Apple target. + * + * Defaults to true. + */ + val enabled: Property = objects.property(Boolean::class.java).convention(true) - /** - * Overrides default Sentry Cocoa version. - * - * Defaults to the version used in the latest KMP SDK. Must be an exact version since the Swift - * Package Manager resolves remote packages by exact version. - */ - val sentryCocoaVersion: Property = - objects.property(String::class.java).convention(BuildConfig.SentryCocoaVersion) -} + /** + * Overrides default Sentry Cocoa version. + * + * Defaults to the version used in the latest KMP SDK. Must be an exact version since the Swift + * Package Manager resolves remote packages by exact version. + */ + val sentryCocoaVersion: Property = + objects.property(String::class.java).convention(BuildConfig.SentryCocoaVersion) + } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinkerIntegrationTest.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinkerIntegrationTest.kt index d67263cbf..32349df25 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinkerIntegrationTest.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinkerIntegrationTest.kt @@ -19,7 +19,9 @@ class CocoaFrameworkLinkerIntegrationTest { * contains only non-Apple targets. */ @Test - fun `linker is not configured when only non-Apple tasks are requested`(@TempDir projectDir: File) { + fun `linker is not configured when only non-Apple tasks are requested`( + @TempDir projectDir: File, + ) { writeBuildFiles(projectDir) val output = ByteArrayOutputStream() @@ -36,7 +38,9 @@ class CocoaFrameworkLinkerIntegrationTest { * task is present in the task graph. */ @Test - fun `linker is configured when an Apple task is requested`(@TempDir projectDir: File) { + fun `linker is configured when an Apple task is requested`( + @TempDir projectDir: File, + ) { writeBuildFiles(projectDir) val output = ByteArrayOutputStream() @@ -60,18 +64,20 @@ class CocoaFrameworkLinkerIntegrationTest { // can resolve a valid framework path even on CI machines where SPM // (and hence DerivedData) is not available. // ----------------------------------------------------------------- - val fakeFrameworkDir = File(dir, "Sentry-Dynamic.xcframework").apply { - // Create minimal structure that satisfies path validation logic - val archDirName = "ios-arm64_x86_64-simulator" // architecture used for iosSimulatorArm64 - val archDir = File(this, archDirName) - archDir.mkdirs() - } + val fakeFrameworkDir = + File(dir, "Sentry-Dynamic.xcframework").apply { + // Create minimal structure that satisfies path validation logic + val archDirName = "ios-arm64_x86_64-simulator" // architecture used for iosSimulatorArm64 + val archDir = File(this, archDirName) + archDir.mkdirs() + } File(dir, "settings.gradle").writeText("""rootProject.name = "fixture"""") - val pluginClasspath = PluginUnderTestMetadataReading - .readImplementationClasspath() - .joinToString(", ") { "\"${it.absolutePath.replace('\\', '/')}\"" } + val pluginClasspath = + PluginUnderTestMetadataReading + .readImplementationClasspath() + .joinToString(", ") { "\"${it.absolutePath.replace('\\', '/')}\"" } File(dir, "build.gradle").writeText( """ @@ -110,17 +116,24 @@ class CocoaFrameworkLinkerIntegrationTest { frameworkPath.set("${fakeFrameworkDir.absolutePath.replace('\\', '/')}") } } - """.trimIndent() + """.trimIndent(), ) } /** Returns a pre-configured [GradleRunner] that logs into [out]. */ - private fun defaultRunner(projectDir: File, out: ByteArrayOutputStream): GradleRunner = - GradleRunner.create() + private fun defaultRunner( + projectDir: File, + out: ByteArrayOutputStream, + ): GradleRunner = + GradleRunner + .create() .withProjectDir(projectDir) .withPluginClasspath() - .withGradleVersion(org.gradle.util.GradleVersion.current().version) - .forwardStdOutput(OutputStreamWriter(SynchronizedOutputStream(out))) + .withGradleVersion( + org.gradle.util.GradleVersion + .current() + .version, + ).forwardStdOutput(OutputStreamWriter(SynchronizedOutputStream(out))) .forwardStdError(OutputStreamWriter(SynchronizedOutputStream(out))) .withArguments("--stacktrace") diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinkerTest.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinkerTest.kt index 473456295..de4f3bb76 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinkerTest.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CocoaFrameworkLinkerTest.kt @@ -23,18 +23,19 @@ class CocoaFrameworkLinkerTest { @Test fun `framework linking succeeds for static Framework binary`() { val kmpExtension = fixture.project.extensions.getByType(KotlinMultiplatformExtension::class.java) - val appleTargets = listOf( - kmpExtension.iosSimulatorArm64(), - kmpExtension.iosArm64(), - kmpExtension.watchosArm32(), - kmpExtension.watchosSimulatorArm64(), - kmpExtension.watchosX64(), - kmpExtension.macosArm64(), - kmpExtension.macosX64(), - kmpExtension.tvosArm64(), - kmpExtension.tvosSimulatorArm64(), - kmpExtension.tvosX64() - ) + val appleTargets = + listOf( + kmpExtension.iosSimulatorArm64(), + kmpExtension.iosArm64(), + kmpExtension.watchosArm32(), + kmpExtension.watchosSimulatorArm64(), + kmpExtension.watchosX64(), + kmpExtension.macosArm64(), + kmpExtension.macosX64(), + kmpExtension.tvosArm64(), + kmpExtension.tvosSimulatorArm64(), + kmpExtension.tvosX64(), + ) appleTargets.forEach { it.binaries.framework { baseName = "MyFramework" @@ -55,18 +56,19 @@ class CocoaFrameworkLinkerTest { @Test fun `framework linking succeeds for dynamic Framework binary`() { val kmpExtension = fixture.project.extensions.getByType(KotlinMultiplatformExtension::class.java) - val appleTargets = listOf( - kmpExtension.iosSimulatorArm64(), - kmpExtension.iosArm64(), - kmpExtension.watchosArm32(), - kmpExtension.watchosSimulatorArm64(), - kmpExtension.watchosX64(), - kmpExtension.macosArm64(), - kmpExtension.macosX64(), - kmpExtension.tvosArm64(), - kmpExtension.tvosSimulatorArm64(), - kmpExtension.tvosX64() - ) + val appleTargets = + listOf( + kmpExtension.iosSimulatorArm64(), + kmpExtension.iosArm64(), + kmpExtension.watchosArm32(), + kmpExtension.watchosSimulatorArm64(), + kmpExtension.watchosX64(), + kmpExtension.macosArm64(), + kmpExtension.macosX64(), + kmpExtension.tvosArm64(), + kmpExtension.tvosSimulatorArm64(), + kmpExtension.tvosX64(), + ) appleTargets.forEach { it.binaries.framework { baseName = "MyFramework" @@ -87,18 +89,19 @@ class CocoaFrameworkLinkerTest { @Test fun `framework linking succeeds for TestExecutable binary`() { val kmpExtension = fixture.project.extensions.getByType(KotlinMultiplatformExtension::class.java) - val appleTargets = listOf( - kmpExtension.iosSimulatorArm64(), - kmpExtension.iosArm64(), - kmpExtension.watchosArm32(), - kmpExtension.watchosSimulatorArm64(), - kmpExtension.watchosX64(), - kmpExtension.macosArm64(), - kmpExtension.macosX64(), - kmpExtension.tvosArm64(), - kmpExtension.tvosSimulatorArm64(), - kmpExtension.tvosX64() - ) + val appleTargets = + listOf( + kmpExtension.iosSimulatorArm64(), + kmpExtension.iosArm64(), + kmpExtension.watchosArm32(), + kmpExtension.watchosSimulatorArm64(), + kmpExtension.watchosX64(), + kmpExtension.macosArm64(), + kmpExtension.macosX64(), + kmpExtension.tvosArm64(), + kmpExtension.tvosSimulatorArm64(), + kmpExtension.tvosX64(), + ) appleTargets.forEach { it.binaries.framework { baseName = "MyFramework" @@ -129,22 +132,19 @@ class CocoaFrameworkLinkerTest { } } - fun getSut(): CocoaFrameworkLinker { - return CocoaFrameworkLinker( + fun getSut(): CocoaFrameworkLinker = + CocoaFrameworkLinker( project.logger, FrameworkPathResolver(project, strategies = listOf(FakeStrategy())), - FrameworkLinker(project.logger) + FrameworkLinker(project.logger), ) - } } } // We don't really care what the strategy exactly does in this test // The strategies themselves are tested independently private class FakeStrategy : FrameworkResolutionStrategy { - override fun resolvePaths(architectures: Set): FrameworkPaths { - return FrameworkPaths(static = staticPath, dynamic = dynamicPath) - } + override fun resolvePaths(architectures: Set): FrameworkPaths = FrameworkPaths(static = staticPath, dynamic = dynamicPath) } private const val staticPath = "/path/to/static/Sentry.xcframework" diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CustomPathStrategyTest.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CustomPathStrategyTest.kt index 8876beb6c..f748c8c4d 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CustomPathStrategyTest.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/CustomPathStrategyTest.kt @@ -25,7 +25,7 @@ class CustomPathStrategyTest { @MethodSource("architectureMappingProvider") fun `should return static path when framework is Sentry xcframework`( expectedArchitecture: Set, - @TempDir dir: Path + @TempDir dir: Path, ) { val xcframeworkPath = dir.resolve("Sentry.xcframework") Files.createDirectory(xcframeworkPath) @@ -42,7 +42,7 @@ class CustomPathStrategyTest { @MethodSource("architectureMappingProvider") fun `should return dynamic path when framework is Sentry xcframework`( expectedArchitecture: Set, - @TempDir dir: Path + @TempDir dir: Path, ) { val xcframeworkPath = dir.resolve("Sentry-Dynamic.xcframework") Files.createDirectory(xcframeworkPath) @@ -72,7 +72,9 @@ class CustomPathStrategyTest { } @Test - fun `should return NONE when framework has invalid name`(@TempDir dir: Path) { + fun `should return NONE when framework has invalid name`( + @TempDir dir: Path, + ) { val xcframeworkPath = dir.resolve("Invalid.xcframework") val sut = fixture.getSut(xcframeworkPath.absolutePathString()) @@ -83,9 +85,10 @@ class CustomPathStrategyTest { companion object { @JvmStatic - fun architectureMappingProvider() = SentryCocoaFrameworkArchitectures.all - .map { Arguments.of(it) } - .toList() + fun architectureMappingProvider() = + SentryCocoaFrameworkArchitectures.all + .map { Arguments.of(it) } + .toList() } private class Fixture { diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataPathTest.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataPathTest.kt index 99c2cab5b..61300b5cb 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataPathTest.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataPathTest.kt @@ -22,24 +22,26 @@ class DerivedDataPathTest { execOperations = mockk() parameters = mockk() - valueSource = object : DerivedDataPathValueSource() { - override val execOperations: ExecOperations = this@DerivedDataPathTest.execOperations - override fun getParameters(): Parameters { - return this@DerivedDataPathTest.parameters + valueSource = + object : DerivedDataPathValueSource() { + override val execOperations: ExecOperations = this@DerivedDataPathTest.execOperations + + override fun getParameters(): Parameters = this@DerivedDataPathTest.parameters } - } } @Test fun `obtain should return correct derived data path`() { - val xcodebuildOutput = """ + val xcodebuildOutput = + """ Build settings for action build and target MyTarget: BUILD_DIR = /DerivedData/Example/Build/Products - """.trimIndent() + """.trimIndent() - every { parameters.xcodeprojPath } returns mockk { - every { get() } returns "/path/to/project.xcodeproj" - } + every { parameters.xcodeprojPath } returns + mockk { + every { get() } returns "/path/to/project.xcodeproj" + } every { execOperations.exec(any()) } answers { val execSpecLambda = it.invocation.args[0] as Action @@ -73,9 +75,10 @@ class DerivedDataPathTest { fun `obtain should return null when BUILD_DIR is not found`() { val xcodebuildOutput = "Some output without BUILD_DIR" - every { parameters.xcodeprojPath } returns mockk { - every { get() } returns "/path/to/project.xcodeproj" - } + every { parameters.xcodeprojPath } returns + mockk { + every { get() } returns "/path/to/project.xcodeproj" + } every { execOperations.exec(any()) } answers { val execSpecLambda = it.invocation.args[0] as Action diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataStrategyTest.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataStrategyTest.kt index 93f1a2749..62c1ddd6d 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataStrategyTest.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/DerivedDataStrategyTest.kt @@ -26,7 +26,7 @@ class DerivedDataStrategyTest { @MethodSource("architectureMappingProvider") fun `if xcodeproj is null and find xcode project successfully then resolve static path`( expectedArchitecture: Set, - @TempDir dir: Path + @TempDir dir: Path, ) { Files.createDirectory(dir.resolve("project.xcodeproj")) val xcframeworkPath = @@ -35,9 +35,10 @@ class DerivedDataStrategyTest { val archDirectory = Files.createDirectory(xcframeworkDirectory.resolve(expectedArchitecture.first())) - val sut = fixture.getSut(null, rootDirPath = dir.toFile().absolutePath) { _: String -> - dir.toFile().absolutePath - } + val sut = + fixture.getSut(null, rootDirPath = dir.toFile().absolutePath) { _: String -> + dir.toFile().absolutePath + } val paths = sut.resolvePaths(expectedArchitecture) assertEquals(archDirectory.absolutePathString(), paths.static) @@ -48,7 +49,7 @@ class DerivedDataStrategyTest { @MethodSource("architectureMappingProvider") fun `if xcodeproj is null and find xcode project successfully then resolve dynamic path`( expectedArchitecture: Set, - @TempDir dir: Path + @TempDir dir: Path, ) { Files.createDirectory(dir.resolve("project.xcodeproj")) val xcframeworkPath = @@ -57,9 +58,10 @@ class DerivedDataStrategyTest { val archDirectory = Files.createDirectory(xcframeworkDirectory.resolve(expectedArchitecture.first())) - val sut = fixture.getSut(null, rootDirPath = dir.toFile().absolutePath) { _: String -> - dir.toFile().absolutePath - } + val sut = + fixture.getSut(null, rootDirPath = dir.toFile().absolutePath) { _: String -> + dir.toFile().absolutePath + } val paths = sut.resolvePaths(expectedArchitecture) assertEquals(archDirectory.absolutePathString(), paths.dynamic) @@ -68,11 +70,12 @@ class DerivedDataStrategyTest { @Test fun `if xcodeproj is null and find xcode project is not successful then return NONE`( - @TempDir dir: Path + @TempDir dir: Path, ) { - val sut = fixture.getSut(null, rootDirPath = dir.toFile().absolutePath) { _: String -> - dir.toFile().absolutePath - } + val sut = + fixture.getSut(null, rootDirPath = dir.toFile().absolutePath) { _: String -> + dir.toFile().absolutePath + } val paths = sut.resolvePaths(setOf("doesnt matter")) assertEquals(FrameworkPaths.NONE, paths) @@ -80,14 +83,15 @@ class DerivedDataStrategyTest { @Test fun `if xcodeproj is not null and find xcode project is not successful then return NONE`( - @TempDir dir: Path + @TempDir dir: Path, ) { - val sut = fixture.getSut( - "some invalid path", - rootDirPath = dir.toFile().absolutePath - ) { _: String -> - dir.toFile().absolutePath - } + val sut = + fixture.getSut( + "some invalid path", + rootDirPath = dir.toFile().absolutePath, + ) { _: String -> + dir.toFile().absolutePath + } val paths = sut.resolvePaths(setOf("doesnt matter")) assertEquals(FrameworkPaths.NONE, paths) @@ -95,20 +99,23 @@ class DerivedDataStrategyTest { companion object { @JvmStatic - fun architectureMappingProvider() = SentryCocoaFrameworkArchitectures.all - .map { Arguments.of(it) } - .toList() + fun architectureMappingProvider() = + SentryCocoaFrameworkArchitectures.all + .map { Arguments.of(it) } + .toList() } private class Fixture { fun getSut( xcodeprojPath: String?, rootDirPath: String, - derivedDataProvider: (String) -> String? + derivedDataProvider: (String) -> String?, ): DerivedDataStrategy { - val project = ProjectBuilder.builder() - .withProjectDir(File(rootDirPath)) - .build() + val project = + ProjectBuilder + .builder() + .withProjectDir(File(rootDirPath)) + .build() project.pluginManager.apply { apply("org.jetbrains.kotlin.multiplatform") diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/FrameworkPathResolverTest.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/FrameworkPathResolverTest.kt index e32839ef8..c1f178f49 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/FrameworkPathResolverTest.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/FrameworkPathResolverTest.kt @@ -23,9 +23,10 @@ class FrameworkPathResolverTest { @Test fun `does not execute subsequent strategies after first success`() { - val strategy1 = mockk { - every { resolvePaths(any()) } returns FrameworkPaths(dynamic = "dyn") - } + val strategy1 = + mockk { + every { resolvePaths(any()) } returns FrameworkPaths(dynamic = "dyn") + } val strategy2 = mockk() val sut = fixture.getSut(listOf(strategy1, strategy2)) diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/ManualSearchStrategyTest.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/ManualSearchStrategyTest.kt index 347c3e1c2..578f5a47e 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/ManualSearchStrategyTest.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/ManualSearchStrategyTest.kt @@ -27,7 +27,7 @@ class ManualSearchStrategyTest { @MethodSource("architectureMappingProvider") fun `should return static path when framework exists`( expectedArchitecture: Set, - @TempDir dir: Path + @TempDir dir: Path, ) { val xcframeworkPath = dir.resolve("somewhere/hidden/Sentry.xcframework").createDirectories() val archDirectory = Files.createDirectory(xcframeworkPath.resolve(expectedArchitecture.first())) @@ -43,7 +43,7 @@ class ManualSearchStrategyTest { @MethodSource("architectureMappingProvider") fun `should return dynamic path when framework exists`( expectedArchitecture: Set, - @TempDir dir: Path + @TempDir dir: Path, ) { val xcframeworkPath = dir.resolve("somewhere/hidden/Sentry-Dynamic.xcframework").createDirectories() val archDirectory = Files.createDirectory(xcframeworkPath.resolve(expectedArchitecture.first())) @@ -59,7 +59,7 @@ class ManualSearchStrategyTest { @MethodSource("architectureMappingProvider") fun `should return most recently used path when multiple framework exists`( expectedArchitecture: Set, - @TempDir dir: Path + @TempDir dir: Path, ) { val xcframeworkPath1 = dir.resolve("somewhere/hidden/Sentry.xcframework").createDirectories() Files.createDirectory(xcframeworkPath1.resolve(expectedArchitecture.first())) @@ -88,9 +88,10 @@ class ManualSearchStrategyTest { companion object { @JvmStatic - fun architectureMappingProvider() = SentryCocoaFrameworkArchitectures.all - .map { Arguments.of(it) } - .toList() + fun architectureMappingProvider() = + SentryCocoaFrameworkArchitectures.all + .map { Arguments.of(it) } + .toList() } private class Fixture { diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/SentryFrameworkArchitectureTest.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/SentryFrameworkArchitectureTest.kt index 3578e8968..37c84b896 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/SentryFrameworkArchitectureTest.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/SentryFrameworkArchitectureTest.kt @@ -18,20 +18,19 @@ import java.util.zip.ZipFile class SentryFrameworkArchitectureTest { companion object { @JvmStatic - fun cocoaVersions(): List = listOf( - Arguments.of("8.37.0"), - Arguments.of("8.38.0"), - Arguments.of("8.58.2") + fun cocoaVersions(): List = + listOf( + Arguments.of("8.37.0"), + Arguments.of("8.38.0"), + Arguments.of("8.58.2"), // Arguments.of("latest"), - // TODO: Latest is already v9 which is currently failing - let's fix this when we bump to v9 - ) + // TODO: Latest is already v9 which is currently failing - let's fix this when we bump to v9 + ) } @ParameterizedTest(name = "Test architecture name compatibility with Cocoa Version {0} in static framework") @MethodSource("cocoaVersions") - fun `finds arch folders in static framework`( - cocoaVersion: String - ) { + fun `finds arch folders in static framework`(cocoaVersion: String) { val project = ProjectBuilder.builder().build() project.pluginManager.apply { apply("org.jetbrains.kotlin.multiplatform") @@ -51,7 +50,7 @@ class SentryFrameworkArchitectureTest { watchosSimulatorArm64(), tvosX64(), tvosArm64(), - tvosSimulatorArm64() + tvosSimulatorArm64(), ).forEach { it.binaries.framework { baseName = "shared" @@ -67,9 +66,10 @@ class SentryFrameworkArchitectureTest { kmpExtension.appleTargets().forEach { val mappedArchNames = it.toSentryFrameworkArchitecture() - val foundMatch = mappedArchNames.any { mappedArchName -> - downloadedArchNames.contains(mappedArchName) - } + val foundMatch = + mappedArchNames.any { mappedArchName -> + downloadedArchNames.contains(mappedArchName) + } assert(foundMatch) { "Expected to find one of $mappedArchNames in $xcFramework for target ${it.name}.\nFound instead: ${ @@ -82,9 +82,7 @@ class SentryFrameworkArchitectureTest { @ParameterizedTest(name = "Test architecture name compatibility with Cocoa Version {0} in dynamic framework") @MethodSource("cocoaVersions") - fun `finds arch folders in dynamic framework`( - cocoaVersion: String - ) { + fun `finds arch folders in dynamic framework`(cocoaVersion: String) { val project = ProjectBuilder.builder().build() project.pluginManager.apply { apply("org.jetbrains.kotlin.multiplatform") @@ -104,7 +102,7 @@ class SentryFrameworkArchitectureTest { watchosSimulatorArm64(), tvosX64(), tvosArm64(), - tvosSimulatorArm64() + tvosSimulatorArm64(), ).forEach { it.binaries.framework { baseName = "shared" @@ -120,9 +118,10 @@ class SentryFrameworkArchitectureTest { kmpExtension.appleTargets().forEach { val mappedArchNames = it.toSentryFrameworkArchitecture() - val foundMatch = mappedArchNames.any { mappedArchName -> - downloadedArchNames.contains(mappedArchName) - } + val foundMatch = + mappedArchNames.any { mappedArchName -> + downloadedArchNames.contains(mappedArchName) + } assert(foundMatch) { "Expected to find one of $mappedArchNames in $xcFramework for target ${it.name}.\nFound instead: ${ @@ -137,18 +136,23 @@ class SentryFrameworkArchitectureTest { fun `returns empty list if target is unsupported`() { val unsupportedTarget = mockk() every { unsupportedTarget.name } returns "unsupported" - every { unsupportedTarget.konanTarget } returns mockk { - every { family } returns mockk { - every { isAppleFamily } returns true + every { unsupportedTarget.konanTarget } returns + mockk { + every { family } returns + mockk { + every { isAppleFamily } returns true + } } - } assert(unsupportedTarget.toSentryFrameworkArchitecture().isEmpty()) { "Expected empty list for unsupported target" } } - private fun downloadAndUnzip(cocoaVersion: String, isStatic: Boolean): File { + private fun downloadAndUnzip( + cocoaVersion: String, + isStatic: Boolean, + ): File { val tempDir = Files.createTempDirectory("sentry-cocoa-test").toFile() tempDir.deleteOnExit() @@ -157,13 +161,19 @@ class SentryFrameworkArchitectureTest { // Download val xcFrameworkZip = if (isStatic) "Sentry.xcframework.zip" else "Sentry-Dynamic.xcframework.zip" val downloadLink = - if (cocoaVersion == "latest") "https://github.com/getsentry/sentry-cocoa/releases/latest/download/$xcFrameworkZip" else "https://github.com/getsentry/sentry-cocoa/releases/download/$cocoaVersion/$xcFrameworkZip" + if (cocoaVersion == + "latest" + ) { + "https://github.com/getsentry/sentry-cocoa/releases/latest/download/$xcFrameworkZip" + } else { + "https://github.com/getsentry/sentry-cocoa/releases/download/$cocoaVersion/$xcFrameworkZip" + } val url = URL(downloadLink) url.openStream().use { input -> Files.copy( input, targetFile.toPath(), - StandardCopyOption.REPLACE_EXISTING + StandardCopyOption.REPLACE_EXISTING, ) } diff --git a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/SentryPluginTest.kt b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/SentryPluginTest.kt index 7ccaa68bf..3c05f1811 100644 --- a/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/SentryPluginTest.kt +++ b/sentry-kotlin-multiplatform-gradle-plugin/src/test/java/io/sentry/kotlin/multiplatform/gradle/SentryPluginTest.kt @@ -146,10 +146,11 @@ class SentryPluginTest { project.installSentryForKmp(project.extensions.getByName("commonMain") as SourceSetAutoInstallExtension) - val sentryDependencies = project.configurations - .flatMap { it.dependencies } - .filter { it.group == "io.sentry" && it.name == "sentry-kotlin-multiplatform" } - .toList() + val sentryDependencies = + project.configurations + .flatMap { it.dependencies } + .filter { it.group == "io.sentry" && it.name == "sentry-kotlin-multiplatform" } + .toList() assertTrue(sentryDependencies.isNotEmpty()) diff --git a/sentry-kotlin-multiplatform/build.gradle.kts b/sentry-kotlin-multiplatform/build.gradle.kts index 5c7ada604..ce725e834 100644 --- a/sentry-kotlin-multiplatform/build.gradle.kts +++ b/sentry-kotlin-multiplatform/build.gradle.kts @@ -72,7 +72,7 @@ kotlin { tvosX64(), tvosSimulatorArm64(), macosX64(), - macosArm64() + macosArm64(), ) addNoOpTargets() @@ -178,7 +178,7 @@ kotlin { "-compiler-option", "-DSentryIntegrationProtocol=SentryIntegrationProtocolUnavailable", "-compiler-option", - "-DSentryMetricsAPIDelegate=SentryMetricsAPIDelegateUnavailable" + "-DSentryMetricsAPIDelegate=SentryMetricsAPIDelegateUnavailable", ) dependency { remotePackageVersion( @@ -186,7 +186,7 @@ kotlin { version = Config.Libs.sentryCocoaVersion, products = { add("Sentry", exportToKotlin = true) - } + }, ) } } diff --git a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/Context.android.kt b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/Context.android.kt index aa0d51e77..4180fdcfc 100644 --- a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/Context.android.kt +++ b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/Context.android.kt @@ -37,7 +37,7 @@ internal class SentryContextProvider : ContentProvider() { projection: Array?, selection: String?, selectionArgs: Array?, - sortOrder: String? + sortOrder: String?, ): Cursor? { error("Not allowed.") } @@ -46,11 +46,18 @@ internal class SentryContextProvider : ContentProvider() { error("Not allowed.") } - override fun insert(uri: Uri, values: ContentValues?): Uri? { + override fun insert( + uri: Uri, + values: ContentValues?, + ): Uri? { error("Not allowed.") } - override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int { + override fun delete( + uri: Uri, + selection: String?, + selectionArgs: Array?, + ): Int { error("Not allowed.") } @@ -58,7 +65,7 @@ internal class SentryContextProvider : ContentProvider() { uri: Uri, values: ContentValues?, selection: String?, - selectionArgs: Array? + selectionArgs: Array?, ): Int { error("Not allowed.") } diff --git a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformInstance.android.kt b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformInstance.android.kt index 0cd4779d5..4126ebc56 100644 --- a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformInstance.android.kt +++ b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformInstance.android.kt @@ -4,10 +4,11 @@ import io.sentry.android.core.SentryAndroid internal actual class SentryPlatformInstance : SentryInstance { actual override fun init(configuration: PlatformOptionsConfiguration) { - val context = applicationContext ?: run { - // TODO: add logging later - return - } + val context = + applicationContext ?: run { + // TODO: add logging later + return + } SentryAndroid.init(context, configuration) } diff --git a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.android.kt b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.android.kt index 8fa945fe5..fdbbbfc95 100644 --- a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.android.kt +++ b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.android.kt @@ -13,8 +13,7 @@ internal actual fun SentryPlatformOptions.prepareForInit() { nativeSdkName = BuildKonfig.SENTRY_KMP_NATIVE_ANDROID_SDK_NAME } -internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration = - toAndroidSentryOptionsCallback() +internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration = toAndroidSentryOptionsCallback() internal actual fun SentryPlatformOptions.prepareForInitBridge() { prepareForInit() diff --git a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.android.kt b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.android.kt index 910d6706d..44ade8df1 100644 --- a/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.android.kt +++ b/sentry-kotlin-multiplatform/src/androidMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.android.kt @@ -8,36 +8,37 @@ import io.sentry.kotlin.multiplatform.SentryOptions import io.sentry.kotlin.multiplatform.SentryReplayOptions import kotlin.collections.forEach as kForEach -internal fun SentryOptions.toAndroidSentryOptionsCallback(): (SentryAndroidOptions) -> Unit = { androidOptions -> - val kmpOptions = this +internal fun SentryOptions.toAndroidSentryOptionsCallback(): (SentryAndroidOptions) -> Unit = + { androidOptions -> + val kmpOptions = this - // Apply base options available to all JVM targets - androidOptions.applyJvmBaseOptions(kmpOptions) + // Apply base options available to all JVM targets + androidOptions.applyJvmBaseOptions(kmpOptions) - // Apply Android specific options - androidOptions.isAttachScreenshot = kmpOptions.attachScreenshot - androidOptions.isAttachViewHierarchy = kmpOptions.attachViewHierarchy - androidOptions.isAnrEnabled = kmpOptions.isAnrEnabled - androidOptions.anrTimeoutIntervalMillis = kmpOptions.anrTimeoutIntervalMillis + // Apply Android specific options + androidOptions.isAttachScreenshot = kmpOptions.attachScreenshot + androidOptions.isAttachViewHierarchy = kmpOptions.attachViewHierarchy + androidOptions.isAnrEnabled = kmpOptions.isAnrEnabled + androidOptions.anrTimeoutIntervalMillis = kmpOptions.anrTimeoutIntervalMillis - // Replay options - androidOptions.sessionReplay.maskAllText = - kmpOptions.sessionReplay.maskAllText - androidOptions.sessionReplay.maskAllImages = - kmpOptions.sessionReplay.maskAllImages - androidOptions.sessionReplay.sessionSampleRate = - kmpOptions.sessionReplay.sessionSampleRate - androidOptions.sessionReplay.onErrorSampleRate = - kmpOptions.sessionReplay.onErrorSampleRate - androidOptions.sessionReplay.quality = - kmpOptions.sessionReplay.quality.toAndroidSentryQuality() + // Replay options + androidOptions.sessionReplay.maskAllText = + kmpOptions.sessionReplay.maskAllText + androidOptions.sessionReplay.maskAllImages = + kmpOptions.sessionReplay.maskAllImages + androidOptions.sessionReplay.sessionSampleRate = + kmpOptions.sessionReplay.sessionSampleRate + androidOptions.sessionReplay.onErrorSampleRate = + kmpOptions.sessionReplay.onErrorSampleRate + androidOptions.sessionReplay.quality = + kmpOptions.sessionReplay.quality.toAndroidSentryQuality() - // kForEach solves an issue with linter where it thinks forEach is the Java version - // see here: https://stackoverflow.com/questions/44751469/kotlin-extension-functions-suddenly-require-api-level-24/68897591#68897591 - this.sdk?.packages?.kForEach { sdkPackage -> - androidOptions.sdkVersion?.addPackage(sdkPackage.name, sdkPackage.version) + // kForEach solves an issue with linter where it thinks forEach is the Java version + // see here: https://stackoverflow.com/questions/44751469/kotlin-extension-functions-suddenly-require-api-level-24/68897591#68897591 + this.sdk?.packages?.kForEach { sdkPackage -> + androidOptions.sdkVersion?.addPackage(sdkPackage.name, sdkPackage.version) + } } -} internal fun SentryReplayOptions.Quality.toAndroidSentryQuality(): JvmSentryReplayQuality { val kmpQuality = this diff --git a/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt b/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt index d32877340..72647c512 100644 --- a/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt +++ b/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt @@ -9,6 +9,7 @@ import kotlin.test.BeforeTest actual abstract class BaseSentryTest { actual val platform: String = "Android" actual val authToken: String? = System.getenv("SENTRY_AUTH_TOKEN") + actual fun sentryInit(optionsConfiguration: OptionsConfiguration) { Sentry.init(optionsConfiguration) } diff --git a/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.android.kt b/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.android.kt index 22e4774f3..089741e7a 100644 --- a/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.android.kt +++ b/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.android.kt @@ -17,8 +17,9 @@ actual interface PlatformOptions : CommonPlatformOptions { val sessionReplay: AndroidSentryReplayOptions } -class SentryAndroidOptionsWrapper(private val androidOptions: SentryAndroidOptions) : - PlatformOptions { +class SentryAndroidOptionsWrapper( + private val androidOptions: SentryAndroidOptions, +) : PlatformOptions { override val dsn: String? get() = androidOptions.dsn @@ -84,8 +85,7 @@ class SentryAndroidOptionsWrapper(private val androidOptions: SentryAndroidOptio } } -actual fun createPlatformOptions(): PlatformOptions = - SentryAndroidOptionsWrapper(SentryAndroidOptions()) +actual fun createPlatformOptions(): PlatformOptions = SentryAndroidOptionsWrapper(SentryAndroidOptions()) actual fun PlatformOptions.assertPlatformSpecificOptions(kmpOptions: SentryOptions) { val androidOptions = this @@ -99,35 +99,36 @@ actual fun PlatformOptions.assertPlatformSpecificOptions(kmpOptions: SentryOptio kmpReplayOptions.maskAllText, androidOptions.sessionReplay.maskViewClasses, androidOptions.sessionReplay.unmaskViewClasses, - AndroidSentryReplayOptions.TEXT_VIEW_CLASS_NAME + AndroidSentryReplayOptions.TEXT_VIEW_CLASS_NAME, ) assertViewClassMasking( kmpReplayOptions.maskAllImages, androidOptions.sessionReplay.maskViewClasses, androidOptions.sessionReplay.unmaskViewClasses, - AndroidSentryReplayOptions.IMAGE_VIEW_CLASS_NAME + AndroidSentryReplayOptions.IMAGE_VIEW_CLASS_NAME, ) assertEquals( androidOptions.sessionReplay.onErrorSampleRate, - kmpReplayOptions.onErrorSampleRate + kmpReplayOptions.onErrorSampleRate, ) assertEquals( androidOptions.sessionReplay.sessionSampleRate, - kmpReplayOptions.sessionSampleRate + kmpReplayOptions.sessionSampleRate, ) assertEquals(androidOptions.sessionReplay.quality.name, kmpReplayOptions.quality.name) assertEquals(androidOptions.proguardUuid, kmpOptions.proguardUuid) } -actual fun createSentryPlatformOptionsConfiguration(): PlatformOptionsConfiguration = { - it.dsn = fakeDsn -} +actual fun createSentryPlatformOptionsConfiguration(): PlatformOptionsConfiguration = + { + it.dsn = fakeDsn + } private fun assertViewClassMasking( kmpMaskAll: Boolean, maskViewClasses: Collection, unmaskViewClasses: Collection, - viewClassName: String + viewClassName: String, ) { if (kmpMaskAll) { assertContains(maskViewClasses, viewClassName) diff --git a/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/SentryAndroidBridgeTest.kt b/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/SentryAndroidBridgeTest.kt index 49981170d..ccf7cf462 100644 --- a/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/SentryAndroidBridgeTest.kt +++ b/sentry-kotlin-multiplatform/src/androidUnitTest/kotlin/io/sentry/kotlin/multiplatform/SentryAndroidBridgeTest.kt @@ -19,9 +19,10 @@ class SentryAndroidBridgeTest { sut.init { } - val option = SentryPlatformOptions().apply { - fixture.sentryInstance.lastConfiguration?.invoke(this) - } + val option = + SentryPlatformOptions().apply { + fixture.sentryInstance.lastConfiguration?.invoke(this) + } assertEquals(BuildKonfig.SENTRY_KMP_NATIVE_ANDROID_SDK_NAME, option.nativeSdkName) } @@ -30,7 +31,5 @@ class SentryAndroidBridgeTest { internal class Fixture { val sentryInstance = FakeSentryInstance() - fun getSut(): SentryBridge { - return SentryBridge(sentryInstance) - } + fun getSut(): SentryBridge = SentryBridge(sentryInstance) } diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.apple.kt index d69637cc4..ecd4d94d5 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.apple.kt @@ -4,7 +4,6 @@ import io.sentry.kotlin.multiplatform.extensions.toByteArray import io.sentry.kotlin.multiplatform.extensions.toNSData public actual class Attachment { - internal lateinit var cocoaAttachment: CocoaAttachment public actual val filename: String @@ -20,9 +19,8 @@ public actual class Attachment { get() = cocoaAttachment.contentType public actual companion object { - public actual fun fromScreenshot(screenshotBytes: ByteArray): Attachment { - return Attachment(screenshotBytes, "screenshot.png", "image/png") - } + public actual fun fromScreenshot(screenshotBytes: ByteArray): Attachment = + Attachment(screenshotBytes, "screenshot.png", "image/png") } public actual constructor(pathname: String) { diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaScopeProvider.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaScopeProvider.kt index 88870d1ee..09cb37989 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaScopeProvider.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/CocoaScopeProvider.kt @@ -9,7 +9,9 @@ import io.sentry.kotlin.multiplatform.extensions.toMutableMap import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.User -internal class CocoaScopeProvider(private val scope: CocoaScope) : Scope { +internal class CocoaScopeProvider( + private val scope: CocoaScope, +) : Scope { /* This bridge exposes private Cocoa SDK API to fetch internal properties such as user, level, etc. We need this in order to return properties because the Cocoa SDK doesn't implement getters. @@ -62,11 +64,17 @@ internal class CocoaScopeProvider(private val scope: CocoaScope) : Scope { scope.clearBreadcrumbs() } - private fun setContextForPrimitiveValues(key: String, value: Any) { + private fun setContextForPrimitiveValues( + key: String, + value: Any, + ) { scope.setContextValue(mapOf("value" to value), key) } - override fun setContext(key: String, value: Any) { + override fun setContext( + key: String, + value: Any, + ) { try { (value as? Map)?.let { scope.setContextValue(it, key) @@ -76,27 +84,45 @@ internal class CocoaScopeProvider(private val scope: CocoaScope) : Scope { } } - override fun setContext(key: String, value: String) { + override fun setContext( + key: String, + value: String, + ) { setContextForPrimitiveValues(key, value) } - override fun setContext(key: String, value: Boolean) { + override fun setContext( + key: String, + value: Boolean, + ) { setContextForPrimitiveValues(key, value) } - override fun setContext(key: String, value: Number) { + override fun setContext( + key: String, + value: Number, + ) { setContextForPrimitiveValues(key, value) } - override fun setContext(key: String, value: Char) { + override fun setContext( + key: String, + value: Char, + ) { setContextForPrimitiveValues(key, value) } - override fun setContext(key: String, value: Array<*>) { + override fun setContext( + key: String, + value: Array<*>, + ) { setContextForPrimitiveValues(key, value) } - override fun setContext(key: String, value: Collection<*>) { + override fun setContext( + key: String, + value: Collection<*>, + ) { setContextForPrimitiveValues(key, value) } @@ -104,7 +130,10 @@ internal class CocoaScopeProvider(private val scope: CocoaScope) : Scope { scope.removeContextForKey(key) } - override fun setTag(key: String, value: String) { + override fun setTag( + key: String, + value: String, + ) { scope.setTagValue(value, key) } @@ -112,7 +141,10 @@ internal class CocoaScopeProvider(private val scope: CocoaScope) : Scope { scope.removeTagForKey(key) } - override fun setExtra(key: String, value: String) { + override fun setExtra( + key: String, + value: String, + ) { scope.setExtraValue(value, key) } diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt index bc02c9f24..9026e5ee3 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.apple.kt @@ -47,10 +47,15 @@ internal actual fun SentryPlatformOptions.prepareForInit() { PrivateSentrySDKOnly.setSdkName(BuildKonfig.SENTRY_KMP_COCOA_SDK_NAME, BuildKonfig.VERSION_NAME) } -internal actual class SentryBridge actual constructor(private val sentryInstance: SentryInstance) { +internal actual class SentryBridge actual constructor( + private val sentryInstance: SentryInstance, +) { private val logger = CocoaSentryLoggerAdapter(SentrySDK::logger) - actual fun init(context: Context, configuration: OptionsConfiguration) { + actual fun init( + context: Context, + configuration: OptionsConfiguration, + ) { init(configuration) } @@ -74,27 +79,35 @@ internal actual class SentryBridge actual constructor(private val sentryInstance return SentryId(cocoaSentryId.toString()) } - actual fun captureMessage(message: String, scopeCallback: ScopeCallback): SentryId { + actual fun captureMessage( + message: String, + scopeCallback: ScopeCallback, + ): SentryId { val cocoaSentryId = SentrySDK.captureMessage(message, configureScopeCallback(scopeCallback)) return SentryId(cocoaSentryId.toString()) } actual fun captureException(throwable: Throwable): SentryId { - val event = throwable.asSentryEvent( - level = kSentryLevelError, - isHandled = true, - markThreadAsCrashed = false - ) + val event = + throwable.asSentryEvent( + level = kSentryLevelError, + isHandled = true, + markThreadAsCrashed = false, + ) val cocoaSentryId = SentrySDK.captureEvent(event) return SentryId(cocoaSentryId.toString()) } - actual fun captureException(throwable: Throwable, scopeCallback: ScopeCallback): SentryId { - val event = throwable.asSentryEvent( - level = kSentryLevelError, - isHandled = true, - markThreadAsCrashed = false - ) + actual fun captureException( + throwable: Throwable, + scopeCallback: ScopeCallback, + ): SentryId { + val event = + throwable.asSentryEvent( + level = kSentryLevelError, + isHandled = true, + markThreadAsCrashed = false, + ) val cocoaSentryId = SentrySDK.captureEvent(event, configureScopeCallback(scopeCallback)) return SentryId(cocoaSentryId.toString()) } @@ -115,32 +128,26 @@ internal actual class SentryBridge actual constructor(private val sentryInstance SentrySDK.setUser(user?.toCocoaUser()) } - actual fun isCrashedLastRun(): Boolean { - return SentrySDK.crashedLastRun() - } + actual fun isCrashedLastRun(): Boolean = SentrySDK.crashedLastRun() - actual fun isEnabled(): Boolean { - return SentrySDK.isEnabled() - } + actual fun isEnabled(): Boolean = SentrySDK.isEnabled() actual fun close() { SentrySDK.close() } - private fun configureScopeCallback(scopeCallback: ScopeCallback): (CocoaScope?) -> Unit { - return { cocoaScope -> - val cocoaScopeProvider = cocoaScope?.let { - CocoaScopeProvider(it) - } + private fun configureScopeCallback(scopeCallback: ScopeCallback): (CocoaScope?) -> Unit = + { cocoaScope -> + val cocoaScopeProvider = + cocoaScope?.let { + CocoaScopeProvider(it) + } cocoaScopeProvider?.let { scopeCallback.invoke(it) } } - } - actual fun logger(): SentryLogger { - return logger - } + actual fun logger(): SentryLogger = logger } @Suppress("unused") diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryEvent.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryEvent.apple.kt index 45c14ff9a..f677a9afe 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryEvent.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/SentryEvent.apple.kt @@ -38,14 +38,20 @@ public actual class SentryEvent actual constructor() : SentryBaseEvent() { val cocoaFingerprint = cocoaSentryEvent.fingerprint()?.toMutableList() as? MutableList val cocoaSentryExceptions = - cocoaSentryEvent.exceptions?.map { (it as CocoaSentryException).toKmpSentryException() } + cocoaSentryEvent.exceptions + ?.map { (it as CocoaSentryException).toKmpSentryException() } ?.toMutableList() val cocoaContexts = cocoaSentryEvent.context?.mapKeys { it.key as String }?.mapValues { it.value as Any } - val cocoaBreadcrumbs = cocoaSentryEvent.breadcrumbs?.mapNotNull { it as? CocoaBreadcrumb } - ?.map { it.toKmpBreadcrumb() }?.toMutableList() + val cocoaBreadcrumbs = + cocoaSentryEvent.breadcrumbs + ?.mapNotNull { it as? CocoaBreadcrumb } + ?.map { it.toKmpBreadcrumb() } + ?.toMutableList() val cocoaTags = - cocoaSentryEvent.tags?.mapKeys { it.key as String }?.mapValues { it.value as String } + cocoaSentryEvent.tags + ?.mapKeys { it.key as String } + ?.mapValues { it.value as String } ?.toMutableMap() cocoaFingerprint?.let { fingerprint = it } diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/BreadcrumbExtensions.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/BreadcrumbExtensions.apple.kt index 385d2af41..2006f121b 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/BreadcrumbExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/BreadcrumbExtensions.apple.kt @@ -3,23 +3,25 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.CocoaBreadcrumb import io.sentry.kotlin.multiplatform.protocol.Breadcrumb -internal fun Breadcrumb.toCocoaBreadcrumb() = CocoaBreadcrumb().apply { - val scope = this@toCocoaBreadcrumb - setMessage(scope.message) - setType(scope.type) - scope.category?.let { setCategory(it) } - scope.level?.let { setLevel(it.toCocoaSentryLevel()) } - setData(scope.getData()?.toMap()) -} +internal fun Breadcrumb.toCocoaBreadcrumb() = + CocoaBreadcrumb().apply { + val scope = this@toCocoaBreadcrumb + setMessage(scope.message) + setType(scope.type) + scope.category?.let { setCategory(it) } + scope.level?.let { setLevel(it.toCocoaSentryLevel()) } + setData(scope.getData()?.toMap()) + } -internal fun CocoaBreadcrumb.toKmpBreadcrumb() = Breadcrumb().apply { - val scope = this@toKmpBreadcrumb - message = scope.message - type = scope.type - category = scope.category - val map = scope.data as? Map - map?.let { - this.setData(it.toMutableMap()) +internal fun CocoaBreadcrumb.toKmpBreadcrumb() = + Breadcrumb().apply { + val scope = this@toKmpBreadcrumb + message = scope.message + type = scope.type + category = scope.category + val map = scope.data as? Map + map?.let { + this.setData(it.toMutableMap()) + } + level = scope.level.toKmpSentryLevel() } - level = scope.level.toKmpSentryLevel() -} diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/FoundationExtensions.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/FoundationExtensions.kt index 8788c4b44..f9d5fde39 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/FoundationExtensions.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/FoundationExtensions.kt @@ -20,15 +20,17 @@ internal fun NSMutableDictionary.toMutableMap(): MutableMap { return map } -internal fun NSData.toByteArray(): ByteArray = ByteArray(this@toByteArray.length.toInt()).apply { - usePinned { - memcpy(it.addressOf(0), this@toByteArray.bytes, this@toByteArray.length) +internal fun NSData.toByteArray(): ByteArray = + ByteArray(this@toByteArray.length.toInt()).apply { + usePinned { + memcpy(it.addressOf(0), this@toByteArray.bytes, this@toByteArray.length) + } } -} -internal fun ByteArray.toNSData(): NSData = memScoped { - NSData.create( - bytes = allocArrayOf(this@toNSData), - length = this@toNSData.size.toULong().convert() - ) -} +internal fun ByteArray.toNSData(): NSData = + memScoped { + NSData.create( + bytes = allocArrayOf(this@toNSData), + length = this@toNSData.size.toULong().convert(), + ) + } diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/MessageExtensions.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/MessageExtensions.apple.kt index c605f9025..f723b6556 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/MessageExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/MessageExtensions.apple.kt @@ -3,11 +3,12 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.CocoaMessage import io.sentry.kotlin.multiplatform.protocol.Message -internal fun CocoaMessage.toKmpMessage() = Message( - message = message, - params = params as? List, - formatted = formatted -) +internal fun CocoaMessage.toKmpMessage() = + Message( + message = message, + params = params as? List, + formatted = formatted, + ) internal fun Message.toCocoaMessage(): CocoaMessage { val scope = this@toCocoaMessage diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryExceptionExtensions.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryExceptionExtensions.apple.kt index d811f745f..4dd0cac7f 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryExceptionExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryExceptionExtensions.apple.kt @@ -3,9 +3,10 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.CocoaSentryException import io.sentry.kotlin.multiplatform.protocol.SentryException -internal fun CocoaSentryException.toKmpSentryException() = SentryException( - type = type, - value = value, - module = module, - threadId = threadId?.longLongValue // longLong represents a 64-bit integer like Kotlin Long -) +internal fun CocoaSentryException.toKmpSentryException() = + SentryException( + type = type, + value = value, + module = module, + threadId = threadId?.longLongValue, // longLong represents a 64-bit integer like Kotlin Long + ) diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt index 40d528167..583554ed5 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.apple.kt @@ -11,9 +11,10 @@ import io.sentry.kotlin.multiplatform.setEnableUnhandledCppExceptionMonitoring import kotlinx.cinterop.convert import platform.Foundation.NSNumber -internal fun SentryOptions.toCocoaOptionsConfiguration(): (CocoaSentryOptions?) -> Unit = { - it?.applyCocoaBaseOptions(this) -} +internal fun SentryOptions.toCocoaOptionsConfiguration(): (CocoaSentryOptions?) -> Unit = + { + it?.applyCocoaBaseOptions(this) + } /** * Applies the given options to this CocoaSentryOptions. @@ -65,9 +66,12 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(kmpOptions: SentryOptions) cocoaOptions.beforeSend = { event -> val sdk = event?.sdk?.toMutableMap() - val packages = kmpOptions.sdk?.packages?.map { - mapOf("name" to it.name, "version" to it.version) - }?.toMutableList() ?: mutableListOf() + val packages = + kmpOptions.sdk + ?.packages + ?.map { + mapOf("name" to it.name, "version" to it.version) + }?.toMutableList() ?: mutableListOf() sdk?.set("packages", packages) @@ -87,17 +91,20 @@ internal fun CocoaSentryOptions.applyCocoaBaseOptions(kmpOptions: SentryOptions) if (kmpOptions.beforeBreadcrumb == null) { cocoaBreadcrumb } else { - cocoaBreadcrumb?.toKmpBreadcrumb() - ?.let { kmpOptions.beforeBreadcrumb?.invoke(it) }?.toCocoaBreadcrumb() + cocoaBreadcrumb + ?.toKmpBreadcrumb() + ?.let { kmpOptions.beforeBreadcrumb?.invoke(it) } + ?.toCocoaBreadcrumb() } } cocoaOptions.enableCaptureFailedRequests = kmpOptions.enableCaptureFailedRequests cocoaOptions.failedRequestTargets = kmpOptions.failedRequestTargets - cocoaOptions.failedRequestStatusCodes = kmpOptions.failedRequestStatusCodes.map { - SentryHttpStatusCodeRange( - min = it.min.convert(), - max = it.max.convert() - ) - } + cocoaOptions.failedRequestStatusCodes = + kmpOptions.failedRequestStatusCodes.map { + SentryHttpStatusCodeRange( + min = it.min.convert(), + max = it.max.convert(), + ) + } } diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/UserExtensions.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/UserExtensions.apple.kt index b2af2f828..d8d7bfe81 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/UserExtensions.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/extensions/UserExtensions.apple.kt @@ -3,18 +3,20 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.CocoaUser import io.sentry.kotlin.multiplatform.protocol.User -internal fun User.toCocoaUser() = CocoaUser().apply { - val scope = this@toCocoaUser - userId = scope.id - username = scope.username - email = scope.email - ipAddress = scope.ipAddress -} +internal fun User.toCocoaUser() = + CocoaUser().apply { + val scope = this@toCocoaUser + userId = scope.id + username = scope.username + email = scope.email + ipAddress = scope.ipAddress + } -internal fun CocoaUser.toKmpUser() = User().apply { - val scope = this@toKmpUser - id = scope.userId - username = scope.username - email = scope.email - ipAddress = scope.ipAddress -} +internal fun CocoaUser.toKmpUser() = + User().apply { + val scope = this@toKmpUser + id = scope.userId + username = scope.username + email = scope.email + ipAddress = scope.ipAddress + } diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/log/CocoaSentryLoggerAdapter.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/log/CocoaSentryLoggerAdapter.kt index 86a4ec47f..1f1dee42c 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/log/CocoaSentryLoggerAdapter.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/log/CocoaSentryLoggerAdapter.kt @@ -11,9 +11,12 @@ import cocoapods.Sentry.SentryLogger as CocoaSentryLogger */ internal class CocoaSentryLoggerAdapter( private val cocoaLoggerProvider: () -> CocoaSentryLogger, - logBuilderFactory: SentryLogBuilderFactory = DefaultSentryLogBuilderFactory + logBuilderFactory: SentryLogBuilderFactory = DefaultSentryLogBuilderFactory, ) : BaseSentryLogger(logBuilderFactory) { - override fun sendLog(level: SentryLogLevel, formatted: FormattedLog) { + override fun sendLog( + level: SentryLogLevel, + formatted: FormattedLog, + ) { val cocoaLogger = cocoaLoggerProvider() val attributes = formatted.attributes.toCocoaMap() when (level) { diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogConverters.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogConverters.apple.kt index d2043b5d6..ed235ec50 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogConverters.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogConverters.apple.kt @@ -13,47 +13,53 @@ import io.sentry.kotlin.multiplatform.SentryAttributes as KmpSentryAttributes * Converts Cocoa SDK's [CocoaSentryLogLevel] to KMP [SentryLogLevel]. */ @Suppress("MagicNumber") -internal fun CocoaSentryLogLevel.toKmpSentryLogLevel(): SentryLogLevel = when (this.convert()) { - 0 -> SentryLogLevel.TRACE - 1 -> SentryLogLevel.DEBUG - 2 -> SentryLogLevel.INFO - 3 -> SentryLogLevel.WARN - 4 -> SentryLogLevel.ERROR - 5 -> SentryLogLevel.FATAL - else -> SentryLogLevel.DEBUG -} +internal fun CocoaSentryLogLevel.toKmpSentryLogLevel(): SentryLogLevel = + when (this.convert()) { + 0 -> SentryLogLevel.TRACE + 1 -> SentryLogLevel.DEBUG + 2 -> SentryLogLevel.INFO + 3 -> SentryLogLevel.WARN + 4 -> SentryLogLevel.ERROR + 5 -> SentryLogLevel.FATAL + else -> SentryLogLevel.DEBUG + } /** * Converts KMP's [SentryLogLevel] to Cocoa SDK's [CocoaSentryLogLevel]. */ @Suppress("MagicNumber") -internal fun SentryLogLevel.toCocoaSentryLogLevel(): CocoaSentryLogLevel = when (this) { - SentryLogLevel.TRACE -> 0.convert() - SentryLogLevel.DEBUG -> 1.convert() - SentryLogLevel.INFO -> 2.convert() - SentryLogLevel.WARN -> 3.convert() - SentryLogLevel.ERROR -> 4.convert() - SentryLogLevel.FATAL -> 5.convert() -} +internal fun SentryLogLevel.toCocoaSentryLogLevel(): CocoaSentryLogLevel = + when (this) { + SentryLogLevel.TRACE -> 0.convert() + SentryLogLevel.DEBUG -> 1.convert() + SentryLogLevel.INFO -> 2.convert() + SentryLogLevel.WARN -> 3.convert() + SentryLogLevel.ERROR -> 4.convert() + SentryLogLevel.FATAL -> 5.convert() + } /** * Converts a Cocoa SentryLog to a KMP SentryLog for use in beforeSendLog callback. * After the callback, changes are applied back via [updateFrom]. */ -internal fun CocoaSentryLog.toKmpSentryLog(): SentryLog = SentryLog( - timestamp = timestamp().timeIntervalSince1970, - level = level().toKmpSentryLogLevel(), - body = body(), - severityNumber = severityNumber()?.intValue, - attributes = toKmpSentryAttributes() -) +internal fun CocoaSentryLog.toKmpSentryLog(): SentryLog = + SentryLog( + timestamp = timestamp().timeIntervalSince1970, + level = level().toKmpSentryLogLevel(), + body = body(), + severityNumber = severityNumber()?.intValue, + attributes = toKmpSentryAttributes(), + ) /** * Updates this Cocoa SentryLog from a KMP SentryLog. * @param kmpLog The modified KMP log after user's beforeSendLog callback. * @param originalKmpAttributes The original KMP attributes before the callback, used to detect changes. */ -internal fun CocoaSentryLog.updateFrom(kmpLog: SentryLog, originalKmpAttributes: KmpSentryAttributes) { +internal fun CocoaSentryLog.updateFrom( + kmpLog: SentryLog, + originalKmpAttributes: KmpSentryAttributes, +) { setBody(kmpLog.body) setLevel(kmpLog.level.toCocoaSentryLogLevel()) setSeverityNumber(kmpLog.severityNumber?.let { NSNumber(int = it) }) @@ -68,8 +74,7 @@ private fun CocoaSentryLog.toKmpSentryAttributes(): KmpSentryAttributes { attributes() .mapNotNull { (key, value) -> (key as? String)?.let { it to (value as? SentryStructuredLogAttribute) } - } - .forEach { (key, attribute) -> + }.forEach { (key, attribute) -> attribute ?: return@forEach when (attribute.type()) { "string" -> kmpAttributes[key] = attribute.value() as String @@ -86,7 +91,7 @@ private fun CocoaSentryLog.toKmpSentryAttributes(): KmpSentryAttributes { */ private fun CocoaSentryLog.updateAttributesFrom( modifiedKmpAttributes: KmpSentryAttributes, - originalKmpAttributes: KmpSentryAttributes + originalKmpAttributes: KmpSentryAttributes, ) { val mergedAttributes = attributes().toMutableMap() @@ -94,13 +99,14 @@ private fun CocoaSentryLog.updateAttributesFrom( (originalKmpAttributes.keys - modifiedKmpAttributes.keys).forEach { mergedAttributes.remove(it) } modifiedKmpAttributes.forEach { (key, attrValue) -> - mergedAttributes[key] = when (attrValue) { - is SentryAttributeValue.LongValue -> - SentryStructuredLogAttribute(integer = (attrValue.value as Long).convert()) - is SentryAttributeValue.DoubleValue -> SentryStructuredLogAttribute(double = attrValue.value as Double) - is SentryAttributeValue.StringValue -> SentryStructuredLogAttribute(string = attrValue.value as String) - is SentryAttributeValue.BooleanValue -> SentryStructuredLogAttribute(boolean = attrValue.value as Boolean) - } + mergedAttributes[key] = + when (attrValue) { + is SentryAttributeValue.LongValue -> + SentryStructuredLogAttribute(integer = (attrValue.value as Long).convert()) + is SentryAttributeValue.DoubleValue -> SentryStructuredLogAttribute(double = attrValue.value as Double) + is SentryAttributeValue.StringValue -> SentryStructuredLogAttribute(string = attrValue.value as String) + is SentryAttributeValue.BooleanValue -> SentryStructuredLogAttribute(boolean = attrValue.value as Boolean) + } } setAttributes(mergedAttributes) diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/NSException.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/NSException.kt index 3ea684d84..686139800 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/NSException.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/NSException.kt @@ -26,17 +26,19 @@ import kotlin.reflect.KClass * of the [causes][Throwable.cause] will be appended, else causes are ignored. */ internal fun Throwable.asNSException(appendCausedBy: Boolean = false): NSException { - val returnAddresses = getFilteredStackTraceAddresses().let { addresses -> - if (!appendCausedBy) return@let addresses - addresses.toMutableList().apply { - for (cause in causes) { - addAll(cause.getFilteredStackTraceAddresses(true, addresses)) + val returnAddresses = + getFilteredStackTraceAddresses() + .let { addresses -> + if (!appendCausedBy) return@let addresses + addresses.toMutableList().apply { + for (cause in causes) { + addAll(cause.getFilteredStackTraceAddresses(true, addresses)) + } + } + }.map { + @Suppress("RemoveExplicitTypeArguments") + NSNumber(unsignedInteger = it.convert()) } - } - }.map { - @Suppress("RemoveExplicitTypeArguments") - NSNumber(unsignedInteger = it.convert()) - } return ThrowableNSException(name, getReason(appendCausedBy), returnAddresses) } @@ -68,7 +70,7 @@ internal fun Throwable.getReason(appendCausedBy: Boolean = false): String? { internal class ThrowableNSException( name: String, reason: String?, - private val returnAddresses: List + private val returnAddresses: List, ) : NSException(name, reason, null) { override fun callStackReturnAddresses(): List = returnAddresses } diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/SentryUnhandledExceptions.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/SentryUnhandledExceptions.kt index 040d22132..0bc0210d3 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/SentryUnhandledExceptions.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/SentryUnhandledExceptions.kt @@ -39,15 +39,15 @@ private typealias CocoapodsSentryEnvelopeItem = cocoapods.Sentry.SentryEnvelopeI /** * Drops the Kotlin crash that follows an unhandled Kotlin exception except our custom SentryEvent. */ -internal fun dropKotlinCrashEvent(event: CocoapodsSentryEvent?): CocoapodsSentryEvent? { - return event?.takeUnless { - (it as InternalSentryEvent).isFatalEvent && ( - it.tags?.containsKey( - KOTLIN_CRASH_TAG - ) ?: false +internal fun dropKotlinCrashEvent(event: CocoapodsSentryEvent?): CocoapodsSentryEvent? = + event?.takeUnless { + (it as InternalSentryEvent).isFatalEvent && + ( + it.tags?.containsKey( + KOTLIN_CRASH_TAG, + ) ?: false ) } -} /** * Sets the unhandled exception hook such that all unhandled exceptions are logged to Sentry as fatal exceptions. @@ -55,25 +55,26 @@ internal fun dropKotlinCrashEvent(event: CocoapodsSentryEvent?): CocoapodsSentry * Note: once the exception is logged the program will be terminated. * @see wrapUnhandledExceptionHook */ -public fun setSentryUnhandledExceptionHook(): Unit = wrapUnhandledExceptionHook { throwable -> - val crashReporter = InternalSentryDependencyContainer.sharedInstance().crashReporter - val handler = crashReporter.uncaughtExceptionHandler +public fun setSentryUnhandledExceptionHook(): Unit = + wrapUnhandledExceptionHook { throwable -> + val crashReporter = InternalSentryDependencyContainer.sharedInstance().crashReporter + val handler = crashReporter.uncaughtExceptionHandler - if (handler != null) { - // This will: - // 1. Write a crash report to disk with ALL synced scope data - // 2. Include tags, user, context, breadcrumbs, etc. - // 3. The crash will be sent on next app launch - handler.invoke(throwable.asNSException(appendCausedBy = true)) - } else { - // Fallback to old approach if handler not available - val envelope = throwable.asSentryEnvelope() - InternalSentrySDK.storeEnvelope(envelope as objcnames.classes.SentryEnvelope) - CocoapodsSentrySDK.configureScope { scope -> - scope?.setTagValue(KOTLIN_CRASH_TAG, KOTLIN_CRASH_TAG) + if (handler != null) { + // This will: + // 1. Write a crash report to disk with ALL synced scope data + // 2. Include tags, user, context, breadcrumbs, etc. + // 3. The crash will be sent on next app launch + handler.invoke(throwable.asNSException(appendCausedBy = true)) + } else { + // Fallback to old approach if handler not available + val envelope = throwable.asSentryEnvelope() + InternalSentrySDK.storeEnvelope(envelope as objcnames.classes.SentryEnvelope) + CocoapodsSentrySDK.configureScope { scope -> + scope?.setTagValue(KOTLIN_CRASH_TAG, KOTLIN_CRASH_TAG) + } } } -} /** * Tag used to mark the Kotlin termination crash. @@ -85,10 +86,12 @@ internal const val KOTLIN_CRASH_TAG = "nsexceptionkt.kotlin_crashed" */ private fun Throwable.asSentryEnvelope(): CocoapodsSentryEnvelope { val event = asSentryEvent() as InternalSentryEvent - val preparedEvent = InternalSentrySDK.currentHub().let { hub -> - hub.getClient() - ?.prepareEvent(event, hub.scope, alwaysAttachStacktrace = false, isFatalEvent = true) - } ?: event + val preparedEvent = + InternalSentrySDK.currentHub().let { hub -> + hub + .getClient() + ?.prepareEvent(event, hub.scope, alwaysAttachStacktrace = false, isFatalEvent = true) + } ?: event val item = CocoapodsSentryEnvelopeItem(event = preparedEvent as cocoapods.Sentry.SentryEvent) // TODO: pass traceState when enabling performance monitoring for KMP SDK val header = CocoapodsSentryEnvelopeHeader(id = preparedEvent.eventId) @@ -106,29 +109,32 @@ private fun Throwable.asSentryEnvelope(): CocoapodsSentryEnvelope { internal fun Throwable.asSentryEvent( level: CocoaSentryLevel = kSentryLevelFatal, isHandled: Boolean = false, - markThreadAsCrashed: Boolean = true + markThreadAsCrashed: Boolean = true, ): CocoapodsSentryEvent = CocoapodsSentryEvent(level).apply { @Suppress("UNCHECKED_CAST") val threads = threadInspector?.getCurrentThreadsWithStackTrace() as List? this.threads = threads - val currentThread = threads?.firstOrNull { it.current?.boolValue ?: false }?.apply { - if (markThreadAsCrashed) { - setCrashed(NSNumber(true)) - // Crashed threads shouldn't have a stacktrace, the thread_id should be set on the exception instead - // https://develop.sentry.dev/sdk/event-payloads/threads/ - stacktrace = null + val currentThread = + threads?.firstOrNull { it.current?.boolValue ?: false }?.apply { + if (markThreadAsCrashed) { + setCrashed(NSNumber(true)) + // Crashed threads shouldn't have a stacktrace, the thread_id should be set on the exception instead + // https://develop.sentry.dev/sdk/event-payloads/threads/ + stacktrace = null + } } - } - debugMeta = threads?.let { - InternalSentryDependencyContainer.sharedInstance().debugImageProvider.getDebugImagesForThreads( - it - ) - } - exceptions = this@asSentryEvent - .let { throwable -> throwable.causes.asReversed() + throwable } - .map { it.asNSException().asSentryException(currentThread?.threadId, isHandled) } + debugMeta = + threads?.let { + InternalSentryDependencyContainer.sharedInstance().debugImageProvider.getDebugImagesForThreads( + it, + ) + } + exceptions = + this@asSentryEvent + .let { throwable -> throwable.causes.asReversed() + throwable } + .map { it.asNSException().asSentryException(currentThread?.threadId, isHandled) } } /** @@ -136,18 +142,21 @@ internal fun Throwable.asSentryEvent( */ private fun NSException.asSentryException( threadId: NSNumber?, - isHandled: Boolean = false -): CocoapodsSentryException = CocoapodsSentryException(reason ?: "", name ?: "Throwable").apply { - this.threadId = threadId - mechanism = CocoapodsSentryMechanism("generic").apply { - setHandled(NSNumber(isHandled)) - } - stacktrace = threadInspector?.stacktraceBuilder?.let { stacktraceBuilder -> - val cursor = NSExceptionKt_SentryCrashStackCursorFromNSException(this@asSentryException) - val stacktrace = stacktraceBuilder.retrieveStacktraceFromCursor(cursor) - stacktrace as CocoapodsSentryStacktrace + isHandled: Boolean = false, +): CocoapodsSentryException = + CocoapodsSentryException(reason ?: "", name ?: "Throwable").apply { + this.threadId = threadId + mechanism = + CocoapodsSentryMechanism("generic").apply { + setHandled(NSNumber(isHandled)) + } + stacktrace = + threadInspector?.stacktraceBuilder?.let { stacktraceBuilder -> + val cursor = NSExceptionKt_SentryCrashStackCursorFromNSException(this@asSentryException) + val stacktrace = stacktraceBuilder.retrieveStacktraceFromCursor(cursor) + stacktrace as CocoapodsSentryStacktrace + } } -} private val threadInspector: InternalSentryThreadInspector? get() = InternalSentrySDK.currentHub().getClient()?.threadInspector diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/Throwable.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/Throwable.kt index 27d8f8ec3..54249dc0c 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/Throwable.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/nsexception/Throwable.kt @@ -19,14 +19,15 @@ package io.sentry.kotlin.multiplatform.nsexception * The first element will be the cause, the second the cause of the cause, etc. * This function stops once a reference cycles is detected. */ -internal val Throwable.causes: List get() = buildList { - val causes = mutableSetOf() - var cause = cause - while (cause != null && causes.add(cause)) { - add(cause) - cause = cause.cause +internal val Throwable.causes: List get() = + buildList { + val causes = mutableSetOf() + var cause = cause + while (cause != null && causes.add(cause)) { + add(cause) + cause = cause.cause + } } -} /** * Returns a list of stack trace addresses representing @@ -37,12 +38,14 @@ internal val Throwable.causes: List get() = buildList { */ internal fun Throwable.getFilteredStackTraceAddresses( keepLastInit: Boolean = false, - commonAddresses: List = emptyList() -): List = getStackTraceAddresses().dropInitAddresses( - qualifiedClassName = this::class.qualifiedName ?: Throwable::class.qualifiedName!!, - stackTrace = getStackTrace(), - keepLast = keepLastInit -).dropCommonAddresses(commonAddresses) + commonAddresses: List = emptyList(), +): List = + getStackTraceAddresses() + .dropInitAddresses( + qualifiedClassName = this::class.qualifiedName ?: Throwable::class.qualifiedName!!, + stackTrace = getStackTrace(), + keepLast = keepLastInit, + ).dropCommonAddresses(commonAddresses) /** * Returns a list containing all addresses expect for the first addresses @@ -52,7 +55,7 @@ internal fun Throwable.getFilteredStackTraceAddresses( internal fun List.dropInitAddresses( qualifiedClassName: String, stackTrace: Array, - keepLast: Boolean = false + keepLast: Boolean = false, ): List { val exceptionInit = "kfun:$qualifiedClassName#" var dropCount = 0 @@ -72,9 +75,7 @@ internal fun List.dropInitAddresses( /** * Returns a list containing all addresses expect for the last addresses that match with the [commonAddresses]. */ -internal fun List.dropCommonAddresses( - commonAddresses: List -): List { +internal fun List.dropCommonAddresses(commonAddresses: List): List { var i = commonAddresses.size if (i == 0) return this diff --git a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.apple.kt b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.apple.kt index 9f054bfee..98f2884cf 100644 --- a/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.apple.kt @@ -2,8 +2,9 @@ package io.sentry.kotlin.multiplatform.protocol import io.sentry.kotlin.multiplatform.CocoaSentryId -public actual data class SentryId actual constructor(val sentryIdString: String) { - +public actual data class SentryId actual constructor( + val sentryIdString: String, +) { public actual companion object { public actual val EMPTY_ID: SentryId = SentryId("") } @@ -11,14 +12,13 @@ public actual data class SentryId actual constructor(val sentryIdString: String) private var cocoaSentryId: CocoaSentryId? = null init { - cocoaSentryId = if (sentryIdString.isEmpty()) { - CocoaSentryId.empty() - } else { - CocoaSentryId(sentryIdString) - } + cocoaSentryId = + if (sentryIdString.isEmpty()) { + CocoaSentryId.empty() + } else { + CocoaSentryId(sentryIdString) + } } - actual override fun toString(): String { - return cocoaSentryId.toString() - } + actual override fun toString(): String = cocoaSentryId.toString() } diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/AppleSentryIdTest.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/AppleSentryIdTest.kt index 9601553be..c2a056b95 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/AppleSentryIdTest.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/AppleSentryIdTest.kt @@ -5,7 +5,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class AppleSentryIdTest { - @Test fun `Cocoa SentryId with invalid uuid string returns only zeroes`() { val uuidString = "ec720-b6f6-4efc--5c1" diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/ApplyKmpEventTest.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/ApplyKmpEventTest.kt index c0f92c77e..47120637f 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/ApplyKmpEventTest.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/ApplyKmpEventTest.kt @@ -7,12 +7,14 @@ import kotlin.test.assertEquals class ApplyKmpEventTest { @Test fun `native release is not set if kmp release has same value`() { - val nativeEvent = FakeSentryEvent().apply { - releaseName = "1.0.0" - } - val kmpEvent = SentryEvent().apply { - release = "1.0.0" - } + val nativeEvent = + FakeSentryEvent().apply { + releaseName = "1.0.0" + } + val kmpEvent = + SentryEvent().apply { + release = "1.0.0" + } nativeEvent.applyKmpEvent(kmpEvent) @@ -21,12 +23,14 @@ class ApplyKmpEventTest { @Test fun `native dist is not set if kmp dist has same value`() { - val nativeEvent = FakeSentryEvent().apply { - dist = "randomDist" - } - val kmpEvent = SentryEvent().apply { - dist = "randomDist" - } + val nativeEvent = + FakeSentryEvent().apply { + dist = "randomDist" + } + val kmpEvent = + SentryEvent().apply { + dist = "randomDist" + } nativeEvent.applyKmpEvent(kmpEvent) @@ -35,12 +39,14 @@ class ApplyKmpEventTest { @Test fun `native release is set if kmp release has different value`() { - val nativeEvent = FakeSentryEvent().apply { - releaseName = "1.0.0" - } - val kmpEvent = SentryEvent().apply { - release = "7.0.0" - } + val nativeEvent = + FakeSentryEvent().apply { + releaseName = "1.0.0" + } + val kmpEvent = + SentryEvent().apply { + release = "7.0.0" + } nativeEvent.applyKmpEvent(kmpEvent) @@ -49,12 +55,14 @@ class ApplyKmpEventTest { @Test fun `native dist is set if kmp dist has different value`() { - val nativeEvent = FakeSentryEvent().apply { - dist = "randomDist" - } - val kmpEvent = SentryEvent().apply { - dist = "differentDist" - } + val nativeEvent = + FakeSentryEvent().apply { + dist = "randomDist" + } + val kmpEvent = + SentryEvent().apply { + dist = "differentDist" + } nativeEvent.applyKmpEvent(kmpEvent) diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt index 3fdcc19e0..49faa3fcd 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt @@ -3,6 +3,7 @@ package io.sentry.kotlin.multiplatform actual abstract class BaseSentryTest { actual val platform: String = "Apple" actual val authToken: String? = "fake-auth-token" + actual fun sentryInit(optionsConfiguration: OptionsConfiguration) { Sentry.init(optionsConfiguration) } diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt index 906f89fd9..bc10c9cf6 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt @@ -4,25 +4,16 @@ import io.sentry.kotlin.multiplatform.extensions.toCocoaBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toKmpSentryLevel import io.sentry.kotlin.multiplatform.protocol.Breadcrumb -actual data class BreadcrumbTestConverter actual constructor(val breadcrumb: Breadcrumb) { +actual data class BreadcrumbTestConverter actual constructor( + val breadcrumb: Breadcrumb, +) { + actual fun getType(): String? = breadcrumb.toCocoaBreadcrumb().type - actual fun getType(): String? { - return breadcrumb.toCocoaBreadcrumb().type - } + actual fun getCategory(): String? = breadcrumb.toCocoaBreadcrumb().category - actual fun getCategory(): String? { - return breadcrumb.toCocoaBreadcrumb().category - } + actual fun getMessage(): String? = breadcrumb.toCocoaBreadcrumb().message - actual fun getMessage(): String? { - return breadcrumb.toCocoaBreadcrumb().message - } + actual fun getData(): MutableMap = breadcrumb.toCocoaBreadcrumb().data as MutableMap - actual fun getData(): MutableMap { - return breadcrumb.toCocoaBreadcrumb().data as MutableMap - } - - actual fun getLevel(): SentryLevel? { - return breadcrumb.toCocoaBreadcrumb().level.toKmpSentryLevel() - } + actual fun getLevel(): SentryLevel? = breadcrumb.toCocoaBreadcrumb().level.toKmpSentryLevel() } diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.apple.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.apple.kt index e772fbefb..eab1cdb7b 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.apple.kt @@ -11,8 +11,9 @@ actual interface PlatformOptions : CommonPlatformOptions { val enableUnhandledCppExceptionMonitoring: Boolean } -open class SentryAppleOptionsWrapper(private val cocoaOptions: CocoaSentryOptions) : - PlatformOptions { +open class SentryAppleOptionsWrapper( + private val cocoaOptions: CocoaSentryOptions, +) : PlatformOptions { private var cachedEnableUnhandledCppExceptionMonitoring = true override val dsn: String? @@ -94,7 +95,8 @@ actual fun PlatformOptions.assertPlatformSpecificOptions(kmpOptions: SentryOptio assertEquals(appleOptions.enableUnhandledCppExceptionMonitoring, kmpOptions.enableUnhandledCppExceptionMonitoring) } -actual fun createSentryPlatformOptionsConfiguration(): PlatformOptionsConfiguration = { - val cocoaOptions = it as CocoaSentryOptions - cocoaOptions.dsn = fakeDsn -} +actual fun createSentryPlatformOptionsConfiguration(): PlatformOptionsConfiguration = + { + val cocoaOptions = it as CocoaSentryOptions + cocoaOptions.dsn = fakeDsn + } diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesConversionTest.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesConversionTest.kt index 578b634b5..3f8c8d60a 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesConversionTest.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesConversionTest.kt @@ -4,6 +4,5 @@ import io.sentry.kotlin.multiplatform.log.toCocoaMap class SentryAttributesConversionTest : BaseSentryAttributesConversionTest() { @Suppress("UNCHECKED_CAST") - override fun SentryAttributes.toMap(): Map = - toCocoaMap() as Map + override fun SentryAttributes.toMap(): Map = toCocoaMap() as Map } diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.apple.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.apple.kt index c6b2ebffa..18e546fbe 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.apple.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.apple.kt @@ -65,9 +65,11 @@ actual class SentryBridgeTest { } // WHEN - val option = SentryPlatformOptions().apply { - fixture.sentryInstance.lastConfiguration?.invoke(this) - }.let { it as CocoaSentryOptions } + val option = + SentryPlatformOptions() + .apply { + fixture.sentryInstance.lastConfiguration?.invoke(this) + }.let { it as CocoaSentryOptions } // THEN assert(option.beforeSend != null) @@ -80,9 +82,11 @@ actual class SentryBridgeTest { fixture.sut.init { } // WHEN - val option = SentryPlatformOptions().apply { - fixture.sentryInstance.lastConfiguration?.invoke(this) - }.let { it as CocoaSentryOptions } + val option = + SentryPlatformOptions() + .apply { + fixture.sentryInstance.lastConfiguration?.invoke(this) + }.let { it as CocoaSentryOptions } // THEN assert(option.beforeSend != null) @@ -93,10 +97,12 @@ actual class SentryBridgeTest { actual fun `default beforeSend in init does not drop the event after prepareForInit`() { fixture.sut.init { } - val option = SentryPlatformOptions().apply { - fixture.sentryInstance.lastConfiguration?.invoke(this) - prepareForInit() - }.let { it as CocoaSentryOptions } + val option = + SentryPlatformOptions() + .apply { + fixture.sentryInstance.lastConfiguration?.invoke(this) + prepareForInit() + }.let { it as CocoaSentryOptions } assert(option.beforeSend != null) assert(option.beforeSend!!.invoke(CocoaSentryEvent()) != null) @@ -108,9 +114,11 @@ actual class SentryBridgeTest { fixture.sut.init { } // WHEN - val option = SentryPlatformOptions().apply { - fixture.sentryInstance.lastConfiguration?.invoke(this) - }.let { it as CocoaSentryOptions } + val option = + SentryPlatformOptions() + .apply { + fixture.sentryInstance.lastConfiguration?.invoke(this) + }.let { it as CocoaSentryOptions } val event = option.beforeSend!!.invoke(CocoaSentryEvent()) val packages = event?.sdk()?.get("packages") as? List> diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryExceptionTest.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryExceptionTest.kt index fbcf20372..56b4521be 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryExceptionTest.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryExceptionTest.kt @@ -11,46 +11,47 @@ class SentryExceptionTest { private val type = "type" private val threadId = 1 - private fun getCocoaSentryException(): CocoaSentryException { - return CocoaSentryException(value = value, type = type) - } + private fun getCocoaSentryException(): CocoaSentryException = CocoaSentryException(value = value, type = type) - private fun getKmpSentryException(threadId: Long? = this.threadId.toLong()): SentryException { - return SentryException(value = value, type = type, threadId = threadId) - } + private fun getKmpSentryException(threadId: Long? = this.threadId.toLong()): SentryException = + SentryException(value = value, type = type, threadId = threadId) @Test fun `SentryException ThreadId NSNumber long conversion`() { - val cocoaSentryException = getCocoaSentryException().apply { - threadId = NSNumber(long = this@SentryExceptionTest.threadId.convert()) - } + val cocoaSentryException = + getCocoaSentryException().apply { + threadId = NSNumber(long = this@SentryExceptionTest.threadId.convert()) + } val sentryException = getKmpSentryException() assert(cocoaSentryException.toKmpSentryException() == sentryException) } @Test fun `SentryException ThreadId NSNumber longLong conversion`() { - val cocoaSentryException = getCocoaSentryException().apply { - threadId = NSNumber(longLong = this@SentryExceptionTest.threadId.convert()) - } + val cocoaSentryException = + getCocoaSentryException().apply { + threadId = NSNumber(longLong = this@SentryExceptionTest.threadId.convert()) + } val sentryException = getKmpSentryException() assert(cocoaSentryException.toKmpSentryException() == sentryException) } @Test fun `SentryException ThreadId NSNumber int conversion`() { - val cocoaSentryException = getCocoaSentryException().apply { - threadId = NSNumber(int = this@SentryExceptionTest.threadId.convert()) - } + val cocoaSentryException = + getCocoaSentryException().apply { + threadId = NSNumber(int = this@SentryExceptionTest.threadId.convert()) + } val sentryException = getKmpSentryException() assert(cocoaSentryException.toKmpSentryException() == sentryException) } @Test fun `SentryException ThreadId NSNumber short conversion`() { - val cocoaSentryException = getCocoaSentryException().apply { - threadId = NSNumber(short = this@SentryExceptionTest.threadId.convert()) - } + val cocoaSentryException = + getCocoaSentryException().apply { + threadId = NSNumber(short = this@SentryExceptionTest.threadId.convert()) + } val sentryException = getKmpSentryException() assert(cocoaSentryException.toKmpSentryException() == sentryException) } diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt index 10ffa1217..c43e300ef 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt @@ -4,7 +4,5 @@ import io.sentry.kotlin.multiplatform.extensions.toCocoaSentryLevel import io.sentry.kotlin.multiplatform.extensions.toKmpSentryLevel actual class SentryLevelTestConverter actual constructor() { - actual fun convert(sentryLevel: SentryLevel?): SentryLevel? { - return sentryLevel?.toCocoaSentryLevel()?.toKmpSentryLevel() - } + actual fun convert(sentryLevel: SentryLevel?): SentryLevel? = sentryLevel?.toCocoaSentryLevel()?.toKmpSentryLevel() } diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackExtensionsTest.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackExtensionsTest.kt index cbdb5f33d..e8ae58fbd 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackExtensionsTest.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackExtensionsTest.kt @@ -7,14 +7,14 @@ import kotlin.test.Test import kotlin.test.assertEquals class UserFeedbackExtensionsTest { - private val sentryIdString = "dcebada57d794590a6da3d1977eed58a" @Test fun `toCocoaUserFeedback correctly maps comments`() { - val userFeedback = UserFeedback(SentryId(sentryIdString)).apply { - comments = "Test comment" - } + val userFeedback = + UserFeedback(SentryId(sentryIdString)).apply { + comments = "Test comment" + } val cocoaUserFeedback = userFeedback.toCocoaUserFeedback() @@ -23,9 +23,10 @@ class UserFeedbackExtensionsTest { @Test fun `toCocoaUserFeedback correctly maps email`() { - val userFeedback = UserFeedback(SentryId(sentryIdString)).apply { - email = "test@email.com" - } + val userFeedback = + UserFeedback(SentryId(sentryIdString)).apply { + email = "test@email.com" + } val cocoaUserFeedback = userFeedback.toCocoaUserFeedback() @@ -34,9 +35,10 @@ class UserFeedbackExtensionsTest { @Test fun `toCocoaUserFeedback correctly maps name`() { - val userFeedback = UserFeedback(SentryId(sentryIdString)).apply { - name = "John Doe" - } + val userFeedback = + UserFeedback(SentryId(sentryIdString)).apply { + name = "John Doe" + } val cocoaUserFeedback = userFeedback.toCocoaUserFeedback() @@ -78,11 +80,12 @@ class UserFeedbackExtensionsTest { @Test fun `toCocoaUserFeedback maps all properties correctly`() { - val userFeedback = UserFeedback(SentryId(sentryIdString)).apply { - name = "John Doe" - email = "john@doe.com" - comments = "I had an error" - } + val userFeedback = + UserFeedback(SentryId(sentryIdString)).apply { + name = "John Doe" + email = "john@doe.com" + comments = "I had an error" + } val cocoaUserFeedback = userFeedback.toCocoaUserFeedback() diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/InitAddressesTests.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/InitAddressesTests.kt index a5a81db20..ae989f8e9 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/InitAddressesTests.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/InitAddressesTests.kt @@ -18,17 +18,17 @@ import kotlin.test.Test import kotlin.test.assertEquals class InitAddressesTests { - private val qualifiedClassName = "my.app.CustomException" private val addresses = listOf(0, 1, 2, 3, 4, 5) - private val stackTrace = arrayOf( - "123 kfun:kotlin.Throwable#(kotlin.String?){} + 24 abc", - "456 kfun:kotlin.Exception#(kotlin.String?){} + 5 def", - "789 kfun:my.app.CustomException#(kotlin.String?){} + 10 hij", - "012 kfun:my.app.CustomException#(){} + 12 klm", - "345 kfun:my.app.class#function1(){} + 50 nop", - "678 kfun:my.app.class#function2(){} + 60 qrs" - ) + private val stackTrace = + arrayOf( + "123 kfun:kotlin.Throwable#(kotlin.String?){} + 24 abc", + "456 kfun:kotlin.Exception#(kotlin.String?){} + 5 def", + "789 kfun:my.app.CustomException#(kotlin.String?){} + 10 hij", + "012 kfun:my.app.CustomException#(){} + 12 klm", + "345 kfun:my.app.class#function1(){} + 50 nop", + "678 kfun:my.app.class#function2(){} + 60 qrs", + ) @Test fun testDropInit() { diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableCausesTests.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableCausesTests.kt index cce236bb8..9610f75b9 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableCausesTests.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableCausesTests.kt @@ -18,7 +18,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class ThrowableCausesTests { - @Test fun testNoCauses() { assert(Throwable().causes.isEmpty()) @@ -39,7 +38,9 @@ class ThrowableCausesTests { assertEquals(listOf(cause2, cause1), throwable.causes) } - private class MyThrowable(override val message: String?) : Throwable() { + private class MyThrowable( + override val message: String?, + ) : Throwable() { override var cause: Throwable? = null } diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableNameTests.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableNameTests.kt index 2caeda5c3..3211bd854 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableNameTests.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableNameTests.kt @@ -18,7 +18,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class ThrowableNameTests { - private class MyThrowable : Throwable() @Test diff --git a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableReasonTests.kt b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableReasonTests.kt index d7cb9f90f..c1801c86d 100644 --- a/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableReasonTests.kt +++ b/sentry-kotlin-multiplatform/src/appleTest/kotlin/io/sentry/kotlin/multiplatform/nsexception/ThrowableReasonTests.kt @@ -18,8 +18,10 @@ import kotlin.test.Test import kotlin.test.assertEquals class ThrowableReasonTests { - - private fun testReasonNoCause(message: String?, appendCausedBy: Boolean) { + private fun testReasonNoCause( + message: String?, + appendCausedBy: Boolean, + ) { val exception = Exception(message) val reason = exception.getReason(appendCausedBy) assertEquals(message, reason) @@ -56,7 +58,7 @@ class ThrowableReasonTests { Test message Caused by: kotlin.Exception: Cause message """.trimIndent(), - reason + reason, ) } @@ -69,7 +71,7 @@ class ThrowableReasonTests { """ Caused by: kotlin.Exception: Cause message """.trimIndent(), - reason + reason, ) } @@ -82,7 +84,7 @@ class ThrowableReasonTests { Test message Caused by: kotlin.Exception """.trimIndent(), - reason + reason, ) } @@ -98,7 +100,7 @@ class ThrowableReasonTests { Caused by: kotlin.Exception: Cause2 message Caused by: kotlin.Exception: Cause1 message """.trimIndent(), - reason + reason, ) } } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.jvm.kt index 3fd4131f0..7dd8a3539 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.jvm.kt @@ -1,7 +1,6 @@ package io.sentry.kotlin.multiplatform public actual class Attachment { - internal var jvmAttachment: JvmAttachment public actual val filename: String @@ -17,9 +16,8 @@ public actual class Attachment { get() = jvmAttachment.contentType public actual companion object { - public actual fun fromScreenshot(screenshotBytes: ByteArray): Attachment { - return Attachment(screenshotBytes, "screenshot.png", "image/png") - } + public actual fun fromScreenshot(screenshotBytes: ByteArray): Attachment = + Attachment(screenshotBytes, "screenshot.png", "image/png") } public actual constructor(pathname: String) { diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmScopeProvider.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmScopeProvider.kt index 766cf9c7f..27c03b057 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmScopeProvider.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/JvmScopeProvider.kt @@ -9,8 +9,9 @@ import io.sentry.kotlin.multiplatform.extensions.toMap import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.User -internal class JvmScopeProvider(private val scope: JvmIScope) : Scope { - +internal class JvmScopeProvider( + private val scope: JvmIScope, +) : Scope { override var level: SentryLevel? set(value) { scope.level = value?.toJvmSentryLevel() @@ -31,13 +32,9 @@ internal class JvmScopeProvider(private val scope: JvmIScope) : Scope { scope.clearAttachments() } - override fun getContexts(): MutableMap { - return scope.contexts.toMap().toMutableMap() - } + override fun getContexts(): MutableMap = scope.contexts.toMap().toMutableMap() - override fun getTags(): MutableMap { - return scope.tags - } + override fun getTags(): MutableMap = scope.tags override fun addBreadcrumb(breadcrumb: Breadcrumb) { scope.addBreadcrumb(breadcrumb.toJvmBreadcrumb()) @@ -47,31 +44,52 @@ internal class JvmScopeProvider(private val scope: JvmIScope) : Scope { scope.clearBreadcrumbs() } - override fun setContext(key: String, value: Any) { + override fun setContext( + key: String, + value: Any, + ) { scope.setContexts(key, value) } - override fun setContext(key: String, value: Boolean) { + override fun setContext( + key: String, + value: Boolean, + ) { scope.setContexts(key, value) } - override fun setContext(key: String, value: String) { + override fun setContext( + key: String, + value: String, + ) { scope.setContexts(key, value) } - override fun setContext(key: String, value: Number) { + override fun setContext( + key: String, + value: Number, + ) { scope.setContexts(key, value) } - override fun setContext(key: String, value: Collection<*>) { + override fun setContext( + key: String, + value: Collection<*>, + ) { scope.setContexts(key, value) } - override fun setContext(key: String, value: Array<*>) { + override fun setContext( + key: String, + value: Array<*>, + ) { scope.setContexts(key, value as Array) } - override fun setContext(key: String, value: Char) { + override fun setContext( + key: String, + value: Char, + ) { scope.setContexts(key, value) } @@ -79,7 +97,10 @@ internal class JvmScopeProvider(private val scope: JvmIScope) : Scope { scope.removeContexts(key) } - override fun setTag(key: String, value: String) { + override fun setTag( + key: String, + value: String, + ) { scope.setTag(key, value) } @@ -87,7 +108,10 @@ internal class JvmScopeProvider(private val scope: JvmIScope) : Scope { scope.removeTag(key) } - override fun setExtra(key: String, value: String) { + override fun setExtra( + key: String, + value: String, + ) { scope.setExtra(key, value) } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.commonJvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.commonJvm.kt index e8a0f8f13..c10b32f90 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.commonJvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.commonJvm.kt @@ -13,10 +13,15 @@ import io.sentry.kotlin.multiplatform.protocol.UserFeedback internal expect fun SentryPlatformOptions.prepareForInitBridge() -internal actual class SentryBridge actual constructor(private val sentryInstance: SentryInstance) { +internal actual class SentryBridge actual constructor( + private val sentryInstance: SentryInstance, +) { private val logger = JvmSentryLoggerAdapter(Sentry::logger) - actual fun init(context: Context, configuration: OptionsConfiguration) { + actual fun init( + context: Context, + configuration: OptionsConfiguration, + ) { init(configuration) } @@ -39,7 +44,10 @@ internal actual class SentryBridge actual constructor(private val sentryInstance return SentryId(jvmSentryId.toString()) } - actual fun captureMessage(message: String, scopeCallback: ScopeCallback): SentryId { + actual fun captureMessage( + message: String, + scopeCallback: ScopeCallback, + ): SentryId { val jvmSentryId = Sentry.captureMessage(message, configureScopeCallback(scopeCallback)) return SentryId(jvmSentryId.toString()) } @@ -49,7 +57,10 @@ internal actual class SentryBridge actual constructor(private val sentryInstance return SentryId(jvmSentryId.toString()) } - actual fun captureException(throwable: Throwable, scopeCallback: ScopeCallback): SentryId { + actual fun captureException( + throwable: Throwable, + scopeCallback: ScopeCallback, + ): SentryId { val jvmSentryId = Sentry.captureException(throwable, configureScopeCallback(scopeCallback)) return SentryId(jvmSentryId.toString()) @@ -71,26 +82,19 @@ internal actual class SentryBridge actual constructor(private val sentryInstance Sentry.setUser(user?.toJvmUser()) } - actual fun logger(): SentryLogger { - return logger - } + actual fun logger(): SentryLogger = logger - actual fun isCrashedLastRun(): Boolean { - return Sentry.isCrashedLastRun() ?: false - } + actual fun isCrashedLastRun(): Boolean = Sentry.isCrashedLastRun() ?: false - actual fun isEnabled(): Boolean { - return Sentry.isEnabled() - } + actual fun isEnabled(): Boolean = Sentry.isEnabled() actual fun close() { Sentry.close() } - private fun configureScopeCallback(scopeCallback: ScopeCallback): (JvmIScope) -> Unit { - return { + private fun configureScopeCallback(scopeCallback: ScopeCallback): (JvmIScope) -> Unit = + { val jvmScopeProvider = JvmScopeProvider(it) scopeCallback.invoke(jvmScopeProvider) } - } } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/BreadcrumbExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/BreadcrumbExtensions.jvm.kt index b8f18cdbe..f15a147b0 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/BreadcrumbExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/BreadcrumbExtensions.jvm.kt @@ -3,22 +3,24 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.JvmBreadcrumb import io.sentry.kotlin.multiplatform.protocol.Breadcrumb -internal fun Breadcrumb.toJvmBreadcrumb() = JvmBreadcrumb().apply { - val scope = this@toJvmBreadcrumb - message = scope.message - type = scope.type - category = scope.category - scope.getData()?.forEach { - setData(it.key, it.value) +internal fun Breadcrumb.toJvmBreadcrumb() = + JvmBreadcrumb().apply { + val scope = this@toJvmBreadcrumb + message = scope.message + type = scope.type + category = scope.category + scope.getData()?.forEach { + setData(it.key, it.value) + } + level = scope.level?.toJvmSentryLevel() } - level = scope.level?.toJvmSentryLevel() -} -internal fun JvmBreadcrumb.toKmpBreadcrumb() = Breadcrumb().apply { - val scope = this@toKmpBreadcrumb - message = scope.message - type = scope.type - category = scope.category - setData(scope.data.toMutableMap()) - level = scope.level?.toKmpSentryLevel() -} +internal fun JvmBreadcrumb.toKmpBreadcrumb() = + Breadcrumb().apply { + val scope = this@toKmpBreadcrumb + message = scope.message + type = scope.type + category = scope.category + setData(scope.data.toMutableMap()) + level = scope.level?.toKmpSentryLevel() + } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/MessageExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/MessageExtensions.jvm.kt index 07c5d7c5c..f9c6ef16a 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/MessageExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/MessageExtensions.jvm.kt @@ -3,15 +3,17 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.JvmMessage import io.sentry.kotlin.multiplatform.protocol.Message -internal fun JvmMessage.toKmpMessage() = Message( - message = message, - params = params, - formatted = formatted -) +internal fun JvmMessage.toKmpMessage() = + Message( + message = message, + params = params, + formatted = formatted, + ) -internal fun Message.toJvmMessage() = JvmMessage().apply { - val scope = this@toJvmMessage - message = scope.message - params = scope.params - formatted = scope.formatted -} +internal fun Message.toJvmMessage() = + JvmMessage().apply { + val scope = this@toJvmMessage + message = scope.message + params = scope.params + formatted = scope.formatted + } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryExceptionExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryExceptionExtensions.jvm.kt index 7fdfcef2d..278171a76 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryExceptionExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryExceptionExtensions.jvm.kt @@ -3,9 +3,10 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.JvmSentryException import io.sentry.kotlin.multiplatform.protocol.SentryException -internal fun JvmSentryException.toKmpSentryException() = SentryException( - type = type, - value = value, - module = module, - threadId = threadId -) +internal fun JvmSentryException.toKmpSentryException() = + SentryException( + type = type, + value = value, + module = module, + threadId = threadId, + ) diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryLevelExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryLevelExtensions.jvm.kt index eb039a06c..7ac792621 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryLevelExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryLevelExtensions.jvm.kt @@ -3,22 +3,20 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.JvmSentryLevel import io.sentry.kotlin.multiplatform.SentryLevel -internal fun SentryLevel.toJvmSentryLevel(): JvmSentryLevel? { - return when (this) { +internal fun SentryLevel.toJvmSentryLevel(): JvmSentryLevel? = + when (this) { SentryLevel.DEBUG -> JvmSentryLevel.DEBUG SentryLevel.INFO -> JvmSentryLevel.INFO SentryLevel.WARNING -> JvmSentryLevel.WARNING SentryLevel.ERROR -> JvmSentryLevel.ERROR SentryLevel.FATAL -> JvmSentryLevel.FATAL } -} -internal fun JvmSentryLevel.toKmpSentryLevel(): SentryLevel? { - return when (this) { +internal fun JvmSentryLevel.toKmpSentryLevel(): SentryLevel? = + when (this) { JvmSentryLevel.DEBUG -> SentryLevel.DEBUG JvmSentryLevel.INFO -> SentryLevel.INFO JvmSentryLevel.WARNING -> SentryLevel.WARNING JvmSentryLevel.ERROR -> SentryLevel.ERROR JvmSentryLevel.FATAL -> SentryLevel.FATAL } -} diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt index f3025ed2b..345265651 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.jvm.kt @@ -6,13 +6,14 @@ import io.sentry.kotlin.multiplatform.SentryOptions import io.sentry.kotlin.multiplatform.log.toKmpSentryLog import io.sentry.kotlin.multiplatform.log.updateFrom -internal fun SentryOptions.toJvmSentryOptionsCallback(): (JvmSentryOptions) -> Unit = { - it.applyJvmBaseOptions(this) +internal fun SentryOptions.toJvmSentryOptionsCallback(): (JvmSentryOptions) -> Unit = + { + it.applyJvmBaseOptions(this) - sdk?.packages?.forEach { sdkPackage -> - it.sdkVersion?.addPackage(sdkPackage.name, sdkPackage.version) + sdk?.packages?.forEach { sdkPackage -> + it.sdkVersion?.addPackage(sdkPackage.name, sdkPackage.version) + } } -} /** * Applies the given base SentryOptions to this JvmSentryOption diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/UserExtensions.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/UserExtensions.jvm.kt index 49f31208e..96a362c44 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/UserExtensions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/extensions/UserExtensions.jvm.kt @@ -3,22 +3,24 @@ package io.sentry.kotlin.multiplatform.extensions import io.sentry.kotlin.multiplatform.JvmUser import io.sentry.kotlin.multiplatform.protocol.User -internal fun User.toJvmUser() = JvmUser().apply { - val scope = this@toJvmUser - id = scope.id - username = scope.username - email = scope.email - ipAddress = scope.ipAddress - data = scope.other?.toMutableMap() - unknown = scope.unknown?.toMutableMap() -} +internal fun User.toJvmUser() = + JvmUser().apply { + val scope = this@toJvmUser + id = scope.id + username = scope.username + email = scope.email + ipAddress = scope.ipAddress + data = scope.other?.toMutableMap() + unknown = scope.unknown?.toMutableMap() + } -internal fun JvmUser.toKmpUser() = User().apply { - val scope = this@toKmpUser - id = scope.id - username = scope.username - email = scope.email - ipAddress = scope.ipAddress - other = scope.data?.toMutableMap() - unknown = scope.unknown?.toMutableMap() -} +internal fun JvmUser.toKmpUser() = + User().apply { + val scope = this@toKmpUser + id = scope.id + username = scope.username + email = scope.email + ipAddress = scope.ipAddress + other = scope.data?.toMutableMap() + unknown = scope.unknown?.toMutableMap() + } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/log/JvmSentryLoggerAdapter.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/log/JvmSentryLoggerAdapter.kt index e4d58e656..cf3e08fb6 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/log/JvmSentryLoggerAdapter.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/log/JvmSentryLoggerAdapter.kt @@ -11,9 +11,12 @@ import io.sentry.logger.SentryLogParameters */ internal class JvmSentryLoggerAdapter( private val jvmLoggerProvider: () -> ILoggerApi, - logBuilderFactory: SentryLogBuilderFactory = DefaultSentryLogBuilderFactory + logBuilderFactory: SentryLogBuilderFactory = DefaultSentryLogBuilderFactory, ) : BaseSentryLogger(logBuilderFactory) { - override fun sendLog(level: SentryLogLevel, formatted: FormattedLog) { + override fun sendLog( + level: SentryLogLevel, + formatted: FormattedLog, + ) { val jvmLogger = jvmLoggerProvider() val jvmLevel = level.toJvmSentryLogLevel() if (formatted.attributes.isEmpty()) { diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogConverters.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogConverters.jvm.kt index 38934f853..2d22113ae 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogConverters.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogConverters.jvm.kt @@ -11,26 +11,28 @@ import io.sentry.kotlin.multiplatform.SentryAttributes as KmpSentryAttributes /** * Converts KMP [SentryLogLevel] to Java SDK's [JvmSentryLogLevel]. */ -internal fun SentryLogLevel.toJvmSentryLogLevel(): JvmSentryLogLevel = when (this) { - SentryLogLevel.TRACE -> JvmSentryLogLevel.TRACE - SentryLogLevel.DEBUG -> JvmSentryLogLevel.DEBUG - SentryLogLevel.INFO -> JvmSentryLogLevel.INFO - SentryLogLevel.WARN -> JvmSentryLogLevel.WARN - SentryLogLevel.ERROR -> JvmSentryLogLevel.ERROR - SentryLogLevel.FATAL -> JvmSentryLogLevel.FATAL -} +internal fun SentryLogLevel.toJvmSentryLogLevel(): JvmSentryLogLevel = + when (this) { + SentryLogLevel.TRACE -> JvmSentryLogLevel.TRACE + SentryLogLevel.DEBUG -> JvmSentryLogLevel.DEBUG + SentryLogLevel.INFO -> JvmSentryLogLevel.INFO + SentryLogLevel.WARN -> JvmSentryLogLevel.WARN + SentryLogLevel.ERROR -> JvmSentryLogLevel.ERROR + SentryLogLevel.FATAL -> JvmSentryLogLevel.FATAL + } /** * Converts Java SDK's [JvmSentryLogLevel] to KMP [SentryLogLevel]. */ -internal fun JvmSentryLogLevel.toKmpSentryLogLevel(): SentryLogLevel = when (this) { - JvmSentryLogLevel.TRACE -> SentryLogLevel.TRACE - JvmSentryLogLevel.DEBUG -> SentryLogLevel.DEBUG - JvmSentryLogLevel.INFO -> SentryLogLevel.INFO - JvmSentryLogLevel.WARN -> SentryLogLevel.WARN - JvmSentryLogLevel.ERROR -> SentryLogLevel.ERROR - JvmSentryLogLevel.FATAL -> SentryLogLevel.FATAL -} +internal fun JvmSentryLogLevel.toKmpSentryLogLevel(): SentryLogLevel = + when (this) { + JvmSentryLogLevel.TRACE -> SentryLogLevel.TRACE + JvmSentryLogLevel.DEBUG -> SentryLogLevel.DEBUG + JvmSentryLogLevel.INFO -> SentryLogLevel.INFO + JvmSentryLogLevel.WARN -> SentryLogLevel.WARN + JvmSentryLogLevel.ERROR -> SentryLogLevel.ERROR + JvmSentryLogLevel.FATAL -> SentryLogLevel.FATAL + } /** * Converts KMP [KmpSentryAttributes] to Java SDK's [JvmSentryAttributes]. @@ -48,20 +50,24 @@ internal fun KmpSentryAttributes.toJvmSentryAttributes(): JvmSentryAttributes { * Converts a JVM SentryLog to a KMP SentryLog for use in beforeSendLog callback. * After the callback, changes are applied back via [updateFrom]. */ -internal fun JvmSentryLog.toKmpSentryLog(): SentryLog = SentryLog( - timestamp = timestamp, - level = level.toKmpSentryLogLevel(), - body = body, - severityNumber = severityNumber, - attributes = toKmpSentryAttributes() -) +internal fun JvmSentryLog.toKmpSentryLog(): SentryLog = + SentryLog( + timestamp = timestamp, + level = level.toKmpSentryLogLevel(), + body = body, + severityNumber = severityNumber, + attributes = toKmpSentryAttributes(), + ) /** * Updates this JVM SentryLog from a KMP SentryLog. * @param kmpLog The modified KMP log after user's beforeSendLog callback. * @param originalKmpAttributes The original KMP attributes before the callback, used to detect changes. */ -internal fun JvmSentryLog.updateFrom(kmpLog: SentryLog, originalKmpAttributes: KmpSentryAttributes) { +internal fun JvmSentryLog.updateFrom( + kmpLog: SentryLog, + originalKmpAttributes: KmpSentryAttributes, +) { body = kmpLog.body level = kmpLog.level.toJvmSentryLogLevel() severityNumber = kmpLog.severityNumber @@ -95,7 +101,7 @@ private fun JvmSentryLog.toKmpSentryAttributes(): KmpSentryAttributes { */ private fun JvmSentryLog.updateAttributesFrom( modifiedKmpAttributes: KmpSentryAttributes, - originalKmpAttributes: KmpSentryAttributes + originalKmpAttributes: KmpSentryAttributes, ) { // Remove attributes that were deleted by the user (present in original but not in modified) (originalKmpAttributes.keys - modifiedKmpAttributes.keys).forEach { key -> @@ -104,12 +110,13 @@ private fun JvmSentryLog.updateAttributesFrom( // Add or update attributes from the modified KMP attributes modifiedKmpAttributes.forEach { (key, attrValue) -> - val jvmType = when (attrValue) { - is KmpSentryAttributeValue.StringValue -> JvmSentryAttributeType.STRING - is KmpSentryAttributeValue.LongValue -> JvmSentryAttributeType.INTEGER - is KmpSentryAttributeValue.DoubleValue -> JvmSentryAttributeType.DOUBLE - is KmpSentryAttributeValue.BooleanValue -> JvmSentryAttributeType.BOOLEAN - } + val jvmType = + when (attrValue) { + is KmpSentryAttributeValue.StringValue -> JvmSentryAttributeType.STRING + is KmpSentryAttributeValue.LongValue -> JvmSentryAttributeType.INTEGER + is KmpSentryAttributeValue.DoubleValue -> JvmSentryAttributeType.DOUBLE + is KmpSentryAttributeValue.BooleanValue -> JvmSentryAttributeType.BOOLEAN + } setAttribute(key, SentryLogEventAttributeValue(jvmType, attrValue.value)) } } diff --git a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.jvm.kt b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.jvm.kt index 1387710ce..a747246c7 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.jvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.jvm.kt @@ -2,8 +2,9 @@ package io.sentry.kotlin.multiplatform.protocol import io.sentry.kotlin.multiplatform.JvmSentryId -public actual data class SentryId actual constructor(val sentryIdString: String) { - +public actual data class SentryId actual constructor( + val sentryIdString: String, +) { public actual companion object { public actual val EMPTY_ID: SentryId = SentryId("") } @@ -11,14 +12,13 @@ public actual data class SentryId actual constructor(val sentryIdString: String) private var jvmSentryId: JvmSentryId? = null init { - jvmSentryId = if (sentryIdString.isEmpty()) { - JvmSentryId.EMPTY_ID - } else { - JvmSentryId(sentryIdString) - } + jvmSentryId = + if (sentryIdString.isEmpty()) { + JvmSentryId.EMPTY_ID + } else { + JvmSentryId(sentryIdString) + } } - actual override fun toString(): String { - return jvmSentryId.toString() - } + actual override fun toString(): String = jvmSentryId.toString() } diff --git a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt index a95a3e24c..2c619a662 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt @@ -4,25 +4,16 @@ import io.sentry.kotlin.multiplatform.extensions.toJvmBreadcrumb import io.sentry.kotlin.multiplatform.extensions.toKmpSentryLevel import io.sentry.kotlin.multiplatform.protocol.Breadcrumb -actual data class BreadcrumbTestConverter actual constructor(val breadcrumb: Breadcrumb) { +actual data class BreadcrumbTestConverter actual constructor( + val breadcrumb: Breadcrumb, +) { + actual fun getType(): String? = breadcrumb.toJvmBreadcrumb().type - actual fun getType(): String? { - return breadcrumb.toJvmBreadcrumb().type - } + actual fun getCategory(): String? = breadcrumb.toJvmBreadcrumb().category - actual fun getCategory(): String? { - return breadcrumb.toJvmBreadcrumb().category - } + actual fun getMessage(): String? = breadcrumb.toJvmBreadcrumb().message - actual fun getMessage(): String? { - return breadcrumb.toJvmBreadcrumb().message - } + actual fun getData(): MutableMap = breadcrumb.toJvmBreadcrumb().data - actual fun getData(): MutableMap { - return breadcrumb.toJvmBreadcrumb().data - } - - actual fun getLevel(): SentryLevel? { - return breadcrumb.toJvmBreadcrumb().level?.toKmpSentryLevel() - } + actual fun getLevel(): SentryLevel? = breadcrumb.toJvmBreadcrumb().level?.toKmpSentryLevel() } diff --git a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/JvmSentryIdTest.kt b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/JvmSentryIdTest.kt index 66b16ee3a..cff4b3438 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/JvmSentryIdTest.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/JvmSentryIdTest.kt @@ -5,7 +5,6 @@ import kotlin.test.Test import kotlin.test.assertFailsWith class JvmSentryIdTest { - @Test fun `Jvm SentryId with invalid uuid string throws IllegalArgumentException`() { val uuidString = "ec720-b6f6-4efc--5c1" diff --git a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesConversionTest.kt b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesConversionTest.kt index b1b978854..82c291267 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesConversionTest.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesConversionTest.kt @@ -4,6 +4,5 @@ import io.sentry.kotlin.multiplatform.log.toJvmSentryAttributes /** Tests for SentryAttributes to JVM conversion. */ class SentryAttributesConversionTest : BaseSentryAttributesConversionTest() { - override fun SentryAttributes.toMap(): Map = - toJvmSentryAttributes().attributes.mapValues { it.value.value } + override fun SentryAttributes.toMap(): Map = toJvmSentryAttributes().attributes.mapValues { it.value.value } } diff --git a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.commonJvm.kt b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.commonJvm.kt index 0d08dbbf8..3b2936856 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.commonJvm.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.commonJvm.kt @@ -49,9 +49,11 @@ actual class SentryBridgeTest { } // WHEN - val option = SentryPlatformOptions().apply { - fixture.sentryInstance.lastConfiguration?.invoke(this) - }.let { it as JvmSentryOptions } + val option = + SentryPlatformOptions() + .apply { + fixture.sentryInstance.lastConfiguration?.invoke(this) + }.let { it as JvmSentryOptions } // THEN assert(option.beforeSend != null) @@ -64,9 +66,11 @@ actual class SentryBridgeTest { fixture.sut.init { } // WHEN - val option = SentryPlatformOptions().apply { - fixture.sentryInstance.lastConfiguration?.invoke(this) - }.let { it as JvmSentryOptions } + val option = + SentryPlatformOptions() + .apply { + fixture.sentryInstance.lastConfiguration?.invoke(this) + }.let { it as JvmSentryOptions } // THEN assert(option.beforeSend != null) @@ -77,10 +81,12 @@ actual class SentryBridgeTest { actual fun `default beforeSend in init does not drop the event after prepareForInit`() { fixture.sut.init { } - val option = SentryPlatformOptions().apply { - fixture.sentryInstance.lastConfiguration?.invoke(this) - prepareForInit() - }.let { it as JvmSentryOptions } + val option = + SentryPlatformOptions() + .apply { + fixture.sentryInstance.lastConfiguration?.invoke(this) + prepareForInit() + }.let { it as JvmSentryOptions } assert(option.beforeSend != null) assert(option.beforeSend!!.execute(JvmSentryEvent(), Hint()) != null) @@ -90,9 +96,11 @@ actual class SentryBridgeTest { actual fun `init sets the SDK packages`() { // WHEN fixture.sut.init { } - val option = SentryPlatformOptions().apply { - fixture.sentryInstance.lastConfiguration?.invoke(this) - }.let { it as JvmSentryOptions } + val option = + SentryPlatformOptions() + .apply { + fixture.sentryInstance.lastConfiguration?.invoke(this) + }.let { it as JvmSentryOptions } // THEN assert(option.sdkVersion?.packageSet != null) @@ -110,9 +118,11 @@ actual class SentryBridgeTest { // When fixture.sut.init(configuration) - val option = SentryPlatformOptions().apply { - fixture.sentryInstance.lastConfiguration?.invoke(this) - }.let { it as JvmSentryOptions } + val option = + SentryPlatformOptions() + .apply { + fixture.sentryInstance.lastConfiguration?.invoke(this) + }.let { it as JvmSentryOptions } // Then assertTrue(option.sdkVersion!!.name.contains("kmp")) diff --git a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt index ac6fcb1f6..4f2d3e9da 100644 --- a/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt +++ b/sentry-kotlin-multiplatform/src/commonJvmTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt @@ -4,7 +4,5 @@ import io.sentry.kotlin.multiplatform.extensions.toJvmSentryLevel import io.sentry.kotlin.multiplatform.extensions.toKmpSentryLevel actual class SentryLevelTestConverter actual constructor() { - actual fun convert(sentryLevel: SentryLevel?): SentryLevel? { - return sentryLevel?.toJvmSentryLevel()?.toKmpSentryLevel() - } + actual fun convert(sentryLevel: SentryLevel?): SentryLevel? = sentryLevel?.toJvmSentryLevel()?.toKmpSentryLevel() } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt index e38013bda..4568ace79 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Attachment.kt @@ -2,7 +2,6 @@ package io.sentry.kotlin.multiplatform /** An attachment to be sent along with the event. */ public expect class Attachment { - /** The bytes of the attachment. */ public val bytes: ByteArray? diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/HttpStatusCodeRange.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/HttpStatusCodeRange.kt index 76694a979..2a22dd473 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/HttpStatusCodeRange.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/HttpStatusCodeRange.kt @@ -9,13 +9,13 @@ package io.sentry.kotlin.multiplatform * @property min the min status code of the range * @property max the max status code of the range */ -public data class HttpStatusCodeRange(val min: Int = DEFAULT_MIN, val max: Int = DEFAULT_MAX) { - +public data class HttpStatusCodeRange( + val min: Int = DEFAULT_MIN, + val max: Int = DEFAULT_MAX, +) { public constructor(statusCode: Int) : this(statusCode, statusCode) - public fun isInRange(statusCode: Int): Boolean { - return statusCode in min..max - } + public fun isInRange(statusCode: Int): Boolean = statusCode in min..max public companion object { /** The default min status code of the range. */ diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Scope.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Scope.kt index 86d540376..5a8f67b30 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Scope.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/Scope.kt @@ -13,7 +13,6 @@ import io.sentry.kotlin.multiplatform.protocol.User * - For Cocoa: [io.sentry.kotlin.multiplatform.CocoaScopeProvider] */ public interface Scope { - /** * Returns the scope's tags */ @@ -61,7 +60,10 @@ public interface Scope { * @param key the context key * @param value the context value */ - public fun setContext(key: String, value: Any) + public fun setContext( + key: String, + value: Any, + ) /** * Sets the Scope's contexts @@ -69,7 +71,10 @@ public interface Scope { * @param key the context key * @param value the context value */ - public fun setContext(key: String, value: Boolean) + public fun setContext( + key: String, + value: Boolean, + ) /** * Sets the Scope's context @@ -77,7 +82,10 @@ public interface Scope { * @param key the context key * @param value the context value */ - public fun setContext(key: String, value: String) + public fun setContext( + key: String, + value: String, + ) /** * Sets the Scope's context @@ -85,7 +93,10 @@ public interface Scope { * @param key the context key * @param value the context value */ - public fun setContext(key: String, value: Number) + public fun setContext( + key: String, + value: Number, + ) /** * Sets the Scope's context @@ -93,7 +104,10 @@ public interface Scope { * @param key the context key * @param value the context value */ - public fun setContext(key: String, value: Collection<*>) + public fun setContext( + key: String, + value: Collection<*>, + ) /** * Sets the Scope's context @@ -101,7 +115,10 @@ public interface Scope { * @param key the context key * @param value the context value */ - public fun setContext(key: String, value: Array<*>) + public fun setContext( + key: String, + value: Array<*>, + ) /** * Sets the Scope's context @@ -109,7 +126,10 @@ public interface Scope { * @param key the context key * @param value the context value */ - public fun setContext(key: String, value: Char) + public fun setContext( + key: String, + value: Char, + ) /** * Removes a value from the Scope's contexts @@ -124,7 +144,10 @@ public interface Scope { * @param key the key * @param value the value */ - public fun setTag(key: String, value: String) + public fun setTag( + key: String, + value: String, + ) /** * Removes a tag from the Scope's tags @@ -139,7 +162,10 @@ public interface Scope { * @param key the key * @param value the value */ - public fun setExtra(key: String, value: String) + public fun setExtra( + key: String, + value: String, + ) /** * Removes an extra from the Scope's extras diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryAttributeValue.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryAttributeValue.kt index 9d18d2a91..ffe7bcdcc 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryAttributeValue.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryAttributeValue.kt @@ -11,19 +11,27 @@ package io.sentry.kotlin.multiplatform */ public sealed class SentryAttributeValue( /** The underlying raw value. */ - public val value: Any + public val value: Any, ) { /** Holds a [String] attribute value. */ - public class StringValue(value: String) : SentryAttributeValue(value) + public class StringValue( + value: String, + ) : SentryAttributeValue(value) /** Holds a [Long] attribute value. */ - public class LongValue(value: Long) : SentryAttributeValue(value) + public class LongValue( + value: Long, + ) : SentryAttributeValue(value) /** Holds a [Double] attribute value. */ - public class DoubleValue(value: Double) : SentryAttributeValue(value) + public class DoubleValue( + value: Double, + ) : SentryAttributeValue(value) /** Holds a [Boolean] attribute value. */ - public class BooleanValue(value: Boolean) : SentryAttributeValue(value) + public class BooleanValue( + value: Boolean, + ) : SentryAttributeValue(value) /** Returns the String value, or null if this is not a [StringValue]. */ public val stringOrNull: String? get() = (this as? StringValue)?.value as? String diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryAttributes.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryAttributes.kt index 863057a4a..d6fe4c6c7 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryAttributes.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryAttributes.kt @@ -6,35 +6,53 @@ package io.sentry.kotlin.multiplatform * (e.g., `stringOrNull`, `longOrNull`) to extract typed values. */ public class SentryAttributes private constructor( - private val attributes: MutableMap + private val attributes: MutableMap, ) : MutableMap by attributes { /** Sets a [String] value by key. */ - public operator fun set(key: String, value: String) { + public operator fun set( + key: String, + value: String, + ) { attributes[key] = SentryAttributeValue.string(value) } /** Sets an [Int] value by key. Stored as 64-bit Long value. */ - public operator fun set(key: String, value: Int) { + public operator fun set( + key: String, + value: Int, + ) { attributes[key] = SentryAttributeValue.long(value.toLong()) } /** Sets a [Long] value by key. */ - public operator fun set(key: String, value: Long) { + public operator fun set( + key: String, + value: Long, + ) { attributes[key] = SentryAttributeValue.long(value) } /** Sets an [Float] value by key. Stored as 64-bit Double value. */ - public operator fun set(key: String, value: Float) { + public operator fun set( + key: String, + value: Float, + ) { attributes[key] = SentryAttributeValue.double(value.toDouble()) } /** Sets a [Double] value by key. */ - public operator fun set(key: String, value: Double) { + public operator fun set( + key: String, + value: Double, + ) { attributes[key] = SentryAttributeValue.double(value) } /** Sets a [Boolean] value by key. */ - public operator fun set(key: String, value: Boolean) { + public operator fun set( + key: String, + value: Boolean, + ) { attributes[key] = SentryAttributeValue.boolean(value) } @@ -46,9 +64,7 @@ public class SentryAttributes private constructor( public fun empty(): SentryAttributes = SentryAttributes(mutableMapOf()) /** Creates a [SentryAttributes] collection from the given map. */ - public fun of(attributes: Map): SentryAttributes { - return SentryAttributes(attributes.toMutableMap()) - } + public fun of(attributes: Map): SentryAttributes = SentryAttributes(attributes.toMutableMap()) /** * Creates a [SentryAttributes] collection from the given key-value pairs. diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBaseEvent.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBaseEvent.kt index 604df1c19..756f703dd 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBaseEvent.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBaseEvent.kt @@ -7,7 +7,7 @@ import io.sentry.kotlin.multiplatform.protocol.User /** Base class for all Sentry events. */ public abstract class SentryBaseEvent( /** The Sentry event ID. */ - public open var eventId: SentryId = SentryId.EMPTY_ID + public open var eventId: SentryId = SentryId.EMPTY_ID, ) { /** The event release. */ public open var release: String? = null @@ -65,7 +65,10 @@ public abstract class SentryBaseEvent( tags.remove(key) } - public fun setTag(key: String, value: String) { + public fun setTag( + key: String, + value: String, + ) { tags.set(key, value) } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt index 33648df5e..18a822b9d 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.kt @@ -6,8 +6,13 @@ import io.sentry.kotlin.multiplatform.protocol.SentryId import io.sentry.kotlin.multiplatform.protocol.User import io.sentry.kotlin.multiplatform.protocol.UserFeedback -internal expect class SentryBridge(sentryInstance: SentryInstance = SentryPlatformInstance()) { - fun init(context: Context, configuration: OptionsConfiguration) +internal expect class SentryBridge( + sentryInstance: SentryInstance = SentryPlatformInstance(), +) { + fun init( + context: Context, + configuration: OptionsConfiguration, + ) fun init(configuration: OptionsConfiguration) @@ -15,11 +20,17 @@ internal expect class SentryBridge(sentryInstance: SentryInstance = SentryPlatfo fun captureMessage(message: String): SentryId - fun captureMessage(message: String, scopeCallback: ScopeCallback): SentryId + fun captureMessage( + message: String, + scopeCallback: ScopeCallback, + ): SentryId fun captureException(throwable: Throwable): SentryId - fun captureException(throwable: Throwable, scopeCallback: ScopeCallback): SentryId + fun captureException( + throwable: Throwable, + scopeCallback: ScopeCallback, + ): SentryId fun configureScope(scopeCallback: ScopeCallback) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt index 7c346c762..1c8bfba19 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryKMP.kt @@ -30,9 +30,12 @@ public object Sentry { @HiddenFromObjC @Deprecated( "Use init(OptionsConfiguration) instead.", - ReplaceWith("Sentry.init(configuration)") + ReplaceWith("Sentry.init(configuration)"), ) - public fun init(context: Context, configuration: OptionsConfiguration) { + public fun init( + context: Context, + configuration: OptionsConfiguration, + ) { bridge.init(context, configuration) } @@ -72,9 +75,7 @@ public object Sentry { * * @param message The message to send. */ - public fun captureMessage(message: String): SentryId { - return bridge.captureMessage(message) - } + public fun captureMessage(message: String): SentryId = bridge.captureMessage(message) /** * Captures the exception. @@ -82,18 +83,17 @@ public object Sentry { * @param message The message to send. * @param scopeCallback The local scope callback. */ - public fun captureMessage(message: String, scopeCallback: ScopeCallback): SentryId { - return bridge.captureMessage(message, scopeCallback) - } + public fun captureMessage( + message: String, + scopeCallback: ScopeCallback, + ): SentryId = bridge.captureMessage(message, scopeCallback) /** * Captures the exception. * * @param throwable The exception. */ - public fun captureException(throwable: Throwable): SentryId { - return bridge.captureException(throwable) - } + public fun captureException(throwable: Throwable): SentryId = bridge.captureException(throwable) /** * Captures the exception. @@ -101,18 +101,17 @@ public object Sentry { * @param throwable The exception. * @param scopeCallback The local scope callback. */ - public fun captureException(throwable: Throwable, scopeCallback: ScopeCallback): SentryId { - return bridge.captureException(throwable, scopeCallback) - } + public fun captureException( + throwable: Throwable, + scopeCallback: ScopeCallback, + ): SentryId = bridge.captureException(throwable, scopeCallback) /** * Captures a manually created user feedback and sends it to Sentry. * * @param userFeedback The user feedback to send to Sentry. */ - public fun captureUserFeedback(userFeedback: UserFeedback) { - return bridge.captureUserFeedback(userFeedback) - } + public fun captureUserFeedback(userFeedback: UserFeedback): Unit = bridge.captureUserFeedback(userFeedback) /** * Configures the scope through the callback. @@ -172,23 +171,17 @@ public object Sentry { /** * Returns true if the app crashed during last run. */ - public fun isCrashedLastRun(): Boolean { - return bridge.isCrashedLastRun() - } + public fun isCrashedLastRun(): Boolean = bridge.isCrashedLastRun() /** * Throws a RuntimeException, useful for testing. */ - public fun crash() { - throw RuntimeException("Uncaught Exception from Kotlin Multiplatform.") - } + public fun crash(): Unit = throw RuntimeException("Uncaught Exception from Kotlin Multiplatform.") /** * Checks if the SDK is enabled. */ - public fun isEnabled(): Boolean { - return bridge.isEnabled() - } + public fun isEnabled(): Boolean = bridge.isEnabled() /** * Closes the SDK. diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryLevel.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryLevel.kt index c07d0b474..6f70a817f 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryLevel.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryLevel.kt @@ -9,26 +9,26 @@ internal object SentryLevelNumConstants { } /** The level of the event similar to logging levels. */ -public enum class SentryLevel(private val value: Int) { +public enum class SentryLevel( + private val value: Int, +) { DEBUG(SentryLevelNumConstants.DEBUG_LEVEL), INFO(SentryLevelNumConstants.INFO_LEVEL), WARNING(SentryLevelNumConstants.WARNING_LEVEL), ERROR(SentryLevelNumConstants.ERROR_LEVEL), - FATAL(SentryLevelNumConstants.FATAL_LEVEL); + FATAL(SentryLevelNumConstants.FATAL_LEVEL), + ; - internal fun toInt(): Int { - return this.value - } + internal fun toInt(): Int = this.value internal companion object { - fun fromInt(value: Int): SentryLevel? { - return try { + fun fromInt(value: Int): SentryLevel? = + try { values().first { it.value == value } } catch (throwable: Throwable) { null } - } } } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryReplayOptions.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryReplayOptions.kt index 286485180..e0fdc20bb 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryReplayOptions.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/SentryReplayOptions.kt @@ -11,7 +11,6 @@ public data class SentryReplayOptions( * The default is null (disabled). */ public var sessionSampleRate: Double? = null, - /** * Indicates the percentage in which a 30 seconds replay will be sent with error events. * Specifying 0 means never, 1.0 means always. The value needs to be >= 0.0 and <= 1.0. @@ -19,26 +18,23 @@ public data class SentryReplayOptions( * The default is null (disabled). */ public var onErrorSampleRate: Double? = null, - /** * Makss all text content. Draws a rectangle of text bounds with text color on top. * * The default is true. */ public var maskAllText: Boolean = true, - /** * Masks all image content. Draws a rectangle of image bounds with image's dominant color on top. * * The default is true. */ public var maskAllImages: Boolean = true, - /** * Defines the quality of the session replay. The higher the quality, the more accurate the replay * will be, but also more data to transfer and more CPU load, defaults to MEDIUM. */ - public var quality: Quality = Quality.MEDIUM + public var quality: Quality = Quality.MEDIUM, ) { /** * Quality of the session replay. @@ -51,7 +47,7 @@ public data class SentryReplayOptions( * Defines the quality of the session replay. Higher bit rates have better replay quality, but * also affect the final payload size to transfer, defaults to 40kbps. */ - public val bitRate: Int + public val bitRate: Int, ) { /** Video Scale: 80% Bit Rate: 50.000 */ LOW(0.8f, 50000), @@ -60,6 +56,6 @@ public data class SentryReplayOptions( MEDIUM(1.0f, 75000), /** Video Scale: 100% Bit Rate: 100.000 */ - HIGH(1.0f, 100000) + HIGH(1.0f, 100000), } } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/BaseSentryLogger.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/BaseSentryLogger.kt index 3d7ccc6f4..d10ccb792 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/BaseSentryLogger.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/BaseSentryLogger.kt @@ -14,7 +14,7 @@ import io.sentry.kotlin.multiplatform.SentryAttributes * the formatted log to their native SDK. */ internal abstract class BaseSentryLogger( - private val logBuilderFactory: SentryLogBuilderFactory + private val logBuilderFactory: SentryLogBuilderFactory, ) : SentryLogger { /** * Sends a formatted log to the native SDK. @@ -23,86 +23,153 @@ internal abstract class BaseSentryLogger( * @param level The log level * @param formatted The formatted log with body and attributes */ - protected abstract fun sendLog(level: SentryLogLevel, formatted: FormattedLog) - - override fun trace(message: String, vararg args: Any?) = - logWithParams(SentryLogLevel.TRACE, message, args) - override fun debug(message: String, vararg args: Any?) = - logWithParams(SentryLogLevel.DEBUG, message, args) - override fun info(message: String, vararg args: Any?) = - logWithParams(SentryLogLevel.INFO, message, args) - override fun warn(message: String, vararg args: Any?) = - logWithParams(SentryLogLevel.WARN, message, args) - override fun error(message: String, vararg args: Any?) = - logWithParams(SentryLogLevel.ERROR, message, args) - override fun fatal(message: String, vararg args: Any?) = - logWithParams(SentryLogLevel.FATAL, message, args) - - override fun trace(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.TRACE, message, attributes = attributes) - override fun debug(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.DEBUG, message, attributes = attributes) - override fun info(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.INFO, message, attributes = attributes) - override fun warn(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.WARN, message, attributes = attributes) - override fun error(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.ERROR, message, attributes = attributes) - override fun fatal(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.FATAL, message, attributes = attributes) - - override fun trace(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.TRACE, message, args, attributes) - override fun debug(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.DEBUG, message, args, attributes) - override fun info(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.INFO, message, args, attributes) - override fun warn(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.WARN, message, args, attributes) - override fun error(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.ERROR, message, args, attributes) - override fun fatal(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) = - logWithParams(SentryLogLevel.FATAL, message, args, attributes) - - override fun log(level: SentryLogLevel, message: String, vararg args: Any?) = - logWithParams(level, message, args) + protected abstract fun sendLog( + level: SentryLogLevel, + formatted: FormattedLog, + ) + + override fun trace( + message: String, + vararg args: Any?, + ) = logWithParams(SentryLogLevel.TRACE, message, args) + + override fun debug( + message: String, + vararg args: Any?, + ) = logWithParams(SentryLogLevel.DEBUG, message, args) + + override fun info( + message: String, + vararg args: Any?, + ) = logWithParams(SentryLogLevel.INFO, message, args) + + override fun warn( + message: String, + vararg args: Any?, + ) = logWithParams(SentryLogLevel.WARN, message, args) + + override fun error( + message: String, + vararg args: Any?, + ) = logWithParams(SentryLogLevel.ERROR, message, args) + + override fun fatal( + message: String, + vararg args: Any?, + ) = logWithParams(SentryLogLevel.FATAL, message, args) + + override fun trace( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.TRACE, message, attributes = attributes) + + override fun debug( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.DEBUG, message, attributes = attributes) + + override fun info( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.INFO, message, attributes = attributes) + + override fun warn( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.WARN, message, attributes = attributes) + + override fun error( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.ERROR, message, attributes = attributes) + + override fun fatal( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.FATAL, message, attributes = attributes) + + override fun trace( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.TRACE, message, args, attributes) + + override fun debug( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.DEBUG, message, args, attributes) + + override fun info( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.INFO, message, args, attributes) + + override fun warn( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.WARN, message, args, attributes) + + override fun error( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.ERROR, message, args, attributes) + + override fun fatal( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) = logWithParams(SentryLogLevel.FATAL, message, args, attributes) + + override fun log( + level: SentryLogLevel, + message: String, + vararg args: Any?, + ) = logWithParams(level, message, args) @Suppress("SpreadOperator") override fun log( level: SentryLogLevel, message: String, vararg args: Any?, - attributes: @SentryLogDsl SentryAttributes.() -> Unit + attributes: @SentryLogDsl SentryAttributes.() -> Unit, ) = logWithParams(level, message, args, attributes) - override fun log(level: SentryLogLevel, block: SentryLogBuilder.() -> Unit) = - logWithBuilder(block, level) - - override fun trace(block: SentryLogBuilder.() -> Unit) = - logWithBuilder(block, SentryLogLevel.TRACE) - override fun debug(block: SentryLogBuilder.() -> Unit) = - logWithBuilder(block, SentryLogLevel.DEBUG) - override fun info(block: SentryLogBuilder.() -> Unit) = - logWithBuilder(block, SentryLogLevel.INFO) - override fun warn(block: SentryLogBuilder.() -> Unit) = - logWithBuilder(block, SentryLogLevel.WARN) - override fun error(block: SentryLogBuilder.() -> Unit) = - logWithBuilder(block, SentryLogLevel.ERROR) - override fun fatal(block: SentryLogBuilder.() -> Unit) = - logWithBuilder(block, SentryLogLevel.FATAL) + override fun log( + level: SentryLogLevel, + block: SentryLogBuilder.() -> Unit, + ) = logWithBuilder(block, level) + + override fun trace(block: SentryLogBuilder.() -> Unit) = logWithBuilder(block, SentryLogLevel.TRACE) + + override fun debug(block: SentryLogBuilder.() -> Unit) = logWithBuilder(block, SentryLogLevel.DEBUG) + + override fun info(block: SentryLogBuilder.() -> Unit) = logWithBuilder(block, SentryLogLevel.INFO) + + override fun warn(block: SentryLogBuilder.() -> Unit) = logWithBuilder(block, SentryLogLevel.WARN) + + override fun error(block: SentryLogBuilder.() -> Unit) = logWithBuilder(block, SentryLogLevel.ERROR) + + override fun fatal(block: SentryLogBuilder.() -> Unit) = logWithBuilder(block, SentryLogLevel.FATAL) @Suppress("SpreadOperator") private fun logWithParams( level: SentryLogLevel, message: String, args: Array = emptyArray(), - attributes: (@SentryLogDsl SentryAttributes.() -> Unit)? = null + attributes: (@SentryLogDsl SentryAttributes.() -> Unit)? = null, ) = logWithBuilder({ if (args.isEmpty()) message(message) else message(message, *args) attributes?.let { attributes(it) } }, level) - private inline fun logWithBuilder(block: SentryLogBuilder.() -> Unit, level: SentryLogLevel) { + private inline fun logWithBuilder( + block: SentryLogBuilder.() -> Unit, + level: SentryLogLevel, + ) { val formatted = logBuilderFactory().apply(block).buildFormatted() ?: return sendLog(level, formatted) } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/DefaultSentryLogBuilder.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/DefaultSentryLogBuilder.kt index d4116e5e3..aaaf0bf77 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/DefaultSentryLogBuilder.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/DefaultSentryLogBuilder.kt @@ -32,7 +32,10 @@ internal class DefaultSentryLogBuilder : SentryLogBuilder { args = emptyArray() } - override fun message(template: String, vararg args: Any?) { + override fun message( + template: String, + vararg args: Any?, + ) { this.template = template this.args = args } @@ -55,7 +58,7 @@ internal class DefaultSentryLogBuilder : SentryLogBuilder { return FormattedLog( body = formattedBody, - attributes = allAttributes + attributes = allAttributes, ) } @@ -63,7 +66,10 @@ internal class DefaultSentryLogBuilder : SentryLogBuilder { * Formats the message by substituting %s placeholders with argument values. * Use %% to produce a literal percent sign. */ - private fun formatMessage(template: String, args: Array): String { + private fun formatMessage( + template: String, + args: Array, + ): String { if (!template.contains('%')) return template var argIndex = 0 @@ -82,7 +88,7 @@ internal class DefaultSentryLogBuilder : SentryLogBuilder { private fun buildAllAttributes( template: String, args: Array, - customAttributes: SentryAttributes + customAttributes: SentryAttributes, ): SentryAttributes { val result = SentryAttributes.empty() diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLog.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLog.kt index f42369ba0..ab69ee45e 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLog.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLog.kt @@ -10,16 +10,12 @@ import io.sentry.kotlin.multiplatform.SentryAttributes public open class SentryLog( /** Unix timestamp in seconds when the log was created. */ public open val timestamp: Double, - /** The severity level of this log entry. */ public open var level: SentryLogLevel, - /** The log message body. */ public open var body: String, - /** Optional numeric severity. */ public open var severityNumber: Int? = null, - /** Custom key-value attributes attached to this log entry. */ - public open val attributes: SentryAttributes = SentryAttributes.empty() + public open val attributes: SentryAttributes = SentryAttributes.empty(), ) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogBuilder.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogBuilder.kt index 9945e0356..208eb6b12 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogBuilder.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogBuilder.kt @@ -50,7 +50,10 @@ public interface SentryLogBuilder { * @param template The message template (use %s for substitution, %% for literal %) * @param args Arguments to substitute into the template via toString() */ - public fun message(template: String, vararg args: Any?) + public fun message( + template: String, + vararg args: Any?, + ) /** * Merges prebuilt attributes into this log entry. @@ -97,5 +100,5 @@ public class FormattedLog( /** The formatted message body with placeholders substituted. */ public val body: String, /** Complete attributes including template info and custom attributes. */ - public val attributes: SentryAttributes + public val attributes: SentryAttributes, ) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogLevel.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogLevel.kt index 98110eded..ad46fd911 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogLevel.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogLevel.kt @@ -9,5 +9,5 @@ public enum class SentryLogLevel { INFO, WARN, ERROR, - FATAL + FATAL, } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogger.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogger.kt index 1f9c604f8..1fc47ba29 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogger.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogger.kt @@ -15,7 +15,11 @@ public interface SentryLogger { * @param message The message template (use %s for substitution, %% for literal %) * @param args Arguments to substitute into the message template via toString() */ - public fun log(level: SentryLogLevel, message: String, vararg args: Any?) + public fun log( + level: SentryLogLevel, + message: String, + vararg args: Any?, + ) /** * Logs a message at a specific level with inline attributes. @@ -29,7 +33,7 @@ public interface SentryLogger { level: SentryLogLevel, message: String, vararg args: Any?, - attributes: @SentryLogDsl SentryAttributes.() -> Unit + attributes: @SentryLogDsl SentryAttributes.() -> Unit, ) /** @@ -49,7 +53,10 @@ public interface SentryLogger { * @param level The log level * @param block A lambda with [SentryLogBuilder] receiver to configure the log entry */ - public fun log(level: SentryLogLevel, block: SentryLogBuilder.() -> Unit) + public fun log( + level: SentryLogLevel, + block: SentryLogBuilder.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.TRACE] level. @@ -57,7 +64,10 @@ public interface SentryLogger { * @param message The message template (use %s for substitution, %% for literal %) * @param args Arguments to substitute into the message template via toString() */ - public fun trace(message: String, vararg args: Any?) + public fun trace( + message: String, + vararg args: Any?, + ) /** * Logs a message at [SentryLogLevel.DEBUG] level. @@ -65,7 +75,10 @@ public interface SentryLogger { * @param message The message template (use %s for substitution, %% for literal %) * @param args Arguments to substitute into the message template via toString() */ - public fun debug(message: String, vararg args: Any?) + public fun debug( + message: String, + vararg args: Any?, + ) /** * Logs a message at [SentryLogLevel.INFO] level. @@ -73,7 +86,10 @@ public interface SentryLogger { * @param message The message template (use %s for substitution, %% for literal %) * @param args Arguments to substitute into the message template via toString() */ - public fun info(message: String, vararg args: Any?) + public fun info( + message: String, + vararg args: Any?, + ) /** * Logs a message at [SentryLogLevel.WARN] level. @@ -81,7 +97,10 @@ public interface SentryLogger { * @param message The message template (use %s for substitution, %% for literal %) * @param args Arguments to substitute into the message template via toString() */ - public fun warn(message: String, vararg args: Any?) + public fun warn( + message: String, + vararg args: Any?, + ) /** * Logs a message at [SentryLogLevel.ERROR] level. @@ -89,7 +108,10 @@ public interface SentryLogger { * @param message The message template (use %s for substitution, %% for literal %) * @param args Arguments to substitute into the message template via toString() */ - public fun error(message: String, vararg args: Any?) + public fun error( + message: String, + vararg args: Any?, + ) /** * Logs a message at [SentryLogLevel.FATAL] level. @@ -97,7 +119,10 @@ public interface SentryLogger { * @param message The message template (use %s for substitution, %% for literal %) * @param args Arguments to substitute into the message template via toString() */ - public fun fatal(message: String, vararg args: Any?) + public fun fatal( + message: String, + vararg args: Any?, + ) /** * Logs a message at [SentryLogLevel.TRACE] level with inline attributes. @@ -113,7 +138,10 @@ public interface SentryLogger { * @param message The log message * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun trace(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun trace( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.DEBUG] level with inline attributes. @@ -129,7 +157,10 @@ public interface SentryLogger { * @param message The log message * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun debug(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun debug( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.INFO] level with inline attributes. @@ -145,7 +176,10 @@ public interface SentryLogger { * @param message The log message * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun info(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun info( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.WARN] level with inline attributes. @@ -161,7 +195,10 @@ public interface SentryLogger { * @param message The log message * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun warn(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun warn( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.TRACE] level with template parameters and inline attributes. @@ -178,7 +215,11 @@ public interface SentryLogger { * @param args Arguments to substitute into the message template via toString() * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun trace(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun trace( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.DEBUG] level with template parameters and inline attributes. @@ -195,7 +236,11 @@ public interface SentryLogger { * @param args Arguments to substitute into the message template via toString() * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun debug(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun debug( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.INFO] level with template parameters and inline attributes. @@ -212,7 +257,11 @@ public interface SentryLogger { * @param args Arguments to substitute into the message template via toString() * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun info(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun info( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.WARN] level with template parameters and inline attributes. @@ -229,7 +278,11 @@ public interface SentryLogger { * @param args Arguments to substitute into the message template via toString() * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun warn(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun warn( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.ERROR] level with template parameters and inline attributes. @@ -246,7 +299,11 @@ public interface SentryLogger { * @param args Arguments to substitute into the message template via toString() * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun error(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun error( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.FATAL] level with template parameters and inline attributes. @@ -263,7 +320,11 @@ public interface SentryLogger { * @param args Arguments to substitute into the message template via toString() * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun fatal(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun fatal( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.ERROR] level with inline attributes. @@ -279,7 +340,10 @@ public interface SentryLogger { * @param message The log message * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun error(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun error( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.FATAL] level with inline attributes. @@ -295,7 +359,10 @@ public interface SentryLogger { * @param message The log message * @param attributes A lambda with [SentryAttributes] receiver to set key-value attributes */ - public fun fatal(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) + public fun fatal( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) /** * Logs a message at [SentryLogLevel.TRACE] level using a DSL builder. diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/Breadcrumb.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/Breadcrumb.kt index 71d95e801..4205cbc30 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/Breadcrumb.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/Breadcrumb.kt @@ -10,107 +10,110 @@ import io.sentry.kotlin.multiplatform.SentryLevel public data class Breadcrumb( /** The breadcrumb's level */ var level: SentryLevel? = null, - /** The breadcrumb's type */ var type: String? = null, - /** The breadcrumb's message */ var message: String? = null, - /** The breadcrumb's category */ var category: String? = null, - - private var data: MutableMap? = null + private var data: MutableMap? = null, ) { - public companion object { - public fun user(category: String, message: String): Breadcrumb { - return Breadcrumb().apply { + public fun user( + category: String, + message: String, + ): Breadcrumb = + Breadcrumb().apply { this.category = category this.message = message this.type = "user" } - } - public fun http(url: String, method: String): Breadcrumb { - return Breadcrumb().apply { + public fun http( + url: String, + method: String, + ): Breadcrumb = + Breadcrumb().apply { this.type = "http" this.category = "http" this.setData("url", url) this.setData("method", method.uppercase()) } - } - public fun http(url: String, method: String, code: Int?): Breadcrumb { - return http(url, method).apply { + public fun http( + url: String, + method: String, + code: Int?, + ): Breadcrumb = + http(url, method).apply { code?.let { this.setData("status_code", code) } } - } - public fun navigation(from: String, to: String): Breadcrumb { - return Breadcrumb().apply { + public fun navigation( + from: String, + to: String, + ): Breadcrumb = + Breadcrumb().apply { this.category = "navigation" this.type = "navigation" this.setData("from", from) this.setData("to", to) } - } - public fun transaction(message: String): Breadcrumb { - return Breadcrumb().apply { + public fun transaction(message: String): Breadcrumb = + Breadcrumb().apply { this.type = "default" this.category = "sentry.transaction" this.message = message } - } public fun debug(message: String): Breadcrumb { - val breadcrumb = Breadcrumb().apply { - this.type = "debug" - this.message = message - this.level = SentryLevel.DEBUG - } + val breadcrumb = + Breadcrumb().apply { + this.type = "debug" + this.message = message + this.level = SentryLevel.DEBUG + } return breadcrumb } - public fun error(message: String): Breadcrumb { - return Breadcrumb().apply { + public fun error(message: String): Breadcrumb = + Breadcrumb().apply { this.type = "error" this.message = message this.level = SentryLevel.ERROR } - } - public fun info(message: String): Breadcrumb { - return Breadcrumb().apply { + public fun info(message: String): Breadcrumb = + Breadcrumb().apply { this.type = "info" this.message = message this.level = SentryLevel.INFO } - } - public fun query(message: String): Breadcrumb { - return Breadcrumb().apply { + public fun query(message: String): Breadcrumb = + Breadcrumb().apply { this.type = "query" this.message = message } - } - public fun ui(category: String, message: String): Breadcrumb { - return Breadcrumb().apply { + public fun ui( + category: String, + message: String, + ): Breadcrumb = + Breadcrumb().apply { this.type = "default" this.category = "ui.$category" this.message = message } - } public fun userInteraction( subCategory: String, viewId: String?, viewClass: String?, - additionalData: Map - ): Breadcrumb { - return Breadcrumb().apply { + additionalData: Map, + ): Breadcrumb = + Breadcrumb().apply { this.type = "user" this.category = "ui.$subCategory" this.level = SentryLevel.INFO @@ -122,15 +125,12 @@ public data class Breadcrumb( } } } - } public fun userInteraction( subCategory: String, viewId: String?, - viewClass: String? - ): Breadcrumb { - return userInteraction(subCategory, viewId, viewClass, emptyMap()) - } + viewClass: String?, + ): Breadcrumb = userInteraction(subCategory, viewId, viewClass, emptyMap()) } /** @@ -139,7 +139,10 @@ public data class Breadcrumb( * @param key The key * @param value The value */ - public fun setData(key: String, value: Any) { + public fun setData( + key: String, + value: Any, + ) { if (data == null) data = mutableMapOf() data?.put(key, value) } @@ -154,9 +157,7 @@ public data class Breadcrumb( } /** Returns the breadcrumb's data */ - public fun getData(): MutableMap? { - return data - } + public fun getData(): MutableMap? = data /** Clears the breadcrumb and returns it to the default state */ public fun clear() { diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/Message.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/Message.kt index 37d525e50..a6f9e4189 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/Message.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/Message.kt @@ -16,5 +16,5 @@ public data class Message( * The formatted message. If `message` and `params` are given, Sentry will attempt to backfill * `formatted` if empty. */ - public var formatted: String? = null + public var formatted: String? = null, ) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SdkVersion.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SdkVersion.kt index c28381d47..f7fd2df69 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SdkVersion.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SdkVersion.kt @@ -4,15 +4,17 @@ package io.sentry.kotlin.multiplatform.protocol public data class SdkVersion( /** The name of the SDK. */ val name: String, - /** The version of the SDK. */ - val version: String + val version: String, ) { /** Packages used by the SDK. */ var packages: List? = mutableListOf() private set - public fun addPackage(name: String, version: String) { + public fun addPackage( + name: String, + version: String, + ) { val mutableList = packages?.toMutableList() mutableList?.add(Package(name, version)) packages = mutableList @@ -24,5 +26,5 @@ public data class Package( /** The name of the package. */ val name: String, /** The version of the package. */ - val version: String + val version: String, ) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryException.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryException.kt index af3db1930..e614ee551 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryException.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryException.kt @@ -14,5 +14,5 @@ public data class SentryException( /** The optional module, or package which the exception type lives in. */ val module: String? = null, /** An optional value that refers to a thread. */ - val threadId: Long? = null + val threadId: Long? = null, ) diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.kt index 1db521a5e..07244c48f 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.kt @@ -1,10 +1,13 @@ package io.sentry.kotlin.multiplatform.protocol /** The Sentry event ID */ -public expect class SentryId(sentryIdString: String) { +public expect class SentryId( + sentryIdString: String, +) { public companion object { /** Returns a new empty SentryId */ public val EMPTY_ID: SentryId } + override fun toString(): String } diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/User.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/User.kt index 0927dfd9e..aa4ef3f59 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/User.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/User.kt @@ -4,33 +4,27 @@ package io.sentry.kotlin.multiplatform.protocol public data class User( /** The user's email */ var email: String? = null, - /** The user's id */ var id: String? = null, - /** The user's username */ var username: String? = null, - /** The user's ip address*/ var ipAddress: String? = null, - /** * Additional arbitrary fields, as stored in the database (and sometimes as sent by clients). All * data from `self.other` should end up here after store normalization. */ var other: MutableMap? = null, - /** Unknown fields, only internal usage. */ - var unknown: MutableMap? = null + var unknown: MutableMap? = null, ) { - public constructor(user: User) : this( user.email, user.id, user.username, user.ipAddress, user.other, - user.unknown + user.unknown, ) // This secondary constructor allows Swift also to init without specifying nil explicitly diff --git a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/UserFeedback.kt b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/UserFeedback.kt index 9569a03ee..b801aae62 100644 --- a/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/UserFeedback.kt +++ b/sentry-kotlin-multiplatform/src/commonMain/kotlin/io/sentry/kotlin/multiplatform/protocol/UserFeedback.kt @@ -3,7 +3,7 @@ package io.sentry.kotlin.multiplatform.protocol /** UserFeedback adds additional information about what happened to an event. */ public data class UserFeedback( /** The Sentry event ID */ - val sentryId: SentryId + val sentryId: SentryId, ) { /** The user's name */ var name: String? = null diff --git a/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/Attachment.commonStub.kt b/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/Attachment.commonStub.kt index 84d0bf2dd..c229840f8 100644 --- a/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/Attachment.commonStub.kt +++ b/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/Attachment.commonStub.kt @@ -1,7 +1,6 @@ package io.sentry.kotlin.multiplatform public actual class Attachment { - public actual val bytes: ByteArray? public actual val contentType: String? public actual val pathname: String? diff --git a/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/NoOpSentryLogger.kt b/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/NoOpSentryLogger.kt index 9870f9f26..b5b3e6606 100644 --- a/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/NoOpSentryLogger.kt +++ b/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/NoOpSentryLogger.kt @@ -9,79 +9,143 @@ import io.sentry.kotlin.multiplatform.log.SentryLogger * No-op implementation of [SentryLogger] for stub/unsupported platforms. */ internal class NoOpSentryLogger : SentryLogger { - override fun trace(message: String, vararg args: Any?) { + override fun trace( + message: String, + vararg args: Any?, + ) { // No-op } - override fun debug(message: String, vararg args: Any?) { + override fun debug( + message: String, + vararg args: Any?, + ) { // No-op } - override fun info(message: String, vararg args: Any?) { + override fun info( + message: String, + vararg args: Any?, + ) { // No-op } - override fun warn(message: String, vararg args: Any?) { + override fun warn( + message: String, + vararg args: Any?, + ) { // No-op } - override fun error(message: String, vararg args: Any?) { + override fun error( + message: String, + vararg args: Any?, + ) { // No-op } - override fun fatal(message: String, vararg args: Any?) { + override fun fatal( + message: String, + vararg args: Any?, + ) { // No-op } - override fun trace(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun trace( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun debug(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun debug( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun info(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun info( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun warn(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun warn( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun error(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun error( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun fatal(message: String, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun fatal( + message: String, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun trace(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun trace( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun debug(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun debug( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun info(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun info( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun warn(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun warn( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun error(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun error( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun fatal(message: String, vararg args: Any?, attributes: @SentryLogDsl SentryAttributes.() -> Unit) { + override fun fatal( + message: String, + vararg args: Any?, + attributes: @SentryLogDsl SentryAttributes.() -> Unit, + ) { // No-op } - override fun log(level: SentryLogLevel, message: String, vararg args: Any?) { + override fun log( + level: SentryLogLevel, + message: String, + vararg args: Any?, + ) { // No-op } @@ -89,12 +153,15 @@ internal class NoOpSentryLogger : SentryLogger { level: SentryLogLevel, message: String, vararg args: Any?, - attributes: @SentryLogDsl SentryAttributes.() -> Unit + attributes: @SentryLogDsl SentryAttributes.() -> Unit, ) { // No-op } - override fun log(level: SentryLogLevel, block: SentryLogBuilder.() -> Unit) { + override fun log( + level: SentryLogLevel, + block: SentryLogBuilder.() -> Unit, + ) { // No-op } diff --git a/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.commonStub.kt b/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.commonStub.kt index 85c2bc8cf..81d7189f4 100644 --- a/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.commonStub.kt +++ b/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/SentryBridge.commonStub.kt @@ -8,9 +8,12 @@ import io.sentry.kotlin.multiplatform.protocol.UserFeedback @Suppress("UnusedPrivateMember") internal actual class SentryBridge actual constructor( - private val sentryInstance: SentryInstance + private val sentryInstance: SentryInstance, ) { - actual fun init(context: Context, configuration: OptionsConfiguration) { + actual fun init( + context: Context, + configuration: OptionsConfiguration, + ) { // No-op } @@ -22,21 +25,19 @@ internal actual class SentryBridge actual constructor( // No-op } - actual fun captureMessage(message: String): SentryId { - return SentryId.EMPTY_ID - } + actual fun captureMessage(message: String): SentryId = SentryId.EMPTY_ID - actual fun captureMessage(message: String, scopeCallback: ScopeCallback): SentryId { - return SentryId.EMPTY_ID - } + actual fun captureMessage( + message: String, + scopeCallback: ScopeCallback, + ): SentryId = SentryId.EMPTY_ID - actual fun captureException(throwable: Throwable): SentryId { - return SentryId.EMPTY_ID - } + actual fun captureException(throwable: Throwable): SentryId = SentryId.EMPTY_ID - actual fun captureException(throwable: Throwable, scopeCallback: ScopeCallback): SentryId { - return SentryId.EMPTY_ID - } + actual fun captureException( + throwable: Throwable, + scopeCallback: ScopeCallback, + ): SentryId = SentryId.EMPTY_ID actual fun configureScope(scopeCallback: ScopeCallback) { // No-op @@ -54,17 +55,11 @@ internal actual class SentryBridge actual constructor( // No-op } - actual fun logger(): SentryLogger { - return NoOpSentryLogger() - } + actual fun logger(): SentryLogger = NoOpSentryLogger() - actual fun isCrashedLastRun(): Boolean { - return false - } + actual fun isCrashedLastRun(): Boolean = false - actual fun isEnabled(): Boolean { - return false - } + actual fun isEnabled(): Boolean = false actual fun close() { // No-op diff --git a/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.commonStub.kt b/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.commonStub.kt index da302990f..910b4abbb 100644 --- a/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.commonStub.kt +++ b/sentry-kotlin-multiplatform/src/commonStub/kotlin/io/sentry/kotlin/multiplatform/protocol/SentryId.commonStub.kt @@ -1,6 +1,8 @@ package io.sentry.kotlin.multiplatform.protocol -public actual data class SentryId actual constructor(private val sentryIdString: String) { +public actual data class SentryId actual constructor( + private val sentryIdString: String, +) { public actual companion object { public actual val EMPTY_ID: SentryId = SentryId("") } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/AttachmentTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/AttachmentTest.kt index c42db0e01..5f12036b4 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/AttachmentTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/AttachmentTest.kt @@ -5,7 +5,6 @@ import kotlin.test.assertContentEquals import kotlin.test.assertEquals class AttachmentTest { - @Test fun `adding pathname to attachment returns correct values`() { val pathname = "test" diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt index 9d168846c..e57982562 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryScopeTest.kt @@ -1,6 +1,5 @@ package io.sentry.kotlin.multiplatform expect abstract class BaseSentryScopeTest() { - fun initializeScope(): Scope } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt index 512b69c4c..b0484e7e7 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt @@ -3,6 +3,8 @@ package io.sentry.kotlin.multiplatform expect abstract class BaseSentryTest() { val platform: String val authToken: String? + fun sentryInit(optionsConfiguration: OptionsConfiguration) + fun sentryInitWithPlatformOptions(platformOptionsConfiguration: PlatformOptionsConfiguration) } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeBreadcrumbIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeBreadcrumbIntegrationTest.kt index 27fe61657..2e68599c7 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeBreadcrumbIntegrationTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeBreadcrumbIntegrationTest.kt @@ -11,127 +11,138 @@ class BeforeBreadcrumbIntegrationTest { @Test fun `breadcrumb is not null if KMP beforeBreadcrumb callback config is null`() { - val breadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - } + val breadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(breadcrumb) } @Test fun `breadcrumb is null if KMP beforeBreadcrumb callback config returns null`() { - val breadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeBreadcrumb = { - null + val breadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeBreadcrumb = { + null + } } - } assertNull(breadcrumb) } @Test fun `breadcrumb is not null if KMP beforeBreadcrumb callback config returns not null`() { - val breadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeBreadcrumb = { breadcrumb -> - breadcrumb + val breadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeBreadcrumb = { breadcrumb -> + breadcrumb + } } - } assertNotNull(breadcrumb) } @Test fun `breadcrumb level is not modified if KMP beforeBreadcrumb callback config does not modify it`() { val originalBreadcrumb = breadcrumbConfigurator.originalBreadcrumb - val modifiedBreadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeBreadcrumb = { breadcrumb -> - breadcrumb + val modifiedBreadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeBreadcrumb = { breadcrumb -> + breadcrumb + } } - } assertEquals(originalBreadcrumb.level, modifiedBreadcrumb?.level) } @Test fun `breadcrumb level is modified if KMP beforeBreadcrumb callback config modifies it`() { - val modifiedBreadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeBreadcrumb = { breadcrumb -> - breadcrumb.level = SentryLevel.WARNING - breadcrumb + val modifiedBreadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeBreadcrumb = { breadcrumb -> + breadcrumb.level = SentryLevel.WARNING + breadcrumb + } } - } assertEquals(SentryLevel.WARNING, modifiedBreadcrumb?.level) } @Test fun `breadcrumb category is not modified if KMP beforeBreadcrumb callback config does not modify it`() { val originalBreadcrumb = breadcrumbConfigurator.originalBreadcrumb - val modifiedBreadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeBreadcrumb = { breadcrumb -> - breadcrumb + val modifiedBreadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeBreadcrumb = { breadcrumb -> + breadcrumb + } } - } assertEquals(originalBreadcrumb.category, modifiedBreadcrumb?.category) } @Test fun `breadcrumb category is modified if KMP beforeBreadcrumb callback config modifies it`() { - val modifiedBreadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeBreadcrumb = { breadcrumb -> - breadcrumb.category = "category" - breadcrumb + val modifiedBreadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeBreadcrumb = { breadcrumb -> + breadcrumb.category = "category" + breadcrumb + } } - } assertEquals("category", modifiedBreadcrumb?.category) } @Test fun `breadcrumb type is not modified if KMP beforeBreadcrumb callback config does not modify it`() { val originalBreadcrumb = breadcrumbConfigurator.originalBreadcrumb - val modifiedBreadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeBreadcrumb = { breadcrumb -> - breadcrumb + val modifiedBreadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeBreadcrumb = { breadcrumb -> + breadcrumb + } } - } assertEquals(originalBreadcrumb.type, modifiedBreadcrumb?.type) } @Test fun `breadcrumb type is modified if KMP beforeBreadcrumb callback config modifies it`() { - val modifiedBreadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeBreadcrumb = { breadcrumb -> - breadcrumb.type = "type" - breadcrumb + val modifiedBreadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeBreadcrumb = { breadcrumb -> + breadcrumb.type = "type" + breadcrumb + } } - } assertEquals("type", modifiedBreadcrumb?.type) } @Test fun `breadcrumb message is not modified if KMP beforeBreadcrumb callback config does not modify it`() { val originalBreadcrumb = breadcrumbConfigurator.originalBreadcrumb - val modifiedBreadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeBreadcrumb = { breadcrumb -> - breadcrumb + val modifiedBreadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeBreadcrumb = { breadcrumb -> + breadcrumb + } } - } assertEquals(originalBreadcrumb.level, modifiedBreadcrumb?.level) } @Test fun `breadcrumb message is modified if KMP beforeBreadcrumb callback config modifies it`() { - val modifiedBreadcrumb = breadcrumbConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeBreadcrumb = { breadcrumb -> - breadcrumb.message = "message" - breadcrumb + val modifiedBreadcrumb = + breadcrumbConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeBreadcrumb = { breadcrumb -> + breadcrumb.message = "message" + breadcrumb + } } - } assertEquals("message", modifiedBreadcrumb?.message) } } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeSendIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeSendIntegrationTest.kt index b143d8df9..35c53924f 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeSendIntegrationTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeSendIntegrationTest.kt @@ -13,44 +13,48 @@ class BeforeSendIntegrationTest { @Test fun `event is not null if KMP beforeSend option is null`() { - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - } + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(event) } @Test fun `event is null if KMP beforeSend callback config returns null`() { - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { - null + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { + null + } } - } assertNull(event) } @Test fun `event is not null if KMP beforeSend callback config returns not null`() { - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event + } } - } assertNotNull(event) } @Test fun `event logger is modified if KMP beforeSend callback config modifies it`() { val expected = "test" - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event.logger = expected - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event.logger = expected + event + } } - } assertNotNull(event) assertEquals(expected, event.logger) } @@ -58,13 +62,14 @@ class BeforeSendIntegrationTest { @Test fun `event level is modified if KMP beforeSend callback config modifies it`() { val expected = SentryLevel.DEBUG - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event.level = expected - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event.level = expected + event + } } - } assertNotNull(event) assertEquals(expected, event.level) } @@ -72,13 +77,14 @@ class BeforeSendIntegrationTest { @Test fun `event message is modified if KMP beforeSend callback config modifies it`() { val expected = Message("test") - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event.message = expected - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event.message = expected + event + } } - } assertNotNull(event) assertEquals(expected, event.message) } @@ -86,13 +92,14 @@ class BeforeSendIntegrationTest { @Test fun `event release is modified if KMP beforeSend callback config modifies it`() { val expected = "test" - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event.release = expected - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event.release = expected + event + } } - } assertNotNull(event) assertEquals(expected, event.release) } @@ -100,13 +107,14 @@ class BeforeSendIntegrationTest { @Test fun `event environment is modified if KMP beforeSend callback config modifies it`() { val expected = "test" - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event.environment = expected - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event.environment = expected + event + } } - } assertNotNull(event) assertEquals(expected, event.environment) } @@ -114,13 +122,14 @@ class BeforeSendIntegrationTest { @Test fun `event serverName is modified if KMP beforeSend callback config modifies it`() { val expected = "test" - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event.serverName = expected - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event.serverName = expected + event + } } - } assertNotNull(event) assertEquals(expected, event.serverName) } @@ -128,13 +137,14 @@ class BeforeSendIntegrationTest { @Test fun `event dist is modified if KMP beforeSend callback config modifies it`() { val expected = "test" - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event.dist = expected - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event.dist = expected + event + } } - } assertNotNull(event) assertEquals(expected, event.dist) } @@ -142,13 +152,14 @@ class BeforeSendIntegrationTest { @Test fun `event fingerprint is modified if KMP beforeSend callback config modifies it`() { val expected = mutableListOf("test") - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event.fingerprint = expected - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event.fingerprint = expected + event + } } - } assertNotNull(event) assertEquals(expected, event.fingerprint) } @@ -156,13 +167,14 @@ class BeforeSendIntegrationTest { @Test fun `event tags are modified if KMP beforeSend callback config modifies it`() { val expected = mutableMapOf("test" to "test") - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event.tags = expected - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event.tags = expected + event + } } - } assertNotNull(event) assertEquals(expected, event.tags) } @@ -170,13 +182,14 @@ class BeforeSendIntegrationTest { @Test fun `event breadcrumbs are modified if KMP beforeSend callback config modifies it`() { val expected = mutableListOf(Breadcrumb.debug("test")) - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - it.beforeSend = { event -> - event.breadcrumbs = expected - event + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + it.beforeSend = { event -> + event.breadcrumbs = expected + event + } } - } assertNotNull(event) assertEquals(expected.first().type, event.breadcrumbs.first().type) assertEquals(expected.first().message, event.breadcrumbs.first().message) @@ -186,9 +199,10 @@ class BeforeSendIntegrationTest { @Test fun `event logger is not modified if KMP beforeSend callback config is not modified`() { val originalEvent = sentryEventConfigurator.originalEvent - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - } + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(event) assertEquals(originalEvent.logger, event.logger) } @@ -204,9 +218,10 @@ class BeforeSendIntegrationTest { @Test fun `event message is not modified if KMP beforeSend callback config is not modified`() { val originalEvent = sentryEventConfigurator.originalEvent - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - } + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(event) assertEquals(originalEvent.message, event.message) } @@ -214,9 +229,10 @@ class BeforeSendIntegrationTest { @Test fun `event release is not modified if KMP beforeSend callback config is not modified`() { val originalEvent = sentryEventConfigurator.originalEvent - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - } + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(event) assertEquals(originalEvent.release, event.release) } @@ -224,9 +240,10 @@ class BeforeSendIntegrationTest { @Test fun `event environment is not modified if KMP beforeSend callback config is not modified`() { val originalEvent = sentryEventConfigurator.originalEvent - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - } + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(event) assertEquals(originalEvent.environment, event.environment) } @@ -234,9 +251,10 @@ class BeforeSendIntegrationTest { @Test fun `event serverName is not modified if KMP beforeSend callback config is not modified`() { val originalEvent = sentryEventConfigurator.originalEvent - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - } + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(event) assertEquals(originalEvent.serverName, event.serverName) } @@ -244,9 +262,10 @@ class BeforeSendIntegrationTest { @Test fun `event dist is not modified if KMP beforeSend callback config is not modified`() { val originalEvent = sentryEventConfigurator.originalEvent - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - } + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(event) assertEquals(originalEvent.dist, event.dist) } @@ -254,9 +273,10 @@ class BeforeSendIntegrationTest { @Test fun `event fingerprint is not modified if KMP beforeSend callback config is not modified`() { val originalEvent = sentryEventConfigurator.originalEvent - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - } + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(event) assertEquals(originalEvent.fingerprint, event.fingerprint) } @@ -264,9 +284,10 @@ class BeforeSendIntegrationTest { @Test fun `event tags are not modified if KMP beforeSend callback config is not modified`() { val originalEvent = sentryEventConfigurator.originalEvent - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - } + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(event) assertEquals(originalEvent.tags, event.tags) } @@ -274,9 +295,10 @@ class BeforeSendIntegrationTest { @Test fun `event breadcrumbs are not modified if KMP beforeSend callback config is not modified`() { val originalEvent = sentryEventConfigurator.originalEvent - val event = sentryEventConfigurator.applyOptions { - it.dsn = fakeDsn - } + val event = + sentryEventConfigurator.applyOptions { + it.dsn = fakeDsn + } assertNotNull(event) assertEquals(originalEvent.breadcrumbs, event.breadcrumbs) } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeSendTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeSendTest.kt index 922515ab6..e6b221196 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeSendTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BeforeSendTest.kt @@ -10,7 +10,6 @@ import kotlin.test.assertTrue /** Tests that verify if the beforeSend hook correctly modifies events */ class BeforeSendTest { - @Test fun `beforeSend drops event`() { val options = SentryOptions() @@ -130,11 +129,12 @@ class BeforeSendTest { @Test fun `beforeSend modifies user`() { - val expected = User().apply { - id = "test" - username = "username" - email = "email" - } + val expected = + User().apply { + id = "test" + username = "username" + email = "email" + } val options = SentryOptions() options.beforeSend = { @@ -218,11 +218,12 @@ class BeforeSendTest { it } - val event = options.beforeSend?.invoke( - SentryEvent().apply { - contexts = mapOf("test" to "test") - } - ) + val event = + options.beforeSend?.invoke( + SentryEvent().apply { + contexts = mapOf("test" to "test") + }, + ) assertEquals(contexts, event?.contexts) } @@ -236,11 +237,12 @@ class BeforeSendTest { it } - val event = options.beforeSend?.invoke( - SentryEvent().apply { - exceptions = listOf(SentryException("test")) - } - ) + val event = + options.beforeSend?.invoke( + SentryEvent().apply { + exceptions = listOf(SentryException("test")) + }, + ) assertEquals(exceptions, event?.exceptions) } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbConfigurator.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbConfigurator.kt index 4dcda258e..fad34df3a 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbConfigurator.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbConfigurator.kt @@ -8,6 +8,8 @@ import io.sentry.kotlin.multiplatform.protocol.Breadcrumb */ expect class BreadcrumbConfigurator() { val originalBreadcrumb: Breadcrumb + fun applyOptions(optionsConfiguration: OptionsConfiguration): Breadcrumb? + fun applyOptions(options: SentryOptions = SentryOptions()): Breadcrumb? } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTest.kt index aa8362442..adc9d3a54 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTest.kt @@ -5,7 +5,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class BreadcrumbTest { - private val testMessage = "TestMessage" private val testCategory = "TestCategory" private val testUrl = "sentry.io" diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt index 5dbdc4b31..db34fdcb5 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/BreadcrumbTestConverter.kt @@ -2,10 +2,16 @@ package io.sentry.kotlin.multiplatform import io.sentry.kotlin.multiplatform.protocol.Breadcrumb -expect class BreadcrumbTestConverter(breadcrumb: Breadcrumb) { +expect class BreadcrumbTestConverter( + breadcrumb: Breadcrumb, +) { fun getType(): String? + fun getCategory(): String? + fun getMessage(): String? + fun getData(): MutableMap + fun getLevel(): SentryLevel? } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/ScopeTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/ScopeTest.kt index d373ae667..b2a789ce9 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/ScopeTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/ScopeTest.kt @@ -8,7 +8,6 @@ import kotlin.test.assertEquals import kotlin.test.assertNull class ScopeTest : BaseSentryScopeTest() { - private val testUsername = "MyUsername" private val testEmail = "Email" private val testId = "TestId" @@ -29,14 +28,13 @@ class ScopeTest : BaseSentryScopeTest() { user = null } - private fun createTestUser(): User { - return User().apply { + private fun createTestUser(): User = + User().apply { username = testUsername email = testEmail id = testId ipAddress = testIpAddress } - } @Test fun `adding user to scope should properly persist user in scope`() { diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributeValueTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributeValueTest.kt index 6567bbba2..cd1772c23 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributeValueTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributeValueTest.kt @@ -6,7 +6,6 @@ import kotlin.test.assertIs /** Tests for [SentryAttributeValue] factory methods and type hierarchy. */ class SentryAttributeValueTest { - @Test fun `string factory creates StringValue with correct value`() { val value = SentryAttributeValue.string("myValue") diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesTest.kt index d95e6150d..33cc83038 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryAttributesTest.kt @@ -8,7 +8,6 @@ import kotlin.test.assertTrue /** Tests for [SentryAttributes] collection operations. */ class SentryAttributesTest { - @Test fun `set and get string value`() { val attrs = SentryAttributes.empty() @@ -100,10 +99,11 @@ class SentryAttributesTest { @Test fun `of from map creates SentryAttributes with entries`() { - val map = mapOf( - "name" to SentryAttributeValue.string("test"), - "count" to SentryAttributeValue.long(5) - ) + val map = + mapOf( + "name" to SentryAttributeValue.string("test"), + "count" to SentryAttributeValue.long(5), + ) val attrs = SentryAttributes.of(map) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.kt index d44a8d2db..31980c515 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryBridgeTest.kt @@ -2,9 +2,14 @@ package io.sentry.kotlin.multiplatform expect class SentryBridgeTest { fun `init sets correct configuration`() + fun `setting null in beforeSend during init drops the event`() + fun `default beforeSend in init does not drop the event`() + fun `default beforeSend in init does not drop the event after prepareForInit`() + fun `init sets the SDK packages`() + fun `init sets SDK version and name`() } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryE2ETest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryE2ETest.kt index 4ec1036e0..aa95e48c1 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryE2ETest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryE2ETest.kt @@ -34,7 +34,7 @@ private data class SentryEventSerializable( val fingerprint: List = listOf(), val level: String? = null, val logger: String? = null, - val title: String? = null + val title: String? = null, ) class SentryE2ETest : BaseSentryTest() { @@ -58,27 +58,29 @@ class SentryE2ETest : BaseSentryTest() { private suspend fun fetchEvent(eventId: String): String { val url = "https://sentry.io/api/0/projects/$org/$projectSlug/events/$eventId/" - val response = client.get(url) { - headers { - append( - HttpHeaders.Authorization, - "Bearer $authToken" - ) + val response = + client.get(url) { + headers { + append( + HttpHeaders.Authorization, + "Bearer $authToken", + ) + } } - } return response.bodyAsText() } private suspend fun waitForEventRetrieval(eventId: String): SentryEventSerializable { var json = "" - val result: SentryEventSerializable = withContext(Dispatchers.Default) { - while (json.isEmpty() || json.contains("Event not found")) { - delay(20000) - json = fetchEvent(eventId) - assertFalse(json.contains("Invalid token"), "Invalid auth token") + val result: SentryEventSerializable = + withContext(Dispatchers.Default) { + while (json.isEmpty() || json.contains("Event not found")) { + delay(20000) + json = fetchEvent(eventId) + assertFalse(json.contains("Invalid token"), "Invalid auth token") + } + jsonDecoder.decodeFromString(json) } - jsonDecoder.decodeFromString(json) - } return result } @@ -86,39 +88,41 @@ class SentryE2ETest : BaseSentryTest() { // See: https://github.com/getsentry/sentry-kotlin-multiplatform/issues/17 @Test - fun `capture message and fetch event from Sentry`() = runTest(timeout = 60.seconds) { - if (platform != "Apple") { - val message = "Test running on $platform" - val eventId = Sentry.captureMessage(message) - val fetchedEvent = waitForEventRetrieval(eventId.toString()) - fetchedEvent.tags.forEach { println(it["value"]) } - assertEquals(eventId.toString(), fetchedEvent.id) - assertEquals(sentEvent?.message?.formatted, fetchedEvent.message) - assertEquals(message, fetchedEvent.title) - assertEquals(sentEvent?.release, fetchedEvent.release) - assertEquals(2, fetchedEvent.tags.find { it["value"] == sentEvent?.environment }?.size) - assertEquals(sentEvent?.fingerprint?.toList(), fetchedEvent.fingerprint) - assertEquals(2, fetchedEvent.tags.find { it["value"] == sentEvent?.level?.name?.lowercase() }?.size) - assertEquals(sentEvent?.logger, fetchedEvent.logger) + fun `capture message and fetch event from Sentry`() = + runTest(timeout = 60.seconds) { + if (platform != "Apple") { + val message = "Test running on $platform" + val eventId = Sentry.captureMessage(message) + val fetchedEvent = waitForEventRetrieval(eventId.toString()) + fetchedEvent.tags.forEach { println(it["value"]) } + assertEquals(eventId.toString(), fetchedEvent.id) + assertEquals(sentEvent?.message?.formatted, fetchedEvent.message) + assertEquals(message, fetchedEvent.title) + assertEquals(sentEvent?.release, fetchedEvent.release) + assertEquals(2, fetchedEvent.tags.find { it["value"] == sentEvent?.environment }?.size) + assertEquals(sentEvent?.fingerprint?.toList(), fetchedEvent.fingerprint) + assertEquals(2, fetchedEvent.tags.find { it["value"] == sentEvent?.level?.name?.lowercase() }?.size) + assertEquals(sentEvent?.logger, fetchedEvent.logger) + } } - } @Test - fun `capture exception and fetch event from Sentry`() = runTest(timeout = 30.seconds) { - if (platform != "Apple") { - val exceptionMessage = "Test exception on platform $platform" - val eventId = - Sentry.captureException(IllegalArgumentException(exceptionMessage)) - val fetchedEvent = waitForEventRetrieval(eventId.toString()) - assertEquals(eventId.toString(), fetchedEvent.id) - assertEquals("IllegalArgumentException: $exceptionMessage", fetchedEvent.title) - assertEquals(sentEvent?.release, fetchedEvent.release) - assertEquals(2, fetchedEvent.tags.find { it["value"] == sentEvent?.environment }?.size) - assertEquals(sentEvent?.fingerprint?.toList(), fetchedEvent.fingerprint) - assertEquals(2, fetchedEvent.tags.find { it["value"] == SentryLevel.ERROR.toString().lowercase() }?.size) - assertEquals(sentEvent?.logger, fetchedEvent.logger) + fun `capture exception and fetch event from Sentry`() = + runTest(timeout = 30.seconds) { + if (platform != "Apple") { + val exceptionMessage = "Test exception on platform $platform" + val eventId = + Sentry.captureException(IllegalArgumentException(exceptionMessage)) + val fetchedEvent = waitForEventRetrieval(eventId.toString()) + assertEquals(eventId.toString(), fetchedEvent.id) + assertEquals("IllegalArgumentException: $exceptionMessage", fetchedEvent.title) + assertEquals(sentEvent?.release, fetchedEvent.release) + assertEquals(2, fetchedEvent.tags.find { it["value"] == sentEvent?.environment }?.size) + assertEquals(sentEvent?.fingerprint?.toList(), fetchedEvent.fingerprint) + assertEquals(2, fetchedEvent.tags.find { it["value"] == SentryLevel.ERROR.toString().lowercase() }?.size) + assertEquals(sentEvent?.logger, fetchedEvent.logger) + } } - } @AfterTest fun tearDown() { diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryEventConfigurator.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryEventConfigurator.kt index d995661d7..67909fc68 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryEventConfigurator.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryEventConfigurator.kt @@ -6,6 +6,8 @@ package io.sentry.kotlin.multiplatform */ expect class SentryEventConfigurator() { val originalEvent: SentryEvent + fun applyOptions(optionsConfiguration: OptionsConfiguration): SentryEvent? + fun applyOptions(options: SentryOptions = SentryOptions()): SentryEvent? } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryEventTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryEventTest.kt index b9e9607f9..712e3fb54 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryEventTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryEventTest.kt @@ -9,7 +9,6 @@ import kotlin.test.assertNull import kotlin.test.assertTrue class SentryEventTest { - @Test fun `setTag should add a new tag`() { val event = SentryEvent() diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIdTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIdTest.kt index d128d27e1..e5a5417a3 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIdTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIdTest.kt @@ -5,7 +5,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class SentryIdTest { - @Test fun `SentryId with valid uuid string returns valid SentryId string`() { val uuidString = "ec81a720-b6f6-4efc-9d74-6627a09157c1" diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIntegrationTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIntegrationTest.kt index c64c956ce..dc0cf2d3e 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIntegrationTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryIntegrationTest.kt @@ -61,11 +61,17 @@ class SentryIntegrationTest : BaseSentryTest() { assertEquals(2, capturedEvents.size) val event = capturedEvents[0] - event.exceptions.first().type?.let { assertTrue(it.contains("RuntimeException")) } + event.exceptions + .first() + .type + ?.let { assertTrue(it.contains("RuntimeException")) } assertEquals("test", event.exceptions.first().value) val event2 = capturedEvents[1] - event2.exceptions.first().type?.let { assertTrue(it.contains("RuntimeException")) } + event2.exceptions + .first() + .type + ?.let { assertTrue(it.contains("RuntimeException")) } assertEquals("test2", event2.exceptions.first().value) } @@ -213,12 +219,13 @@ class SentryIntegrationTest : BaseSentryTest() { } Sentry.configureScope { - it.user = User().apply { - this.email = expectedEmail - this.id = expectedId - this.ipAddress = expectedIpAddress - this.username = expectedUsername - } + it.user = + User().apply { + this.email = expectedEmail + this.id = expectedId + this.ipAddress = expectedIpAddress + this.username = expectedUsername + } } Sentry.captureException(RuntimeException("test")) @@ -244,59 +251,60 @@ class SentryIntegrationTest : BaseSentryTest() { } @Test - fun `global scope sets context correctly with different data types`() = runTest { - val stringKey = "stringKey" - val stringValue = "stringValue" - val booleanKey = "booleanKey" - val booleanValue = true - val numberKey = "numberKey" - val numberValue = 123 - val collectionKey = "collectionKey" - val collectionValue = listOf("abc", 123, true) - - val expectedStringValue = mapOf("value" to stringValue) - val expectedBooleanValue = mapOf("value" to booleanValue) - val expectedNumberValue = mapOf("value" to numberValue) - val expectedCollectionValue = mapOf("value" to collectionValue) - - var actualStringValue: Map? = null - var actualBooleanValue: Map? = null - var actualNumberValue: Map? = null - var actualCollectionValue: Map? = null - - sentryInit { - it.dsn = fakeDsn - it.beforeSend = { event -> - val contexts = event.contexts - assertNotNull(contexts) - actualStringValue = contexts[stringKey] as Map? - actualBooleanValue = contexts[booleanKey] as Map? - actualNumberValue = contexts[numberKey] as Map? - actualCollectionValue = contexts[collectionKey] as Map? - null + fun `global scope sets context correctly with different data types`() = + runTest { + val stringKey = "stringKey" + val stringValue = "stringValue" + val booleanKey = "booleanKey" + val booleanValue = true + val numberKey = "numberKey" + val numberValue = 123 + val collectionKey = "collectionKey" + val collectionValue = listOf("abc", 123, true) + + val expectedStringValue = mapOf("value" to stringValue) + val expectedBooleanValue = mapOf("value" to booleanValue) + val expectedNumberValue = mapOf("value" to numberValue) + val expectedCollectionValue = mapOf("value" to collectionValue) + + var actualStringValue: Map? = null + var actualBooleanValue: Map? = null + var actualNumberValue: Map? = null + var actualCollectionValue: Map? = null + + sentryInit { + it.dsn = fakeDsn + it.beforeSend = { event -> + val contexts = event.contexts + assertNotNull(contexts) + actualStringValue = contexts[stringKey] as Map? + actualBooleanValue = contexts[booleanKey] as Map? + actualNumberValue = contexts[numberKey] as Map? + actualCollectionValue = contexts[collectionKey] as Map? + null + } } - } - Sentry.configureScope { - it.setContext(stringKey, stringValue) - it.setContext(booleanKey, booleanValue) - it.setContext(numberKey, numberValue) - it.setContext(collectionKey, collectionValue) - } + Sentry.configureScope { + it.setContext(stringKey, stringValue) + it.setContext(booleanKey, booleanValue) + it.setContext(numberKey, numberValue) + it.setContext(collectionKey, collectionValue) + } - Sentry.captureException(RuntimeException("test")) + Sentry.captureException(RuntimeException("test")) - assertEquals(expectedStringValue, actualStringValue) - assertEquals(expectedBooleanValue, actualBooleanValue) - assertEquals(expectedNumberValue, actualNumberValue) - assertEquals(expectedCollectionValue, actualCollectionValue) - } + assertEquals(expectedStringValue, actualStringValue) + assertEquals(expectedBooleanValue, actualBooleanValue) + assertEquals(expectedNumberValue, actualNumberValue) + assertEquals(expectedCollectionValue, actualCollectionValue) + } // region Logger Tests private fun initWithLogCapture( enabled: Boolean = true, - beforeSend: ((SentryLog) -> SentryLog?)? = null + beforeSend: ((SentryLog) -> SentryLog?)? = null, ): MutableList { val capturedLogs = mutableListOf() sentryInit { @@ -323,14 +331,15 @@ class SentryIntegrationTest : BaseSentryTest() { assertEquals(6, capturedLogs.size) - val expectedLevels = listOf( - SentryLogLevel.TRACE, - SentryLogLevel.DEBUG, - SentryLogLevel.INFO, - SentryLogLevel.WARN, - SentryLogLevel.ERROR, - SentryLogLevel.FATAL - ) + val expectedLevels = + listOf( + SentryLogLevel.TRACE, + SentryLogLevel.DEBUG, + SentryLogLevel.INFO, + SentryLogLevel.WARN, + SentryLogLevel.ERROR, + SentryLogLevel.FATAL, + ) val expectedBodies = listOf("trace", "debug", "info", "warn", "error", "fatal") capturedLogs.forEachIndexed { index, log -> diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelConversionTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelConversionTest.kt index ca429292b..afa21aed0 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelConversionTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelConversionTest.kt @@ -4,7 +4,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class SentryLevelConversionTest { - private var converter: SentryLevelTestConverter? = SentryLevelTestConverter() @Test diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt index 27f80a0bc..d7988b231 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryLevelTestConverter.kt @@ -1,6 +1,5 @@ package io.sentry.kotlin.multiplatform expect class SentryLevelTestConverter() { - fun convert(sentryLevel: SentryLevel?): SentryLevel? } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryOptionsTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryOptionsTest.kt index 293caf8ee..0c6187cb5 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryOptionsTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/SentryOptionsTest.kt @@ -47,19 +47,21 @@ class SentryOptionsTest : BaseSentryTest() { configuration.invoke(options) } - val expectedBreadcrumb = Breadcrumb().apply { - message = "changed message" - type = "changed type" - category = "changed category" - setData(mutableMapOf("data1" to 12, "data2" to "value", "key" to "value")) - } + val expectedBreadcrumb = + Breadcrumb().apply { + message = "changed message" + type = "changed type" + category = "changed category" + setData(mutableMapOf("data1" to 12, "data2" to "value", "key" to "value")) + } - val breadcrumb = Breadcrumb().apply { - message = "another message" - type = "another type" - category = "another category" - setData(mutableMapOf("data1" to 12, "data2" to "value")) - } + val breadcrumb = + Breadcrumb().apply { + message = "another message" + type = "another type" + category = "another category" + setData(mutableMapOf("data1" to 12, "data2" to "value")) + } mockInit { it.beforeBreadcrumb = { breadcrumb -> @@ -140,36 +142,37 @@ class SentryOptionsTest : BaseSentryTest() { @Test fun `GIVEN non-default SentryOptions WHEN options initialized THEN applies values to native options`() { - val options = SentryOptions().apply { - dsn = fakeDsn - attachStackTrace = false - release = "release" - debug = true - environment = "environment" - dist = "dist" - enableAutoSessionTracking = false - sessionTrackingIntervalMillis = 1000L - diagnosticLevel = SentryLevel.ERROR - maxBreadcrumbs = 10 - maxAttachmentSize = 100L - sampleRate = 0.5 - tracesSampleRate = 0.5 - attachScreenshot = true - attachViewHierarchy = true - enableAppHangTracking = false - appHangTimeoutIntervalMillis = 1000L - isAnrEnabled = false - anrTimeoutIntervalMillis = 1000L - enableWatchdogTerminationTracking = false - enableUnhandledCppExceptionMonitoring = false - sessionReplay.onErrorSampleRate = 0.5 - sessionReplay.sessionSampleRate = 0.5 - sessionReplay.maskAllText = false - sessionReplay.maskAllImages = false - sessionReplay.quality = SentryReplayOptions.Quality.LOW - sendDefaultPii = true - proguardUuid = "test-proguard-uuid-12345" - } + val options = + SentryOptions().apply { + dsn = fakeDsn + attachStackTrace = false + release = "release" + debug = true + environment = "environment" + dist = "dist" + enableAutoSessionTracking = false + sessionTrackingIntervalMillis = 1000L + diagnosticLevel = SentryLevel.ERROR + maxBreadcrumbs = 10 + maxAttachmentSize = 100L + sampleRate = 0.5 + tracesSampleRate = 0.5 + attachScreenshot = true + attachViewHierarchy = true + enableAppHangTracking = false + appHangTimeoutIntervalMillis = 1000L + isAnrEnabled = false + anrTimeoutIntervalMillis = 1000L + enableWatchdogTerminationTracking = false + enableUnhandledCppExceptionMonitoring = false + sessionReplay.onErrorSampleRate = 0.5 + sessionReplay.sessionSampleRate = 0.5 + sessionReplay.maskAllText = false + sessionReplay.maskAllImages = false + sessionReplay.quality = SentryReplayOptions.Quality.LOW + sendDefaultPii = true + proguardUuid = "test-proguard-uuid-12345" + } val platformOptions = createPlatformOptions() platformOptions.applyFromOptions(options) diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackTest.kt index c6b09de33..e1ce35adc 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserFeedbackTest.kt @@ -6,7 +6,6 @@ import kotlin.test.Test import kotlin.test.assertEquals class UserFeedbackTest { - private val sentryIdString = "dcebada57d794590a6da3d1977eed58a" @Test diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserTest.kt index f343d1d07..e2215228d 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/UserTest.kt @@ -8,8 +8,8 @@ import kotlin.test.assertEquals class UserTest { private var user = User() - private fun createTestUser(): User { - return User().apply { + private fun createTestUser(): User = + User().apply { username = "TestUsername" email = "TestEmail" id = "TestId" @@ -17,7 +17,6 @@ class UserTest { unknown = mutableMapOf("key" to "value", "key2" to 12) other = mutableMapOf("key" to "value") } - } @BeforeTest fun setup() { diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/BaseSentryLoggerTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/BaseSentryLoggerTest.kt index 666a384e4..a9c2ce814 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/BaseSentryLoggerTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/BaseSentryLoggerTest.kt @@ -5,7 +5,6 @@ import kotlin.test.assertEquals import kotlin.test.assertTrue class BaseSentryLoggerTest { - // region Simple message API (level-specific) @Test @@ -497,7 +496,12 @@ class BaseSentryLoggerTest { assertEquals(1, logger.logs.size) assertEquals(SentryLogLevel.TRACE, logger.logs[0].level) assertEquals("User alice logged in", logger.logs[0].formatted.body) - assertEquals("us-east", logger.logs[0].formatted.attributes["region"]?.stringOrNull) + assertEquals( + "us-east", + logger.logs[0] + .formatted.attributes["region"] + ?.stringOrNull, + ) } @Test @@ -629,9 +633,9 @@ class BaseSentryLoggerTest { SentryLogLevel.INFO, SentryLogLevel.WARN, SentryLogLevel.ERROR, - SentryLogLevel.FATAL + SentryLogLevel.FATAL, ), - logger.logs.map { it.level } + logger.logs.map { it.level }, ) } @@ -642,11 +646,17 @@ class BaseSentryLoggerTest { * Test implementation of [BaseSentryLogger] that captures all logs for verification. */ private class TestSentryLogger : BaseSentryLogger(::DefaultSentryLogBuilder) { - data class CapturedLog(val level: SentryLogLevel, val formatted: FormattedLog) + data class CapturedLog( + val level: SentryLogLevel, + val formatted: FormattedLog, + ) val logs = mutableListOf() - override fun sendLog(level: SentryLogLevel, formatted: FormattedLog) { + override fun sendLog( + level: SentryLogLevel, + formatted: FormattedLog, + ) { logs.add(CapturedLog(level, formatted)) } } diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogBuilderTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogBuilderTest.kt index bcc0edda0..93d4d3808 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogBuilderTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogBuilderTest.kt @@ -8,7 +8,6 @@ import kotlin.test.assertTrue /** Tests for [DefaultSentryLogBuilder] DSL builder. */ class SentryLogBuilderTest { - // region Message configuration @Test diff --git a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogOptionsTest.kt b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogOptionsTest.kt index 003fc74a8..840ec0d76 100644 --- a/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogOptionsTest.kt +++ b/sentry-kotlin-multiplatform/src/commonTest/kotlin/io/sentry/kotlin/multiplatform/log/SentryLogOptionsTest.kt @@ -7,7 +7,6 @@ import kotlin.test.assertNull /** Tests for [SentryLogOptions] configuration and beforeSend callback. */ class SentryLogOptionsTest { - @Test fun `enabled is false by default`() { val options = SentryLogOptions() @@ -102,6 +101,6 @@ class SentryLogOptionsTest { private fun createTestLog( timestamp: Double = 1234567890.0, level: SentryLogLevel = SentryLogLevel.INFO, - body: String = "test message" + body: String = "test message", ): SentryLog = SentryLog(timestamp, level, body) } diff --git a/sentry-kotlin-multiplatform/src/commonTvWatchMacOsMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.tvwatchmacos.kt b/sentry-kotlin-multiplatform/src/commonTvWatchMacOsMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.tvwatchmacos.kt index c2c52ad06..f801bb0d2 100644 --- a/sentry-kotlin-multiplatform/src/commonTvWatchMacOsMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.tvwatchmacos.kt +++ b/sentry-kotlin-multiplatform/src/commonTvWatchMacOsMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.tvwatchmacos.kt @@ -4,5 +4,4 @@ import io.sentry.kotlin.multiplatform.extensions.toCocoaOptionsConfiguration public actual typealias SentryPlatformOptions = cocoapods.Sentry.SentryOptions -internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration = - toCocoaOptionsConfiguration() +internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration = toCocoaOptionsConfiguration() diff --git a/sentry-kotlin-multiplatform/src/commonTvWatchMacOsTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.tvwatchmacos.kt b/sentry-kotlin-multiplatform/src/commonTvWatchMacOsTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.tvwatchmacos.kt index c3f579a22..7d9a4818a 100644 --- a/sentry-kotlin-multiplatform/src/commonTvWatchMacOsTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.tvwatchmacos.kt +++ b/sentry-kotlin-multiplatform/src/commonTvWatchMacOsTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.tvwatchmacos.kt @@ -2,8 +2,9 @@ package io.sentry.kotlin.multiplatform actual interface ApplePlatformOptions : PlatformOptions -class SentryTvWatchMacOsOptionsWrapper(cocoaOptions: CocoaSentryOptions) : - SentryAppleOptionsWrapper(cocoaOptions), +class SentryTvWatchMacOsOptionsWrapper( + cocoaOptions: CocoaSentryOptions, +) : SentryAppleOptionsWrapper(cocoaOptions), ApplePlatformOptions actual fun createApplePlatformOptions(): PlatformOptions = SentryTvWatchMacOsOptionsWrapper(CocoaSentryOptions()) diff --git a/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.ios.kt b/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.ios.kt index b495be182..31d07b259 100644 --- a/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.ios.kt +++ b/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.ios.kt @@ -4,5 +4,4 @@ import io.sentry.kotlin.multiplatform.extensions.toIosOptionsConfiguration public actual typealias SentryPlatformOptions = cocoapods.Sentry.SentryOptions -internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration = - toIosOptionsConfiguration() +internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration = toIosOptionsConfiguration() diff --git a/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.ios.kt b/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.ios.kt index f5311921b..4bec55fd9 100644 --- a/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.ios.kt +++ b/sentry-kotlin-multiplatform/src/iosMain/kotlin/io/sentry/kotlin/multiplatform/extensions/SentryOptionsExtensions.ios.kt @@ -4,34 +4,40 @@ import cocoapods.Sentry.SentryReplayOptions import io.sentry.kotlin.multiplatform.CocoaSentryOptions import io.sentry.kotlin.multiplatform.SentryOptions -internal fun SentryOptions.toIosOptionsConfiguration(): (CocoaSentryOptions?) -> Unit = { options -> - options?.let { cocoaOptions -> - val kmpOptions = this@toIosOptionsConfiguration +internal fun SentryOptions.toIosOptionsConfiguration(): (CocoaSentryOptions?) -> Unit = + { options -> + options?.let { cocoaOptions -> + val kmpOptions = this@toIosOptionsConfiguration - // Apply base options available to all Cocoa/Apple targets - cocoaOptions.applyCocoaBaseOptions(kmpOptions) + // Apply base options available to all Cocoa/Apple targets + cocoaOptions.applyCocoaBaseOptions(kmpOptions) - // Apply iOS specific options - cocoaOptions.attachScreenshot = this.attachScreenshot - cocoaOptions.attachViewHierarchy = this.attachViewHierarchy + // Apply iOS specific options + cocoaOptions.attachScreenshot = this.attachScreenshot + cocoaOptions.attachViewHierarchy = this.attachViewHierarchy - // Replay options - val replayOptions = SentryReplayOptions( - dictionary = mapOf( - // Setting the onErrorSampleRate like this, using setOnErrorSampleRate - // crashes on compose multiplatform for some unknown reason - "errorSampleRate" to kmpOptions.sessionReplay.onErrorSampleRate?.toFloat() - ) - ).apply { - setMaskAllText(kmpOptions.sessionReplay.maskAllText) - setMaskAllImages(kmpOptions.sessionReplay.maskAllImages) - kmpOptions.sessionReplay.sessionSampleRate?.let { setSessionSampleRate(it.toFloat()) } - setQuality(kmpOptions.sessionReplay.quality.ordinal.toLong()) + // Replay options + val replayOptions = + SentryReplayOptions( + dictionary = + mapOf( + // Setting the onErrorSampleRate like this, using setOnErrorSampleRate + // crashes on compose multiplatform for some unknown reason + "errorSampleRate" to kmpOptions.sessionReplay.onErrorSampleRate?.toFloat(), + ), + ).apply { + setMaskAllText(kmpOptions.sessionReplay.maskAllText) + setMaskAllImages(kmpOptions.sessionReplay.maskAllImages) + kmpOptions.sessionReplay.sessionSampleRate?.let { setSessionSampleRate(it.toFloat()) } + setQuality( + kmpOptions.sessionReplay.quality.ordinal + .toLong(), + ) + } + cocoaOptions.setSessionReplay(replayOptions) + } ?: run { + // Log a warning if options is null + // TODO: Replace with actual logging when a logger is available + println("Warning: CocoaSentryOptions is null, skipping iOS configuration") } - cocoaOptions.setSessionReplay(replayOptions) - } ?: run { - // Log a warning if options is null - // TODO: Replace with actual logging when a logger is available - println("Warning: CocoaSentryOptions is null, skipping iOS configuration") } -} diff --git a/sentry-kotlin-multiplatform/src/iosTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.ios.kt b/sentry-kotlin-multiplatform/src/iosTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.ios.kt index 914eb46fb..d66b6e9aa 100644 --- a/sentry-kotlin-multiplatform/src/iosTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.ios.kt +++ b/sentry-kotlin-multiplatform/src/iosTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.ios.kt @@ -12,7 +12,10 @@ actual interface ApplePlatformOptions : PlatformOptions { val sessionReplay: SentryReplayOptions } -class SentryIosOptionsWrapper(private val cocoaOptions: CocoaSentryOptions) : SentryAppleOptionsWrapper(cocoaOptions), ApplePlatformOptions { +class SentryIosOptionsWrapper( + private val cocoaOptions: CocoaSentryOptions, +) : SentryAppleOptionsWrapper(cocoaOptions), + ApplePlatformOptions { override val attachScreenshot: Boolean get() = cocoaOptions.attachScreenshot @@ -45,5 +48,9 @@ actual fun ApplePlatformOptions.assertApplePlatformSpecificOptions(options: Sent assertEquals(sessionReplay.maskAllImages(), options.sessionReplay.maskAllImages) assertEquals(sessionReplay.onErrorSampleRate().toDouble(), options.sessionReplay.onErrorSampleRate) assertEquals(sessionReplay.sessionSampleRate().toDouble(), options.sessionReplay.sessionSampleRate) - assertEquals(sessionReplay.quality(), options.sessionReplay.quality.ordinal.toLong()) + assertEquals( + sessionReplay.quality(), + options.sessionReplay.quality.ordinal + .toLong(), + ) } diff --git a/sentry-kotlin-multiplatform/src/jvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.jvm.kt b/sentry-kotlin-multiplatform/src/jvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.jvm.kt index 0a7a8d285..c42082418 100644 --- a/sentry-kotlin-multiplatform/src/jvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/jvmMain/kotlin/io/sentry/kotlin/multiplatform/SentryPlatformOptions.jvm.kt @@ -12,5 +12,4 @@ internal actual fun SentryPlatformOptions.prepareForInit() { } } -internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration = - toJvmSentryOptionsCallback() +internal actual fun SentryOptions.toPlatformOptionsConfiguration(): PlatformOptionsConfiguration = toJvmSentryOptionsCallback() diff --git a/sentry-kotlin-multiplatform/src/jvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt b/sentry-kotlin-multiplatform/src/jvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt index 717a2b0e3..4886eba40 100644 --- a/sentry-kotlin-multiplatform/src/jvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt +++ b/sentry-kotlin-multiplatform/src/jvmTest/kotlin/io/sentry/kotlin/multiplatform/BaseSentryTest.kt @@ -3,6 +3,7 @@ package io.sentry.kotlin.multiplatform actual abstract class BaseSentryTest { actual val platform: String = "JVM" actual val authToken: String? = System.getenv("SENTRY_AUTH_TOKEN") + actual fun sentryInit(optionsConfiguration: OptionsConfiguration) { Sentry.init(optionsConfiguration) } diff --git a/sentry-kotlin-multiplatform/src/jvmTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.jvm.kt b/sentry-kotlin-multiplatform/src/jvmTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.jvm.kt index 3a8059a1a..3bab0c7c6 100644 --- a/sentry-kotlin-multiplatform/src/jvmTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.jvm.kt +++ b/sentry-kotlin-multiplatform/src/jvmTest/kotlin/io/sentry/kotlin/multiplatform/PlatformOptions.jvm.kt @@ -7,7 +7,9 @@ import kotlin.test.assertEquals actual interface PlatformOptions : CommonPlatformOptions -class SentryJvmOptionsWrapper(private val jvmOptions: JvmSentryOptions) : PlatformOptions { +class SentryJvmOptionsWrapper( + private val jvmOptions: JvmSentryOptions, +) : PlatformOptions { override val dsn: String? get() = jvmOptions.dsn @@ -64,6 +66,7 @@ actual fun PlatformOptions.assertPlatformSpecificOptions(kmpOptions: SentryOptio assertEquals(proguardUuid, kmpOptions.proguardUuid) } -actual fun createSentryPlatformOptionsConfiguration(): PlatformOptionsConfiguration = { - it.dsn = fakeDsn -} +actual fun createSentryPlatformOptionsConfiguration(): PlatformOptionsConfiguration = + { + it.dsn = fakeDsn + } diff --git a/sentry-samples/kmp-app-spm/desktopApp/src/jvmMain/kotlin/sample.kmp.app.desktop/Main.kt b/sentry-samples/kmp-app-spm/desktopApp/src/jvmMain/kotlin/sample.kmp.app.desktop/Main.kt index 987c29d5d..9dd9f8ca4 100644 --- a/sentry-samples/kmp-app-spm/desktopApp/src/jvmMain/kotlin/sample.kmp.app.desktop/Main.kt +++ b/sentry-samples/kmp-app-spm/desktopApp/src/jvmMain/kotlin/sample.kmp.app.desktop/Main.kt @@ -27,7 +27,7 @@ fun App() { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { val btnBackgroundColor = Color(56, 31, 67) Button({ @@ -48,20 +48,21 @@ fun App() { } } -fun main() = application { - Window(onCloseRequest = ::exitApplication, title = "Jetpack Compose Desktop App (SPM Sample Version)") { - // Initialize Sentry using shared code - initializeSentry() +fun main() = + application { + Window(onCloseRequest = ::exitApplication, title = "Jetpack Compose Desktop App (SPM Sample Version)") { + // Initialize Sentry using shared code + initializeSentry() - // Shared scope across all platforms - configureSentryScope() + // Shared scope across all platforms + configureSentryScope() - // Add platform specific scope in addition to the shared scope - Sentry.configureScope { - it.setContext("JVM Desktop Context", mapOf("context1" to 12, "context2" to false)) - it.addBreadcrumb(Breadcrumb.debug("initialized Sentry on JVM Desktop")) - } + // Add platform specific scope in addition to the shared scope + Sentry.configureScope { + it.setContext("JVM Desktop Context", mapOf("context1" to 12, "context2" to false)) + it.addBreadcrumb(Breadcrumb.debug("initialized Sentry on JVM Desktop")) + } - App() + App() + } } -} diff --git a/sentry-samples/kmp-app-spm/shared/build.gradle.kts b/sentry-samples/kmp-app-spm/shared/build.gradle.kts index ac6ff1691..b57a43843 100644 --- a/sentry-samples/kmp-app-spm/shared/build.gradle.kts +++ b/sentry-samples/kmp-app-spm/shared/build.gradle.kts @@ -25,7 +25,7 @@ kotlin { listOf( iosX64(), iosArm64(), - iosSimulatorArm64() + iosSimulatorArm64(), ).forEach { it.binaries.framework { baseName = "shared" diff --git a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt index db6e90c08..06273d38f 100644 --- a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt +++ b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/LoginImpl.kt @@ -6,7 +6,9 @@ import io.sentry.kotlin.multiplatform.protocol.Breadcrumb import io.sentry.kotlin.multiplatform.protocol.User import io.sentry.kotlin.multiplatform.protocol.UserFeedback -class InvalidUsernameException(message: String) : Exception(message) +class InvalidUsernameException( + message: String, +) : Exception(message) object LoginImpl { /** @@ -23,24 +25,27 @@ object LoginImpl { try { validateUsername(username) } catch (exception: InvalidUsernameException) { - val sentryId = Sentry.captureException(exception) { - val breadcrumb = Breadcrumb.debug("this is a test breadcrumb") - breadcrumb.setData("touch event", "on login") - it.addBreadcrumb(breadcrumb) - it.setContext("Login", "Failed with Invalid Username") - it.setTag("login", "failed auth") - it.level = SentryLevel.WARNING - val user = User().apply { - this.username = "John Doe" - this.email = "john@doe.com" + val sentryId = + Sentry.captureException(exception) { + val breadcrumb = Breadcrumb.debug("this is a test breadcrumb") + breadcrumb.setData("touch event", "on login") + it.addBreadcrumb(breadcrumb) + it.setContext("Login", "Failed with Invalid Username") + it.setTag("login", "failed auth") + it.level = SentryLevel.WARNING + val user = + User().apply { + this.username = "John Doe" + this.email = "john@doe.com" + } + it.user = user + } + val userFeedback = + UserFeedback(sentryId).apply { + name = "John Doe" + email = "john@doe.com" + comments = "I had an error during login on ${Platform().platform}" } - it.user = user - } - val userFeedback = UserFeedback(sentryId).apply { - name = "John Doe" - email = "john@doe.com" - comments = "I had an error during login on ${Platform().platform}" - } Sentry.captureUserFeedback(userFeedback) } catch (exception: IllegalArgumentException) { throw exception diff --git a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt index be7e6e27a..e023590cf 100644 --- a/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt +++ b/sentry-samples/kmp-app-spm/shared/src/commonMain/kotlin/sample.kmp.app/SentrySetup.kt @@ -13,8 +13,8 @@ fun configureSentryScope() { it.addAttachment( Attachment( "This is a shared text attachment".encodeToByteArray(), - "shared.log" - ) + "shared.log", + ), ) } } @@ -28,8 +28,8 @@ fun initializeSentry() { } /** Returns a shared options configuration */ -private fun optionsConfiguration(): OptionsConfiguration { - return { +private fun optionsConfiguration(): OptionsConfiguration = + { it.dsn = "https://83f281ded2844eda83a8a413b080dbb9@o447951.ingest.sentry.io/5903800" it.attachStackTrace = true it.attachThreads = true @@ -50,4 +50,3 @@ private fun optionsConfiguration(): OptionsConfiguration { } } } -} diff --git a/sentry-samples/kmp-app-spm/shared/src/iosMain/kotlin/sample.kmp.app/HttpClient.kt b/sentry-samples/kmp-app-spm/shared/src/iosMain/kotlin/sample.kmp.app/HttpClient.kt index b63d03af6..b82766cb0 100644 --- a/sentry-samples/kmp-app-spm/shared/src/iosMain/kotlin/sample.kmp.app/HttpClient.kt +++ b/sentry-samples/kmp-app-spm/shared/src/iosMain/kotlin/sample.kmp.app/HttpClient.kt @@ -9,13 +9,14 @@ import platform.Foundation.dataTaskWithRequest fun captureHttpClientError() { val url = NSURL(string = "https://httpbin.org/status/404") val request = NSURLRequest(uRL = url) - NSURLSession.sharedSession.dataTaskWithRequest(request) { data, response, error -> - if (error != null) { - // handle error - println("error: $error") - } else { - // handle successful response - println("response: $response") - } - }.resume() + NSURLSession.sharedSession + .dataTaskWithRequest(request) { data, response, error -> + if (error != null) { + // handle error + println("error: $error") + } else { + // handle successful response + println("response: $response") + } + }.resume() }