diff --git a/model/src/main/kotlin/OrtConfigFile.kt b/model/src/main/kotlin/OrtConfigFile.kt new file mode 100644 index 0000000000000..115979e4a1681 --- /dev/null +++ b/model/src/main/kotlin/OrtConfigFile.kt @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2023 The ORT Project Authors (see ) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +package org.ossreviewtoolkit.model + +import org.ossreviewtoolkit.utils.ort.ORT_CONFIG_FILENAME +import org.ossreviewtoolkit.utils.ort.ORT_COPYRIGHT_GARBAGE_FILENAME +import org.ossreviewtoolkit.utils.ort.ORT_CUSTOM_LICENSE_TEXTS_DIRNAME +import org.ossreviewtoolkit.utils.ort.ORT_EVALUATOR_RULES_FILENAME +import org.ossreviewtoolkit.utils.ort.ORT_HOW_TO_FIX_TEXT_PROVIDER_FILENAME +import org.ossreviewtoolkit.utils.ort.ORT_LICENSE_CLASSIFICATIONS_FILENAME +import org.ossreviewtoolkit.utils.ort.ORT_NOTIFIER_SCRIPT_FILENAME +import org.ossreviewtoolkit.utils.ort.ORT_PACKAGE_CONFIGURATIONS_DIRNAME +import org.ossreviewtoolkit.utils.ort.ORT_PACKAGE_CONFIGURATION_FILENAME +import org.ossreviewtoolkit.utils.ort.ORT_PACKAGE_CURATIONS_DIRNAME +import org.ossreviewtoolkit.utils.ort.ORT_PACKAGE_CURATIONS_FILENAME +import org.ossreviewtoolkit.utils.ort.ORT_REPO_CONFIG_FILENAME +import org.ossreviewtoolkit.utils.ort.ORT_RESOLUTIONS_FILENAME + +/** + * An enum representing the different ORT configuration files. + */ +enum class OrtConfigFile( + /** + * The default name of the config file. + */ + val defaultFilename: String, + + /** + * The default name of the config directory, if the config can be read from multiple files inside a directory. + */ + val defaultDirectoryName: String? = null, + + /** + * The [OrtConfigType]s provided by the config file. + */ + val providedTypes: Set +) { + COPYRIGHT_GARBAGE( + defaultFilename = ORT_COPYRIGHT_GARBAGE_FILENAME, + providedTypes = setOf(OrtConfigType.COPYRIGHT_GARBAGE) + ), + + CUSTOM_LICENSE_TEXTS( + defaultFilename = ORT_CUSTOM_LICENSE_TEXTS_DIRNAME, + providedTypes = setOf(OrtConfigType.CUSTOM_LICENSE_TEXTS) + ), + + EVALUATOR_RULES( + defaultFilename = ORT_EVALUATOR_RULES_FILENAME, + providedTypes = setOf(OrtConfigType.EVALUATOR_RULES) + ), + + HOW_TO_FIX_TEXT_PROVIDER( + defaultFilename = ORT_HOW_TO_FIX_TEXT_PROVIDER_FILENAME, + providedTypes = setOf(OrtConfigType.HOW_TO_FIX_TEXTS) + ), + + LICENSE_CLASSIFICATIONS( + defaultFilename = ORT_LICENSE_CLASSIFICATIONS_FILENAME, + providedTypes = setOf(OrtConfigType.LICENSE_CLASSIFICATIONS) + ), + + NOTIFIER_SCRIPT( + defaultFilename = ORT_NOTIFIER_SCRIPT_FILENAME, + providedTypes = setOf(OrtConfigType.NOTIFIER_RULES) + ), + + ORT_CONFIG( + defaultFilename = ORT_CONFIG_FILENAME, + providedTypes = setOf(OrtConfigType.ORT_CONFIG) + ), + + PACKAGE_CONFIGURATIONS( + defaultFilename = ORT_PACKAGE_CONFIGURATION_FILENAME, + defaultDirectoryName = ORT_PACKAGE_CONFIGURATIONS_DIRNAME, + providedTypes = setOf(OrtConfigType.PACKAGE_CONFIGURATIONS) + ), + + PACKAGE_CURATIONS( + defaultFilename = ORT_PACKAGE_CURATIONS_FILENAME, + defaultDirectoryName = ORT_PACKAGE_CURATIONS_DIRNAME, + providedTypes = setOf(OrtConfigType.PACKAGE_CURATIONS) + ), + + REPOSITORY_CONFIGURATION( + defaultFilename = ORT_REPO_CONFIG_FILENAME, + providedTypes = setOf( + OrtConfigType.LICENSE_CHOICES, + OrtConfigType.ORT_CONFIG, + OrtConfigType.PACKAGE_CONFIGURATIONS, + OrtConfigType.PACKAGE_CURATIONS, + OrtConfigType.RESOLUTIONS + ) + ), + + RESOLUTIONS( + defaultFilename = ORT_RESOLUTIONS_FILENAME, + providedTypes = setOf(OrtConfigType.RESOLUTIONS) + ) +} diff --git a/model/src/main/kotlin/OrtConfigType.kt b/model/src/main/kotlin/OrtConfigType.kt new file mode 100644 index 0000000000000..cfc0391972625 --- /dev/null +++ b/model/src/main/kotlin/OrtConfigType.kt @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 The ORT Project Authors (see ) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +package org.ossreviewtoolkit.model + +/** + * An enum representing the different kinds of configuration the ORT tools consume. + */ +enum class OrtConfigType(val resolvable: Boolean) { + COPYRIGHT_GARBAGE(resolvable = false), + CUSTOM_LICENSE_TEXTS(resolvable = false), + EVALUATOR_RULES(resolvable = false), + HOW_TO_FIX_TEXTS(resolvable = false), + LICENSE_CHOICES(resolvable = false), + LICENSE_CLASSIFICATIONS(resolvable = false), + NOTIFIER_RULES(resolvable = false), + ORT_CONFIG(resolvable = false), + PACKAGE_CONFIGURATIONS(resolvable = true), + PACKAGE_CURATIONS(resolvable = true), + RESOLUTIONS(resolvable = true); + + fun resolvableTypes() = values().filter { it.resolvable } +} diff --git a/model/src/main/kotlin/OrtTool.kt b/model/src/main/kotlin/OrtTool.kt new file mode 100644 index 0000000000000..72472492958a7 --- /dev/null +++ b/model/src/main/kotlin/OrtTool.kt @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2023 The ORT Project Authors (see ) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * License-Filename: LICENSE + */ + +package org.ossreviewtoolkit.model + +/** + * An enum representing the different ORT tools and how they depend on each other. + */ +enum class OrtTool( + /** + * Tools whose output is required to run this tool. + */ + val requiredInput: Set, + + /** + * Tools whose output is used if it is available. + */ + val optionalInput: Set, + + /** + * The different [OrtConfigType]s consumed by the tool. + */ + val consumedConfig: Set +) { + ANALYZER( + requiredInput = emptySet(), + optionalInput = emptySet(), + consumedConfig = setOf( + OrtConfigType.ORT_CONFIG, + OrtConfigType.PACKAGE_CURATIONS, + OrtConfigType.RESOLUTIONS + ) + ), + + ADVISOR( + requiredInput = setOf(ANALYZER), + optionalInput = emptySet(), + consumedConfig = setOf( + OrtConfigType.ORT_CONFIG, + OrtConfigType.RESOLUTIONS + ) + ), + + SCANNER( + requiredInput = setOf(ANALYZER), + optionalInput = emptySet(), + consumedConfig = setOf( + OrtConfigType.ORT_CONFIG, + OrtConfigType.RESOLUTIONS + ) + ), + + EVALUATOR( + requiredInput = setOf(ANALYZER), + optionalInput = setOf(ADVISOR, SCANNER), + consumedConfig = setOf( + OrtConfigType.COPYRIGHT_GARBAGE, + OrtConfigType.EVALUATOR_RULES, + OrtConfigType.LICENSE_CHOICES, + OrtConfigType.LICENSE_CLASSIFICATIONS, + OrtConfigType.ORT_CONFIG, + OrtConfigType.PACKAGE_CONFIGURATIONS, + OrtConfigType.PACKAGE_CURATIONS, + OrtConfigType.RESOLUTIONS + ) + ), + + REPORTER( + requiredInput = setOf(ANALYZER), + optionalInput = setOf(ADVISOR, SCANNER, EVALUATOR), + consumedConfig = setOf( + OrtConfigType.COPYRIGHT_GARBAGE, + OrtConfigType.CUSTOM_LICENSE_TEXTS, + OrtConfigType.HOW_TO_FIX_TEXTS, + OrtConfigType.LICENSE_CHOICES, + OrtConfigType.LICENSE_CLASSIFICATIONS, + OrtConfigType.ORT_CONFIG, + OrtConfigType.PACKAGE_CONFIGURATIONS, + OrtConfigType.PACKAGE_CURATIONS, + OrtConfigType.RESOLUTIONS + ) + ), + + NOTIFIER( + requiredInput = setOf(ANALYZER), + optionalInput = setOf(ADVISOR, SCANNER, EVALUATOR), + consumedConfig = setOf( + OrtConfigType.COPYRIGHT_GARBAGE, + OrtConfigType.CUSTOM_LICENSE_TEXTS, + OrtConfigType.LICENSE_CHOICES, + OrtConfigType.LICENSE_CLASSIFICATIONS, + OrtConfigType.ORT_CONFIG, + OrtConfigType.PACKAGE_CONFIGURATIONS, + OrtConfigType.PACKAGE_CURATIONS, + OrtConfigType.RESOLUTIONS + ) + ); + + val alias = name.lowercase() + val input = requiredInput + optionalInput +} diff --git a/model/src/main/kotlin/utils/OrtResultExtensions.kt b/model/src/main/kotlin/utils/OrtResultExtensions.kt index b07d8983a129e..66276381a5a02 100644 --- a/model/src/main/kotlin/utils/OrtResultExtensions.kt +++ b/model/src/main/kotlin/utils/OrtResultExtensions.kt @@ -19,7 +19,9 @@ package org.ossreviewtoolkit.model.utils +import org.ossreviewtoolkit.model.OrtConfigType import org.ossreviewtoolkit.model.OrtResult +import org.ossreviewtoolkit.model.OrtTool import org.ossreviewtoolkit.model.RepositoryProvenance import org.ossreviewtoolkit.model.config.CopyrightGarbage import org.ossreviewtoolkit.model.config.LicenseFilePatterns @@ -77,12 +79,12 @@ fun OrtResult.createLicenseInfoResolver( addAuthorsToCopyrights: Boolean = false, archiver: FileArchiver? = null ) = LicenseInfoResolver( - DefaultLicenseInfoProvider(this, packageConfigurationProvider), - copyrightGarbage, - addAuthorsToCopyrights, - archiver, - LicenseFilePatterns.getInstance() - ) + DefaultLicenseInfoProvider(this, packageConfigurationProvider), + copyrightGarbage, + addAuthorsToCopyrights, + archiver, + LicenseFilePatterns.getInstance() +) /** * Return the path where the repository given by [provenance] is linked into the source tree. @@ -104,3 +106,50 @@ fun OrtResult.getRepositoryPath(provenance: RepositoryProvenance): String { * Copy this [OrtResult] and add all [labels] to the existing labels, overwriting existing labels on conflict. */ fun OrtResult.mergeLabels(labels: Map) = copy(labels = this.labels + labels) + +/** + * Return true if the provided [type] is [resolvable][OrtConfigType.resolvable] and the + * [resolved configuration][OrtResult.resolvedConfiguration] contains the respective configuration. + */ +fun OrtResult.hasResolvedConfiguration(type: OrtConfigType): Boolean = + when (type) { + OrtConfigType.PACKAGE_CONFIGURATIONS -> resolvedConfiguration.packageConfigurations != null + OrtConfigType.PACKAGE_CURATIONS -> resolvedConfiguration.packageCurations.isNotEmpty() + OrtConfigType.RESOLUTIONS -> resolvedConfiguration.resolutions != null + + else -> { + require(!type.resolvable) { + "${type.name} is resolvable but no handling is implemented in this function." + } + + false + } + } + +fun OrtResult.hasToolResult(tool: OrtTool): Boolean = + when (tool) { + OrtTool.ANALYZER -> analyzer != null + OrtTool.ADVISOR -> advisor != null + OrtTool.SCANNER -> scanner != null + OrtTool.EVALUATOR -> evaluator != null + + // The remaining tools do not add their output to the OrtResult. + else -> false + } + +fun OrtResult.resolveConfiguration(tool: OrtTool, types: Set): OrtResult { + tool.input.filter { hasToolResult(it) }.forEach { inputTool -> + types.forEach { type -> + if (type in inputTool.consumedConfig) { + println( + "Resolving configuration '${type.name}' which previously resolved and already consumed by the " + + "'${inputTool.alias}'. This can lead to inconsistencies in the result." + ) + } + } + } + + // TODO: Implement actual resolution. + + return this +}