diff --git a/build.gradle.kts b/build.gradle.kts
index 4f7cdb7cbb2..52e17b1d309 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -117,6 +117,7 @@ subprojects {
buildUponDefaultConfig = true
allRules = true
config.setFrom("${rootProject.rootDir}/detekt.yml")
+ baseline = file("detekt-baseline.xml")
}
}
diff --git a/sentry-android-distribution/build.gradle.kts b/sentry-android-distribution/build.gradle.kts
index bd88690c1cc..074d56c08e6 100644
--- a/sentry-android-distribution/build.gradle.kts
+++ b/sentry-android-distribution/build.gradle.kts
@@ -4,6 +4,7 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
plugins {
id("com.android.library")
alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.detekt)
}
android {
diff --git a/sentry-android-distribution/detekt-baseline.xml b/sentry-android-distribution/detekt-baseline.xml
new file mode 100644
index 00000000000..78b4ed376de
--- /dev/null
+++ b/sentry-android-distribution/detekt-baseline.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ MagicNumber:DistributionHttpClient.kt$DistributionHttpClient$200
+ MagicNumber:DistributionHttpClient.kt$DistributionHttpClient$299
+ MagicNumber:DistributionHttpClient.kt$DistributionHttpClient.HttpResponse$200
+ MagicNumber:DistributionHttpClient.kt$DistributionHttpClient.HttpResponse$299
+ MagicNumber:UpdateResponseParser.kt$UpdateResponseParser$200
+ MagicNumber:UpdateResponseParser.kt$UpdateResponseParser$400
+ MagicNumber:UpdateResponseParser.kt$UpdateResponseParser$499
+ MagicNumber:UpdateResponseParser.kt$UpdateResponseParser$500
+ MagicNumber:UpdateResponseParser.kt$UpdateResponseParser$599
+ MaxLineLength:DistributionHttpClient.kt$DistributionHttpClient$"/api/0/projects/${URLEncoder.encode(orgSlug, "UTF-8")}/${URLEncoder.encode(projectSlug, "UTF-8")}/preprodartifacts/check-for-updates/"
+ SwallowedException:DistributionIntegration.kt$DistributionIntegration$e: android.content.ActivityNotFoundException
+ TooGenericExceptionCaught:DistributionIntegration.kt$DistributionIntegration$e: Exception
+ TooGenericExceptionCaught:UpdateResponseParser.kt$UpdateResponseParser$e: Exception
+ UseCheckOrError:DistributionHttpClient.kt$DistributionHttpClient$throw IllegalStateException( "Missing required distribution configuration: orgSlug, projectSlug, or orgAuthToken" )
+ UseCheckOrError:DistributionHttpClient.kt$DistributionHttpClient$throw IllegalStateException("sentryClientName must be set")
+ UseCheckOrError:DistributionIntegration.kt$DistributionIntegration$throw IllegalStateException("buildConfiguration must be set in distribution options")
+ UseRequire:UpdateResponseParser.kt$UpdateResponseParser$throw IllegalArgumentException( "Missing required fields in API response: ${missingFields.joinToString(", ")}" )
+ WildcardImport:DistributionHttpClientTest.kt$import org.junit.Assert.*
+
+
diff --git a/sentry-android-replay/build.gradle.kts b/sentry-android-replay/build.gradle.kts
index 0a40a920a7c..1318f7767c9 100644
--- a/sentry-android-replay/build.gradle.kts
+++ b/sentry-android-replay/build.gradle.kts
@@ -8,8 +8,7 @@ plugins {
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.gradle.versions)
- // TODO: enable it later
- // alias(libs.plugins.detekt)
+ alias(libs.plugins.detekt)
}
android {
diff --git a/sentry-android-replay/detekt-baseline.xml b/sentry-android-replay/detekt-baseline.xml
new file mode 100644
index 00000000000..54c6754e2d8
--- /dev/null
+++ b/sentry-android-replay/detekt-baseline.xml
@@ -0,0 +1,165 @@
+
+
+
+
+ ComplexCondition:ReplayCache.kt$ReplayCache.Companion$height == null || width == null || frameRate == null || bitRate == null || (segmentId == null || segmentId == -1) || segmentTimestamp == null || replayType == null
+ ComplexCondition:ReplayIntegration.kt$ReplayIntegration$isManualPause || lastKnownConnectionStatus == DISCONNECTED || scopes?.rateLimiter?.isActiveForCategory(All) == true || scopes?.rateLimiter?.isActiveForCategory(Replay) == true
+ ComplexCondition:ReplayIntegration.kt$ReplayIntegration$name.startsWith("replay_") && !name.contains(replayId.toString()) && !(unfinishedReplayId.isNotBlank() && name.contains(unfinishedReplayId))
+ ComplexCondition:ReplayIntegration.kt$ReplayIntegration$state.get().captureStrategy is SessionCaptureStrategy && (lastKnownConnectionStatus == DISCONNECTED || scopes?.rateLimiter?.isActiveForCategory(All) == true || scopes?.rateLimiter?.isActiveForCategory(Replay) == true)
+ ComplexCondition:ScreenshotRecorder.kt$ScreenshotRecorder$root == null || root.width <= 0 || root.height <= 0 || !root.isShown
+ ComplexCondition:SimpleVideoEncoder.kt$SimpleVideoEncoder$Build.MANUFACTURER.contains("xiaomi", ignoreCase = true) || Build.MANUFACTURER.contains("motorola", ignoreCase = true) || SystemProperties.get(SystemProperties.Property.SOC_MANUFACTURER) .equals("spreadtrum", ignoreCase = true) || SystemProperties.get(SystemProperties.Property.SOC_MANUFACTURER) .equals("unisoc", ignoreCase = true)
+ CyclomaticComplexMethod:CaptureStrategy.kt$CaptureStrategy.Companion$@Suppress("NewApi") private fun buildReplay( options: SentryOptions, video: File, currentReplayId: SentryId, segmentTimestamp: Date, segmentId: Int, height: Int, width: Int, frameCount: Int, frameRate: Int, videoDuration: Long, replayType: ReplayType, screenAtStart: String?, breadcrumbs: List<Breadcrumb>, events: Deque<RRWebEvent>, traceIds: List<String>, segmentNames: List<String>, ): ReplaySegment
+ CyclomaticComplexMethod:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$private fun fromComposeNode( node: LayoutNode, parent: ViewHierarchyNode?, distance: Int, isComposeRoot: Boolean, options: SentryMaskingOptions, logger: ILogger, ): ViewHierarchyNode?
+ CyclomaticComplexMethod:DefaultReplayBreadcrumbConverter.kt$DefaultReplayBreadcrumbConverter$override fun convert(breadcrumb: Breadcrumb): RRWebEvent?
+ CyclomaticComplexMethod:DefaultReplayBreadcrumbConverter.kt$DefaultReplayBreadcrumbConverter$private fun Breadcrumb.toRRWebSpanEvent(): RRWebSpanEvent
+ CyclomaticComplexMethod:ReplayCache.kt$ReplayCache$public fun createVideoOf( duration: Long, from: Long, segmentId: Int, height: Int, width: Int, frameRate: Int, bitRate: Int, videoFile: File = File(replayCacheDir, "$segmentId.mp4"), ): GeneratedVideo?
+ CyclomaticComplexMethod:ReplayCache.kt$ReplayCache.Companion$internal fun fromDisk( options: SentryOptions, replayId: SentryId, replayCacheProvider: ((replayId: SentryId) -> ReplayCache)? = null, ): LastSegmentData?
+ CyclomaticComplexMethod:ReplayGestureConverter.kt$ReplayGestureConverter$fun convert( event: MotionEvent, recorderConfig: ScreenshotRecorderConfig, ): List<RRWebIncrementalSnapshotEvent>?
+ CyclomaticComplexMethod:ReplayLifecycle.kt$internal fun ReplayLifecycleState.isAllowed(newState: ReplayLifecycleState): Boolean
+ CyclomaticComplexMethod:SimpleVideoEncoder.kt$SimpleVideoEncoder$private fun drainCodec(endOfStream: Boolean)
+ EmptyCatchBlock:ReplaySmokeTest.kt$ReplaySmokeTest${}
+ EmptyDefaultConstructor:ScreenshotRecorderTest.kt$ScreenshotRecorderTest.Fixture$()
+ EmptyFunctionBlock:ReplayExecutorService.kt$CompletedFuture${}
+ ForbiddenComment:BufferCaptureStrategy.kt$BufferCaptureStrategy$// TODO: can be a single while-loop
+ ForbiddenComment:BufferCaptureStrategy.kt$BufferCaptureStrategy$// TODO: capture envelopes for buffered segments instead, but don't send them until buffer is
+ ForbiddenComment:CaptureStrategy.kt$CaptureStrategy.Companion$// TODO: support non-fullscreen windows later
+ ForbiddenComment:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$// TODO: if we get reports that it's slow, we can drop this, and just mask
+ ForbiddenComment:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$// TODO: support editable text (currently there's a way to get @Composable's padding only
+ ForbiddenComment:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$// TODO: the whole view instead of per-line
+ ForbiddenComment:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$// TODO: this currently does not support embedded AndroidViews, we'd have to
+ ForbiddenComment:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$// TODO: traverse the ViewHierarchyNode here again. For now we can recommend
+ ForbiddenComment:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$// TODO: using custom modifiers to obscure the entire node if it's sensitive
+ ForbiddenComment:Nodes.kt$// TODO: probably most of the below we can do via bytecode instrumentation and speed up at runtime
+ ForbiddenComment:Persistable.kt$PersistableLinkedList$// TODO: enable this back after we are able to serialize individual touches to disk to not overload
+ ForbiddenComment:PixelCopyStrategy.kt$PixelCopyStrategy$// TODO: disableAllMasking here and dont traverse?
+ ForbiddenComment:ReplayCache.kt$ReplayCache$// TODO: it's awful, choose a better serialization format
+ ForbiddenComment:ReplayIntegration.kt$ReplayIntegration$// TODO: previous run and set them directly to the ReplayEvent so they don't get overwritten in
+ ForbiddenComment:ReplayIntegration.kt$ReplayIntegration$// TODO: read persisted options/scope values form the
+ ForbiddenComment:ReplaySmokeTest.kt$ReplaySmokeTest$// TODO: figure out why there's more than 10
+ ForbiddenComment:SimpleVideoEncoder.kt$SimpleVideoEncoder$// TODO: because the screenshot config has to match the video config
+ ForbiddenComment:SimpleVideoEncoder.kt$SimpleVideoEncoder$// TODO: if this ever becomes a problem, move this to ScreenshotRecorderConfig.from()
+ ForbiddenComment:SimpleVideoEncoder.kt$SimpleVideoEncoder$// TODO: maybe enable this back later, for now variable bitrate seems to provide much better
+ ForbiddenComment:SimpleVideoEncoder.kt$SimpleVideoEncoder$// TODO: quality with almost no overhead in terms of video size, let's monitor that
+ ForbiddenComment:Views.kt$// TODO: maybe find a way how to check if the drawable is coming from the apk or loaded from
+ ForbiddenComment:Views.kt$// TODO: otherwise maybe check for the bitmap size and don't mask those that take a lot of height
+ FunctionParameterNaming:PixelCopyStrategyTest.kt$DeferredWindowPixelCopyShadow.Companion$_dest: Bitmap
+ FunctionParameterNaming:PixelCopyStrategyTest.kt$DeferredWindowPixelCopyShadow.Companion$_source: Window
+ LargeClass:CanvasStrategy.kt$TextIgnoringDelegateCanvas : Canvas
+ LargeClass:ReplayIntegrationTest.kt$ReplayIntegrationTest
+ LongMethod:CaptureStrategy.kt$CaptureStrategy.Companion$@Suppress("NewApi") private fun buildReplay( options: SentryOptions, video: File, currentReplayId: SentryId, segmentTimestamp: Date, segmentId: Int, height: Int, width: Int, frameCount: Int, frameRate: Int, videoDuration: Long, replayType: ReplayType, screenAtStart: String?, breadcrumbs: List<Breadcrumb>, events: Deque<RRWebEvent>, traceIds: List<String>, segmentNames: List<String>, ): ReplaySegment
+ LongMethod:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$private fun fromComposeNode( node: LayoutNode, parent: ViewHierarchyNode?, distance: Int, isComposeRoot: Boolean, options: SentryMaskingOptions, logger: ILogger, ): ViewHierarchyNode?
+ LongMethod:DefaultReplayBreadcrumbConverter.kt$DefaultReplayBreadcrumbConverter$override fun convert(breadcrumb: Breadcrumb): RRWebEvent?
+ LongMethod:DefaultReplayBreadcrumbConverter.kt$DefaultReplayBreadcrumbConverter$private fun Breadcrumb.toRRWebSpanEvent(): RRWebSpanEvent
+ LongMethod:PixelCopyStrategy.kt$PixelCopyStrategy$@SuppressLint("NewApi") override fun capture(root: View)
+ LongMethod:ReplayCache.kt$ReplayCache$public fun createVideoOf( duration: Long, from: Long, segmentId: Int, height: Int, width: Int, frameRate: Int, bitRate: Int, videoFile: File = File(replayCacheDir, "$segmentId.mp4"), ): GeneratedVideo?
+ LongMethod:ReplayCache.kt$ReplayCache.Companion$internal fun fromDisk( options: SentryOptions, replayId: SentryId, replayCacheProvider: ((replayId: SentryId) -> ReplayCache)? = null, ): LastSegmentData?
+ LongMethod:ReplayGestureConverter.kt$ReplayGestureConverter$fun convert( event: MotionEvent, recorderConfig: ScreenshotRecorderConfig, ): List<RRWebIncrementalSnapshotEvent>?
+ LongMethod:ReplayGestureConverterTest.kt$ReplayGestureConverterTest$@Test fun `convert multi-pointer events`()
+ LongMethod:ReplayIntegrationTest.kt$ReplayIntegrationTest$@Test fun `register finalizes previous replay`()
+ LongMethod:ReplayIntegrationWithRecorderTest.kt$ReplayIntegrationWithRecorderTest$@Test fun `works with different recorder`()
+ LongMethod:SimpleVideoEncoder.kt$SimpleVideoEncoder$private fun drainCodec(endOfStream: Boolean)
+ LongMethod:ViewHierarchyNode.kt$ViewHierarchyNode.Companion$@JvmStatic fun fromView( view: View, parent: ViewHierarchyNode?, distance: Int, options: SentryMaskingOptions, ): ViewHierarchyNode
+ LongParameterList:BaseCaptureStrategy.kt$BaseCaptureStrategy$( duration: Long, currentSegmentTimestamp: Date, replayId: SentryId, segmentId: Int, height: Int, width: Int, frameRate: Int, bitRate: Int, replayType: ReplayType = this.replayType, cache: ReplayCache? = this.cache, screenAtStart: String? = this.screenAtStart, breadcrumbs: List<Breadcrumb>? = null, events: Deque<RRWebEvent> = this.currentEvents, )
+ LongParameterList:CaptureStrategy.kt$CaptureStrategy.Companion$( options: SentryOptions, video: File, currentReplayId: SentryId, segmentTimestamp: Date, segmentId: Int, height: Int, width: Int, frameCount: Int, frameRate: Int, videoDuration: Long, replayType: ReplayType, screenAtStart: String?, breadcrumbs: List<Breadcrumb>, events: Deque<RRWebEvent>, traceIds: List<String>, segmentNames: List<String>, )
+ LongParameterList:CaptureStrategy.kt$CaptureStrategy.Companion$( scopes: IScopes?, options: SentryOptions, duration: Long, currentSegmentTimestamp: Date, replayId: SentryId, segmentId: Int, height: Int, width: Int, replayType: ReplayType, cache: ReplayCache?, frameRate: Int, bitRate: Int, screenAtStart: String?, breadcrumbs: List<Breadcrumb>?, events: Deque<RRWebEvent>, traceIds: List<String> = emptyList(), segmentNames: List<String> = emptyList(), )
+ LongParameterList:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$( node: LayoutNode, parent: ViewHierarchyNode?, distance: Int, isComposeRoot: Boolean, options: SentryMaskingOptions, logger: ILogger, )
+ LongParameterList:PixelCopyStrategy.kt$( destCanvas: Canvas, destPaint: Paint, tmpSrc: Rect, tmpDst: RectF, sourceBitmap: Bitmap, sourceX: Int, sourceY: Int, windowX: Int, windowY: Int, scaleFactorX: Float, scaleFactorY: Float, )
+ LongParameterList:PixelCopyStrategy.kt$PixelCopyStrategy$( root: View, captures: Array<SurfaceViewCapture?>, viewHierarchy: ViewHierarchyNode, windowX: Int, windowY: Int, resetUnstableCaptures: Boolean, )
+ LongParameterList:ReplayCache.kt$ReplayCache$( duration: Long, from: Long, segmentId: Int, height: Int, width: Int, frameRate: Int, bitRate: Int, videoFile: File = File(replayCacheDir, "$segmentId.mp4"), )
+ LongParameterList:ReplayIntegration.kt$ReplayIntegration$( context: Context, dateProvider: ICurrentDateProvider, recorderProvider: (() -> Recorder)?, replayCacheProvider: ((replayId: SentryId) -> ReplayCache)?, replayCaptureStrategyProvider: ((isFullSession: Boolean) -> CaptureStrategy)? = null, mainLooperHandler: MainLooperHandler? = null, gestureRecorderProvider: (() -> GestureRecorder)? = null, )
+ LongParameterList:ReplayIntegrationTest.kt$ReplayIntegrationTest.Fixture$( context: Context, sessionSampleRate: Double = 1.0, onErrorSampleRate: Double = 1.0, isRateLimited: Boolean = false, recorderProvider: (() -> Recorder)? = null, replayCaptureStrategyProvider: ((isFullSession: Boolean) -> CaptureStrategy)? = null, gestureRecorderProvider: (() -> GestureRecorder)? = null, dateProvider: ICurrentDateProvider = CurrentDateProvider.getInstance(), mainLooperHandler: MainLooperHandler = mock { doAnswer { (it.arguments[0] as Runnable).run() true } .whenever(mock) .post(any()) }, )
+ LongParameterList:ViewHierarchyNode.kt$ViewHierarchyNode$( val x: Float, val y: Float, val width: Int, val height: Int, // Elevation (in px) val elevation: Float, // Distance to the parent (index) val distance: Int, val parent: ViewHierarchyNode? = null, val shouldMask: Boolean = false, // Whether the node is important for content capture (=non-empty container) var isImportantForContentCapture: Boolean = false, val isVisible: Boolean = false, val visibleRect: Rect? = null, )
+ LongParameterList:ViewHierarchyNode.kt$ViewHierarchyNode.GenericViewHierarchyNode$( x: Float, y: Float, width: Int, height: Int, elevation: Float, distance: Int, parent: ViewHierarchyNode? = null, shouldMask: Boolean = false, isImportantForContentCapture: Boolean = false, isVisible: Boolean = false, visibleRect: Rect? = null, )
+ LongParameterList:ViewHierarchyNode.kt$ViewHierarchyNode.ImageViewHierarchyNode$( x: Float, y: Float, width: Int, height: Int, elevation: Float, distance: Int, parent: ViewHierarchyNode? = null, shouldMask: Boolean = false, isImportantForContentCapture: Boolean = false, isVisible: Boolean = false, visibleRect: Rect? = null, )
+ LongParameterList:ViewHierarchyNode.kt$ViewHierarchyNode.SurfaceViewHierarchyNode$( val surfaceViewRef: WeakReference<SurfaceView>, x: Float, y: Float, width: Int, height: Int, elevation: Float, distance: Int, parent: ViewHierarchyNode? = null, shouldMask: Boolean = false, isImportantForContentCapture: Boolean = false, isVisible: Boolean = false, visibleRect: Rect? = null, )
+ LongParameterList:ViewHierarchyNode.kt$ViewHierarchyNode.TextViewHierarchyNode$( val layout: TextLayout? = null, val dominantColor: Int? = null, val paddingLeft: Int = 0, val paddingTop: Int = 0, x: Float, y: Float, width: Int, height: Int, elevation: Float, distance: Int, parent: ViewHierarchyNode? = null, shouldMask: Boolean = false, isImportantForContentCapture: Boolean = false, isVisible: Boolean = false, visibleRect: Rect? = null, )
+ LoopWithTooManyJumpStatements:PixelCopyStrategy.kt$PixelCopyStrategy$for
+ LoopWithTooManyJumpStatements:ReplayCache.kt$ReplayCache$while
+ LoopWithTooManyJumpStatements:SimpleVideoEncoder.kt$SimpleVideoEncoder$while
+ MagicNumber:BaseCaptureStrategy.kt$BaseCaptureStrategy$26
+ MagicNumber:BufferCaptureStrategy.kt$BufferCaptureStrategy$26
+ MagicNumber:CanvasStrategy.kt$TextIgnoringDelegateCanvas$100
+ MagicNumber:CanvasStrategy.kt$TextIgnoringDelegateCanvas$10f
+ MagicNumber:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$26
+ MagicNumber:DebugOverlayDrawable.kt$DebugOverlayDrawable$6f
+ MagicNumber:DefaultReplayBreadcrumbConverter.kt$DefaultReplayBreadcrumbConverter$1000.0
+ MagicNumber:Persistable.kt$PersistableLinkedList$26
+ MagicNumber:ReplayCache.kt$ReplayCache$1000
+ MagicNumber:ReplayCache.kt$ReplayCache.Companion$1000
+ MagicNumber:ReplayGestureConverter.kt$ReplayGestureConverter$10
+ MagicNumber:ScreenshotRecorder.kt$ScreenshotRecorder$26
+ MagicNumber:ScreenshotRecorder.kt$ScreenshotRecorderConfig.Companion$16
+ MagicNumber:ScreenshotRecorder.kt$ScreenshotRecorderConfig.Companion$8
+ MagicNumber:SimpleVideoEncoder.kt$MuxerConfig$24
+ MagicNumber:SimpleVideoEncoder.kt$SimpleVideoEncoder$26
+ MagicNumber:SimpleVideoEncoder.kt$SimpleVideoEncoder$6
+ MagicNumber:ViewHierarchyNode.kt$ViewHierarchyNode$26
+ MagicNumber:Views.kt$10
+ MagicNumber:Views.kt$21
+ MagicNumber:WindowRecorder.kt$WindowRecorder$100L
+ MagicNumber:WindowRecorder.kt$WindowRecorder$26
+ MagicNumber:WindowRecorder.kt$WindowRecorder.Capturer$1000L
+ MatchingDeclarationName:ModifierExtensions.kt$SentryReplayModifiers
+ MatchingDeclarationName:Nodes.kt$ComposeTextLayout : TextLayout
+ MatchingDeclarationName:Persistable.kt$PersistableLinkedList : ConcurrentLinkedDeque
+ MatchingDeclarationName:ReplayLifecycle.kt$ReplayLifecycleState
+ MaxLineLength:ComposeMaskingOptionsTest.kt$ComposeMaskingOptionsTest$"Flaky: Robolectric intermittently reports zero bounds for nodes, causing isVisible=false and making the assertion non-deterministic"
+ NestedBlockDepth:CaptureStrategy.kt$CaptureStrategy.Companion$@Suppress("NewApi") private fun buildReplay( options: SentryOptions, video: File, currentReplayId: SentryId, segmentTimestamp: Date, segmentId: Int, height: Int, width: Int, frameCount: Int, frameRate: Int, videoDuration: Long, replayType: ReplayType, screenAtStart: String?, breadcrumbs: List<Breadcrumb>, events: Deque<RRWebEvent>, traceIds: List<String>, segmentNames: List<String>, ): ReplaySegment
+ NestedBlockDepth:DefaultReplayBreadcrumbConverter.kt$DefaultReplayBreadcrumbConverter$private fun Breadcrumb.toRRWebSpanEvent(): RRWebSpanEvent
+ NestedBlockDepth:Nodes.kt$internal fun LayoutNode.findPainter(): Painter?
+ NestedBlockDepth:Nodes.kt$internal fun LayoutNode.findTextColor(): Color?
+ NestedBlockDepth:ReplayGestureConverter.kt$ReplayGestureConverter$fun convert( event: MotionEvent, recorderConfig: ScreenshotRecorderConfig, ): List<RRWebIncrementalSnapshotEvent>?
+ NestedBlockDepth:SimpleVideoEncoder.kt$SimpleVideoEncoder$private fun drainCodec(endOfStream: Boolean)
+ ReturnCount:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$fun fromView( view: View, parent: ViewHierarchyNode?, options: SentryMaskingOptions, logger: ILogger, ): Boolean
+ ReturnCount:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$private fun SemanticsConfiguration?.shouldMask( isImage: Boolean, options: SentryMaskingOptions, ): Boolean
+ ReturnCount:DefaultReplayBreadcrumbConverter.kt$DefaultReplayBreadcrumbConverter$override fun convert(breadcrumb: Breadcrumb): RRWebEvent?
+ ReturnCount:ReplayCache.kt$ReplayCache.Companion$internal fun fromDisk( options: SentryOptions, replayId: SentryId, replayCacheProvider: ((replayId: SentryId) -> ReplayCache)? = null, ): LastSegmentData?
+ ReturnCount:ReplayGestureConverter.kt$ReplayGestureConverter$fun convert( event: MotionEvent, recorderConfig: ScreenshotRecorderConfig, ): List<RRWebIncrementalSnapshotEvent>?
+ ReturnCount:ReplayIntegration.kt$ReplayIntegration$override fun captureReplay(isTerminating: Boolean?): SentryId
+ ReturnCount:ScreenshotRecorder.kt$ScreenshotRecorder$fun capture()
+ ReturnCount:SentryLayoutNodeHelper.kt$SentryLayoutNodeHelper$@Suppress("UNCHECKED_CAST") fun getChildren(node: LayoutNode): List<LayoutNode>
+ ReturnCount:SentryLayoutNodeHelper.kt$SentryLayoutNodeHelper$fun isTransparent(node: LayoutNode): Boolean
+ ReturnCount:ViewHierarchyNode.kt$ViewHierarchyNode.Companion$@JvmStatic fun fromView( view: View, parent: ViewHierarchyNode?, distance: Int, options: SentryMaskingOptions, ): ViewHierarchyNode
+ ReturnCount:ViewHierarchyNode.kt$ViewHierarchyNode.Companion$private fun View.shouldMask(options: SentryMaskingOptions): Boolean
+ ReturnCount:Views.kt$internal fun View.isVisibleToUser(): Pair<Boolean, Rect?>
+ SwallowedException:Nodes.kt$e: Throwable
+ SwallowedException:ReplayCache.kt$ReplayCache.Companion$e: Throwable
+ SwallowedException:ReplaySmokeTest.kt$ReplaySmokeTest$e: ConditionTimeoutException
+ SwallowedException:Views.kt$e: NullPointerException
+ ThrowsCount:SimpleVideoEncoder.kt$SimpleVideoEncoder$private fun drainCodec(endOfStream: Boolean)
+ TooGenericExceptionCaught:BaseCaptureStrategy.kt$BaseCaptureStrategy.<no name provided>$e: Throwable
+ TooGenericExceptionCaught:BufferCaptureStrategy.kt$BufferCaptureStrategy$e: Throwable
+ TooGenericExceptionCaught:CanvasStrategy.kt$CanvasStrategy$t: Throwable
+ TooGenericExceptionCaught:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$e: Throwable
+ TooGenericExceptionCaught:ComposeViewHierarchyNode.kt$ComposeViewHierarchyNode$t: Throwable
+ TooGenericExceptionCaught:Executors.kt$e: Throwable
+ TooGenericExceptionCaught:GestureRecorder.kt$GestureRecorder.SentryReplayGestureRecorder$e: Throwable
+ TooGenericExceptionCaught:Nodes.kt$e: Throwable
+ TooGenericExceptionCaught:PixelCopyStrategy.kt$PixelCopyStrategy$e: RuntimeException
+ TooGenericExceptionCaught:PixelCopyStrategy.kt$PixelCopyStrategy$e: Throwable
+ TooGenericExceptionCaught:ReplayCache.kt$ReplayCache$e: Throwable
+ TooGenericExceptionCaught:ReplayCache.kt$ReplayCache$t: Throwable
+ TooGenericExceptionCaught:ReplayCache.kt$ReplayCache.Companion$e: Throwable
+ TooGenericExceptionCaught:ReplayExecutorService.kt$ReplayExecutorService$e: Throwable
+ TooGenericExceptionCaught:ReplayIntegration.kt$ReplayIntegration$e: Throwable
+ TooGenericExceptionCaught:ScreenshotRecorder.kt$ScreenshotRecorder$e: Throwable
+ TooGenericExceptionCaught:SimpleVideoEncoder.kt$SimpleVideoEncoder$e: RuntimeException
+ TooGenericExceptionCaught:SimpleVideoEncoder.kt$SimpleVideoEncoder$e: Throwable
+ TooGenericExceptionCaught:Views.kt$e: NullPointerException
+ TooGenericExceptionCaught:WindowRecorder.kt$WindowRecorder.Capturer$e: Throwable
+ TooGenericExceptionThrown:ReplayIntegrationTest.kt$ReplayIntegrationTest$throw RuntimeException("test")
+ TooGenericExceptionThrown:SimpleVideoEncoder.kt$SimpleVideoEncoder$throw RuntimeException("encoderOutputBuffer $encoderStatus was null")
+ TooGenericExceptionThrown:SimpleVideoEncoder.kt$SimpleVideoEncoder$throw RuntimeException("format changed twice")
+ TooGenericExceptionThrown:SimpleVideoEncoder.kt$SimpleVideoEncoder$throw RuntimeException("muxer hasn't started")
+ TooManyFunctions:BaseCaptureStrategy.kt$BaseCaptureStrategy : CaptureStrategy
+ TooManyFunctions:BufferCaptureStrategy.kt$BufferCaptureStrategy : BaseCaptureStrategy
+ TooManyFunctions:CanvasStrategy.kt$TextIgnoringDelegateCanvas : Canvas
+ TooManyFunctions:CaptureStrategy.kt$CaptureStrategy
+ TooManyFunctions:PixelCopyStrategy.kt$PixelCopyStrategy : ScreenshotStrategy
+ TooManyFunctions:ReplayIntegration.kt$ReplayIntegration : IntegrationCloseableScreenshotRecorderCallbackTouchRecorderCallbackReplayControllerIConnectionStatusObserverIRateLimitObserverWindowCallback
+ TooManyFunctions:WindowRecorder.kt$WindowRecorder : RecorderOnRootViewsChangedListenerExecutorProvider
+ UnusedPrivateProperty:DebugOverlayDrawable.kt$DebugOverlayDrawable$private val padding = 6f
+ UseCheckOrError:ReplayShadowMediaCodec.kt$ReplayShadowMediaCodec$throw IllegalStateException("Simulated codec start failure")
+ UtilityClassWithPublicConstructor:PixelCopyStrategyTest.kt$DeferredWindowPixelCopyShadow
+
+
diff --git a/sentry-apollo-3/build.gradle.kts b/sentry-apollo-3/build.gradle.kts
index 70f43d946ef..357d5224495 100644
--- a/sentry-apollo-3/build.gradle.kts
+++ b/sentry-apollo-3/build.gradle.kts
@@ -5,6 +5,7 @@ plugins {
`java-library`
id("io.sentry.javadoc")
alias(libs.plugins.kotlin.jvm)
+ alias(libs.plugins.detekt)
alias(libs.plugins.errorprone)
alias(libs.plugins.gradle.versions)
alias(libs.plugins.buildconfig)
diff --git a/sentry-apollo-3/detekt-baseline.xml b/sentry-apollo-3/detekt-baseline.xml
new file mode 100644
index 00000000000..6bb8edffb36
--- /dev/null
+++ b/sentry-apollo-3/detekt-baseline.xml
@@ -0,0 +1,33 @@
+
+
+
+
+ ClassNaming:LaunchDetailsQuery_ResponseAdapter.kt$LaunchDetailsQuery_ResponseAdapter
+ ClassNaming:LaunchDetailsQuery_VariablesAdapter.kt$LaunchDetailsQuery_VariablesAdapter : Adapter
+ CyclomaticComplexMethod:SentryApollo3HttpInterceptor.kt$SentryApollo3HttpInterceptor$private fun captureEvent( request: HttpRequest, response: HttpResponse, operationName: String?, operationType: String?, )
+ LongMethod:SentryApollo3HttpInterceptor.kt$SentryApollo3HttpInterceptor$private fun captureEvent( request: HttpRequest, response: HttpResponse, operationName: String?, operationType: String?, )
+ LongParameterList:SentryApollo3HttpInterceptor.kt$SentryApollo3HttpInterceptor$( span: ISpan?, request: HttpRequest, response: HttpResponse?, statusCode: Int?, operationName: String?, operationType: String?, operationId: String?, )
+ LongParameterList:SentryApollo3InterceptorClientErrors.kt$SentryApollo3InterceptorClientErrors.Fixture$( captureFailedRequests: Boolean = DEFAULT_CAPTURE_FAILED_REQUESTS, failedRequestTargets: List<String> = listOf(DEFAULT_PROPAGATION_TARGETS), httpStatusCode: Int = 200, responseBody: String = responseBodyOk, sendDefaultPii: Boolean = false, includeCookies: Boolean = sendDefaultPii, socketPolicy: SocketPolicy = SocketPolicy.KEEP_OPEN, configureOptions: SentryOptions.() -> Unit = {}, )
+ MaxLineLength:LaunchDetailsQuery.kt$LaunchDetailsQuery.Companion$"query LaunchDetails(${'$'}id: ID!) { launch(id: ${'$'}id) { id site mission { name missionPatch(size: LARGE) } rocket { name type } } }"
+ MaxLineLength:SentryApollo3InterceptorTest.kt$SentryApollo3InterceptorTest$"thirdPartyBaggage=someValue,secondThirdPartyBaggage=secondValue; property;propertyKey=propertyValue,anotherThirdPartyBaggage=anotherValue"
+ MaxLineLength:SentryApollo3InterceptorTest.kt$SentryApollo3InterceptorTest.Fixture$"secondThirdPartyBaggage=secondValue; property;propertyKey=propertyValue,anotherThirdPartyBaggage=anotherValue"
+ NestedBlockDepth:SentryApollo3HttpInterceptor.kt$SentryApollo3HttpInterceptor$private fun captureEvent( request: HttpRequest, response: HttpResponse, operationName: String?, operationType: String?, )
+ NestedBlockDepth:SentryApollo3HttpInterceptor.kt$SentryApollo3HttpInterceptor$private fun finish( span: ISpan?, request: HttpRequest, response: HttpResponse?, statusCode: Int?, operationName: String?, operationType: String?, operationId: String?, )
+ NestedBlockDepth:SentryApollo3HttpInterceptor.kt$SentryApollo3HttpInterceptor$private fun maybeAddTracingHeaders( scopes: IScopes, request: HttpRequest, span: ISpan?, ): HttpRequest
+ ReturnCount:SentryApollo3HttpInterceptor.kt$SentryApollo3HttpInterceptor$private fun captureEvent( request: HttpRequest, response: HttpResponse, operationName: String?, operationType: String?, )
+ SwallowedException:SentryApollo3InterceptorClientErrors.kt$SentryApollo3InterceptorClientErrors$e: ApolloException
+ SwallowedException:SentryApollo3InterceptorTest.kt$SentryApollo3InterceptorTest$e: ApolloException
+ SwallowedException:SentryApollo3InterceptorWithVariablesTest.kt$SentryApollo3InterceptorWithVariablesTest$e: ApolloException
+ TooGenericExceptionCaught:SentryApollo3HttpInterceptor.kt$SentryApollo3HttpInterceptor$e: Throwable
+ TooGenericExceptionThrown:SentryApollo3InterceptorTest.kt$SentryApollo3InterceptorTest$throw RuntimeException()
+ TooManyFunctions:SentryApollo3HttpInterceptor.kt$SentryApollo3HttpInterceptor : HttpInterceptor
+ UseCheckOrError:LaunchDetailsQuery_VariablesAdapter.kt$LaunchDetailsQuery_VariablesAdapter$throw IllegalStateException("Input type used in output position")
+ UtilityClassWithPublicConstructor:GraphQLBoolean.kt$GraphQLBoolean
+ UtilityClassWithPublicConstructor:GraphQLID.kt$GraphQLID
+ UtilityClassWithPublicConstructor:GraphQLString.kt$GraphQLString
+ UtilityClassWithPublicConstructor:Launch.kt$Launch
+ UtilityClassWithPublicConstructor:Mission.kt$Mission
+ UtilityClassWithPublicConstructor:Query.kt$Query
+ UtilityClassWithPublicConstructor:Rocket.kt$Rocket
+
+
diff --git a/sentry-apollo-4/build.gradle.kts b/sentry-apollo-4/build.gradle.kts
index 4f1276f0bf4..078d26b8ff8 100644
--- a/sentry-apollo-4/build.gradle.kts
+++ b/sentry-apollo-4/build.gradle.kts
@@ -5,6 +5,7 @@ plugins {
`java-library`
id("io.sentry.javadoc")
alias(libs.plugins.kotlin.jvm)
+ alias(libs.plugins.detekt)
alias(libs.plugins.errorprone)
alias(libs.plugins.gradle.versions)
alias(libs.plugins.buildconfig)
diff --git a/sentry-apollo-4/detekt-baseline.xml b/sentry-apollo-4/detekt-baseline.xml
new file mode 100644
index 00000000000..371c726cb9f
--- /dev/null
+++ b/sentry-apollo-4/detekt-baseline.xml
@@ -0,0 +1,34 @@
+
+
+
+
+ ClassNaming:LaunchDetailsQuery_ResponseAdapter.kt$LaunchDetailsQuery_ResponseAdapter
+ ClassNaming:LaunchDetailsQuery_VariablesAdapter.kt$LaunchDetailsQuery_VariablesAdapter : Adapter
+ CyclomaticComplexMethod:SentryApollo4HttpInterceptor.kt$SentryApollo4HttpInterceptor$private fun captureEvent( request: HttpRequest, response: HttpResponse, operationName: String?, operationType: String?, )
+ LongMethod:SentryApollo4HttpInterceptor.kt$SentryApollo4HttpInterceptor$private fun captureEvent( request: HttpRequest, response: HttpResponse, operationName: String?, operationType: String?, )
+ LongParameterList:SentryApollo4BuilderExtensionsClientErrorsTest.kt$SentryApollo4BuilderExtensionsClientErrorsTest.Fixture$( captureFailedRequests: Boolean = DEFAULT_CAPTURE_FAILED_REQUESTS, failedRequestTargets: List<String> = listOf(DEFAULT_PROPAGATION_TARGETS), httpStatusCode: Int = 200, responseBody: String = responseBodyOk, sendDefaultPii: Boolean = false, includeCookies: Boolean = sendDefaultPii, socketPolicy: SocketPolicy = SocketPolicy.KEEP_OPEN, configureOptions: SentryOptions.() -> Unit = {}, )
+ LongParameterList:SentryApollo4HttpInterceptor.kt$SentryApollo4HttpInterceptor$( span: ISpan?, request: HttpRequest, response: HttpResponse?, statusCode: Int?, operationName: String?, operationType: String?, operationId: String?, )
+ MaxLineLength:LaunchDetailsQuery.kt$LaunchDetailsQuery.Companion$"query LaunchDetails(${'$'}id: ID!) { launch(id: ${'$'}id) { id site mission { name missionPatch(size: LARGE) } rocket { name type } } }"
+ MaxLineLength:LaunchDetailsQuerySelections.kt$LaunchDetailsQuerySelections$CompiledArgument.Builder(CompiledArgumentDefinition.Builder("size").build()).value("LARGE").build()
+ MaxLineLength:SentryApollo4HttpInterceptorTest.kt$SentryApollo4HttpInterceptorTest$"thirdPartyBaggage=someValue,secondThirdPartyBaggage=secondValue; property;propertyKey=propertyValue,anotherThirdPartyBaggage=anotherValue"
+ MaxLineLength:SentryApollo4HttpInterceptorTest.kt$SentryApollo4HttpInterceptorTest.Fixture$"secondThirdPartyBaggage=secondValue; property;propertyKey=propertyValue,anotherThirdPartyBaggage=anotherValue"
+ NestedBlockDepth:SentryApollo4HttpInterceptor.kt$SentryApollo4HttpInterceptor$private fun captureEvent( request: HttpRequest, response: HttpResponse, operationName: String?, operationType: String?, )
+ NestedBlockDepth:SentryApollo4HttpInterceptor.kt$SentryApollo4HttpInterceptor$private fun finish( span: ISpan?, request: HttpRequest, response: HttpResponse?, statusCode: Int?, operationName: String?, operationType: String?, operationId: String?, )
+ NestedBlockDepth:SentryApollo4HttpInterceptor.kt$SentryApollo4HttpInterceptor$private fun maybeAddTracingHeaders( scopes: IScopes, request: HttpRequest, span: ISpan?, ): HttpRequest
+ ReturnCount:SentryApollo4HttpInterceptor.kt$SentryApollo4HttpInterceptor$private fun captureEvent( request: HttpRequest, response: HttpResponse, operationName: String?, operationType: String?, )
+ SwallowedException:SentryApollo4BuilderExtensionsClientErrorsTest.kt$SentryApollo4BuilderExtensionsClientErrorsTest$e: ApolloException
+ SwallowedException:SentryApollo4BuilderExtensionsTest.kt$SentryApollo4BuilderExtensionsTest$e: ApolloException
+ SwallowedException:SentryApollo4HttpInterceptorTest.kt$SentryApollo4HttpInterceptorTest$e: ApolloException
+ TooGenericExceptionCaught:SentryApollo4HttpInterceptor.kt$SentryApollo4HttpInterceptor$e: Throwable
+ TooGenericExceptionThrown:SentryApollo4HttpInterceptorTest.kt$SentryApollo4HttpInterceptorTest$throw RuntimeException()
+ TooManyFunctions:SentryApollo4HttpInterceptor.kt$SentryApollo4HttpInterceptor : HttpInterceptor
+ UseCheckOrError:LaunchDetailsQuery_VariablesAdapter.kt$LaunchDetailsQuery_VariablesAdapter$throw IllegalStateException("Input type used in output position")
+ UtilityClassWithPublicConstructor:GraphQLBoolean.kt$GraphQLBoolean
+ UtilityClassWithPublicConstructor:GraphQLID.kt$GraphQLID
+ UtilityClassWithPublicConstructor:GraphQLString.kt$GraphQLString
+ UtilityClassWithPublicConstructor:Launch.kt$Launch
+ UtilityClassWithPublicConstructor:Mission.kt$Mission
+ UtilityClassWithPublicConstructor:Query.kt$Query
+ UtilityClassWithPublicConstructor:Rocket.kt$Rocket
+
+
diff --git a/sentry-apollo/build.gradle.kts b/sentry-apollo/build.gradle.kts
index 2da8d8b20c1..570214e60b8 100644
--- a/sentry-apollo/build.gradle.kts
+++ b/sentry-apollo/build.gradle.kts
@@ -5,6 +5,7 @@ plugins {
`java-library`
id("io.sentry.javadoc")
alias(libs.plugins.kotlin.jvm)
+ alias(libs.plugins.detekt)
alias(libs.plugins.errorprone)
alias(libs.plugins.gradle.versions)
alias(libs.plugins.buildconfig)
diff --git a/sentry-apollo/detekt-baseline.xml b/sentry-apollo/detekt-baseline.xml
new file mode 100644
index 00000000000..d010e1a4336
--- /dev/null
+++ b/sentry-apollo/detekt-baseline.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ EmptyFunctionBlock:SentryApolloInterceptor.kt$SentryApolloInterceptor${}
+ SwallowedException:SentryApolloInterceptorTest.kt$SentryApolloInterceptorTest$e: ApolloException
+ TooGenericExceptionCaught:SentryApolloInterceptor.kt$SentryApolloInterceptor$e: Exception
+ TooGenericExceptionThrown:SentryApolloInterceptorTest.kt$SentryApolloInterceptorTest$throw RuntimeException()
+
+
diff --git a/sentry-compose/build.gradle.kts b/sentry-compose/build.gradle.kts
index c5bb5715830..394885df1b8 100644
--- a/sentry-compose/build.gradle.kts
+++ b/sentry-compose/build.gradle.kts
@@ -121,6 +121,9 @@ android {
}
}
+// The default detekt source set is src/{main,test}, which doesn't exist in a multiplatform module.
+detekt { source.setFrom("src/androidMain/kotlin", "src/androidUnitTest/kotlin") }
+
tasks.withType().configureEach {
// Target version of the generated JVM bytecode. It is used for type resolution.
jvmTarget = JavaVersion.VERSION_1_8.toString()
diff --git a/sentry-compose/detekt-baseline.xml b/sentry-compose/detekt-baseline.xml
new file mode 100644
index 00000000000..b59189497e9
--- /dev/null
+++ b/sentry-compose/detekt-baseline.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ CyclomaticComplexMethod:ComposeGestureTargetLocator.kt$ComposeGestureTargetLocator$override fun locate(root: Any?, x: Float, y: Float, targetType: UiElement.Type): UiElement?
+ FunctionOnlyReturningConstant:SentryModifier.kt$SentryModifier.SentryTagModifierNode$@Suppress("unused") fun isImportantForBounds(): Boolean
+ LongMethod:ComposeGestureTargetLocator.kt$ComposeGestureTargetLocator$override fun locate(root: Any?, x: Float, y: Float, targetType: UiElement.Type): UiElement?
+ LongParameterList:ComposeGestureTargetLocatorTest.kt$ComposeGestureTargetLocatorTest$( isPlaced: Boolean, tag: String?, width: Int, height: Int, children: List<LayoutNode> = emptyList(), semanticsKeys: List<String> = emptyList(), nodeModifierClassName: String? = null, left: Float = 0f, top: Float = 0f, )
+ LongParameterList:SentryComposeTracing.kt$BucketSpans$( ownerSpan: ISpan, startTimestamp: SentryDate, cached: WeakReference<ISpan>?, operation: String, description: String, setCached: (WeakReference<ISpan>) -> Unit, )
+ NestedBlockDepth:ComposeGestureTargetLocator.kt$ComposeGestureTargetLocator$override fun locate(root: Any?, x: Float, y: Float, targetType: UiElement.Type): UiElement?
+ NestedBlockDepth:SentryComposeHelper.kt$SentryComposeHelper$fun extractTag(modifier: Modifier): String?
+ ReturnCount:ComposeGestureTargetLocator.kt$ComposeGestureTargetLocator$override fun locate(root: Any?, x: Float, y: Float, targetType: UiElement.Type): UiElement?
+ ReturnCount:ComposeIntegrationTests.kt$ComposeIntegrationTests$private fun locateAndroidComposeView(root: View?): Any?
+ ReturnCount:SentryComposeHelper.kt$SentryComposeHelper$fun extractTag(modifier: Modifier): String?
+ SwallowedException:SentryComposeHelper.kt$SentryComposeHelper$e: Throwable
+ SwallowedException:SentryComposeHelper.kt$SentryComposeHelper.Companion$e: Exception
+ TooGenericExceptionCaught:SentryComposeHelper.kt$SentryComposeHelper$e: Throwable
+ TooGenericExceptionCaught:SentryComposeHelper.kt$SentryComposeHelper.Companion$e: Exception
+
+
diff --git a/sentry-ktor-client/build.gradle.kts b/sentry-ktor-client/build.gradle.kts
index fefcdbfebaf..a1eb9150d6f 100644
--- a/sentry-ktor-client/build.gradle.kts
+++ b/sentry-ktor-client/build.gradle.kts
@@ -4,6 +4,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
`java-library`
alias(libs.plugins.kotlin.jvm)
+ alias(libs.plugins.detekt)
id("io.sentry.javadoc")
alias(libs.plugins.errorprone)
alias(libs.plugins.gradle.versions)
diff --git a/sentry-ktor-client/detekt-baseline.xml b/sentry-ktor-client/detekt-baseline.xml
new file mode 100644
index 00000000000..23405d6fda1
--- /dev/null
+++ b/sentry-ktor-client/detekt-baseline.xml
@@ -0,0 +1,15 @@
+
+
+
+
+ MagicNumber:SentryKtorClientUtils.kt$SentryKtorClientUtils$1000L
+ MaxLineLength:SentryKtorClientPluginTest.kt$SentryKtorClientPluginTest$fun
+ TooGenericExceptionCaught:SentryKtorClientPlugin.kt$t: Throwable
+ UnusedParameter:SentryKtorClientPluginTest.kt$SentryKtorClientPluginTest.Fixture$beforeSpan: SentryKtorClientPluginConfig.BeforeSpanCallback? = null
+ WildcardImport:SentryKtorClientPlugin.kt$import io.ktor.client.plugins.api.*
+ WildcardImport:SentryKtorClientPlugin.kt$import io.ktor.client.request.*
+ WildcardImport:SentryKtorClientPlugin.kt$import io.ktor.client.statement.*
+ WildcardImport:SentryKtorClientPlugin.kt$import io.ktor.util.*
+ WildcardImport:SentryKtorClientPlugin.kt$import io.ktor.util.pipeline.*
+
+
diff --git a/sentry-okhttp/build.gradle.kts b/sentry-okhttp/build.gradle.kts
index 94575f54984..5abd1cf26b9 100644
--- a/sentry-okhttp/build.gradle.kts
+++ b/sentry-okhttp/build.gradle.kts
@@ -4,6 +4,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
`java-library`
alias(libs.plugins.kotlin.jvm)
+ alias(libs.plugins.detekt)
id("io.sentry.javadoc")
alias(libs.plugins.errorprone)
alias(libs.plugins.gradle.versions)
diff --git a/sentry-okhttp/detekt-baseline.xml b/sentry-okhttp/detekt-baseline.xml
new file mode 100644
index 00000000000..b0d75302aa0
--- /dev/null
+++ b/sentry-okhttp/detekt-baseline.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ CyclomaticComplexMethod:SentryOkHttpInterceptor.kt$SentryOkHttpInterceptor$@Suppress("LongMethod") @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response
+ NestedBlockDepth:SentryOkHttpInterceptor.kt$SentryOkHttpInterceptor$@Suppress("LongMethod") @Throws(IOException::class) override fun intercept(chain: Interceptor.Chain): Response
+ ReturnCount:SentryOkHttpInterceptor.kt$SentryOkHttpInterceptor$private fun shouldCaptureClientError(request: Request, response: Response): Boolean
+ TooGenericExceptionCaught:SentryOkHttpInterceptor.kt$SentryOkHttpInterceptor$e: Exception
+
+