Skip to content
This repository has been archived by the owner on Oct 14, 2024. It is now read-only.

Commit

Permalink
Add files arg + use path APIs in sarif merging (#76)
Browse files Browse the repository at this point in the history
* Add files arg + use path APIs

* Cleanup and fix arg name shadowing

* Use require()
  • Loading branch information
ZacSweers authored Nov 30, 2023
1 parent 2125fd5 commit e167305
Showing 1 changed file with 60 additions and 35 deletions.
95 changes: 60 additions & 35 deletions src/main/kotlin/slack/cli/sarif/MergeSarifReports.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,22 @@
package slack.cli.sarif

import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.multiple
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.required
import com.github.ajalt.clikt.parameters.types.file
import com.github.ajalt.clikt.parameters.types.path
import io.github.detekt.sarif4k.SarifSchema210
import io.github.detekt.sarif4k.SarifSerializer
import java.io.File
import java.nio.file.Path
import kotlin.io.path.absolutePathString
import kotlin.io.path.createParentDirectories
import kotlin.io.path.deleteIfExists
import kotlin.io.path.exists
import kotlin.io.path.readText
import kotlin.io.path.relativeTo
import kotlin.io.path.writeText
import kotlin.system.exitProcess
import slack.cli.projectDirOption
import slack.cli.skipBuildAndCacheDirs
Expand All @@ -34,8 +42,10 @@ public class MergeSarifReports :
) {

private val projectDir by projectDirOption()
private val outputFile: File by option("--output-file").file().required()
private val filePrefix by option("--file-prefix").required()
private val outputFile by option("--output-file").path().required()
private val filePrefix by option("--file-prefix")
private val argFiles by
argument("--files").path(mustExist = true, canBeDir = false, mustBeReadable = true).multiple()
private val verbose by option("--verbose", "-v").flag()
private val remapSrcRoots by
option(
Expand Down Expand Up @@ -68,13 +78,11 @@ public class MergeSarifReports :
}

private fun prepareOutput() {
if (outputFile.exists()) {
outputFile.delete()
}
outputFile.parentFile?.mkdirs()
outputFile.deleteIfExists()
outputFile.createParentDirectories()
}

private fun findBuildFiles(): List<File> {
private fun findBuildFiles(): List<Path> {
log("Finding build files in ${projectDir.toFile().canonicalFile}")
val buildFiles =
projectDir
Expand All @@ -83,32 +91,49 @@ public class MergeSarifReports :
.walkTopDown()
.skipBuildAndCacheDirs()
.filter { it.name == "build.gradle.kts" }
.map { it.toPath() }
.toList()
log("${buildFiles.size} build files found")
return buildFiles
}

private fun String.prefixPathWith(prefix: String) = "$prefix/$this"

private fun findSarifFiles(): List<File> {
// Find build files first, this gives us an easy hook to then go looking in build/reports dirs.
// Otherwise we don't have a way to easily exclude populated build dirs that would take forever.
val buildFiles = findBuildFiles()
private fun findSarifFiles(): List<Path> {
require(filePrefix != null || argFiles.isNotEmpty()) {
"Must specify either --file-prefix or pass files as arguments"
}

log("Finding sarif files")
return buildFiles
.asSequence()
.flatMap { buildFile ->
val reportsDir = File(buildFile.parentFile, "build/reports")
if (reportsDir.exists()) {
reportsDir.walkTopDown().filter {
it.isFile && it.extension == "sarif" && it.nameWithoutExtension.startsWith(filePrefix)
val files = mutableListOf<Path>()

files += argFiles

filePrefix?.let { prefix ->
// Find build files first, this gives us an easy hook to then go looking in build/reports
// dirs.
// Otherwise we don't have a way to easily exclude populated build dirs that would take
// forever.
val buildFiles = findBuildFiles()

log("Finding sarif files")
files +=
buildFiles.asSequence().flatMap { buildFile ->
val reportsDir = buildFile.parent.resolve("build/reports")
if (reportsDir.exists()) {
reportsDir
.toFile()
.walkTopDown()
.filter {
it.isFile && it.extension == "sarif" && it.nameWithoutExtension.startsWith(prefix)
}
.map { it.toPath() }
} else {
emptySequence()
}
} else {
emptySequence()
}
}
.toList()
}

return files
}

/**
Expand Down Expand Up @@ -143,16 +168,16 @@ public class MergeSarifReports :
* libraries/lib/src/main/java/com/example/app/LibActivity.kt
* ```
*/
private fun SarifSchema210.remapSrcRoots(sarifFile: File): SarifSchema210 {
// <module>/─────────────────────────────────
// build/─────────────────────┐
// reports/──────┐
//
val module = sarifFile.parentFile.parentFile.parentFile
check(File(module, "build.gradle.kts").exists()) {
private fun SarifSchema210.remapSrcRoots(sarifFile: Path): SarifSchema210 {
// <module>/─────────────────────────┐
// build/─────────────────
// reports/──────┐
//
val module = sarifFile.parent.parent.parent
check(module.resolve("build.gradle.kts").exists()) {
"Expected to find build.gradle.kts in $module"
}
val modulePrefix = module.toRelativeString(projectDir.toFile())
val modulePrefix = module.relativeTo(projectDir).toString()
return copy(
runs =
runs.map { run ->
Expand Down Expand Up @@ -232,7 +257,7 @@ public class MergeSarifReports :
)
}

private fun loadSarifs(inputs: List<File>): List<SarifSchema210> {
private fun loadSarifs(inputs: List<Path>): List<SarifSchema210> {
return inputs.map { sarifFile ->
log("Parsing $sarifFile")
val parsed = SarifSerializer.fromJson(sarifFile.readText())
Expand All @@ -249,7 +274,7 @@ public class MergeSarifReports :
}
}

private fun merge(inputs: List<File>) {
private fun merge(inputs: List<Path>) {
log("Parsing ${inputs.size} sarif files")
val sarifs = loadSarifs(inputs)

Expand Down

0 comments on commit e167305

Please sign in to comment.