All Downloads are FREE. Search and download functionalities are using the official Maven repository.

config.AnalyzerConfiguration.kt Maven / Gradle / Ivy

/*
 * Copyright (C) 2017 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.config

import com.fasterxml.jackson.annotation.JsonInclude

@JsonInclude(JsonInclude.Include.NON_NULL)
data class AnalyzerConfiguration(
    /**
     * Enable the analysis of projects that use version ranges to declare their dependencies. If set to true,
     * dependencies of exactly the same project might change with another scan done at a later time if any of the
     * (transitive) dependencies are declared using version ranges and a new version of such a dependency was
     * published in the meantime. If set to false, analysis of projects that use version ranges will fail. Defaults to
     * false.
     */
    val allowDynamicVersions: Boolean = false,

    /**
     * A list of the case-insensitive names of package managers that are enabled. Disabling a package manager in
     * [disabledPackageManagers] overrides enabling it here.
     */
    val enabledPackageManagers: List? = null,

    /**
     * A list of the case-insensitive names of package managers that are disabled. Disabling a package manager in this
     * list overrides [enabledPackageManagers].
     */
    val disabledPackageManagers: List? = null,

    /**
     * Package manager specific configurations. The key needs to match the name of the package manager class, e.g.
     * "NuGet" for the NuGet package manager.
     */
    val packageManagers: Map? = null,

    /**
     * A flag to control whether excluded scopes and paths should be skipped during the analysis.
     */
    val skipExcluded: Boolean = false
) {
    /**
     * A copy of [packageManagers] with case-insensitive keys.
     */
    private val packageManagersCaseInsensitive: Map? =
        packageManagers?.toSortedMap(String.CASE_INSENSITIVE_ORDER)

    init {
        val duplicatePackageManagers =
            packageManagers?.keys.orEmpty() - packageManagersCaseInsensitive?.keys?.toSet().orEmpty()

        require(duplicatePackageManagers.isEmpty()) {
            "The following package managers have duplicate configuration: ${duplicatePackageManagers.joinToString()}."
        }
    }

    /**
     * Get a [PackageManagerConfiguration] from [packageManagers]. The difference to accessing the map directly is that
     * [packageManager] can be case-insensitive.
     */
    fun getPackageManagerConfiguration(packageManager: String) = packageManagersCaseInsensitive?.get(packageManager)

    /**
     * Merge this [AnalyzerConfiguration] with [other]. Values of [other] take precedence.
     */
    fun merge(other: RepositoryAnalyzerConfiguration): AnalyzerConfiguration {
        val mergedPackageManagers = when {
            packageManagers == null -> other.packageManagers
            other.packageManagers == null -> packageManagers
            else -> {
                val keys = sortedSetOf(String.CASE_INSENSITIVE_ORDER).apply {
                    addAll(packageManagers.keys)
                    addAll(other.packageManagers.keys)
                }

                val result = sortedMapOf(String.CASE_INSENSITIVE_ORDER)

                keys.forEach { key ->
                    val configSelf = getPackageManagerConfiguration(key)
                    val configOther = other.getPackageManagerConfiguration(key)

                    result[key] = when {
                        configSelf == null -> configOther
                        configOther == null -> configSelf
                        else -> configSelf.merge(configOther)
                    }
                }

                result
            }
        }

        return AnalyzerConfiguration(
            allowDynamicVersions = other.allowDynamicVersions ?: allowDynamicVersions,
            enabledPackageManagers = other.enabledPackageManagers ?: enabledPackageManagers,
            disabledPackageManagers = other.disabledPackageManagers ?: disabledPackageManagers,
            packageManagers = mergedPackageManagers,
            skipExcluded = other.skipExcluded ?: skipExcluded
        )
    }

    /**
     * Return a copy of this [AnalyzerConfiguration] "patched" with [name]-specific options to contain the given [key]
     * and [value] pair, overriding any existing entry.
     */
    fun withPackageManagerOption(name: String, key: String, value: String): AnalyzerConfiguration {
        val managers = packageManagers.orEmpty().toMutableMap()
        val configuration = managers[name] ?: PackageManagerConfiguration()
        val options = configuration.options.orEmpty().toMutableMap()

        options[key] = value
        managers[name] = configuration.copy(options = options)

        return copy(packageManagers = managers)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy