Skip to content

Commit

Permalink
refactor: applied formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
janniclas committed Sep 4, 2024
1 parent 4d70917 commit e755b8b
Show file tree
Hide file tree
Showing 10 changed files with 236 additions and 602 deletions.
441 changes: 22 additions & 419 deletions .editorconfig

Large diffs are not rendered by default.

26 changes: 11 additions & 15 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
plugins {
kotlin("jvm") version "2.0.10"
}
plugins { kotlin("jvm") version "2.0.10" }

group = "de.fraunhofer.iem"

version = "1.0-SNAPSHOT"

repositories {
mavenCentral()
}
repositories { mavenCentral() }

dependencies { testImplementation(kotlin("test")) }

tasks.register("ktfmtCheck") { dependsOn(gradle.includedBuild("spha-cli").task(":ktfmtCheck")) }

tasks.register("ktfmtFormat") { dependsOn(gradle.includedBuild("spha-cli").task(":ktfmtFormat")) }

dependencies {
testImplementation(kotlin("test"))
}
tasks.test { useJUnitPlatform() }

tasks.test {
useJUnitPlatform()
}
kotlin {
jvmToolchain(21)
}
kotlin { jvmToolchain(21) }
20 changes: 10 additions & 10 deletions spha-cli/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
plugins {
alias(libs.plugins.kotlin)
alias(libs.plugins.serialization)
alias(libs.plugins.ktfmt)
application
}

group = "de.fraunhofer.iem.spha"

version = "0.0.2-SNAPSHOT"

repositories {
mavenCentral()
}
repositories { mavenCentral() }

dependencies{
dependencies {
implementation(libs.bundles.kpiCalculator)

implementation(libs.kotlin.cli)
Expand All @@ -30,18 +30,18 @@ dependencies{
testImplementation(libs.test.junit5.params)
}

tasks.test {
useJUnitPlatform()
ktfmt {
// KotlinLang style - 4 space indentation - From kotlinlang.org/docs/coding-conventions.html
kotlinLangStyle()
}

application{
mainClass = "de.fraunhofer.iem.spha.cli.MainKt"
}
tasks.test { useJUnitPlatform() }

application { mainClass = "de.fraunhofer.iem.spha.cli.MainKt" }

kotlin {
compilerOptions {
jvmToolchain(21)
apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_2_0)
}
}

2 changes: 2 additions & 0 deletions spha-cli/gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mockk = "1.13.12"
jimfs = "1.3.0"
apache-commoms = "3.16.0"
junit = "5.11.0"
ktfmt = "0.20.1"

[libraries]
# KPI calculator
Expand Down Expand Up @@ -36,6 +37,7 @@ test-junit5-params = { module = "org.junit.jupiter:junit-jupiter-params", versio
[plugins]
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
ktfmt = { id = "com.ncorti.ktfmt.gradle", version.ref = "ktfmt" }

[bundles]
kpiCalculator = ["kpi-calculator-adapter", "kpi-calculator-core", "kpi-calculator-model"]
Expand Down
78 changes: 43 additions & 35 deletions spha-cli/src/main/kotlin/de/fraunhofer/iem/spha/cli/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,73 +9,81 @@ import de.fraunhofer.iem.spha.cli.commands.TransformToolResultCommand
import de.fraunhofer.iem.spha.cli.transformer.RawKpiTransformer
import de.fraunhofer.iem.spha.cli.transformer.Tool2RawKpiTransformer
import io.github.oshai.kotlinlogging.KotlinLogging
import java.nio.file.FileSystem
import java.nio.file.FileSystems
import kotlin.system.exitProcess
import org.koin.core.component.KoinComponent
import org.koin.core.context.GlobalContext.startKoin
import org.koin.dsl.module
import org.slf4j.simple.SimpleLogger
import java.nio.file.FileSystem
import java.nio.file.FileSystems
import kotlin.system.exitProcess

internal val appModules = module {
single<RawKpiTransformer>{ Tool2RawKpiTransformer() }
single<FileSystem>{ FileSystems.getDefault() }
single<RawKpiTransformer> { Tool2RawKpiTransformer() }
single<FileSystem> { FileSystems.getDefault() }
}

fun main(args: Array<String>) {
startKoin{
modules(appModules)
}
startKoin { modules(appModules) }

try {
MainSphaToolCommand()
.subcommands(TransformToolResultCommand())
.main(args)
} catch (e : Exception){
val logger = KotlinLogging.logger{}
logger.error(e, {e.message})
MainSphaToolCommand().subcommands(TransformToolResultCommand()).main(args)
} catch (e: Exception) {
val logger = KotlinLogging.logger {}
logger.error(e, { e.message })
exitProcess(1)
}
}

/**
* The Main command of this application. Supports a global switch to enable verbose logging mode.
*/
private class MainSphaToolCommand : NoOpCliktCommand(){
private class MainSphaToolCommand : NoOpCliktCommand() {

val verbose by option("--verbose", "-v",
help="When set, the application provides detailed logging. Default is unset.")
.flag()
val verbose by
option(
"--verbose",
"-v",
help = "When set, the application provides detailed logging. Default is unset.",
)
.flag()

override fun run() {
configureLogging()
}

private fun configureLogging(){
if (verbose)
System.setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "TRACE")
private fun configureLogging() {
if (verbose) System.setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "TRACE")
}
}

/**
* Base class for all commands of this application, except for the main command.
* @implNote Due to the design of clikt, the main command should be separate
* and this base class should not introduce the --verbose switch. Otherwise, the following cli input would be legal:
* './spha -v transform -t abc -v'. The first -v switch actually triggers the logging configuration,
* where the second -v switch is independent to the first switch. This will cause confusion for users, which switch to use.
* Base class for all commands of this application, except for the main command. @implNote Due to
* the design of clikt, the main command should be separate and this base class should not introduce
* the --verbose switch. Otherwise, the following cli input would be legal: './spha -v transform -t
* abc -v'. The first -v switch actually triggers the logging configuration, where the second -v
* switch is independent to the first switch. This will cause confusion for users, which switch to
* use.
*/
internal abstract class SphaToolCommandBase(name: String? = null, help: String = "")
: CliktCommand(name = name, help = help), KoinComponent {
// NB: Needs to be lazy, as otherwise we initialize this variable before setting the logger configuration.
private val _lazyLogger = lazy { KotlinLogging.logger{} }
protected val Logger get() = _lazyLogger.value
internal abstract class SphaToolCommandBase(name: String? = null, help: String = "") :
CliktCommand(name = name, help = help), KoinComponent {
// NB: Needs to be lazy, as otherwise we initialize this variable before setting the logger
// configuration.
private val _lazyLogger = lazy { KotlinLogging.logger {} }
protected val Logger
get() = _lazyLogger.value

val strict by option("--strict",
help="When set, the application is less tolerant to unknown input formats. Default is unset.")
.flag()
val strict by
option(
"--strict",
help =
"When set, the application is less tolerant to unknown input formats. Default is unset.",
)
.flag()

override fun run() {
Logger.trace { "Original command arguments: '${currentContext.originalArgv.joinToString()}}'" }
Logger.trace {
"Original command arguments: '${currentContext.originalArgv.joinToString()}}'"
}
Logger.debug { "Running command: $commandName" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,54 @@ import com.github.ajalt.clikt.parameters.options.required
import de.fraunhofer.iem.spha.cli.SphaToolCommandBase
import de.fraunhofer.iem.spha.cli.transformer.RawKpiTransformer
import de.fraunhofer.iem.spha.cli.transformer.TransformerOptions
import java.nio.file.FileSystem
import java.nio.file.Path
import kotlin.io.path.createDirectories
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.encodeToStream
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.nio.file.FileSystem
import java.nio.file.Path
import kotlin.io.path.createDirectories

internal class TransformToolResultCommand : SphaToolCommandBase(
name = "transform",
help = "transforms a specified KPI-provider (such as a SAST tool) result into a uniform data format, " +
"so that it can be used for the 'calculate' command."
), KoinComponent {
internal class TransformToolResultCommand :
SphaToolCommandBase(
name = "transform",
help =
"transforms a specified KPI-provider (such as a SAST tool) result into a uniform data format, " +
"so that it can be used for the 'calculate' command.",
),
KoinComponent {

private val transformer by inject<RawKpiTransformer>()
private val fileSystem by inject<FileSystem>()

private val toolName by option(
"-t", "--tool",
help = "The identifier of the KPI-provider tool that produced the input. " +
"Use the command --list-tools to get a list of available identifiers."
)
.required()

private val inputFiles by option(
"-i", "--inputFile",
help = "List of input files. Usually these are result files produced by the tool as specified by --tool." +
"To specify multiple input files (if supported by --tool), the option can be used multiple times."
)
.multiple()
private val toolName by
option(
"-t",
"--tool",
help =
"The identifier of the KPI-provider tool that produced the input. " +
"Use the command --list-tools to get a list of available identifiers.",
)
.required()

private val output by option(
"-o", "--output",
help = "The output directory where the result of the operation is stored. Default is the current working directory."
)
private val inputFiles by
option(
"-i",
"--inputFile",
help =
"List of input files. Usually these are result files produced by the tool as specified by --tool." +
"To specify multiple input files (if supported by --tool), the option can be used multiple times.",
)
.multiple()

private val output by
option(
"-o",
"--output",
help =
"The output directory where the result of the operation is stored. Default is the current working directory.",
)

@OptIn(ExperimentalSerializationApi::class)
override fun run() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import de.fraunhofer.iem.kpiCalculator.model.adapter.trivy.TrivyDto
import de.fraunhofer.iem.kpiCalculator.model.kpi.RawValueKpi
import de.fraunhofer.iem.spha.cli.StrictModeConstraintFailed
import io.github.oshai.kotlinlogging.KotlinLogging
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.io.InputStream
import java.nio.file.FileSystem
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject

internal fun interface RawKpiTransformer {
fun getRawKpis(options: TransformerOptions, strictMode: Boolean): Collection<RawValueKpi>
Expand All @@ -22,48 +22,56 @@ internal class Tool2RawKpiTransformer : RawKpiTransformer, KoinComponent {
private val _fileSystem by inject<FileSystem>()
private val _logger = KotlinLogging.logger {}

override fun getRawKpis(options: TransformerOptions, strictMode: Boolean): Collection<RawValueKpi> {
override fun getRawKpis(
options: TransformerOptions,
strictMode: Boolean,
): Collection<RawValueKpi> {

val result: Collection<AdapterResult> = when (options.tool) {
// "occmd" -> {
// val adapterInput: OccmdDto = OccmdAdapter.createInputFrom(input)
// OccmdAdapter.transformDataToKpi(adapterInput)
// }
"trivy" -> {
getSingleInputStreamFromInputFile(options.inputFiles, strictMode).use {
_logger.info { "Selected supported tool: Trivy" }
val adapterInput: TrivyDto = TrivyAdapter.dtoFromJson(it)
return@use TrivyAdapter.transformDataToKpi(listOf(adapterInput))
val result: Collection<AdapterResult> =
when (options.tool) {
// "occmd" -> {
// val adapterInput: OccmdDto = OccmdAdapter.createInputFrom(input)
// OccmdAdapter.transformDataToKpi(adapterInput)
// }
"trivy" -> {
getSingleInputStreamFromInputFile(options.inputFiles, strictMode).use {
_logger.info { "Selected supported tool: Trivy" }
val adapterInput: TrivyDto = TrivyAdapter.dtoFromJson(it)
return@use TrivyAdapter.transformDataToKpi(listOf(adapterInput))
}
}
}

else -> throw ToolNotFoundException("Tool ${options.tool} is not yet supported.")
}
else -> throw ToolNotFoundException("Tool ${options.tool} is not yet supported.")
}

val rawKpis = result.mapNotNull {
if (it !is AdapterResult.Success)
return@mapNotNull null
return@mapNotNull it.rawValueKpi
}
val rawKpis =
result.mapNotNull {
if (it !is AdapterResult.Success) return@mapNotNull null
return@mapNotNull it.rawValueKpi
}

// If we have unequal counts, we know that adapter returned faulted elements. Thus, we throw in strict mode.
// If we have unequal counts, we know that adapter returned faulted elements. Thus, we throw
// in strict mode.
if (strictMode && rawKpis.count() != result.count()) {
throw StrictModeConstraintFailed("The adapter produced faulted results.")
}

return rawKpis
}

internal fun getSingleInputStreamFromInputFile(inputFiles: List<String>?, strictMode: Boolean): InputStream {
check(!inputFiles.isNullOrEmpty()) {
"No input files specified."
}
internal fun getSingleInputStreamFromInputFile(
inputFiles: List<String>?,
strictMode: Boolean,
): InputStream {
check(!inputFiles.isNullOrEmpty()) { "No input files specified." }

if (inputFiles.count() > 1) {
if (strictMode) {
throw StrictModeConstraintFailed("Expected only one input file.")
}
_logger.warn { "Expected only one input file. But go #${inputFiles.count()}. Will use first entry." }
_logger.warn {
"Expected only one input file. But go #${inputFiles.count()}. Will use first entry."
}
}

return _fileSystem.provider().newInputStream(_fileSystem.getPath(inputFiles.first()))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
package de.fraunhofer.iem.spha.cli.transformer

data class TransformerOptions(
val tool : String,
val inputFiles : List<String>? = null
)
data class TransformerOptions(val tool: String, val inputFiles: List<String>? = null)
Loading

0 comments on commit e755b8b

Please sign in to comment.