
toolkit.evaluator.28.0.0.source-code.ProjectSourceRule.kt Maven / Gradle / Ivy
/*
* 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 - 2025 Weber Informatics LLC | Privacy Policy