diff --git a/build.gradle.kts b/build.gradle.kts index ecbadd9..19512b8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,6 +5,29 @@ plugins { alias(libs.plugins.android.library) apply false alias(libs.plugins.android.application) apply false alias(libs.plugins.ksp) apply false + alias(libs.plugins.detekt) +} + +detekt { + config.setFrom(files("config/detekt/detekt.yml")) + buildUponDefaultConfig = true + allRules = false + source.setFrom(files(".")) + parallel = true + ignoreFailures = false +} + +tasks.withType().configureEach { + exclude("**/build/**") + exclude("**/generated/**") + exclude("**/test/**") + exclude("**/androidTest/**") + reports { + html.required.set(true) + xml.required.set(true) + txt.required.set(true) + sarif.required.set(true) + } } allprojects { diff --git a/config/detekt/detekt.yml b/config/detekt/detekt.yml new file mode 100644 index 0000000..5d676ce --- /dev/null +++ b/config/detekt/detekt.yml @@ -0,0 +1,640 @@ +build: + maxIssues: 0 + excludeCorrectable: false + weights: + complexity: 2 + formatting: 1 + comments: 1 + +config: + validation: true + warningsAsErrors: false + excludes: "**/build/**,**/generated/**,**/test/**,**/androidTest/**" + +processors: + active: true + exclude: + - 'DetektProgressListener' + +console-reports: + active: true + +output-reports: + active: true + +comments: + active: true + AbsentOrWrongFileLicense: + active: false + CommentOverPrivateFunction: + active: false + CommentOverPrivateProperty: + active: false + DeprecatedBlockTag: + active: false + EndOfSentenceFormat: + active: false + +complexity: + active: true + ComplexCondition: + active: true + threshold: 4 + ComplexInterface: + active: false + ComplexMethod: + active: true + threshold: 15 + ignoreSingleWhenExpression: true + LabeledExpression: + active: false + LongMethod: + active: true + threshold: 60 + excludes: "**/test/**,**/androidTest/**" + LongParameterList: + active: true + functionThreshold: 6 + constructorThreshold: 7 + ignoreDefaultParameters: true + ignoreDataClasses: true + NestedBlockDepth: + active: true + threshold: 4 + StringLiteralDuplication: + active: false + TooManyFunctions: + active: true + thresholdInFiles: 11 + thresholdInClasses: 11 + thresholdInInterfaces: 11 + thresholdInObjects: 11 + thresholdInEnums: 11 + ignoreDeprecated: true + ignorePrivate: true + ignoreOverridden: true + +coroutines: + active: true + GlobalCoroutineUsage: + active: true + RedundantSuspendModifier: + active: true + SleepInsteadOfDelay: + active: true + SuspendFunWithCoroutineScopeReceiver: + active: false + SuspendFunWithFlowReturnType: + active: true + +empty-blocks: + active: true + EmptyCatchBlock: + active: true + EmptyClassBlock: + active: true + EmptyDefaultConstructor: + active: true + EmptyDoWhileBlock: + active: true + EmptyElseBlock: + active: true + EmptyFinallyBlock: + active: true + EmptyForBlock: + active: true + EmptyFunctionBlock: + active: true + ignoreOverridden: true + EmptyIfBlock: + active: true + EmptyInitBlock: + active: true + EmptyKtFile: + active: true + EmptySecondaryConstructor: + active: true + EmptyTryBlock: + active: true + EmptyWhenBlock: + active: true + EmptyWhileBlock: + active: true + +exceptions: + active: true + ExceptionRaisedInUnexpectedLocation: + active: true + InstanceOfCheckForException: + active: true + NotImplementedDeclaration: + active: false + ObjectExtendsThrowable: + active: false + PrintStackTrace: + active: true + RethrowCaughtException: + active: true + ReturnFromFinally: + active: true + ignoreLabeled: false + SwallowedException: + active: true + ignoredExceptionTypes: + - InterruptedException + - NumberFormatException + - ParseException + - MalformedURLException + ThrowingExceptionFromFinally: + active: true + ThrowingExceptionInMain: + active: false + ThrowingExceptionsWithoutMessageOrCause: + active: true + ThrowingNewInstanceOfSameException: + active: true + TooGenericExceptionCaught: + active: false + TooGenericExceptionThrown: + active: true + +formatting: + active: true + android: true + autoCorrect: true + AnnotationOnSeparateLine: + active: false + AnnotationSpacing: + active: false + ArgumentListWrapping: + active: true + indentSize: 4 + maxLineLength: 150 + ChainWrapping: + active: true + CommentSpacing: + active: true + EnumEntryNameCase: + active: true + Filename: + active: true + FinalNewline: + active: true + ImportOrdering: + active: false + Indentation: + active: true + indentSize: 4 + MaximumLineLength: + active: true + maxLineLength: 150 + ignoreBackTickedIdentifier: false + ModifierOrdering: + active: true + MultiLineIfElse: + active: true + NoBlankLineBeforeRbrace: + active: true + NoConsecutiveBlankLines: + active: true + NoEmptyClassBody: + active: true + NoEmptyFirstLineInMethodBlock: + active: true + NoLineBreakAfterElse: + active: true + NoLineBreakBeforeAssignment: + active: true + NoMultipleSpaces: + active: true + NoSemicolons: + active: true + NoTrailingSpaces: + active: true + NoUnusedImports: + active: true + NoWildcardImports: + active: true + packagesToUseImportAliasRestriction: '' + PackageName: + active: true + ParameterListWrapping: + active: true + maxLineLength: 150 + SpacingAroundAngleBrackets: + active: true + SpacingAroundColon: + active: true + SpacingAroundComma: + active: true + SpacingAroundCurly: + active: true + SpacingAroundDot: + active: true + SpacingAroundDoubleColon: + active: true + SpacingAroundKeyword: + active: true + SpacingAroundOperators: + active: true + SpacingAroundParens: + active: true + SpacingAroundRangeOperator: + active: true + SpacingAroundUnaryOperator: + active: true + SpacingBetweenDeclarationsWithAnnotations: + active: false + SpacingBetweenDeclarationsWithComments: + active: false + StringTemplate: + active: true + +naming: + active: true + BooleanPropertyNaming: + active: false + ClassNaming: + active: true + classPattern: '[A-Z][a-zA-Z0-9]*' + ConstructorParameterNaming: + active: true + parameterPattern: '[a-z][A-Za-z0-9]*' + privateParameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + EnumNaming: + active: true + enumEntryPattern: '[A-Z][_a-zA-Z0-9]*' + ForbiddenClassName: + active: false + FunctionMaxLength: + active: false + FunctionMinLength: + active: false + FunctionNaming: + active: true + functionPattern: '([a-z][a-zA-Z0-9]*)|(`.*`)' + excludeClassPattern: '$^' + FunctionParameterNaming: + active: true + parameterPattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + InvalidPackageDeclaration: + active: true + rootPackage: '' + LambdaParameterNaming: + active: false + MatchingDeclarationName: + active: true + mustBeFirst: true + MemberNameEqualsClassName: + active: true + NoNameShadowing: + active: true + NonBooleanPropertyPrefixedWithIs: + active: false + ObjectPropertyNaming: + active: true + constantPattern: '[A-Za-z][_A-Za-z0-9]*' + propertyPattern: '[A-Za-z][_A-Za-z0-9]*' + privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*' + PackageNaming: + active: true + packagePattern: '^[a-z]+(\.[a-z][a-z0-9]*)*$' + TopLevelPropertyNaming: + active: true + constantPattern: '[A-Z][_A-Z0-9]*' + propertyPattern: '[a-z][A-Za-z0-9]*' + privatePropertyPattern: '_?[a-z][A-Za-z0-9]*' + VariableMaxLength: + active: false + VariableMinLength: + active: false + VariableNaming: + active: true + variablePattern: '[a-z][A-Za-z0-9]*' + excludeClassPattern: '$^' + +performance: + active: true + ArrayPrimitive: + active: true + CouldBeSequence: + active: false + ForEachOnRange: + active: true + excludes: "**/test/**,**/androidTest/**" + SpreadOperator: + active: true + excludes: "**/test/**,**/androidTest/**" + UnnecessaryPartOfBinaryExpression: + active: false + UnnecessaryTemporaryInstantiation: + active: true + +potential-bugs: + active: true + AvoidReferentialEquality: + active: true + forbiddenTypePatterns: + - 'kotlin.String' + CastNullableToNonNullableType: + active: false + CastToNullableType: + active: false + Deprecation: + active: true + DontDowncastCollectionTypes: + active: false + DoubleMutabilityForCollection: + active: true + mutableTypes: + - 'kotlin.collections.MutableList' + - 'kotlin.collections.MutableMap' + - 'kotlin.collections.MutableSet' + - 'java.util.ArrayList' + - 'java.util.LinkedHashSet' + - 'java.util.HashSet' + - 'java.util.LinkedHashMap' + - 'java.util.HashMap' + ElseCaseInsteadOfExhaustiveWhen: + active: false + EqualsAlwaysReturnsTrueOrFalse: + active: true + EqualsWithHashCodeExist: + active: true + ExitOutsideMain: + active: false + ExplicitGarbageCollectionCall: + active: true + HasPlatformType: + active: true + IgnoredReturnValue: + active: true + restrictToConfig: true + returnValueAnnotations: + - '*.CheckResult' + - '*.CheckReturnValue' + ImplicitDefaultLocale: + active: true + ImplicitUnitReturnType: + active: false + InvalidRange: + active: true + IteratorHasNextCallsNextMethod: + active: true + IteratorNotThrowingNoSuchElementException: + active: true + LateinitUsage: + active: false + LazyExpectParameterType: + active: true + MapGetWithNotNullAssertionOperator: + active: true + MissingPackageDeclaration: + active: false + MissingWhenCase: + active: true + NullCheckOnMutableProperty: + active: true + NullableToStringCall: + active: false + PropertyUsedBeforeDeclaration: + active: false + RedundantElseInWhen: + active: true + UnconditionalJumpStatementInLoop: + active: true + UnnamedParameterUse: + active: false + UnnecessaryNotNullCheck: + active: false + UnnecessaryNotNullOperator: + active: true + UnnecessarySafeCall: + active: true + UnreachableCatchBlock: + active: true + UnreachableCode: + active: true + UnsafeCallOnNullableType: + active: true + excludes: "**/test/**" + UnsafeCast: + active: true + UnusedUnaryOperator: + active: true + UselessPostfixExpression: + active: true + WrongEqualsTypeParameter: + active: true + +style: + active: true + AlsoCouldBeApply: + active: true + BracesOnIfStatements: + active: false + BracesOnWhenStatements: + active: false + CanBeNonNullable: + active: false + CascadingCallWrapping: + active: true + includeElvis: true + ClassOrdering: + active: false + CollapsibleIfStatements: + active: true + DataClassContainsFunctions: + active: false + DataClassShouldBeImmutable: + active: false + DestructuringDeclarationWithTooManyEntries: + active: true + maxDestructuringEntries: 3 + DoubleNegativeLambda: + active: false + EqualsNullCall: + active: true + EqualsOnSignatureLine: + active: false + ExplicitCollectionElementAccessMethod: + active: false + ExplicitItLambdaParameter: + active: true + ExpressionBodySyntax: + active: false + ForbiddenAnnotation: + active: false + ForbiddenComment: + active: true + comments: + - reason: 'Forbidden FIXME todo marker in comment, please fix the problem.' + value: 'FIXME:' + - reason: 'Forbidden STOPSHIP todo marker in comment, please address the problem before shipping.' + value: 'STOPSHIP:' + - reason: 'Forbidden TODO todo marker in comment, please do the work.' + value: 'TODO:' + allowedPatterns: '' + ForbiddenImport: + active: false + ForbiddenMethodCall: + active: false + ForbiddenSuppress: + active: false + ForbiddenVoid: + active: true + ignoreOverridden: false + ignoreUsageInGenerics: false + FunctionOnlyReturningConstant: + active: true + LoopWithTooManyJumpStatements: + active: true + maxJumpCount: 1 + MagicNumber: + active: false + MandatoryBracesLoops: + active: false + MaxChainedCallsOnSameLine: + active: false + MaxLineLength: + active: true + maxLineLength: 150 + excludePackageStatements: true + excludeImportStatements: true + excludeCommentStatements: false + excludeRawStrings: true + MayBeConst: + active: true + ModifierOrder: + active: true + MultilineLambdaItParameter: + active: true + MultilineRawStringIndentation: + active: false + NestedClassesVisibility: + active: true + NewLineAtEndOfFile: + active: true + NoTabs: + active: true + NullableBooleanCheck: + active: false + ObjectLiteralToLambda: + active: true + OptionalAbstractKeyword: + active: true + OptionalWhenBraces: + active: false + PreferToOverPairSyntax: + active: false + ProtectedMemberInFinalClass: + active: true + RangeUntilInsteadOfRangeTo: + active: false + RedundantExplicitType: + active: true + RedundantHigherOrderMapUsage: + active: true + RedundantVisibilityModifierRule: + active: false + ReturnCount: + active: true + max: 2 + excludedFunctions: + - 'equals' + excludeLabeled: false + excludeReturnFromLambda: true + excludeGuardClauses: false + SafeCast: + active: true + SerialVersionUIDInSerializableClass: + active: true + SpacingBetweenPackageAndImports: + active: true + StringShouldBeRawString: + active: false + ThrowsCount: + active: true + max: 2 + excludeGuardClauses: false + TrailingWhitespace: + active: true + TrimMultilineRawString: + active: false + UnderscoresInNumericLiterals: + active: false + UnnecessaryAbstractClass: + active: true + UnnecessaryAnnotationUseSiteTarget: + active: false + UnnecessaryApply: + active: true + UnnecessaryBackticks: + active: false + UnnecessaryBracesAroundTrailingLambda: + active: false + UnnecessaryFilter: + active: true + UnnecessaryInheritance: + active: true + UnnecessaryInnerClass: + active: false + UnnecessaryLet: + active: true + UnnecessaryParentheses: + active: false + UntilInsteadOfRangeTo: + active: true + UnusedImports: + active: true + UnusedParameter: + active: true + allowedNames: 'ignored|expected' + UnusedPrivateClass: + active: true + UnusedPrivateMember: + active: true + allowedNames: '(_|ignored|expected|serialVersionUID)' + UnusedPrivateProperty: + active: true + allowedNames: '_|ignored|expected|serialVersionUID' + UseAnyOrNoneInsteadOfFind: + active: true + UseArrayLiteralsInAnnotations: + active: true + UseCheckNotNull: + active: true + UseCheckOrError: + active: true + UseDataClass: + active: true + allowVars: false + UseEmptyCounterpart: + active: true + UseIfEmptyOrIfBlank: + active: true + UseIfInsteadOfWhen: + active: false + UseIsNullOrEmpty: + active: true + UseOrEmpty: + active: true + UseRequire: + active: true + UseRequireNotNull: + active: true + UseSumOfInsteadOfFlatMapSize: + active: false + UselessCallOnNotNull: + active: true + UtilityClassWithPublicConstructor: + active: true + VarCouldBeVal: + active: true + ignoreAnnotated: [] + WildcardImport: + active: true + excludeImports: + - 'java.util.*' diff --git a/detekt.yml b/detekt.yml deleted file mode 100644 index 49b9559..0000000 --- a/detekt.yml +++ /dev/null @@ -1,331 +0,0 @@ -build: - maxIssues: 0 - excludeCorrectable: false - weights: - complexity: 2 - formatting: 1 - comments: 1 - -config: - validation: true - warningsAsErrors: false - -processors: - active: true - exclude: - - 'DetektProgressListener' - -console-reports: - active: true - -output-reports: - active: true - -comments: - active: true - AbsentOrWrongFileLicense: - active: false - CommentOverPrivateFunction: - active: false - CommentOverPrivateProperty: - active: false - -complexity: - active: true - ComplexCondition: - active: true - threshold: 4 - ComplexInterface: - active: false - ComplexMethod: - active: true - threshold: 15 - LabeledExpression: - active: false - LongMethod: - active: true - threshold: 60 - LongParameterList: - active: true - functionThreshold: 6 - constructorThreshold: 7 - NestedBlockDepth: - active: true - threshold: 4 - TooManyFunctions: - active: true - thresholdInFiles: 11 - thresholdInClasses: 11 - thresholdInInterfaces: 11 - thresholdInObjects: 11 - thresholdInEnums: 11 - -coroutines: - active: true - GlobalCoroutineUsage: - active: true - RedundantSuspendModifier: - active: true - SleepInsteadOfDelay: - active: true - -empty-blocks: - active: true - EmptyCatchBlock: - active: true - EmptyClassBlock: - active: true - EmptyDefaultConstructor: - active: true - EmptyDoWhileBlock: - active: true - EmptyElseBlock: - active: true - EmptyFinallyBlock: - active: true - EmptyForBlock: - active: true - EmptyFunctionBlock: - active: true - ignoreOverridden: false - EmptyIfBlock: - active: true - EmptyInitBlock: - active: true - EmptyKtFile: - active: true - EmptySecondaryConstructor: - active: true - EmptyTryBlock: - active: true - EmptyWhenBlock: - active: true - EmptyWhileBlock: - active: true - -exceptions: - active: true - ExceptionRaisedInUnexpectedLocation: - active: true - InstanceOfCheckForException: - active: true - NotImplementedDeclaration: - active: false - ObjectExtendsThrowable: - active: false - RethrowCaughtException: - active: true - ReturnFromFinally: - active: true - SwallowedException: - active: true - ThrowingExceptionFromFinally: - active: true - ThrowingExceptionInMain: - active: false - ThrowingExceptionsWithoutMessageOrCause: - active: true - ThrowingNewInstanceOfSameException: - active: true - TooGenericExceptionCaught: - active: true - TooGenericExceptionThrown: - active: true - -formatting: - active: true - AnnotationOnSeparateLine: - active: false - MaximumLineLength: - active: true - maxLineLength: 150 - NoTrailingSpaces: - active: true - NoUnusedImports: - active: true - NoWildcardImports: - active: true - ParameterListWrapping: - active: true - -naming: - active: true - ClassNaming: - active: true - classPattern: '[A-Z][a-zA-Z0-9]*' - FunctionNaming: - active: true - functionPattern: '([a-z][a-zA-Z0-9]*)|(`.*`)' - VariableNaming: - active: true - variablePattern: '[a-z][A-Za-z0-9]*' - PackageNaming: - active: true - packagePattern: '^[a-z]+(\.[a-z][a-z0-9]*)*$' - TopLevelPropertyNaming: - active: true - constantPattern: '[A-Z][_A-Z0-9]*' - propertyPattern: '[a-z][A-Za-z0-9]*' - -performance: - active: true - ArrayPrimitive: - active: true - ForEachOnRange: - active: true - SpreadOperator: - active: true - UnnecessaryTemporaryInstantiation: - active: true - -potential-bugs: - active: true - Deprecation: - active: true - DuplicateCaseInWhenExpression: - active: true - EqualsAlwaysReturnsTrueOrFalse: - active: true - ExplicitGarbageCollectionCall: - active: true - HasPlatformType: - active: true - ImplicitDefaultLocale: - active: true - InvalidRange: - active: true - IteratorHasNextCallsNextMethod: - active: true - IteratorNotThrowingNoSuchElementException: - active: true - LateinitUsage: - active: false - MapGetWithNotNullAssertionOperator: - active: true - MissingWhenCase: - active: true - NullCheckOnMutableProperty: - active: true - RedundantElseInWhen: - active: true - UnconditionalJumpStatementInLoop: - active: true - UnnecessaryNotNullOperator: - active: true - UnnecessarySafeCall: - active: true - UnreachableCode: - active: true - UnsafeCallOnNullableType: - active: true - UnsafeCast: - active: true - UselessPostfixExpression: - active: true - WrongEqualsTypeParameter: - active: true - -style: - active: true - CollapsibleIfStatements: - active: true - DataClassContainsFunctions: - active: false - EqualsNullCall: - active: true - ExplicitItLambdaParameter: - active: true - ForbiddenComment: - active: true - ForbiddenImport: - active: false - ForbiddenVoid: - active: true - FunctionOnlyReturningConstant: - active: true - LoopWithTooManyJumpStatements: - active: true - MagicNumber: - active: false - MaxLineLength: - active: true - maxLineLength: 150 - MayBeConst: - active: true - ModifierOrder: - active: true - MultilineLambdaItParameter: - active: true - NestedClassesVisibility: - active: true - NewLineAtEndOfFile: - active: true - NoTabs: - active: true - OptionalAbstractKeyword: - active: true - OptionalWhenBraces: - active: false - ProtectedMemberInFinalClass: - active: true - RedundantExplicitType: - active: true - RedundantVisibilityModifierRule: - active: true - ReturnCount: - active: true - max: 2 - SafeCast: - active: true - SerialVersionUIDInSerializableClass: - active: true - SpacingBetweenPackageAndImports: - active: true - ThrowsCount: - active: true - max: 2 - TrailingWhitespace: - active: true - UnderscoresInNumericLiterals: - active: false - UnnecessaryAbstractClass: - active: true - UnnecessaryApply: - active: true - UnnecessaryFilter: - active: true - UnnecessaryInheritance: - active: true - UnnecessaryLet: - active: true - UnnecessaryParentheses: - active: true - UntilInsteadOfRangeTo: - active: true - UnusedImports: - active: true - UnusedPrivateClass: - active: true - UnusedPrivateMember: - active: true - allowedNames: '(_|ignored|expected|serialVersionUID)' - UseCheckOrError: - active: true - UseDataClass: - active: true - UseEmptyCounterpart: - active: true - UseIfEmptyOrIfBlank: - active: true - UseIsNullOrEmpty: - active: true - UseOrEmpty: - active: true - UseRequire: - active: true - UseRequireNotNull: - active: true - VarCouldBeVal: - active: true - WildcardImport: - active: true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8be7f71..e39144a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,6 +13,7 @@ junit = "4.13.2" coroutines-test = "1.7.3" mockk = "1.13.9" mockwebserver = "4.12.0" +detekt = "1.23.6" [libraries] kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" } @@ -48,3 +49,4 @@ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", versi ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } android-library = { id = "com.android.library", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" } +detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }