Skip to content

Commit 854f72c

Browse files
authored
Merge pull request #670 from modelix/feature/MODELIX-794-Adapt-the-detekt-configuration-according-to-the-discussions-from-the-coding-conventions-workshop
MODELIX-794: adapt the detekt configuration according to the discussions from the coding conventions workshop
2 parents 19e7e52 + 688bed5 commit 854f72c

File tree

12 files changed

+187
-151
lines changed

12 files changed

+187
-151
lines changed

.detekt.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,23 @@ style:
1010
active: false
1111
ThrowsCount:
1212
active: false
13+
14+
# Enforce some proper documentation standards (cf. MODELIX-794)
15+
comments:
16+
OutdatedDocumentation:
17+
active: true
18+
UndocumentedPublicClass:
19+
active: true
20+
UndocumentedPublicFunction:
21+
active: true
22+
UndocumentedPublicProperty:
23+
active: true
24+
25+
# Try to enforce good handling of nullability
26+
potential-bugs:
27+
CastNullableToNonNullableType:
28+
active: true
29+
30+
modelix:
31+
AvoidNonNullAssertionOperator:
32+
active: true

.github/workflows/build.yaml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
- name: Build
3333
env:
3434
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35-
run: ./gradlew --build-cache build detekt :koverHtmlReport :koverXmlReport -PciBuild=true
35+
run: ./gradlew --build-cache build detekt detektJsMain detektJsTest detektJvmMain detektJvmTest :koverHtmlReport :koverXmlReport -PciBuild=true
3636
- name: Publish test results
3737
uses: EnricoMi/publish-unit-test-result-action@v2
3838
# Also report in case the build failed
@@ -56,10 +56,18 @@ jobs:
5656
token: ${{ secrets.GITHUB_TOKEN }}
5757
title: JVM coverage report
5858
update-comment: true
59+
# We need to combine the SARIF files because GitHub has a limit of 20 runs. Our number of modules + targets
60+
# exceeds this limit. Therefore, we combine the individual runs in the SARIF files.
61+
- uses: actions/setup-node@v4
62+
with:
63+
node-version: '20.x'
64+
- name: Combine SARIF files
65+
run: |
66+
npx @microsoft/sarif-multitool merge --merge-runs --output-file merged.sarif $(find . -iname '*.sarif*')
5967
- name: Upload SARIF file
6068
uses: github/codeql-action/upload-sarif@v3
6169
with:
62-
sarif_file: 'build/reports/detekt/'
70+
sarif_file: merged.sarif
6371
category: detekt
6472

6573
test-model-api-gen-gradle:

build.gradle.kts

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ plugins {
4343
alias(libs.plugins.spotless) apply false
4444
alias(libs.plugins.dokka)
4545
alias(libs.plugins.node) apply false
46-
alias(libs.plugins.detekt) apply false
46+
alias(libs.plugins.detekt)
4747
alias(libs.plugins.kotlinx.kover)
4848
}
4949

@@ -82,7 +82,6 @@ subprojects {
8282
val subproject = this
8383
apply(plugin = "maven-publish")
8484
apply(plugin = "org.jetbrains.dokka")
85-
apply(plugin = "io.gitlab.arturbosch.detekt")
8685
apply(plugin = "org.jetbrains.kotlinx.kover")
8786

8887
version = rootProject.version
@@ -94,22 +93,6 @@ subprojects {
9493
}
9594
}
9695

97-
tasks.withType<Detekt> {
98-
parallel = true
99-
// For now, we only use the results here as hints
100-
ignoreFailures = true
101-
102-
buildUponDefaultConfig = true
103-
config.setFrom(parentProject.projectDir.resolve(".detekt.yml"))
104-
105-
reports {
106-
sarif.required.set(true)
107-
// This is required for the GitHub upload action to easily find all sarif files in a single directory.
108-
sarif.outputLocation.set(parentProject.layout.buildDirectory.file("reports/detekt/${project.name}.sarif"))
109-
html.required.set(true)
110-
}
111-
}
112-
11396
val kotlinApiVersion = org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_6
11497
subproject.tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
11598
if (!name.lowercase().contains("test")) {
@@ -168,6 +151,29 @@ subprojects {
168151
download.set(true)
169152
}
170153
}
154+
155+
// Configure detekt including our custom rule sets
156+
if (project.name != "detekt-rules") {
157+
apply(plugin = "io.gitlab.arturbosch.detekt")
158+
dependencies {
159+
detektPlugins(project(":detekt-rules"))
160+
}
161+
tasks.withType<Detekt> {
162+
dependsOn(":detekt-rules:assemble")
163+
164+
parallel = true
165+
// For now, we only use the results here as hints
166+
ignoreFailures = true
167+
168+
buildUponDefaultConfig = true
169+
config.setFrom(parentProject.projectDir.resolve(".detekt.yml"))
170+
171+
reports {
172+
sarif.required.set(true)
173+
html.required.set(true)
174+
}
175+
}
176+
}
171177
}
172178

173179
allprojects {
@@ -203,7 +209,8 @@ allprojects {
203209
url = uri("https://maven.pkg.github.com/modelix/modelix")
204210
credentials {
205211
username = project.findProperty("gpr.user") as? String ?: System.getenv("GITHUB_ACTOR")
206-
password = project.findProperty("gpr.universalkey") as? String ?: System.getenv("GHP_UNIVERSAL_TOKEN")
212+
password =
213+
project.findProperty("gpr.universalkey") as? String ?: System.getenv("GHP_UNIVERSAL_TOKEN")
207214
}
208215
} else {
209216
url = uri("https://maven.pkg.github.com/modelix/modelix.core")

detekt-rules/build.gradle.kts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
plugins {
2+
kotlin("jvm")
3+
}
4+
5+
dependencies {
6+
compileOnly(libs.detekt.api)
7+
8+
testImplementation(libs.junit)
9+
testImplementation(libs.detekt.test)
10+
testImplementation(kotlin("test"))
11+
}
12+
13+
tasks.test {
14+
useJUnitPlatform()
15+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2024.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.modelix.detekt
18+
19+
import io.gitlab.arturbosch.detekt.api.CodeSmell
20+
import io.gitlab.arturbosch.detekt.api.Config
21+
import io.gitlab.arturbosch.detekt.api.Debt
22+
import io.gitlab.arturbosch.detekt.api.Entity
23+
import io.gitlab.arturbosch.detekt.api.Issue
24+
import io.gitlab.arturbosch.detekt.api.Rule
25+
import io.gitlab.arturbosch.detekt.api.Severity
26+
import org.jetbrains.kotlin.psi.KtReferenceExpression
27+
28+
class AvoidNonNullAssertionOperator(config: Config) : Rule(config) {
29+
override val issue = Issue(
30+
javaClass.simpleName,
31+
Severity.Warning,
32+
"Reports instances of !! which should be replace by checkNotNull or requireNotNull " +
33+
"with a descriptive message of why we assume a value to be not null",
34+
Debt.FIVE_MINS,
35+
)
36+
37+
override fun visitReferenceExpression(expression: KtReferenceExpression) {
38+
super.visitReferenceExpression(expression)
39+
40+
if (expression.node.text == "!!") {
41+
report(
42+
CodeSmell(
43+
issue,
44+
Entity.from(expression.originalElement),
45+
"Prefer checkNotNull or requireNotNull with an explanatory message over the !! operator",
46+
),
47+
)
48+
}
49+
}
50+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright (c) 2024.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.modelix.detekt
18+
19+
import io.gitlab.arturbosch.detekt.api.Config
20+
import io.gitlab.arturbosch.detekt.api.RuleSet
21+
import io.gitlab.arturbosch.detekt.api.RuleSetProvider
22+
23+
class RuleSetProvider : RuleSetProvider {
24+
override val ruleSetId: String = "modelix"
25+
26+
override fun instance(config: Config): RuleSet = RuleSet(
27+
ruleSetId,
28+
listOf(
29+
AvoidNonNullAssertionOperator(config),
30+
),
31+
)
32+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
org.modelix.detekt.RuleSetProvider
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
modelix:
2+
AvoidNonNullAssertionOperator:
3+
active: true
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.modelix.detekt
2+
3+
import io.gitlab.arturbosch.detekt.api.Config
4+
import io.gitlab.arturbosch.detekt.test.compileAndLint
5+
import org.junit.jupiter.api.Assertions.assertEquals
6+
import org.junit.jupiter.api.Test
7+
8+
class AvoidNonNullAssertionOperatorTest {
9+
@Test
10+
fun `find double bang operator`() {
11+
val code = """
12+
fun main() {
13+
val x: String? = null
14+
val y = x!!
15+
}
16+
"""
17+
18+
val findings = AvoidNonNullAssertionOperator(Config.empty).compileAndLint(code)
19+
20+
assertEquals(1, findings.size)
21+
}
22+
}

gradle/libs.versions.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ spotless = { id = "com.diffplug.spotless", version = "6.25.0" }
1616
modelix-mps-buildtools = { id = "org.modelix.mps.build-tools", version.ref = "modelixBuildtools" }
1717
dokka = {id = "org.jetbrains.dokka", version.ref = "dokka"}
1818
node = {id = "com.github.node-gradle.node", version = "7.0.2"}
19-
detekt = { id = "io.gitlab.arturbosch.detekt", version = "1.23.6" }
19+
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
2020
npm-publish = { id = "dev.petuska.npm.publish", version = "3.4.2" }
2121
test-logger = { id = "com.adarshr.test-logger", version = "4.0.0" }
2222
shadow = { id = "com.github.johnrengelman.shadow", version = "8.1.1" }
@@ -37,6 +37,7 @@ modelixBuildtools="1.4.1"
3737
openapi = "7.5.0"
3838
micrometer = "1.12.5"
3939
dokka = "1.9.20"
40+
detekt = "1.23.6"
4041

4142
[libraries]
4243

@@ -116,3 +117,6 @@ modelix-buildtools-gradle = { group = "org.modelix.mps", name = "build-tools-gra
116117
modelix-buildtools-lib = { group = "org.modelix.mps", name = "build-tools-lib", version.ref = "modelixBuildtools"}
117118

118119
micrometer-registry-prometheus = { group = "io.micrometer", name = "micrometer-registry-prometheus", version.ref = "micrometer"}
120+
121+
detekt-api = { group = "io.gitlab.arturbosch.detekt", name= "detekt-api", version.ref = "detekt" }
122+
detekt-test = { group = "io.gitlab.arturbosch.detekt", name= "detekt-test", version.ref = "detekt" }

0 commit comments

Comments
 (0)