Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement generic config resolution #6785

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
117 changes: 117 additions & 0 deletions model/src/main/kotlin/OrtConfigFile.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright (C) 2023 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
*
* 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<OrtConfigType>
) {
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)
)
}
39 changes: 39 additions & 0 deletions model/src/main/kotlin/OrtConfigType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2023 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
*
* 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 }
}
117 changes: 117 additions & 0 deletions model/src/main/kotlin/OrtTool.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Copyright (C) 2023 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
*
* 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<OrtTool>,

/**
* Tools whose output is used if it is available.
*/
val optionalInput: Set<OrtTool>,

/**
* The different [OrtConfigType]s consumed by the tool.
*/
val consumedConfig: Set<OrtConfigType>
) {
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
}
61 changes: 55 additions & 6 deletions model/src/main/kotlin/utils/OrtResultExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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<String, String>) = 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<OrtConfigType>): 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
}