Skip to content

Commit

Permalink
WIP: Scanner plugin migration
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Nonnenmacher <martin.nonnenmacher@bosch.com>
  • Loading branch information
mnonnenmacher committed Jan 26, 2025
1 parent 527fada commit f83b7ba
Showing 46 changed files with 624 additions and 786 deletions.
17 changes: 9 additions & 8 deletions plugins/commands/scanner/src/main/kotlin/ScannerCommand.kt
Original file line number Diff line number Diff line change
@@ -51,6 +51,7 @@ import org.ossreviewtoolkit.model.config.OrtConfiguration
import org.ossreviewtoolkit.model.utils.DefaultResolutionProvider
import org.ossreviewtoolkit.model.utils.mergeLabels
import org.ossreviewtoolkit.plugins.api.OrtPlugin
import org.ossreviewtoolkit.plugins.api.PluginConfig
import org.ossreviewtoolkit.plugins.api.PluginDescriptor
import org.ossreviewtoolkit.plugins.commands.api.OrtCommand
import org.ossreviewtoolkit.plugins.commands.api.OrtCommandFactory
@@ -167,34 +168,34 @@ class ScannerCommand(descriptor: PluginDescriptor = ScannerCommandFactory.descri

@Suppress("ForbiddenMethodCall")
private fun runScanners(
scannerWrapperFactories: List<ScannerWrapperFactory<*>>,
projectScannerWrapperFactories: List<ScannerWrapperFactory<*>>,
scannerWrapperFactories: List<ScannerWrapperFactory>,
projectScannerWrapperFactories: List<ScannerWrapperFactory>,
ortConfig: OrtConfiguration
): OrtResult {
val packageScannerWrappers = scannerWrapperFactories
.takeIf { PackageType.PACKAGE in packageTypes }.orEmpty()
.map {
val config = ortConfig.scanner.config?.get(it.type)
it.create(config?.options.orEmpty(), config?.secrets.orEmpty())
val config = ortConfig.scanner.config?.get(it.descriptor.id)
it.create(PluginConfig(config?.options.orEmpty(), config?.secrets.orEmpty()))
}

val projectScannerWrappers = projectScannerWrapperFactories
.takeIf { PackageType.PROJECT in packageTypes }.orEmpty()
.map {
val config = ortConfig.scanner.config?.get(it.type)
it.create(config?.options.orEmpty(), config?.secrets.orEmpty())
val config = ortConfig.scanner.config?.get(it.descriptor.id)
it.create(PluginConfig(config?.options.orEmpty(), config?.secrets.orEmpty()))
}

if (projectScannerWrappers.isNotEmpty()) {
echo("Scanning projects with:")
echo(projectScannerWrappers.joinToString { "\t${it.name} (version ${it.version})" })
echo(projectScannerWrappers.joinToString { "\t${it.descriptor.displayName} (version ${it.version})" })
} else {
echo("Projects will not be scanned.")
}

if (packageScannerWrappers.isNotEmpty()) {
echo("Scanning packages with:")
echo(packageScannerWrappers.joinToString { "\t${it.name} (version ${it.version})" })
echo(packageScannerWrappers.joinToString { "\t${it.descriptor.displayName} (version ${it.version})" })
} else {
echo("Packages will not be scanned.")
}
4 changes: 3 additions & 1 deletion plugins/scanners/askalono/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@

plugins {
// Apply precompiled plugins.
id("ort-library-conventions")
id("ort-plugin-conventions")

// Apply third-party plugins.
alias(libs.plugins.kotlinSerialization)
@@ -32,5 +32,7 @@ dependencies {
implementation(libs.kotlinx.serialization.core)
implementation(libs.kotlinx.serialization.json)

ksp(projects.scanner)

funTestApi(testFixtures(projects.scanner))
}
Original file line number Diff line number Diff line change
@@ -22,10 +22,9 @@ package org.ossreviewtoolkit.plugins.scanners.askalono
import org.ossreviewtoolkit.model.LicenseFinding
import org.ossreviewtoolkit.model.TextLocation
import org.ossreviewtoolkit.scanner.AbstractPathScannerWrapperFunTest
import org.ossreviewtoolkit.scanner.ScannerWrapperConfig

class AskalonoFunTest : AbstractPathScannerWrapperFunTest() {
override val scanner = Askalono("Askalono", ScannerWrapperConfig.EMPTY)
override val scanner = AskalonoFactory.create()

override val expectedFileLicenses = listOf(
LicenseFinding("Apache-2.0", TextLocation("LICENSE", TextLocation.UNKNOWN_LINE), 1.0f)
80 changes: 65 additions & 15 deletions plugins/scanners/askalono/src/main/kotlin/Askalono.kt
Original file line number Diff line number Diff line change
@@ -32,34 +32,84 @@ import org.ossreviewtoolkit.model.LicenseFinding
import org.ossreviewtoolkit.model.ScanSummary
import org.ossreviewtoolkit.model.Severity
import org.ossreviewtoolkit.model.TextLocation
import org.ossreviewtoolkit.plugins.api.OrtPlugin
import org.ossreviewtoolkit.plugins.api.OrtPluginOption
import org.ossreviewtoolkit.plugins.api.PluginDescriptor
import org.ossreviewtoolkit.scanner.CommandLinePathScannerWrapper
import org.ossreviewtoolkit.scanner.ScanContext
import org.ossreviewtoolkit.scanner.ScanException
import org.ossreviewtoolkit.scanner.ScannerMatcher
import org.ossreviewtoolkit.scanner.ScannerWrapperConfig
import org.ossreviewtoolkit.scanner.ScannerMatcherConfig
import org.ossreviewtoolkit.scanner.ScannerWrapperFactory
import org.ossreviewtoolkit.utils.common.Options
import org.ossreviewtoolkit.utils.common.Os

private const val CONFIDENCE_NOTICE = "Confidence threshold not high enough for any known license"

private val JSON = Json { ignoreUnknownKeys = true }

class Askalono internal constructor(name: String, private val wrapperConfig: ScannerWrapperConfig) :
CommandLinePathScannerWrapper(name) {
class Factory : ScannerWrapperFactory<Unit>("Askalono") {
override fun create(config: Unit, wrapperConfig: ScannerWrapperConfig) = Askalono(type, wrapperConfig)

override fun parseConfig(options: Options, secrets: Options) = Unit
}

data class AskalonoConfig(
/**
* A regular expression to match the scanner name when looking up scan results in the storage.
*/
val regScannerName: String?,

/**
* The minimum version of stored scan results to use.
*/
val minVersion: String?,

/**
* The maximum version of stored scan results to use.
*/
val maxVersion: String?,

/**
* The configuration to use for the scanner. Only scan results with the same configuration are used when looking up
* scan results in the storage.
*/
val configuration: String?,

/**
* Whether to read scan results from the storage.
*/
@OrtPluginOption(defaultValue = "true")
val readFromStorage: Boolean,

/**
* Whether to write scan results to the storage.
*/
@OrtPluginOption(defaultValue = "true")
val writeToStorage: Boolean
)

@OrtPlugin(
id = "askalono",
displayName = "askalono",
description = "askalono is a library and command-line tool to help detect license texts. It's designed to be " +
"fast, accurate, and to support a wide variety of license texts.",
factory = ScannerWrapperFactory::class
)
class Askalono(

Check warning on line 92 in plugins/scanners/askalono/src/main/kotlin/Askalono.kt

GitHub Actions / qodana-scan

Unused symbol

Class "Askalono" is never used

Check warning

Code scanning / QDJVMC

Unused symbol Warning

Class "Askalono" is never used
override val descriptor: PluginDescriptor = AskalonoFactory.descriptor,
config: AskalonoConfig
) : CommandLinePathScannerWrapper() {
override val configuration = ""

override val matcher by lazy { ScannerMatcher.create(details, wrapperConfig.matcherConfig) }
override val matcher by lazy {
ScannerMatcher.create(
details,
ScannerMatcherConfig(
config.regScannerName,
config.minVersion,
config.maxVersion,
config.configuration
)
)
}

override val readFromStorage by lazy { wrapperConfig.readFromStorageWithDefault(matcher) }
override val readFromStorage = config.readFromStorage

override val writeToStorage by lazy { wrapperConfig.writeToStorageWithDefault(matcher) }
override val writeToStorage = config.writeToStorage

override fun command(workingDir: File?) =
listOfNotNull(workingDir, if (Os.isWindows) "askalono.exe" else "askalono").joinToString(File.separator)
@@ -90,7 +140,7 @@ class Askalono internal constructor(name: String, private val wrapperConfig: Sca

val issues = mutableListOf(
Issue(
source = name,
source = descriptor.id,
message = "This scanner is not capable of detecting copyright statements.",
severity = Severity.HINT
)
@@ -107,7 +157,7 @@ class Askalono internal constructor(name: String, private val wrapperConfig: Sca

if (it.error != null) {
issues += Issue(
source = name,
source = descriptor.id,
message = it.error,
severity = if (it.error == CONFIDENCE_NOTICE) Severity.HINT else Severity.ERROR
)

This file was deleted.

4 changes: 3 additions & 1 deletion plugins/scanners/boyterlc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@

plugins {
// Apply precompiled plugins.
id("ort-library-conventions")
id("ort-plugin-conventions")

// Apply third-party plugins.
alias(libs.plugins.kotlinSerialization)
@@ -32,5 +32,7 @@ dependencies {
implementation(libs.kotlinx.serialization.core)
implementation(libs.kotlinx.serialization.json)

ksp(projects.scanner)

funTestApi(testFixtures(projects.scanner))
}
Original file line number Diff line number Diff line change
@@ -22,10 +22,9 @@ package org.ossreviewtoolkit.plugins.scanners.boyterlc
import org.ossreviewtoolkit.model.LicenseFinding
import org.ossreviewtoolkit.model.TextLocation
import org.ossreviewtoolkit.scanner.AbstractPathScannerWrapperFunTest
import org.ossreviewtoolkit.scanner.ScannerWrapperConfig

class BoyterLcFunTest : AbstractPathScannerWrapperFunTest() {
override val scanner = BoyterLc("BoyterLc", ScannerWrapperConfig.EMPTY)
override val scanner = BoyterLcFactory.create()

override val expectedFileLicenses = listOf(
LicenseFinding("Apache-2.0", TextLocation("LICENSE", TextLocation.UNKNOWN_LINE), 0.98388565f),
78 changes: 64 additions & 14 deletions plugins/scanners/boyterlc/src/main/kotlin/BoyterLc.kt
Original file line number Diff line number Diff line change
@@ -31,41 +31,91 @@ import org.ossreviewtoolkit.model.LicenseFinding
import org.ossreviewtoolkit.model.ScanSummary
import org.ossreviewtoolkit.model.Severity
import org.ossreviewtoolkit.model.TextLocation
import org.ossreviewtoolkit.plugins.api.OrtPlugin
import org.ossreviewtoolkit.plugins.api.OrtPluginOption
import org.ossreviewtoolkit.plugins.api.PluginDescriptor
import org.ossreviewtoolkit.scanner.CommandLinePathScannerWrapper
import org.ossreviewtoolkit.scanner.ScanContext
import org.ossreviewtoolkit.scanner.ScanException
import org.ossreviewtoolkit.scanner.ScannerMatcher
import org.ossreviewtoolkit.scanner.ScannerWrapperConfig
import org.ossreviewtoolkit.scanner.ScannerMatcherConfig
import org.ossreviewtoolkit.scanner.ScannerWrapperFactory
import org.ossreviewtoolkit.utils.common.Options
import org.ossreviewtoolkit.utils.common.Os
import org.ossreviewtoolkit.utils.common.safeDeleteRecursively
import org.ossreviewtoolkit.utils.ort.createOrtTempDir

private val JSON = Json { ignoreUnknownKeys = true }

class BoyterLc internal constructor(name: String, private val wrapperConfig: ScannerWrapperConfig) :
CommandLinePathScannerWrapper(name) {
data class BoyterLcConfig(
/**
* A regular expression to match the scanner name when looking up scan results in the storage.
*/
val regScannerName: String?,

/**
* The minimum version of stored scan results to use.
*/
val minVersion: String?,

/**
* The maximum version of stored scan results to use.
*/
val maxVersion: String?,

/**
* The configuration to use for the scanner. Only scan results with the same configuration are used when looking up
* scan results in the storage.
*/
val configuration: String?,

/**
* Whether to read scan results from the storage.
*/
@OrtPluginOption(defaultValue = "true")
val readFromStorage: Boolean,

/**
* Whether to write scan results to the storage.
*/
@OrtPluginOption(defaultValue = "true")
val writeToStorage: Boolean
)

@OrtPlugin(
id = "BoyterLc",
displayName = "BoyterLc",
description = "A command line application which scans directories and identifies what software license things " +
"are under.",
factory = ScannerWrapperFactory::class
)
class BoyterLc(

Check warning on line 91 in plugins/scanners/boyterlc/src/main/kotlin/BoyterLc.kt

GitHub Actions / qodana-scan

Unused symbol

Class "BoyterLc" is never used

Check warning

Code scanning / QDJVMC

Unused symbol Warning

Class "BoyterLc" is never used
override val descriptor: PluginDescriptor = BoyterLcFactory.descriptor,
config: BoyterLcConfig
) : CommandLinePathScannerWrapper() {
companion object {
val CONFIGURATION_OPTIONS = listOf(
"--confidence", "0.95", // Cut-off value to only get most relevant matches.
"--format", "json"
)
}

class Factory : ScannerWrapperFactory<Unit>("BoyterLc") {
override fun create(config: Unit, wrapperConfig: ScannerWrapperConfig) = BoyterLc(type, wrapperConfig)

override fun parseConfig(options: Options, secrets: Options) = Unit
}

override val configuration = CONFIGURATION_OPTIONS.joinToString(" ")

override val matcher by lazy { ScannerMatcher.create(details, wrapperConfig.matcherConfig) }
override val matcher by lazy {
ScannerMatcher.create(
details,
ScannerMatcherConfig(
config.regScannerName,
config.minVersion,
config.maxVersion,
config.configuration
)
)
}

override val readFromStorage by lazy { wrapperConfig.readFromStorageWithDefault(matcher) }
override val readFromStorage = config.readFromStorage

override val writeToStorage by lazy { wrapperConfig.writeToStorageWithDefault(matcher) }
override val writeToStorage = config.writeToStorage

override fun command(workingDir: File?) =
listOfNotNull(workingDir, if (Os.isWindows) "lc.exe" else "lc").joinToString(File.separator)
@@ -111,7 +161,7 @@ class BoyterLc internal constructor(name: String, private val wrapperConfig: Sca
licenseFindings = licenseFindings,
issues = listOf(
Issue(
source = name,
source = descriptor.id,
message = "This scanner is not capable of detecting copyright statements.",
severity = Severity.HINT
)

This file was deleted.

4 changes: 3 additions & 1 deletion plugins/scanners/dos/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@

plugins {
// Apply precompiled plugins.
id("ort-library-conventions")
id("ort-plugin-conventions")

// Apply third-party plugins.
alias(libs.plugins.kotlinSerialization)
@@ -40,6 +40,8 @@ dependencies {
implementation(libs.kotlinx.serialization.json)
implementation(libs.log4j.api)

ksp(projects.scanner)

testImplementation(libs.mockk)
testImplementation(libs.wiremock)
}
Loading

0 comments on commit f83b7ba

Please sign in to comment.