diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index fb7f4a8a..6f55712b 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,15 @@
-
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index d6d139c0..b2a778b4 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -20,6 +20,7 @@
+
@@ -42,12 +43,12 @@
-
-
-
+
+
+
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index ca5114c6..a2e866a4 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -96,6 +96,7 @@ dependencies {
implementation(project(":core:network-impl"))
detektPlugins(libs.detekt.formatting)
+ detektPlugins(project(":detekt-rules"))
implementation(project(":feature:example-home:api"))
implementation(project(":feature:example-profile:api"))
diff --git a/detekt-rules/.gitignore b/detekt-rules/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/detekt-rules/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/detekt-rules/build.gradle.kts b/detekt-rules/build.gradle.kts
new file mode 100644
index 00000000..aff5e89c
--- /dev/null
+++ b/detekt-rules/build.gradle.kts
@@ -0,0 +1,19 @@
+plugins {
+ id("java-library")
+ alias(libs.plugins.jvm)
+}
+java {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+}
+
+dependencies {
+ implementation(libs.detekt.api)
+ compileOnly(libs.kotlin.compiler.embeddable)
+}
+
+kotlin {
+ compilerOptions {
+ jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
+ }
+}
diff --git a/detekt-rules/src/main/kotlin/ru/yeahub/rules/CustomRuleSetProvider.kt b/detekt-rules/src/main/kotlin/ru/yeahub/rules/CustomRuleSetProvider.kt
new file mode 100644
index 00000000..53bc4cf8
--- /dev/null
+++ b/detekt-rules/src/main/kotlin/ru/yeahub/rules/CustomRuleSetProvider.kt
@@ -0,0 +1,17 @@
+package ru.yeahub.rules
+
+import io.gitlab.arturbosch.detekt.api.Config
+import io.gitlab.arturbosch.detekt.api.RuleSet
+import io.gitlab.arturbosch.detekt.api.RuleSetProvider
+
+class CustomRuleSetProvider : RuleSetProvider {
+
+ override val ruleSetId: String = "yeahub"
+
+ override fun instance(config: Config): RuleSet {
+ return RuleSet(
+ id = ruleSetId,
+ rules = listOf(NoNotNullAssertionRule(config))
+ )
+ }
+}
\ No newline at end of file
diff --git a/detekt-rules/src/main/kotlin/ru/yeahub/rules/NoNotNullAssertionRule.kt b/detekt-rules/src/main/kotlin/ru/yeahub/rules/NoNotNullAssertionRule.kt
new file mode 100644
index 00000000..08d5df76
--- /dev/null
+++ b/detekt-rules/src/main/kotlin/ru/yeahub/rules/NoNotNullAssertionRule.kt
@@ -0,0 +1,38 @@
+package ru.yeahub.rules
+
+import io.gitlab.arturbosch.detekt.api.CodeSmell
+import io.gitlab.arturbosch.detekt.api.Config
+import io.gitlab.arturbosch.detekt.api.Debt
+import io.gitlab.arturbosch.detekt.api.Entity
+import io.gitlab.arturbosch.detekt.api.Issue
+import io.gitlab.arturbosch.detekt.api.Rule
+import io.gitlab.arturbosch.detekt.api.Severity
+import org.jetbrains.kotlin.psi.KtUnaryExpression
+
+class NoNotNullAssertionRule(config: Config = Config.Companion.empty) : Rule(config) {
+
+ init {
+ println(">>> NoNotNullAssertionRule: ПРАВИЛО ЗАГРУЖЕНО! <<<")
+ }
+
+ override val issue = Issue(
+ "NoNotNullAssertionRule",
+ Severity.Style,
+ "Оператор !! запрещён. Используйте безопасные вызовы (.?) или элвис-оператор (?:).",
+ Debt.Companion.FIVE_MINS
+ )
+
+ override fun visitUnaryExpression(expression: KtUnaryExpression) {
+ val operatorText = expression.operationReference.text
+ if (operatorText == "!!") {
+ report(
+ CodeSmell(
+ issue,
+ Entity.Companion.from(expression),
+ message = "Использование оператора !! запрещено"
+ )
+ )
+ }
+ super.visitUnaryExpression(expression)
+ }
+}
\ No newline at end of file
diff --git a/detekt-rules/src/main/resources/META-INF/services/io.gitlab.arturbosch.detekt.api.RuleSetProvider b/detekt-rules/src/main/resources/META-INF/services/io.gitlab.arturbosch.detekt.api.RuleSetProvider
new file mode 100644
index 00000000..b60673c6
--- /dev/null
+++ b/detekt-rules/src/main/resources/META-INF/services/io.gitlab.arturbosch.detekt.api.RuleSetProvider
@@ -0,0 +1 @@
+ru.yeahub.rules.CustomRuleSetProvider
\ No newline at end of file
diff --git a/detekt-setting/detekt.yml b/detekt-setting/detekt.yml
index 86ff507f..1ecfd2a5 100644
--- a/detekt-setting/detekt.yml
+++ b/detekt-setting/detekt.yml
@@ -42,4 +42,8 @@ complexity:
LongMethod:
active: false
TooManyFunctions:
- active: false
\ No newline at end of file
+ active: false
+
+yeahub:
+ NoNotNullAssertionRule:
+ active: true
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 00f8973c..2590d293 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -4,6 +4,7 @@ kotlin = "2.0.21"
coreKtx = "1.10.1"
junit = "5.8.2"
junitPlatformLauncher = "1.8.2"
+kotlinCompilerEmbeddable = "2.0.21"
lifecycleRuntimeCompose = "2.7.0"
mockk = "1.14.2"
espressoCore = "3.5.1"
@@ -47,6 +48,8 @@ androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-man
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
+detekt-api = { module = "io.gitlab.arturbosch.detekt:detekt-api", version.ref = "detekt" }
+kotlin-compiler-embeddable = { module = "org.jetbrains.kotlin:kotlin-compiler-embeddable", version.ref = "kotlinCompilerEmbeddable" }
timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 616cc767..7fcd9fd7 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -57,4 +57,4 @@ include(":feature:public-collections:api")
include(":feature:questions-or-collections")
include(":feature:questions-or-collections:api")
include(":feature:questions-or-collections:impl")
-
+include(":detekt-rules")