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

toolkit.evaluator.33.1.0.source-code.ProjectSourceRule.kt Maven / Gradle / Ivy

Go to download

Part of the OSS Review Toolkit (ORT), a suite to automate software compliance checks.

There is a newer version: 40.0.1
Show newest version
/*
 * Copyright (C) 2022 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.evaluator

import java.io.File

import org.ossreviewtoolkit.model.LicenseSource
import org.ossreviewtoolkit.model.RepositoryProvenance
import org.ossreviewtoolkit.model.VcsType
import org.ossreviewtoolkit.model.utils.getRepositoryPath
import org.ossreviewtoolkit.utils.common.FileMatcher

/**
 * An [OrtResultRule] which allows downloading the project's source code if needed.
 */
open class ProjectSourceRule(
    ruleSet: RuleSet,
    name: String
) : OrtResultRule(ruleSet, name) {
    /**
     * The directory containing the source code of the project. Accessing the property for the first time triggers a
     * clone and may take a while.
     */
    @Suppress("MemberVisibilityCanBePrivate") // This property is used in rules.
    val projectSourcesDir: File by lazy { ruleSet.projectSourceResolver.rootDir }

    private val detectedLicensesForFilePath: Map> by lazy {
        val result = mutableMapOf>()
        val projectIds = ruleSet.ortResult.getProjects().map { it.id }
        val licenseInfos = projectIds.map { ruleSet.licenseInfoResolver.resolveLicenseInfo(it) }

        licenseInfos.forEach { licenseInfo ->
            licenseInfo.licenses.filter {
                LicenseSource.DETECTED in it.sources
            }.forEach { resolvedLicense ->
                resolvedLicense.locations.forEach { resolvedLocation ->
                    val provenance = resolvedLocation.provenance as RepositoryProvenance
                    val repositoryPath = ortResult.getRepositoryPath(provenance)
                    val path = "$repositoryPath${resolvedLocation.location.path}".removePrefix("/")

                    result.getOrPut(path) { mutableSetOf() } += resolvedLicense.license.simpleLicense()
                }
            }
        }

        result
    }

    /**
     * Return all directories from the project's source tree which match any of the
     * provided [glob expressions][patterns].
     */
    fun projectSourceFindDirectories(vararg patterns: String): List =
        projectSourcesDir.walkBottomUp().filterTo(mutableListOf()) {
            it.isDirectory && FileMatcher.match(patterns.toList(), it.relativeTo(projectSourcesDir).path)
        }

    /**
     * Return all files from the project's source tree which match any of the provided [glob expressions][patterns].
     */
    fun projectSourceFindFiles(vararg patterns: String): List =
        projectSourcesDir.walkBottomUp().filterTo(mutableListOf()) {
            it.isFile && FileMatcher.match(patterns.toList(), it.relativeTo(projectSourcesDir).path)
        }

    /**
     * Return the detected licenses for any file matching the given [glob expressions][patterns].
     */
    fun projectSourceGetDetectedLicensesByFilePath(vararg patterns: String): Map> =
        detectedLicensesForFilePath.filter { (filePath, _) ->
            FileMatcher.match(patterns.toList(), filePath)
        }

    /**
     * Return the [VcsType] of the project's code repository.
     */
    fun projectSourceGetVcsType(): VcsType = ortResult.repository.vcsProcessed.type

    /**
     * Return the file paths matching any of the given [glob expressions][patterns] with its file content matching
     * [contentPattern].
     */
    fun projectSourceFindFilesWithContent(contentPattern: String, vararg patterns: String): List {
        val regex = contentPattern.toRegex(setOf(RegexOption.DOT_MATCHES_ALL, RegexOption.MULTILINE))

        return projectSourceFindFiles(*patterns).filter { path ->
            val content = projectSourcesDir.resolve(path).readText()

            content.matches(regex)
        }
    }

    /**
     * A [RuleMatcher] that checks whether the project's source tree contains at least one directory matching any of the
     * provided [glob expressions][patterns].
     */
    fun projectSourceHasDirectory(vararg patterns: String): RuleMatcher =
        object : RuleMatcher {
            override val description = "projectSourceHasDirectory('${patterns.joinToString()}')"

            override fun matches(): Boolean = projectSourceFindDirectories(*patterns).isNotEmpty()
        }

    /**
     * A [RuleMatcher] that checks whether the project's source tree contains at least one file matching any of the
     * provided [glob expressions][patterns].
     */
    fun projectSourceHasFile(vararg patterns: String): RuleMatcher =
        object : RuleMatcher {
            override val description = "projectSourceHasFile('${patterns.joinToString()}')"
            override fun matches(): Boolean = projectSourceFindFiles(*patterns).isNotEmpty()
        }

    /**
     * A [RuleMatcher] that checks whether the project's source tree contains at least one file matching any of the
     * given [glob expressions][patterns] with its file content matching [contentPattern].
     */
    fun projectSourceHasFileWithContent(contentPattern: String, vararg patterns: String): RuleMatcher =
        object : RuleMatcher {
            override val description =
                "projectSourceHasFileWithContents('$contentPattern', '${patterns.joinToString()}')"

            override fun matches(): Boolean = projectSourceFindFilesWithContent(contentPattern, *patterns).isNotEmpty()
        }

    /**
     * A [RuleMatcher] that checks whether the [VcsType] of the project's code repository is contained in the given
     * [vcsTypes].
     */
    fun projectSourceHasVcsType(vararg vcsTypes: VcsType): RuleMatcher =
        object : RuleMatcher {
            private val types = vcsTypes.toSet()

            override val description =
                "projectSourceHasVcsType('${vcsTypes.joinToString()}')"

            override fun matches(): Boolean = projectSourceGetVcsType() in types
        }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy