Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions advisor/src/test/kotlin/AdvisorTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ class AdvisorTest : WordSpec({
)

val failingFactory = mockk<AdviceProviderFactory> {
every { descriptor } returns PluginDescriptor("failing-provider", "FailingProvider", "", emptyList())
every { descriptor } returns
PluginDescriptor("failing-provider", "FailingProvider", "", options = emptyList())
every { create(any()) } throws IllegalStateException("Could not initialize provider")
}

Expand Down Expand Up @@ -259,7 +260,7 @@ private fun createPackage(index: Int): Package =

private fun mockkAdviceProvider(displayName: String = "Provider"): AdviceProvider =
mockk<AdviceProvider>().apply {
every { descriptor } returns PluginDescriptor(displayName, displayName, "", emptyList())
every { descriptor } returns PluginDescriptor(displayName, displayName, "", options = emptyList())
}

private fun mockkAdvisorResult(): AdvisorResult =
Expand Down
17 changes: 16 additions & 1 deletion buildSrc/src/main/kotlin/GeneratePluginDocsTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,16 @@ abstract class GeneratePluginDocsTask : DefaultTask() {
appendLine()
appendLine("![${descriptor["id"]}](https://img.shields.io/badge/Plugin_ID-${descriptor["id"]}-gold)")
appendLine()
appendLine(descriptor["description"])
appendLine("***${descriptor["summary"]}***")
appendLine()

descriptor["description"].takeIf { it != null && it != descriptor["summary"]}?.also {
appendLine("## Description")
appendLine()
appendLine(convertKdocLinks(it as String))
appendLine()
}

val allOptions = ((descriptor["options"]) as List<*>).map { it as Map<*, *> }

if (allOptions.isEmpty()) return@buildString
Expand Down Expand Up @@ -231,3 +238,11 @@ abstract class GeneratePluginDocsTask : DefaultTask() {
}
}
}

private val KDOC_LINK_REGEX = Regex("""\[([^]]+)](?:\[([^]]+)])?(?!\()""")

/** Convert KDoc symbol links into inline code blocks. */
fun convertKdocLinks(input: String) = input.replace(KDOC_LINK_REGEX) {
val (text, target) = it.destructured
if (target.isNotEmpty()) "$text (`$target`)" else "`$text`"
}
6 changes: 3 additions & 3 deletions plugins/advisors/black-duck/src/main/kotlin/BlackDuck.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ import org.ossreviewtoolkit.utils.common.collectMessages

/**
* This advice provider by default retrieves vulnerabilities by the purl corresponding to the package. If a package has
* the label [BlackDuck.PACKAGE_LABEL_BLACK_DUCK_ORIGIN_ID] set, then the vulnerabilities are retrieved by that
* origin-id instead of by the purl.
* the label ["black-duck:origin-id"][BlackDuck.PACKAGE_LABEL_BLACK_DUCK_ORIGIN_ID] set, then the vulnerabilities are
* retrieved by that origin-id instead of by the purl.
*/
@OrtPlugin(
displayName = "Black Duck",
description = "An advisor that retrieves vulnerability information from a Black Duck instance.",
summary = "An advisor that retrieves vulnerability information from a Black Duck instance.",
factory = AdviceProviderFactory::class
)
class BlackDuck(
Expand Down
2 changes: 1 addition & 1 deletion plugins/advisors/oss-index/src/main/kotlin/OssIndex.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private const val BULK_REQUEST_SIZE = 128
@OrtPlugin(
id = "OSSIndex",
displayName = "OSS Index",
description = "An advisor that uses Sonatype's OSS Index to determine vulnerabilities in dependencies.",
summary = "An advisor that uses Sonatype's OSS Index to determine vulnerabilities in dependencies.",
factory = AdviceProviderFactory::class
)
class OssIndex(
Expand Down
4 changes: 2 additions & 2 deletions plugins/advisors/osv/src/main/kotlin/Osv.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ import org.ossreviewtoolkit.utils.common.toUri
import org.ossreviewtoolkit.utils.ort.OkHttpClientHelper

/**
* An advice provider that obtains vulnerability information from Open Source Vulnerabilities (https://osv.dev/).
* An advice provider that obtains vulnerability information from [Open Source Vulnerabilities](https://osv.dev/).
*/
@OrtPlugin(
id = "OSV",
displayName = "OSV",
description = "An advisor that retrieves vulnerability information from the Open Source Vulnerabilities database.",
summary = "An advisor that retrieves vulnerability information from the Open Source Vulnerabilities database.",
factory = AdviceProviderFactory::class
)
class Osv(
Expand Down
4 changes: 2 additions & 2 deletions plugins/advisors/scanoss/src/main/kotlin/ScanOss.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ import org.ossreviewtoolkit.utils.ort.okHttpClient

/**
* An [AdviceProvider] implementation that obtains security vulnerability information from a
* [SCANOSS][https://github.com/aboutcode-org/vulnerablecode] instance.
* [SCANOSS](https://github.com/aboutcode-org/vulnerablecode) instance.
*/
@OrtPlugin(
displayName = "SCANOSS",
description = "An advisor that uses a SCANOSS instance to determine vulnerabilities in dependencies.",
summary = "An advisor that uses a SCANOSS instance to determine vulnerabilities in dependencies.",
factory = AdviceProviderFactory::class
)
class ScanOss(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ private const val MAX_SUMMARY_LENGTH = 64

/**
* An [AdviceProvider] implementation that obtains security vulnerability information from a
* [VulnerableCode][https://github.com/aboutcode-org/vulnerablecode] instance.
* [VulnerableCode](https://github.com/aboutcode-org/vulnerablecode) instance.
*/
@OrtPlugin(
displayName = "VulnerableCode",
description = "An advisor that uses a VulnerableCode instance to determine vulnerabilities in dependencies.",
summary = "An advisor that uses a VulnerableCode instance to determine vulnerabilities in dependencies.",
factory = AdviceProviderFactory::class
)
class VulnerableCode(
Expand Down
10 changes: 10 additions & 0 deletions plugins/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,16 @@ class ExampleAdvisor(override val descriptor: PluginDescriptor, val config: Exam
}
```

The KDoc of the plugin class is used as the description of the plugin when generating the `PluginDescriptor`.
Therefore, it should be written with the intention to be read by users of the plugin.
For example, for package managers, it should document requirements and limitations of the plugin, helping users to successfully analyze their projects.
As the description is also used for the website, certain limitations apply:

* It should not use reference-style links (like `[some website][1]`).
* It should not use footnotes (like `[^1]`).
* It should only use headings of level 3 or higher (like `### Heading`).
* KDoc symbol references (like `[SomeClass]`) are replaced with inline-code blocks.

### Plugin Configuration Class

The configuration class must be a data class with a single constructor that takes all configuration options as arguments.
Expand Down
4 changes: 2 additions & 2 deletions plugins/api/src/main/kotlin/OrtPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ annotation class OrtPlugin(
/** The display name of the plugin. */
val displayName: String,

/** The description of the plugin. */
val description: String,
/** The short description of the plugin. */
val summary: String,

/** The factory class that represents the ORT extension point for this plugin. */
val factory: KClass<*>
Expand Down
4 changes: 1 addition & 3 deletions plugins/api/src/main/kotlin/OrtPluginOption.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ package org.ossreviewtoolkit.plugins.api
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.SOURCE)
annotation class OrtPluginOption(
/**
* The default value of the option.
*/
/** The default value of the option. */
val defaultValue: String = NO_DEFAULT_VALUE,

/**
Expand Down
20 changes: 5 additions & 15 deletions plugins/api/src/main/kotlin/PluginConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore

import org.ossreviewtoolkit.utils.common.Options

/**
* The configuration of a plugin, used as input for [PluginFactory.create].
*/
/** The configuration of a plugin, used as input for [PluginFactory.create]. */
data class PluginConfig(
/**
* The configuration options of the plugin.
*/
/** The configuration options of the plugin. */
val options: Options = emptyMap(),

/**
Expand All @@ -41,19 +37,13 @@ data class PluginConfig(
val secrets: Options = emptyMap()
) {
companion object {
/**
* Constant for an empty [PluginConfig].
*/
/** Constant for an empty [PluginConfig]. */
val EMPTY = PluginConfig()
}

/**
* Return a string representation that does not contain the [secrets].
*/
/** Return a string representation that does not contain the [secrets]. */
override fun toString() = "${this::class.simpleName}(options=$options, secrets=[***])"
}

/**
* Returns this [PluginConfig] if it is not `null`, or the [empty][PluginConfig.EMPTY] [PluginConfig] otherwise.
*/
/** Returns this [PluginConfig] if it is not `null`, or the [empty][PluginConfig.EMPTY] [PluginConfig] otherwise. */
fun PluginConfig?.orEmpty() = this ?: PluginConfig.EMPTY
73 changes: 21 additions & 52 deletions plugins/api/src/main/kotlin/PluginDescriptor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,25 @@

package org.ossreviewtoolkit.plugins.api

/**
* A descriptor holding the metadata of a plugin.
*/
/** A descriptor holding the metadata of a plugin. */
data class PluginDescriptor(
/**
* The id of the plugin class. Must be unique among all plugins for the same factory class.
*/
/** The id of the plugin class. Must be unique among all plugins for the same factory class. */
val id: String,

/**
* The display name of the plugin.
*/
/** The display name of the plugin. */
val displayName: String,

/**
* The description of the plugin.
*/
val description: String,
/** The short description of the plugin. */
val summary: String,

/** The detailed description of the plugin. */
val description: String? = null,

/**
* The configuration options supported by the plugin.
*/
/** The configuration options supported by the plugin. */
val options: List<PluginOption> = emptyList()
)

/**
* The supported types of plugin options.
*/
/** The supported types of plugin options. */
enum class PluginOptionType(val typeName: String) {
/** A [Boolean] option. */
BOOLEAN("Boolean"),
Expand Down Expand Up @@ -75,53 +66,33 @@ enum class PluginOptionType(val typeName: String) {
override fun toString() = typeName
}

/**
* A configuration option for a plugin.
*/
/** A configuration option for a plugin. */
data class PluginOption(
/**
* The name of the option. Must be unique among all options of the same plugin.
*/
/** The name of the option. Must be unique among all options of the same plugin. */
val name: String,

/**
* The description of the option.
*/
/** The description of the option. */
val description: String,

/**
* The [type][PluginOptionType] of the option.
*/
/** The [type][PluginOptionType] of the option. */
val type: PluginOptionType,

/**
* The enum type name if [type] is [PluginOptionType.ENUM] or [PluginOptionType.ENUM_LIST], `null` otherwise.
*/
/** The enum type name if [type] is [PluginOptionType.ENUM] or [PluginOptionType.ENUM_LIST], `null` otherwise. */
val enumType: String?,

/**
* The enum entries if [type] is [PluginOptionType.ENUM] or [PluginOptionType.ENUM_LIST], `null` otherwise.
*/
/** The enum entries if [type] is [PluginOptionType.ENUM] or [PluginOptionType.ENUM_LIST], `null` otherwise. */
val enumEntries: List<EnumEntry>?,

/**
* The default value of the option, or `null` if the option is required.
*/
/** The default value of the option, or `null` if the option is required. */
val defaultValue: String?,

/**
* A list of alternative names for the option.
*/
/** A list of alternative names for the option. */
val aliases: List<String>,

/**
* Whether the option is nullable.
*/
/** Whether the option is nullable. */
val isNullable: Boolean,

/**
* Whether the option is required.
*/
/** Whether the option is required. */
val isRequired: Boolean
)

Expand All @@ -137,9 +108,7 @@ data class EnumEntry(
val aliases: List<String>
)

/**
* A secret value that should not be printed in logs.
*/
/** A secret value that should not be printed in logs. */
@JvmInline
value class Secret(val value: String) {
override fun toString() = "***"
Expand Down
20 changes: 5 additions & 15 deletions plugins/api/src/main/kotlin/PluginFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ import java.util.ServiceLoader
*/
interface PluginFactory<out PLUGIN : Plugin> {
companion object {
/**
* Return all plugin factories of type [FACTORY].
*/
/** Return all plugin factories of type [FACTORY]. */
inline fun <reified FACTORY : PluginFactory<PLUGIN>, PLUGIN : Plugin> getAll() =
getLoaderFor<FACTORY>()
.iterator()
Expand All @@ -39,25 +37,17 @@ interface PluginFactory<out PLUGIN : Plugin> {
}
}

/**
* The descriptor of the plugin
*/
/** The descriptor of the plugin */
val descriptor: PluginDescriptor

/**
* Create a new instance of [PLUGIN] from [config].
*/
/** Create a new instance of [PLUGIN] from [config]. */
fun create(config: PluginConfig): PLUGIN
}

/**
* A plugin that ORT can use. Each plugin extension point of ORT must inherit from this interface.
*/
/** A plugin that ORT can use. Each plugin extension point of ORT must inherit from this interface. */
interface Plugin {
val descriptor: PluginDescriptor
}

/**
* Return a [ServiceLoader] that is capable of loading services of type [T].
*/
/** Return a [ServiceLoader] that is capable of loading services of type [T]. */
inline fun <reified T : Any> getLoaderFor(): ServiceLoader<T> = ServiceLoader.load(T::class.java)
2 changes: 1 addition & 1 deletion plugins/api/src/test/kotlin/OptionParsersTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ private fun createFactory(option: PluginOption) =
private val pluginDescriptor = PluginDescriptor(
id = "test",
displayName = "Test",
description = "Test plugin",
summary = "Test plugin",
options = listOf(option)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ import org.ossreviewtoolkit.utils.ort.ortConfigDirectory

@OrtPlugin(
displayName = "Advise",
description = "Check dependencies for security vulnerabilities.",
summary = "Check dependencies for security vulnerabilities.",
factory = OrtCommandFactory::class
)
class AdviseCommand(descriptor: PluginDescriptor = AdviseCommandFactory.descriptor) : OrtCommand(descriptor) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ import org.ossreviewtoolkit.utils.ort.ortConfigDirectory

@OrtPlugin(
displayName = "Analyze",
description = "Determine dependencies of a software project.",
summary = "Determine dependencies of a software project.",
factory = OrtCommandFactory::class
)
class AnalyzeCommand(descriptor: PluginDescriptor = AnalyzeCommandFactory.descriptor) : OrtCommand(descriptor) {
Expand Down
2 changes: 1 addition & 1 deletion plugins/commands/api/src/main/kotlin/OrtCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import org.ossreviewtoolkit.utils.ort.ORT_CONFIG_FILENAME
* An interface for [CliktCommand]-based ORT commands that come as [Plugin]s.
*/
abstract class OrtCommand(override val descriptor: PluginDescriptor) : CliktCommand(), Plugin {
override fun help(context: Context) = descriptor.description
override fun help(context: Context) = descriptor.summary

protected val ortConfig by requireObject<OrtConfiguration>()

Expand Down
Loading
Loading