Skip to content

Commit

Permalink
Supported ExpectedWarningsFormat.PLAIN (#569)
Browse files Browse the repository at this point in the history
- supported reading expected results from external plain file
  • Loading branch information
nulls authored Feb 28, 2024
1 parent 29a7c36 commit e7d0d24
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ enum class ActualWarningsFormat {
*/
enum class ExpectedWarningsFormat {
IN_PLACE,
PLAIN,
SARIF,
;
}
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,19 @@ fun FileSystem.findAncestorDirContainingFile(path: Path, fileName: String): Path
}
}

/**
* Find a file in any of parent directories and return this file
*
* @param path path for which ancestors should be checked
* @param fileName a name of the file that will be searched for
* @return a path to a file with name [fileName] or null
*/
fun FileSystem.findFileInAncestorDir(path: Path, fileName: String): Path? = findAncestorDirContainingFile(
path, fileName
)?.let {
it / fileName
}

/**
* @return current working directory
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

package com.saveourtool.save.core.utils

import com.saveourtool.save.core.files.findAncestorDirContainingFile
import com.saveourtool.save.core.files.findFileInAncestorDir
import com.saveourtool.save.core.files.fs
import com.saveourtool.save.core.files.parents
import com.saveourtool.save.core.plugin.PluginException
Expand Down Expand Up @@ -51,11 +51,9 @@ fun FileSystem.topmostTestDirectory(path: Path): Path = path.parents().last { pa
* @return path to sarif
* @throws PluginException in case of absence of sarif file
*/
fun calculatePathToSarifFile(sarifFileName: String, anchorTestFilePath: Path): Path = fs.findAncestorDirContainingFile(
fun calculatePathToSarifFile(sarifFileName: String, anchorTestFilePath: Path): Path = fs.findFileInAncestorDir(
anchorTestFilePath, sarifFileName
)?.let {
it / sarifFileName
} ?: throw PluginException(
) ?: throw PluginException(
"Could not find SARIF file with expected warnings/fixes for file $anchorTestFilePath. " +
"Please check if correct `FarningsFormat`/`FixFormat` is set (should be SARIF) and if the file is present and called `$sarifFileName`."
"Please check if correct `WarningsFormat`/`FixFormat` is set (should be SARIF) and if the file is present and called `$sarifFileName`."
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.saveourtool.save.plugin.warn.sarif.toWarnings
import com.saveourtool.save.plugin.warn.utils.CmdExecutorWarn
import com.saveourtool.save.plugin.warn.utils.ResultsChecker
import com.saveourtool.save.plugin.warn.utils.Warning
import com.saveourtool.save.plugin.warn.utils.collectWarningsFromPlain
import com.saveourtool.save.plugin.warn.utils.collectWarningsFromSarif
import com.saveourtool.save.plugin.warn.utils.collectionMultilineWarnings
import com.saveourtool.save.plugin.warn.utils.collectionSingleWarnings
Expand All @@ -37,7 +38,6 @@ 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 @@ -258,30 +258,52 @@ class WarnPlugin(
)
}.asSequence()

@Suppress("TooGenericExceptionCaught", "SwallowedException")
@Suppress(
"TooGenericExceptionCaught",
"SwallowedException",
"TOO_LONG_FUNCTION"
)
private fun collectExpectedWarnings(
generalConfig: GeneralConfig,
warnPluginConfig: WarnPluginConfig,
originalPaths: List<Path>,
copyPaths: List<Path>,
workingDirectory: Path,
): WarningMap = if (warnPluginConfig.expectedWarningsFormat == ExpectedWarningsFormat.SARIF) {
val warningsFromSarif = try {
collectWarningsFromSarif(warnPluginConfig, originalPaths, fs, workingDirectory)
} catch (e: Exception) {
throw SarifParsingException("We failed to parse sarif. Check the your tool generation of sarif report, cause: ${e.message}", e.cause)
}
copyPaths.associate { copyPath ->
copyPath.name to warningsFromSarif.filter { it.fileName == copyPath.name }
): WarningMap {
val expectedWarningsFileName: String by lazy {
warnPluginConfig.expectedWarningsFileName
?: throw IllegalArgumentException("<expectedWarningsFileName> is not provided for expectedWarningsFormat=${warnPluginConfig.expectedWarningsFormat}")
}
} else {
copyPaths.associate { copyPath ->
val warningsForCurrentPath =
copyPath.collectExpectedWarningsWithLineNumbers(
return when (warnPluginConfig.expectedWarningsFormat) {
ExpectedWarningsFormat.PLAIN -> {
val warningsFromPlain = collectWarningsFromPlain(expectedWarningsFileName, originalPaths, fs) { plainFile ->
plainFile.collectExpectedWarningsWithLineNumbers(
warnPluginConfig,
generalConfig
)
copyPath.name to warningsForCurrentPath
}
copyPaths.associate { copyPath ->
copyPath.name to warningsFromPlain.filter { it.fileName == copyPath.name }
}
}
ExpectedWarningsFormat.SARIF -> {
val warningsFromSarif = try {
collectWarningsFromSarif(expectedWarningsFileName, originalPaths, fs, workingDirectory)
} catch (e: Exception) {
throw SarifParsingException("We failed to parse sarif. Check the your tool generation of sarif report, cause: ${e.message}", e.cause)
}
copyPaths.associate { copyPath ->
copyPath.name to warningsFromSarif.filter { it.fileName == copyPath.name }
}
}
else -> copyPaths.associate { copyPath ->
val warningsForCurrentPath =
copyPath.collectExpectedWarningsWithLineNumbers(
warnPluginConfig,
generalConfig
)
copyPath.name to warningsForCurrentPath
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package com.saveourtool.save.plugin.warn.utils

import com.saveourtool.save.core.files.findFileInAncestorDir
import com.saveourtool.save.core.files.readFile
import com.saveourtool.save.core.plugin.GeneralConfig
import com.saveourtool.save.core.plugin.PluginException
Expand All @@ -18,7 +19,6 @@ import io.github.detekt.sarif4k.SarifSchema210
import okio.FileSystem
import okio.Path

import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

/**
Expand Down Expand Up @@ -97,21 +97,42 @@ internal fun collectionSingleWarnings(
.sortedBy { warn -> warn.message }

/**
* @param warnPluginConfig
* @param plainFileName
* @param originalPaths
* @param fs
* @param warningExtractor extractor of warning from [Path]
* @return a list of warnings extracted from PLAIN file for test [file]
* @throws PluginException
*/
internal fun collectWarningsFromPlain(
plainFileName: String,
originalPaths: List<Path>,
fs: FileSystem,
warningExtractor: (Path) -> List<Warning>,
): List<Warning> {
// Since we have one <PLAIN> file for all tests, just take the first of them as anchor for calculation of paths
val anchorTestFilePath = originalPaths.first()
val plainFile = fs.findFileInAncestorDir(anchorTestFilePath, plainFileName) ?: throw PluginException(
"Could not find PLAIN file with expected warnings/fixes for file $anchorTestFilePath. " +
"Please check if correct `WarningsFormat`/`FixFormat` is set (should be PLAIN) and if the file is present and called `$plainFileName`."
)
return warningExtractor(plainFile)
}

/**
* @param sarifFileName
* @param originalPaths
* @param fs
* @param workingDirectory initial working directory, when SAVE started
* @return a list of warnings extracted from SARIF file for test [file]
* @throws PluginException
*/
internal fun collectWarningsFromSarif(
warnPluginConfig: WarnPluginConfig,
sarifFileName: String,
originalPaths: List<Path>,
fs: FileSystem,
workingDirectory: Path,
): List<Warning> {
val sarifFileName = warnPluginConfig.expectedWarningsFileName!!

// Since we have one .sarif file for all tests, just take the first of them as anchor for calculation of paths
val anchorTestFilePath = originalPaths.first()
val sarif = calculatePathToSarifFile(
Expand Down

0 comments on commit e7d0d24

Please sign in to comment.