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

Commit e167305

Browse files
authored
Add files arg + use path APIs in sarif merging (#76)
* Add files arg + use path APIs * Cleanup and fix arg name shadowing * Use require()
1 parent 2125fd5 commit e167305

File tree

1 file changed

+60
-35
lines changed

1 file changed

+60
-35
lines changed

src/main/kotlin/slack/cli/sarif/MergeSarifReports.kt

Lines changed: 60 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,22 @@
1616
package slack.cli.sarif
1717

1818
import com.github.ajalt.clikt.core.CliktCommand
19+
import com.github.ajalt.clikt.parameters.arguments.argument
20+
import com.github.ajalt.clikt.parameters.arguments.multiple
1921
import com.github.ajalt.clikt.parameters.options.flag
2022
import com.github.ajalt.clikt.parameters.options.option
2123
import com.github.ajalt.clikt.parameters.options.required
22-
import com.github.ajalt.clikt.parameters.types.file
24+
import com.github.ajalt.clikt.parameters.types.path
2325
import io.github.detekt.sarif4k.SarifSchema210
2426
import io.github.detekt.sarif4k.SarifSerializer
25-
import java.io.File
27+
import java.nio.file.Path
2628
import kotlin.io.path.absolutePathString
29+
import kotlin.io.path.createParentDirectories
30+
import kotlin.io.path.deleteIfExists
31+
import kotlin.io.path.exists
32+
import kotlin.io.path.readText
33+
import kotlin.io.path.relativeTo
34+
import kotlin.io.path.writeText
2735
import kotlin.system.exitProcess
2836
import slack.cli.projectDirOption
2937
import slack.cli.skipBuildAndCacheDirs
@@ -34,8 +42,10 @@ public class MergeSarifReports :
3442
) {
3543

3644
private val projectDir by projectDirOption()
37-
private val outputFile: File by option("--output-file").file().required()
38-
private val filePrefix by option("--file-prefix").required()
45+
private val outputFile by option("--output-file").path().required()
46+
private val filePrefix by option("--file-prefix")
47+
private val argFiles by
48+
argument("--files").path(mustExist = true, canBeDir = false, mustBeReadable = true).multiple()
3949
private val verbose by option("--verbose", "-v").flag()
4050
private val remapSrcRoots by
4151
option(
@@ -68,13 +78,11 @@ public class MergeSarifReports :
6878
}
6979

7080
private fun prepareOutput() {
71-
if (outputFile.exists()) {
72-
outputFile.delete()
73-
}
74-
outputFile.parentFile?.mkdirs()
81+
outputFile.deleteIfExists()
82+
outputFile.createParentDirectories()
7583
}
7684

77-
private fun findBuildFiles(): List<File> {
85+
private fun findBuildFiles(): List<Path> {
7886
log("Finding build files in ${projectDir.toFile().canonicalFile}")
7987
val buildFiles =
8088
projectDir
@@ -83,32 +91,49 @@ public class MergeSarifReports :
8391
.walkTopDown()
8492
.skipBuildAndCacheDirs()
8593
.filter { it.name == "build.gradle.kts" }
94+
.map { it.toPath() }
8695
.toList()
8796
log("${buildFiles.size} build files found")
8897
return buildFiles
8998
}
9099

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

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

98-
log("Finding sarif files")
99-
return buildFiles
100-
.asSequence()
101-
.flatMap { buildFile ->
102-
val reportsDir = File(buildFile.parentFile, "build/reports")
103-
if (reportsDir.exists()) {
104-
reportsDir.walkTopDown().filter {
105-
it.isFile && it.extension == "sarif" && it.nameWithoutExtension.startsWith(filePrefix)
107+
val files = mutableListOf<Path>()
108+
109+
files += argFiles
110+
111+
filePrefix?.let { prefix ->
112+
// Find build files first, this gives us an easy hook to then go looking in build/reports
113+
// dirs.
114+
// Otherwise we don't have a way to easily exclude populated build dirs that would take
115+
// forever.
116+
val buildFiles = findBuildFiles()
117+
118+
log("Finding sarif files")
119+
files +=
120+
buildFiles.asSequence().flatMap { buildFile ->
121+
val reportsDir = buildFile.parent.resolve("build/reports")
122+
if (reportsDir.exists()) {
123+
reportsDir
124+
.toFile()
125+
.walkTopDown()
126+
.filter {
127+
it.isFile && it.extension == "sarif" && it.nameWithoutExtension.startsWith(prefix)
128+
}
129+
.map { it.toPath() }
130+
} else {
131+
emptySequence()
106132
}
107-
} else {
108-
emptySequence()
109133
}
110-
}
111-
.toList()
134+
}
135+
136+
return files
112137
}
113138

114139
/**
@@ -143,16 +168,16 @@ public class MergeSarifReports :
143168
* libraries/lib/src/main/java/com/example/app/LibActivity.kt
144169
* ```
145170
*/
146-
private fun SarifSchema210.remapSrcRoots(sarifFile: File): SarifSchema210 {
147-
// <module>/─────────────────────────────────
148-
// build/─────────────────────┐
149-
// reports/──────┐
150-
//
151-
val module = sarifFile.parentFile.parentFile.parentFile
152-
check(File(module, "build.gradle.kts").exists()) {
171+
private fun SarifSchema210.remapSrcRoots(sarifFile: Path): SarifSchema210 {
172+
// <module>/─────────────────────────┐
173+
// build/─────────────────
174+
// reports/──────┐
175+
//
176+
val module = sarifFile.parent.parent.parent
177+
check(module.resolve("build.gradle.kts").exists()) {
153178
"Expected to find build.gradle.kts in $module"
154179
}
155-
val modulePrefix = module.toRelativeString(projectDir.toFile())
180+
val modulePrefix = module.relativeTo(projectDir).toString()
156181
return copy(
157182
runs =
158183
runs.map { run ->
@@ -232,7 +257,7 @@ public class MergeSarifReports :
232257
)
233258
}
234259

235-
private fun loadSarifs(inputs: List<File>): List<SarifSchema210> {
260+
private fun loadSarifs(inputs: List<Path>): List<SarifSchema210> {
236261
return inputs.map { sarifFile ->
237262
log("Parsing $sarifFile")
238263
val parsed = SarifSerializer.fromJson(sarifFile.readText())
@@ -249,7 +274,7 @@ public class MergeSarifReports :
249274
}
250275
}
251276

252-
private fun merge(inputs: List<File>) {
277+
private fun merge(inputs: List<Path>) {
253278
log("Parsing ${inputs.size} sarif files")
254279
val sarifs = loadSarifs(inputs)
255280

0 commit comments

Comments
 (0)