Skip to content

Commit

Permalink
Introduce primary logic and tests (#3)
Browse files Browse the repository at this point in the history
### What's done:
* Introduce primary logic and tests
  • Loading branch information
kgevorkyan authored Dec 5, 2022
1 parent d9b5156 commit 15c5697
Show file tree
Hide file tree
Showing 12 changed files with 729 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ fun Project.configureDiktat() {
"buildSrc/**/*.kts",
"*.kts"
)
exclude("build", "buildSrc/build")
exclude("build", "buildSrc/build", "src/**/resources/*")
} else {
include("src/**/*.kt", "*.kts", "src/**/*.kts")
exclude("build/**")
exclude("build/**", "src/**/resources/*")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.saveourtool.sarifutils.cli.adapter

import com.saveourtool.sarifutils.cli.config.FileReplacements
import com.saveourtool.sarifutils.cli.config.RuleReplacements
import com.saveourtool.sarifutils.cli.files.fs
import com.saveourtool.sarifutils.cli.files.readFile

import io.github.detekt.sarif4k.Run
import io.github.detekt.sarif4k.SarifSchema210
import okio.Path
import okio.Path.Companion.toPath

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

/**
* Adapter for applying sarif fix object replacements to the corresponding test files
*
* @param sarifFile path to the sarif file with fix object replacements
* @param testFiles list of the test file, to which above fixes need to be applied
*/
class SarifFixAdapter(
private val sarifFile: Path,
private val testFiles: List<Path>
) {
/**
* Main entry for processing and applying fixes from sarif file into the test files
*/
fun process() {
val sarifSchema210: SarifSchema210 = Json.decodeFromString(
fs.readFile(sarifFile)
)
// A run object describes a single run of an analysis tool and contains the output of that run.
sarifSchema210.runs.forEachIndexed { index, run ->
val runReplacements: List<RuleReplacements?>? = extractFixObject(run)
if (runReplacements.isNullOrEmpty()) {
// TODO: Use logging library
println("Run #$index have no fix object section!")
} else {
applyReplacementsToFile(runReplacements, testFiles)
}
}
}

/**
* @param run describes a single run of an analysis tool, and contains the reported output of that run
* @return list of replacements for all files from single [run]
*/
fun extractFixObject(run: Run): List<RuleReplacements?>? {
if (!run.isFixObjectExist()) {
return emptyList()
}
// A result object describes a single result detected by an analysis tool.
// Each result is produced by the evaluation of a rule.
return run.results?.map { result ->
// A fix object represents a proposed fix for the problem indicated by the result.
// It specifies a set of artifacts to modify.
// For each artifact, it specifies regions to remove, and provides new content to insert.
result.fixes?.flatMap { fix ->
fix.artifactChanges.map { artifactChange ->
// TODO: What if uri is not provided? Could it be?
val filePath = artifactChange.artifactLocation.uri!!.toPath()
val replacements = artifactChange.replacements
FileReplacements(filePath, replacements)
}
}
}
}

private fun Run.isFixObjectExist(): Boolean = this.results?.any { result ->
result.fixes != null
} ?: false

// TODO if insertedContent?.text is null -- only delete region
@Suppress("UnusedPrivateMember")
private fun applyReplacementsToFile(runReplacements: List<RuleReplacements?>?, testFiles: List<Path>) {
runReplacements?.forEach { ruleReplacements ->
ruleReplacements?.forEach { fileReplacements ->
println("\n-------------------Replacements for file ${fileReplacements.filePath}-------------------------\n")
fileReplacements.replacements.forEach { replacement ->
println("Start line: ${replacement.deletedRegion.startLine}," +
"Start column: ${replacement.deletedRegion.startColumn}," +
"Replacement: ${replacement.insertedContent?.text}")
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.saveourtool.sarifutils.cli.config

import io.github.detekt.sarif4k.Replacement
import okio.Path

typealias RuleReplacements = List<FileReplacements>

/**
* @property filePath path to the file
* @property replacements list of artifact changes for this [file]
*/
data class FileReplacements(
val filePath: Path,
val replacements: List<Replacement>
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Utility methods to work with file system
*/

package com.saveourtool.sarifutils.cli.files

import okio.FileSystem
import okio.Path

expect val fs: FileSystem

/**
* @param path a path to a file
* @return string from the file
*/
fun FileSystem.readFile(path: Path): String = this.read(path) {
this.readUtf8()
}

This file was deleted.

Loading

0 comments on commit 15c5697

Please sign in to comment.