Skip to content

Commit

Permalink
Adding the support for the actual input of analyzers in SARIF format (#…
Browse files Browse the repository at this point in the history
…357)

### What's done:
- supported reading of actual warnings in SARIF format
  • Loading branch information
orchestr7 authored Feb 4, 2022
1 parent 10dce68 commit c4414a8
Show file tree
Hide file tree
Showing 16 changed files with 108 additions and 13 deletions.
9 changes: 7 additions & 2 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

object Versions {
object IntegrationTest {
const val ktlint = "0.39.0"
const val ktlint = "0.43.2"
const val ktlintLink = "https://github.com/pinterest/ktlint/releases/download/$ktlint/ktlint"
const val diktat = "1.0.0-rc.2"
const val diktat = "1.0.2"
const val diktatLink = "https://github.com/cqfn/diKTat/releases/download/v$diktat/diktat-$diktat.jar"

const val oldKtlint = "0.39.0"
const val oldKtlintLink = "https://github.com/pinterest/ktlint/releases/download/$oldKtlint/ktlint"
const val oldDiktat = "1.0.0-rc.2"
const val oldDiktatLink = "https://github.com/cqfn/diKTat/releases/download/v$oldDiktat/diktat-$oldDiktat.jar"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ fun Project.createDiktatTask() {
apply<DiktatGradlePlugin>()
configure<DiktatExtension> {
diktatConfigFile = rootProject.file("diktat-analysis.yml")
// FixMe: temporary before the release 1.0.3 of diktat
// reporterType = "sarif"
inputs {
include(
"$rootDir/buildSrc/src/**/*.kt",
Expand All @@ -54,4 +56,9 @@ fun Project.createDiktatTask() {
tasks.findByName("diktatFix")?.let { this@register.dependsOn(it) }
}
}

// FixMe: temporary before the release 1.0.3 of diktat
/* this.configurations.getByName("diktat").dependencies.add(
this.dependencies.create("com.pinterest.ktlint:ktlint-reporter-sarif:0.43.2")
) */
}
1 change: 0 additions & 1 deletion examples/kotlin-diktat/fix_and_warn/save.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
tags = ["fix and warn"]
description = "Autofixing of issues discovered by diKTat on smoke tests and warn about issues, which couldn't be auto-corrected"
suiteName = "Autofix and Warn"
execCmd = "java -jar ktlint -R diktat.jar"

["fix and warn"]
["fix and warn".fix]
Expand Down
21 changes: 21 additions & 0 deletions examples/kotlin-diktat/sarif-actual/save.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[general]
tags = ["warn", "sarif"]
description = "Test warnings discovered by diKTat, reading expected warnings from SARIF file"
suiteName = "Only Warnings: with SARIF format"
expectedWarningsPattern = "// ;warn:?(.*):(\\d+):? ?(.+)?"
execCmd = "java -jar ktlint --disabled_rules=standard -R diktat.jar"



[warn]
execFlags = "--reporter=sarif"
# regular expression to detect tests
testNameRegex = ".*Test.kt"
actualWarningsFormat = "SARIF"
fileNameCaptureGroupOut = 1
lineCaptureGroupOut = 2
columnCaptureGroupOut = 3
messageCaptureGroupOut = 4
exactWarningsMatch = false
warningTextHasColumn = true
warningTextHasLine = true
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.cqfn.diktat.test.resources.test.paragraph1.naming.enum_

// ;warn:3:1: [MISSING_KDOC_TOP_LEVEL] all public and internal top-level classes and functions should have Kdoc: EnumValueSnakeCaseTest (cannot be auto-corrected)
// ;warn:35: [WRONG_DECLARATIONS_ORDER] declarations of constants and enum members should be sorted alphabetically: enum entries order is incorrect
// ;warn:10:5: [ENUMS_SEPARATED] enum is incorrectly formatted: enums must end with semicolon
enum class EnumValueSnakeCaseTest {
// ;warn:$line+1:5: [ENUM_VALUE] enum values should be{{ in }}selected UPPER_CASE snake/PascalCase format: paSC_SAl_l
paSC_SAl_l,

// ;warn:5: [ENUM_VALUE] enum values{{ should }}be in selected{{ UPPER_CASE }}snake/PascalCase format: PascAsl_f
PascAsl_f
// ;warn:$line-2:5: [ENUMS_SEPARATED] enum is incorrectly formatted: last enum entry must end with a comma

// ;warn:1:9: {{.*}}[PACKAGE_NAME_INCORRECT_PREFIX] package name should start from company's domain: org.cqfn.save{{.*}}
}
2 changes: 1 addition & 1 deletion examples/kotlin-diktat/save.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[general]
execCmd = "java -jar ktlint -R diktat.jar"
execCmd = "java -jar ktlint-old --disabled_rules=standard -R diktat-old.jar"
description = "Test for diktat - linter and formatter for Kotlin"
language = "Kotlin"
# this is the default value, you don't need to add it explicitly, but can be useful, if you have different pattern:
Expand Down
2 changes: 1 addition & 1 deletion examples/kotlin-diktat/warn-dir/save.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[general]
execCmd = "java -jar ktlint --disabled_rules=standard -R diktat.jar"
execCmd = "java -jar ktlint-old --disabled_rules=standard -R diktat-old.jar"
tags = ["warn"]
description = "Test for directory mode"

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ group=org.cqfn.save
# gradle performance
org.gradle.parallel=true
org.gradle.vfs.watch=true
org.gradle.jvmargs=-Xmx1g -XX:MaxMetaspaceSize=512m
org.gradle.jvmargs=-Xmx4096M -XX:MaxMetaspaceSize=512m
org.gradle.caching=true

# Kotlin
Expand Down
1 change: 1 addition & 0 deletions save-cli/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ kotlin {

tasks.withType<Test>().configureEach {
dependsOn(":save-core:downloadTestResources")
dependsOn(":save-core:downloadOldTestResources")
}

// disable building of some binaries to speed up build
Expand Down
7 changes: 5 additions & 2 deletions save-cli/src/jvmTest/kotlin/org/cqfn/save/cli/GeneralTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ class GeneralTest {
assertTrue(fs.exists(destination))

// Check for existence of diktat and ktlint
assertTrue(fs.exists((examplesDir.toPath() / "diktat.jar")))
assertTrue(fs.exists((examplesDir.toPath() / "ktlint")))
assertTrue(fs.exists((examplesDir.toPath() / "diktat-old.jar")))
assertTrue(fs.exists((examplesDir.toPath() / "ktlint-old")))

// Make sure, that we will check report, which will be obtained after current execution; remove old report if exist
val reportFile = examplesDir.toPath() / "save.out.json".toPath()
Expand All @@ -88,6 +88,9 @@ class GeneralTest {
assertTrue(fs.exists(reportFile))

val reports: List<Report> = json.decodeFromString(fs.readFile(reportFile))

println("Following tests failed: ${reports.map { it.testSuite }}")

// Almost all result statuses should be Pass, except the few cases
reports.forEach { report ->
report.pluginExecutions.forEach { pluginExecution ->
Expand Down
21 changes: 21 additions & 0 deletions save-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,23 @@ tasks.withType<KotlinCompile<*>>().forEach {
it.dependsOn(generateVersionFileTaskProvider)
}

tasks.register<Download>("downloadOldTestResources") {
src(listOf(
Versions.IntegrationTest.oldKtlintLink,
Versions.IntegrationTest.oldDiktatLink,
))
dest("../examples/kotlin-diktat")
doLast {
file("../examples/kotlin-diktat/diktat-${Versions.IntegrationTest.oldDiktat}.jar").renameTo(
file("../examples/kotlin-diktat/diktat-old.jar")
)

file("../examples/kotlin-diktat/ktlint").renameTo(
file("../examples/kotlin-diktat/ktlint-old")
)
}
}

tasks.register<Download>("downloadTestResources") {
src(listOf(
Versions.IntegrationTest.ktlintLink,
Expand All @@ -83,15 +100,19 @@ tasks.register<Download>("downloadTestResources") {
)
}
}

val cleanupTask = tasks.register("cleanupTestResources") {
this.dependsOn(":save-cli:jvmTest")
mustRunAfter(tasks.withType<Test>())
doFirst {
file("../examples/kotlin-diktat/ktlint-old").delete()
file("../examples/kotlin-diktat/ktlint").delete()
file("../examples/kotlin-diktat/diktat-old.jar").delete()
file("../examples/kotlin-diktat/diktat.jar").delete()
}
}
tasks.withType<Test>().configureEach {
dependsOn("downloadTestResources")
dependsOn("downloadOldTestResources")
finalizedBy("cleanupTestResources")
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,15 @@ class ClassicWarnTest {
@Test
fun `execute warn-plugin with expected warnings from SARIF`() {
runTestsWithDiktat(
listOf("sarif"),
listOf("sarif-expected"),
1
)
}

@Test
fun `execute warn-plugin with actual warnings from SARIF`() {
runTestsWithDiktat(
listOf("sarif-actual"),
1
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.cqfn.save.core.result.TestResult
import org.cqfn.save.core.utils.ExecutionResult
import org.cqfn.save.core.utils.ProcessExecutionException
import org.cqfn.save.core.utils.ProcessTimeoutException
import org.cqfn.save.plugin.warn.sarif.toWarnings
import org.cqfn.save.plugin.warn.utils.CmdExecutorWarn
import org.cqfn.save.plugin.warn.utils.ResultsChecker
import org.cqfn.save.plugin.warn.utils.Warning
Expand All @@ -26,10 +27,13 @@ import org.cqfn.save.plugin.warn.utils.collectionSingleWarnings
import org.cqfn.save.plugin.warn.utils.extractWarning
import org.cqfn.save.plugin.warn.utils.getLineNumber

import io.github.detekt.sarif4k.SarifSchema210
import okio.FileSystem
import okio.Path

import kotlin.random.Random
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

private typealias WarningMap = Map<String, List<Warning>>

Expand Down Expand Up @@ -108,7 +112,12 @@ class WarnPlugin(

val expectedWarningsMap: WarningMap = copyPaths.zip(originalPaths).associate { (copyPath, originalPath) ->
val warningsForCurrentPath =
copyPath.collectExpectedWarningsWithLineNumbers(warnPluginConfig, generalConfig, originalPaths, originalPath)
copyPath.collectExpectedWarningsWithLineNumbers(
warnPluginConfig,
generalConfig,
originalPaths,
originalPath
)
copyPath.name to warningsForCurrentPath
}

Expand Down Expand Up @@ -236,9 +245,16 @@ class WarnPlugin(
@Suppress("AVOID_NULL_CHECKS")
private fun collectActualWarningsWithLineNumbers(
result: ExecutionResult,
warnPluginConfig: WarnPluginConfig
warnPluginConfig: WarnPluginConfig,
): WarningMap = when (warnPluginConfig.actualWarningsFormat) {
ActualWarningsFormat.SARIF -> throw NotImplementedError()
ActualWarningsFormat.SARIF -> Json.decodeFromString<SarifSchema210>(
result.stdout.joinToString("\n")
)
// setting emptyList() here instead of originalPaths to avoid invalid mapping
.toWarnings(testConfig.getRootConfig().directory, emptyList())
.groupBy { it.fileName }
.mapValues { (_, warning) -> warning.sortedBy { it.message } }

else -> result.stdout.mapNotNull {
with(warnPluginConfig) {
it.extractWarning(
Expand All @@ -253,7 +269,6 @@ class WarnPlugin(
}
.groupBy { it.fileName }
.mapValues { (_, warning) -> warning.sortedBy { it.message } }

}

private fun warnMissingExpectedWarnings(
Expand Down

0 comments on commit c4414a8

Please sign in to comment.