From 401738e9f48ffd84fda7b7d6de6cc4afdf36ad60 Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Tue, 1 Jul 2025 12:40:17 +0200 Subject: [PATCH 01/12] refactor(Repository): Add `RepositoryProvenance` attribute In order to support non-VCS input for ORT, `KnownProvenance`s need to be supported as input for `anaylzer` and `scanner`. The `Repository` data structure appears to be the best place to facilitate this change. This change focusses on adding a `RepositoryProvenance` attribute to `Repository`, which allows to keep previous behavior. For now it also exposes the raw `VcsInfo` of the `provenance` as its `vcs` attribute. Signed-off-by: Jens Keim --- analyzer/src/main/kotlin/Analyzer.kt | 16 +++++++++++++++- ...CreateAnalyzerResultFromPackageListCommand.kt | 8 +++++++- .../src/test/kotlin/ProjectSourceRuleTest.kt | 7 ++++++- evaluator/src/testFixtures/kotlin/TestData.kt | 3 +-- model/src/main/kotlin/Repository.kt | 11 ++++++++++- model/src/test/kotlin/OrtResultTest.kt | 6 ++++-- model/src/testFixtures/kotlin/TestData.kt | 2 +- .../kotlin/CtrlXAutomationReporterFunTest.kt | 7 +++++-- .../fossid/src/test/kotlin/FossIdReporterTest.kt | 7 +++++-- .../kotlin/FreeMarkerTemplateProcessorTest.kt | 6 +++++- .../src/test/kotlin/OpossumReporterTest.kt | 6 ++++-- .../spdx/src/testFixtures/kotlin/TestData.kt | 7 ++++++- reporter/src/testFixtures/kotlin/TestData.kt | 12 ++++++++---- 13 files changed, 77 insertions(+), 21 deletions(-) diff --git a/analyzer/src/main/kotlin/Analyzer.kt b/analyzer/src/main/kotlin/Analyzer.kt index 4b154fdaa7e63..a661eb10e7c9a 100644 --- a/analyzer/src/main/kotlin/Analyzer.kt +++ b/analyzer/src/main/kotlin/Analyzer.kt @@ -42,6 +42,8 @@ import org.ossreviewtoolkit.model.AnalyzerResult import org.ossreviewtoolkit.model.AnalyzerRun import org.ossreviewtoolkit.model.OrtResult import org.ossreviewtoolkit.model.Repository +import org.ossreviewtoolkit.model.RepositoryProvenance +import org.ossreviewtoolkit.model.VcsInfo import org.ossreviewtoolkit.model.config.AnalyzerConfiguration import org.ossreviewtoolkit.model.config.Excludes import org.ossreviewtoolkit.model.config.RepositoryConfiguration @@ -147,7 +149,19 @@ class Analyzer(private val config: AnalyzerConfiguration, private val labels: Ma // Only include nested VCS if they are part of the analyzed directory. workingTree.getRootPath().resolve(path).startsWith(info.absoluteProjectPath) }.orEmpty() - val repository = Repository(vcs = vcs, nestedRepositories = nestedVcs, config = info.repositoryConfiguration) + + val repository = if (vcs == VcsInfo.EMPTY) { + Repository.EMPTY + } else { + Repository( + provenance = RepositoryProvenance( + vcsInfo = vcs, + resolvedRevision = vcs.revision + ), + nestedRepositories = nestedVcs, + config = info.repositoryConfiguration + ) + } val endTime = Instant.now() diff --git a/cli-helper/src/main/kotlin/commands/CreateAnalyzerResultFromPackageListCommand.kt b/cli-helper/src/main/kotlin/commands/CreateAnalyzerResultFromPackageListCommand.kt index ada2e96f0d401..7c2c7503fdbe8 100644 --- a/cli-helper/src/main/kotlin/commands/CreateAnalyzerResultFromPackageListCommand.kt +++ b/cli-helper/src/main/kotlin/commands/CreateAnalyzerResultFromPackageListCommand.kt @@ -41,6 +41,7 @@ import org.ossreviewtoolkit.model.PackageReference import org.ossreviewtoolkit.model.Project import org.ossreviewtoolkit.model.RemoteArtifact import org.ossreviewtoolkit.model.Repository +import org.ossreviewtoolkit.model.RepositoryProvenance import org.ossreviewtoolkit.model.Scope import org.ossreviewtoolkit.model.VcsInfo import org.ossreviewtoolkit.model.VcsType @@ -120,7 +121,12 @@ internal class CreateAnalyzerResultFromPackageListCommand : OrtHelperCommand( environment = Environment() ), repository = Repository( - vcs = projectVcs.normalize(), + provenance = projectVcs.normalize().let { + RepositoryProvenance( + vcsInfo = it, + resolvedRevision = it.revision + ) + }, config = RepositoryConfiguration( excludes = Excludes( scopes = listOf( diff --git a/evaluator/src/test/kotlin/ProjectSourceRuleTest.kt b/evaluator/src/test/kotlin/ProjectSourceRuleTest.kt index 1b5b270536929..4cd601c3c8798 100644 --- a/evaluator/src/test/kotlin/ProjectSourceRuleTest.kt +++ b/evaluator/src/test/kotlin/ProjectSourceRuleTest.kt @@ -214,7 +214,12 @@ private fun createOrtResult( } return OrtResult.EMPTY.copy( - repository = Repository(vcsInfo), + repository = Repository( + provenance = RepositoryProvenance( + vcsInfo = vcsInfo, + resolvedRevision = vcsInfo.revision + ) + ), analyzer = AnalyzerRun.EMPTY.copy( result = AnalyzerResult.EMPTY.copy( projects = setOf( diff --git a/evaluator/src/testFixtures/kotlin/TestData.kt b/evaluator/src/testFixtures/kotlin/TestData.kt index 92b2878996923..38e6e9e630b4e 100644 --- a/evaluator/src/testFixtures/kotlin/TestData.kt +++ b/evaluator/src/testFixtures/kotlin/TestData.kt @@ -42,7 +42,6 @@ import org.ossreviewtoolkit.model.ScannerDetails import org.ossreviewtoolkit.model.Scope import org.ossreviewtoolkit.model.TextLocation import org.ossreviewtoolkit.model.UnknownProvenance -import org.ossreviewtoolkit.model.VcsInfo import org.ossreviewtoolkit.model.config.AdvisorConfiguration import org.ossreviewtoolkit.model.config.AnalyzerConfiguration import org.ossreviewtoolkit.model.config.Excludes @@ -179,7 +178,7 @@ val allProjects = setOf( val ortResult = OrtResult( repository = Repository( - vcs = VcsInfo.EMPTY, + provenance = Repository.EMPTY.provenance, config = RepositoryConfiguration( excludes = Excludes( paths = listOf( diff --git a/model/src/main/kotlin/Repository.kt b/model/src/main/kotlin/Repository.kt index 480cb869613bd..9400ebd8f6e63 100644 --- a/model/src/main/kotlin/Repository.kt +++ b/model/src/main/kotlin/Repository.kt @@ -28,10 +28,15 @@ import org.ossreviewtoolkit.utils.ort.ORT_REPO_CONFIG_FILENAME * A description of the source code repository that was used as input for ORT. */ data class Repository( + /** + * Provenance wrapper for original VCS information, if present. + */ + val provenance: RepositoryProvenance, + /** * Original VCS-related information from the working tree containing the analyzer root. */ - val vcs: VcsInfo, + val vcs: VcsInfo = provenance.vcsInfo, /** * Processed VCS-related information from the working tree containing the analyzer root that has e.g. common @@ -57,6 +62,10 @@ data class Repository( */ @JvmField val EMPTY = Repository( + provenance = RepositoryProvenance( + vcsInfo = VcsInfo.EMPTY, + resolvedRevision = HashAlgorithm.SHA1.emptyValue + ), vcs = VcsInfo.EMPTY, vcsProcessed = VcsInfo.EMPTY, nestedRepositories = emptyMap(), diff --git a/model/src/test/kotlin/OrtResultTest.kt b/model/src/test/kotlin/OrtResultTest.kt index d07eed327347f..0c7e1ff73626a 100644 --- a/model/src/test/kotlin/OrtResultTest.kt +++ b/model/src/test/kotlin/OrtResultTest.kt @@ -163,6 +163,7 @@ class OrtResultTest : WordSpec({ "getDefinitionFilePathRelativeToAnalyzerRoot()" should { "use the correct vcs" { val vcs = VcsInfo(type = VcsType.GIT, url = "https://example.com/git", revision = "") + val provenance = RepositoryProvenance(vcsInfo = vcs, resolvedRevision = vcs.revision) val nestedVcs1 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git1", revision = "") val nestedVcs2 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git2", revision = "") val project1 = Project.EMPTY.copy( @@ -185,7 +186,7 @@ class OrtResultTest : WordSpec({ ) val ortResult = OrtResult( Repository( - vcs = vcs, + provenance = provenance, nestedRepositories = mapOf( "path/1" to nestedVcs1, "path/2" to nestedVcs2 @@ -203,6 +204,7 @@ class OrtResultTest : WordSpec({ "fail if no vcs matches" { val vcs = VcsInfo(type = VcsType.GIT, url = "https://example.com/git", revision = "") + val provenance = RepositoryProvenance(vcsInfo = vcs, resolvedRevision = vcs.revision) val nestedVcs1 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git1", revision = "") val nestedVcs2 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git2", revision = "") val project = Project.EMPTY.copy( @@ -213,7 +215,7 @@ class OrtResultTest : WordSpec({ ) val ortResult = OrtResult( Repository( - vcs = vcs, + provenance = provenance, nestedRepositories = mapOf( "path/1" to nestedVcs1 ) diff --git a/model/src/testFixtures/kotlin/TestData.kt b/model/src/testFixtures/kotlin/TestData.kt index e1f6922424a96..c347a87730324 100644 --- a/model/src/testFixtures/kotlin/TestData.kt +++ b/model/src/testFixtures/kotlin/TestData.kt @@ -136,7 +136,7 @@ val scanResults = listOf( val ortResult = OrtResult( repository = Repository( - vcs = VcsInfo.EMPTY, + provenance = Repository.EMPTY.provenance, config = RepositoryConfiguration( excludes = Excludes( paths = listOf( diff --git a/plugins/reporters/ctrlx/src/funTest/kotlin/CtrlXAutomationReporterFunTest.kt b/plugins/reporters/ctrlx/src/funTest/kotlin/CtrlXAutomationReporterFunTest.kt index ed1efef626c99..a5fd0618e82ec 100644 --- a/plugins/reporters/ctrlx/src/funTest/kotlin/CtrlXAutomationReporterFunTest.kt +++ b/plugins/reporters/ctrlx/src/funTest/kotlin/CtrlXAutomationReporterFunTest.kt @@ -42,6 +42,7 @@ import org.ossreviewtoolkit.model.OrtResult import org.ossreviewtoolkit.model.Package import org.ossreviewtoolkit.model.Project import org.ossreviewtoolkit.model.Repository +import org.ossreviewtoolkit.model.RepositoryProvenance import org.ossreviewtoolkit.model.RootDependencyIndex import org.ossreviewtoolkit.model.Scope import org.ossreviewtoolkit.model.VcsInfo @@ -165,8 +166,10 @@ private fun createReporterInput(): ReporterInput { return ReporterInput( OrtResult( repository = Repository( - vcs = analyzedVcs, - vcsProcessed = analyzedVcs + provenance = RepositoryProvenance( + vcsInfo = analyzedVcs, + resolvedRevision = analyzedVcs.revision + ) ), analyzer = AnalyzerRun.EMPTY.copy( result = AnalyzerResult( diff --git a/plugins/reporters/fossid/src/test/kotlin/FossIdReporterTest.kt b/plugins/reporters/fossid/src/test/kotlin/FossIdReporterTest.kt index b69e14e0d627f..f42f12f7563b2 100644 --- a/plugins/reporters/fossid/src/test/kotlin/FossIdReporterTest.kt +++ b/plugins/reporters/fossid/src/test/kotlin/FossIdReporterTest.kt @@ -42,6 +42,7 @@ import org.ossreviewtoolkit.clients.fossid.model.report.SelectionType import org.ossreviewtoolkit.model.Identifier import org.ossreviewtoolkit.model.OrtResult import org.ossreviewtoolkit.model.Repository +import org.ossreviewtoolkit.model.RepositoryProvenance import org.ossreviewtoolkit.model.ScanResult import org.ossreviewtoolkit.model.ScanSummary import org.ossreviewtoolkit.model.ScannerDetails @@ -266,8 +267,10 @@ private fun createReporterInput(vararg scanCodes: String): ReporterInput { ) ) ), - vcs = analyzedVcs, - vcsProcessed = analyzedVcs + provenance = RepositoryProvenance( + vcsInfo = analyzedVcs, + resolvedRevision = analyzedVcs.revision + ) ), scanner = scannerRunOf(*results.toList().toTypedArray()) ) diff --git a/plugins/reporters/freemarker/src/test/kotlin/FreeMarkerTemplateProcessorTest.kt b/plugins/reporters/freemarker/src/test/kotlin/FreeMarkerTemplateProcessorTest.kt index 38f706c484a67..ec9f4e4197aaf 100644 --- a/plugins/reporters/freemarker/src/test/kotlin/FreeMarkerTemplateProcessorTest.kt +++ b/plugins/reporters/freemarker/src/test/kotlin/FreeMarkerTemplateProcessorTest.kt @@ -97,6 +97,10 @@ private val PROJECT_ROOT_VCS_INFO = VcsInfo( private val PROJECT_SUB_VCS_INFO = PROJECT_ROOT_VCS_INFO.copy( path = "sub-dir" ) +private val PROJECT_PROVENANCE = RepositoryProvenance( + vcsInfo = PROJECT_ROOT_VCS_INFO, + resolvedRevision = PROJECT_ROOT_VCS_INFO.revision +) private val NESTED_VCS_INFO = VcsInfo( type = VcsType.GIT, url = "ssh://git@host/project/repo", @@ -110,7 +114,7 @@ private val idNestedProject = Identifier("SpdxDocumentFile:@ort:project-in-neste private val ORT_RESULT = OrtResult( repository = Repository( - vcs = PROJECT_ROOT_VCS_INFO, + provenance = PROJECT_PROVENANCE, config = RepositoryConfiguration(), nestedRepositories = mapOf("nested-vcs-dir" to NESTED_VCS_INFO) ), diff --git a/plugins/reporters/opossum/src/test/kotlin/OpossumReporterTest.kt b/plugins/reporters/opossum/src/test/kotlin/OpossumReporterTest.kt index 025df80de6712..8f526430e2ee2 100644 --- a/plugins/reporters/opossum/src/test/kotlin/OpossumReporterTest.kt +++ b/plugins/reporters/opossum/src/test/kotlin/OpossumReporterTest.kt @@ -244,8 +244,10 @@ private fun createOrtResult(): OrtResult { return OrtResult( repository = Repository( - vcs = analyzedVcs, - vcsProcessed = analyzedVcs + provenance = RepositoryProvenance( + vcsInfo = analyzedVcs, + resolvedRevision = analyzedVcs.revision + ) ), analyzer = AnalyzerRun.EMPTY.copy( config = AnalyzerConfiguration(allowDynamicVersions = true), diff --git a/plugins/reporters/spdx/src/testFixtures/kotlin/TestData.kt b/plugins/reporters/spdx/src/testFixtures/kotlin/TestData.kt index fcf3e2d830da2..7fce7b059e01d 100644 --- a/plugins/reporters/spdx/src/testFixtures/kotlin/TestData.kt +++ b/plugins/reporters/spdx/src/testFixtures/kotlin/TestData.kt @@ -53,6 +53,11 @@ private val ANALYZED_VCS = VcsInfo( url = "https://github.com/path/proj1-repo.git" ) +private val ANALYZED_PROVENANCE = RepositoryProvenance( + vcsInfo = ANALYZED_VCS, + resolvedRevision = ANALYZED_VCS.revision +) + val ORT_RESULT = OrtResult( repository = Repository( config = RepositoryConfiguration( @@ -66,7 +71,7 @@ val ORT_RESULT = OrtResult( ) ) ), - vcs = ANALYZED_VCS, + provenance = ANALYZED_PROVENANCE, vcsProcessed = ANALYZED_VCS ), analyzer = AnalyzerRun.EMPTY.copy( diff --git a/reporter/src/testFixtures/kotlin/TestData.kt b/reporter/src/testFixtures/kotlin/TestData.kt index 751a96956af69..310f277d82880 100644 --- a/reporter/src/testFixtures/kotlin/TestData.kt +++ b/reporter/src/testFixtures/kotlin/TestData.kt @@ -41,6 +41,7 @@ import org.ossreviewtoolkit.model.PackageReference import org.ossreviewtoolkit.model.Project import org.ossreviewtoolkit.model.RemoteArtifact import org.ossreviewtoolkit.model.Repository +import org.ossreviewtoolkit.model.RepositoryProvenance import org.ossreviewtoolkit.model.ScanResult import org.ossreviewtoolkit.model.ScanSummary import org.ossreviewtoolkit.model.ScannerDetails @@ -66,10 +67,13 @@ import org.ossreviewtoolkit.utils.test.scannerRunOf // TODO: Create a way to reduce the code required to prepare an OrtResult for testing. val ORT_RESULT = OrtResult( repository = Repository( - vcs = VcsInfo( - type = VcsType.GIT, - url = "https://github.com/oss-review-toolkit/ort.git", - revision = "main" + provenance = RepositoryProvenance( + vcsInfo = VcsInfo( + type = VcsType.GIT, + url = "https://github.com/oss-review-toolkit/ort.git", + revision = "main" + ), + resolvedRevision = "main" ), config = RepositoryConfiguration( excludes = Excludes( From 391552dc429edb123b353a807ec8e06d49a9360a Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Thu, 11 Sep 2025 15:00:25 +0200 Subject: [PATCH 02/12] refactor(Repository): Remove `vcs` attributes Remove `vcs` and `vcsProcessed` attributes from `Repository`, since the `RepositoryProvenance` `provenance` is now the main attribute. Add `RepositoryDeserializer` to support parsing of legacy `OrtResult` files containing the previous attributes `vcs` and `vcsProcessed`, as well as the new format. It also needs to handle the `nestedRepositories` and `config` attributes for both legacy and recent `OrtResult` files. Signed-off-by: Jens Keim --- .../src/main/kotlin/utils/Extensions.kt | 2 +- .../src/main/kotlin/ProjectSourceRule.kt | 2 +- evaluator/src/main/kotlin/RuleSet.kt | 2 +- model/src/main/kotlin/Repository.kt | 71 +++++++++++++++---- model/src/test/kotlin/OrtResultTest.kt | 6 +- .../src/main/kotlin/CycloneDxReporter.kt | 4 +- .../src/main/kotlin/OpossumReporter.kt | 2 +- .../spdx/src/testFixtures/kotlin/TestData.kt | 3 +- .../main/kotlin/TablesReportModelMapper.kt | 2 +- .../scanners/ScannerIntegrationFunTest.kt | 7 +- 10 files changed, 74 insertions(+), 27 deletions(-) diff --git a/cli-helper/src/main/kotlin/utils/Extensions.kt b/cli-helper/src/main/kotlin/utils/Extensions.kt index 8fbc70b787211..6d2be9c5b207c 100644 --- a/cli-helper/src/main/kotlin/utils/Extensions.kt +++ b/cli-helper/src/main/kotlin/utils/Extensions.kt @@ -716,7 +716,7 @@ internal fun OrtResult.getScanResultFor(packageConfiguration: PackageConfigurati * tree. */ internal fun OrtResult.getRepositoryPaths(): Map> { - val result = mutableMapOf(repository.vcsProcessed.url to mutableSetOf("")) + val result = mutableMapOf(repository.provenance.vcsInfo.normalize().url to mutableSetOf("")) repository.nestedRepositories.mapValues { (path, vcsInfo) -> result.getOrPut(vcsInfo.url) { mutableSetOf() } += path diff --git a/evaluator/src/main/kotlin/ProjectSourceRule.kt b/evaluator/src/main/kotlin/ProjectSourceRule.kt index fc89f1729735e..af503c45baa18 100644 --- a/evaluator/src/main/kotlin/ProjectSourceRule.kt +++ b/evaluator/src/main/kotlin/ProjectSourceRule.kt @@ -93,7 +93,7 @@ open class ProjectSourceRule( /** * Return the [VcsType] of the project's code repository. */ - fun projectSourceGetVcsType(): VcsType = ortResult.repository.vcsProcessed.type + fun projectSourceGetVcsType(): VcsType = ortResult.repository.provenance.vcsInfo.normalize().type /** * Return the file paths matching any of the given [glob expressions][patterns] with its file content matching diff --git a/evaluator/src/main/kotlin/RuleSet.kt b/evaluator/src/main/kotlin/RuleSet.kt index d8fe06df95973..fd9331f34de36 100644 --- a/evaluator/src/main/kotlin/RuleSet.kt +++ b/evaluator/src/main/kotlin/RuleSet.kt @@ -159,7 +159,7 @@ fun ruleSet( licenseInfoResolver: LicenseInfoResolver = ortResult.createLicenseInfoResolver(), resolutionProvider: ResolutionProvider = DefaultResolutionProvider.create(), projectSourceResolver: SourceTreeResolver = SourceTreeResolver.forRemoteRepository( - ortResult.repository.vcsProcessed + ortResult.repository.provenance.vcsInfo.normalize() ), configure: RuleSet.() -> Unit = {} ) = RuleSet(ortResult, licenseInfoResolver, resolutionProvider, projectSourceResolver).apply(configure) diff --git a/model/src/main/kotlin/Repository.kt b/model/src/main/kotlin/Repository.kt index 9400ebd8f6e63..5a23ea806ad2a 100644 --- a/model/src/main/kotlin/Repository.kt +++ b/model/src/main/kotlin/Repository.kt @@ -20,6 +20,12 @@ package org.ossreviewtoolkit.model import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.fasterxml.jackson.module.kotlin.treeToValue import org.ossreviewtoolkit.model.config.RepositoryConfiguration import org.ossreviewtoolkit.utils.ort.ORT_REPO_CONFIG_FILENAME @@ -27,23 +33,13 @@ import org.ossreviewtoolkit.utils.ort.ORT_REPO_CONFIG_FILENAME /** * A description of the source code repository that was used as input for ORT. */ +@JsonDeserialize(using = RepositoryDeserializer::class) data class Repository( /** * Provenance wrapper for original VCS information, if present. */ val provenance: RepositoryProvenance, - /** - * Original VCS-related information from the working tree containing the analyzer root. - */ - val vcs: VcsInfo = provenance.vcsInfo, - - /** - * Processed VCS-related information from the working tree containing the analyzer root that has e.g. common - * mistakes corrected. - */ - val vcsProcessed: VcsInfo = vcs.normalize(), - /** * A map of nested repositories, for example Git submodules or Git-Repo modules. The key is the path to the * nested repository relative to the root of the main repository. @@ -66,8 +62,6 @@ data class Repository( vcsInfo = VcsInfo.EMPTY, resolvedRevision = HashAlgorithm.SHA1.emptyValue ), - vcs = VcsInfo.EMPTY, - vcsProcessed = VcsInfo.EMPTY, nestedRepositories = emptyMap(), config = RepositoryConfiguration() ) @@ -82,8 +76,57 @@ data class Repository( val normalizedVcs = vcs.normalize() - if (vcsProcessed.matches(normalizedVcs)) return "" + if (provenance.vcsInfo.normalize().matches(normalizedVcs)) return "" return nestedRepositories.entries.find { (_, nestedVcs) -> nestedVcs.normalize().matches(normalizedVcs) }?.key } } + +/** + * A custom deserializer for [Repository] to support the legacy "vcs" and "vcsProcessed" attributes. + */ +private class RepositoryDeserializer : StdDeserializer(Repository::class.java) { + override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Repository { + val node = p.codec.readTree(p) + val parsedProvenance = when { + node.has("vcs") -> { + // Parse [vcs] and [vcsProcessed] attributes. + val vcs = jsonMapper.treeToValue(node["vcs"]) + val vcsProcess = jsonMapper.treeToValue(node["vcs_processed"]) + + // Fall back to [vcsProcessed], if [vcs] is empty. + val vcsInfo = if (vcs != VcsInfo.EMPTY) vcs else vcsProcess + + // Get the [vcs]'s revision. + // Fall back to [vcsProcessed], if [vcs] has empty revision. + val resolvedRevision = vcs.revision.ifEmpty { + vcsProcess.revision.ifEmpty { + HashAlgorithm.SHA1.emptyValue + } + } + + // Build a RepositoryProvenance from the parsed VcsInfo fields. + RepositoryProvenance(vcsInfo, resolvedRevision) + } + + else -> { + // Parse the [provenance], if no legacy fields are present. + jsonMapper.treeToValue(node["provenance"]) + } + } + + val nestedRepositories = if (node.has("nested_repositories")) { + jsonMapper.treeToValue>(node["nested_repositories"]) + } else { + emptyMap() + } + + val config = if (node.has("config")) { + jsonMapper.treeToValue(node["config"]) + } else { + RepositoryConfiguration() + } + + return Repository(provenance = parsedProvenance, nestedRepositories, config) + } +} diff --git a/model/src/test/kotlin/OrtResultTest.kt b/model/src/test/kotlin/OrtResultTest.kt index 0c7e1ff73626a..956e0b31e477e 100644 --- a/model/src/test/kotlin/OrtResultTest.kt +++ b/model/src/test/kotlin/OrtResultTest.kt @@ -415,8 +415,10 @@ class OrtResultTest : WordSpec({ val ortResult = OrtResult.EMPTY.copy( repository = Repository.EMPTY.copy( - vcs = vcs, - vcsProcessed = vcs, + provenance = RepositoryProvenance( + vcsInfo = vcs, + resolvedRevision = vcs.revision + ), config = RepositoryConfiguration( excludes = Excludes( paths = listOf( diff --git a/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt b/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt index b62a0cc07e71b..a068b4e35b251 100644 --- a/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt +++ b/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt @@ -154,7 +154,7 @@ class CycloneDxReporter( // There is no component type for repositories. type = Component.Type.FILE - with(input.ortResult.repository.vcsProcessed) { + with(input.ortResult.repository.provenance.vcsInfo.normalize()) { bomRef = "$url@$revision" name = url @@ -178,7 +178,7 @@ class CycloneDxReporter( // distributable), just create a single BOM for all projects in that case for now. As there also is no // single correct project to pick for adding external references in that case, simply only use the global // repository VCS information here. - val vcs = input.ortResult.repository.vcsProcessed + val vcs = input.ortResult.repository.provenance.vcsInfo.normalize() bom.addExternalReference( ExternalReference.Type.VCS, vcs.url, diff --git a/plugins/reporters/opossum/src/main/kotlin/OpossumReporter.kt b/plugins/reporters/opossum/src/main/kotlin/OpossumReporter.kt index 903daaf22c1c8..ce06ad6fe16cb 100644 --- a/plugins/reporters/opossum/src/main/kotlin/OpossumReporter.kt +++ b/plugins/reporters/opossum/src/main/kotlin/OpossumReporter.kt @@ -127,7 +127,7 @@ class OpossumReporter( private val externalAttributionSources: MutableMap = mutableMapOf() internal fun create(input: ReporterInput, maxDepth: Int = Int.MAX_VALUE): OpossumInput { - addBaseUrl("/", input.ortResult.repository.vcs) + addBaseUrl("/", input.ortResult.repository.provenance.vcsInfo) SpdxLicense.entries.forEach { val licenseText = input.licenseFactProvider.getLicenseText(it.id)?.text diff --git a/plugins/reporters/spdx/src/testFixtures/kotlin/TestData.kt b/plugins/reporters/spdx/src/testFixtures/kotlin/TestData.kt index 7fce7b059e01d..741ddea3fd695 100644 --- a/plugins/reporters/spdx/src/testFixtures/kotlin/TestData.kt +++ b/plugins/reporters/spdx/src/testFixtures/kotlin/TestData.kt @@ -71,8 +71,7 @@ val ORT_RESULT = OrtResult( ) ) ), - provenance = ANALYZED_PROVENANCE, - vcsProcessed = ANALYZED_VCS + provenance = ANALYZED_PROVENANCE ), analyzer = AnalyzerRun.EMPTY.copy( result = AnalyzerResult( diff --git a/plugins/reporters/static-html/src/main/kotlin/TablesReportModelMapper.kt b/plugins/reporters/static-html/src/main/kotlin/TablesReportModelMapper.kt index abab130df40db..b686ed3d23004 100644 --- a/plugins/reporters/static-html/src/main/kotlin/TablesReportModelMapper.kt +++ b/plugins/reporters/static-html/src/main/kotlin/TablesReportModelMapper.kt @@ -48,7 +48,7 @@ internal object TablesReportModelMapper { .sortedBy { it.id } return TablesReport( - input.ortResult.repository.vcsProcessed, + input.ortResult.repository.provenance.vcsInfo.normalize(), input.ortResult.repository.config, ruleViolations, getAnalyzerIssueSummaryTable(input), diff --git a/scanner/src/funTest/kotlin/scanners/ScannerIntegrationFunTest.kt b/scanner/src/funTest/kotlin/scanners/ScannerIntegrationFunTest.kt index 526d89bba554e..b3faa822ef00d 100644 --- a/scanner/src/funTest/kotlin/scanners/ScannerIntegrationFunTest.kt +++ b/scanner/src/funTest/kotlin/scanners/ScannerIntegrationFunTest.kt @@ -36,6 +36,7 @@ import org.ossreviewtoolkit.model.PackageReference import org.ossreviewtoolkit.model.PackageType import org.ossreviewtoolkit.model.Project import org.ossreviewtoolkit.model.Repository +import org.ossreviewtoolkit.model.RepositoryProvenance import org.ossreviewtoolkit.model.ScanSummary import org.ossreviewtoolkit.model.Scope import org.ossreviewtoolkit.model.TextLocation @@ -167,8 +168,10 @@ private fun createAnalyzerResultWithProject(project: Project, vararg packages: P return OrtResult.EMPTY.copy( analyzer = analyzerRun, repository = Repository.EMPTY.copy( - vcsProcessed = projectWithScope.vcsProcessed, - vcs = projectWithScope.vcs + provenance = RepositoryProvenance( + vcsInfo = projectWithScope.vcs, + resolvedRevision = projectWithScope.vcs.revision + ) ) ) } From 9e4490aa635cb0867f7079f3a6ab459b6b52b033 Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Tue, 16 Sep 2025 12:45:20 +0200 Subject: [PATCH 03/12] fix(OrtResultTest): No more blank revisions Signed-off-by: Jens Keim --- model/src/test/kotlin/OrtResultTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/model/src/test/kotlin/OrtResultTest.kt b/model/src/test/kotlin/OrtResultTest.kt index 956e0b31e477e..d24a65c899d72 100644 --- a/model/src/test/kotlin/OrtResultTest.kt +++ b/model/src/test/kotlin/OrtResultTest.kt @@ -163,7 +163,7 @@ class OrtResultTest : WordSpec({ "getDefinitionFilePathRelativeToAnalyzerRoot()" should { "use the correct vcs" { val vcs = VcsInfo(type = VcsType.GIT, url = "https://example.com/git", revision = "") - val provenance = RepositoryProvenance(vcsInfo = vcs, resolvedRevision = vcs.revision) + val provenance = RepositoryProvenance(vcsInfo = vcs, resolvedRevision = HashAlgorithm.SHA1.emptyValue) val nestedVcs1 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git1", revision = "") val nestedVcs2 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git2", revision = "") val project1 = Project.EMPTY.copy( @@ -204,7 +204,7 @@ class OrtResultTest : WordSpec({ "fail if no vcs matches" { val vcs = VcsInfo(type = VcsType.GIT, url = "https://example.com/git", revision = "") - val provenance = RepositoryProvenance(vcsInfo = vcs, resolvedRevision = vcs.revision) + val provenance = RepositoryProvenance(vcsInfo = vcs, resolvedRevision = HashAlgorithm.SHA1.emptyValue) val nestedVcs1 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git1", revision = "") val nestedVcs2 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git2", revision = "") val project = Project.EMPTY.copy( From d4a2a91b18938eab59549a445297aa597a3e0f4e Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Tue, 16 Sep 2025 13:29:12 +0200 Subject: [PATCH 04/12] fix(ScannerIntegrationFunTest): Fallback on `emptyValue` if revision blank Signed-off-by: Jens Keim --- .../src/funTest/kotlin/scanners/ScannerIntegrationFunTest.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scanner/src/funTest/kotlin/scanners/ScannerIntegrationFunTest.kt b/scanner/src/funTest/kotlin/scanners/ScannerIntegrationFunTest.kt index b3faa822ef00d..8d029ade0cfac 100644 --- a/scanner/src/funTest/kotlin/scanners/ScannerIntegrationFunTest.kt +++ b/scanner/src/funTest/kotlin/scanners/ScannerIntegrationFunTest.kt @@ -28,6 +28,7 @@ import java.io.File import org.ossreviewtoolkit.downloader.DefaultWorkingTreeCache import org.ossreviewtoolkit.model.AnalyzerResult import org.ossreviewtoolkit.model.AnalyzerRun +import org.ossreviewtoolkit.model.HashAlgorithm import org.ossreviewtoolkit.model.Identifier import org.ossreviewtoolkit.model.LicenseFinding import org.ossreviewtoolkit.model.OrtResult @@ -165,12 +166,14 @@ private fun createAnalyzerResultWithProject(project: Project, vararg packages: P config = AnalyzerConfiguration(enabledPackageManagers = emptyList()) ) + val resolvedRevision = projectWithScope.vcs.revision.ifEmpty { HashAlgorithm.SHA1.emptyValue } + return OrtResult.EMPTY.copy( analyzer = analyzerRun, repository = Repository.EMPTY.copy( provenance = RepositoryProvenance( vcsInfo = projectWithScope.vcs, - resolvedRevision = projectWithScope.vcs.revision + resolvedRevision = resolvedRevision ) ) ) From f71005e9d34c6a70f259600f55aa0dd516578d07 Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Wed, 17 Sep 2025 12:58:41 +0200 Subject: [PATCH 05/12] fix(ScannerIntegrationFunTest): Add revision to result files Signed-off-by: Jens Keim --- .../scanner-integration-all-pkgs-expected-ort-result.yml | 4 ++-- .../scanner-integration-subset-pkgs-expected-ort-result.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scanner/src/funTest/resources/scanner-integration-all-pkgs-expected-ort-result.yml b/scanner/src/funTest/resources/scanner-integration-all-pkgs-expected-ort-result.yml index 07a38a800a5a7..c3bffc1b022c5 100644 --- a/scanner/src/funTest/resources/scanner-integration-all-pkgs-expected-ort-result.yml +++ b/scanner/src/funTest/resources/scanner-integration-all-pkgs-expected-ort-result.yml @@ -3,12 +3,12 @@ repository: vcs: type: "" url: "" - revision: "" + revision: "da39a3ee5e6b4b0d3255bfef95601890afd80709" path: "" vcs_processed: type: "" url: "" - revision: "" + revision: "da39a3ee5e6b4b0d3255bfef95601890afd80709" path: "" config: {} analyzer: diff --git a/scanner/src/funTest/resources/scanner-integration-subset-pkgs-expected-ort-result.yml b/scanner/src/funTest/resources/scanner-integration-subset-pkgs-expected-ort-result.yml index 3ca86ec7cfbd8..051963d923741 100644 --- a/scanner/src/funTest/resources/scanner-integration-subset-pkgs-expected-ort-result.yml +++ b/scanner/src/funTest/resources/scanner-integration-subset-pkgs-expected-ort-result.yml @@ -3,12 +3,12 @@ repository: vcs: type: "" url: "" - revision: "" + revision: "da39a3ee5e6b4b0d3255bfef95601890afd80709" path: "" vcs_processed: type: "" url: "" - revision: "" + revision: "da39a3ee5e6b4b0d3255bfef95601890afd80709" path: "" config: {} analyzer: From 8237a1fe36ddcd0b45b2693641598bda959581ee Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Wed, 17 Sep 2025 16:43:37 +0200 Subject: [PATCH 06/12] fix(ScannerIntegrationFunTest): Change repo syntax in result files Signed-off-by: Jens Keim --- ...integration-all-pkgs-expected-ort-result.yml | 17 +++++++---------- ...egration-subset-pkgs-expected-ort-result.yml | 17 +++++++---------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/scanner/src/funTest/resources/scanner-integration-all-pkgs-expected-ort-result.yml b/scanner/src/funTest/resources/scanner-integration-all-pkgs-expected-ort-result.yml index c3bffc1b022c5..df5fa3508ebff 100644 --- a/scanner/src/funTest/resources/scanner-integration-all-pkgs-expected-ort-result.yml +++ b/scanner/src/funTest/resources/scanner-integration-all-pkgs-expected-ort-result.yml @@ -1,15 +1,12 @@ --- repository: - vcs: - type: "" - url: "" - revision: "da39a3ee5e6b4b0d3255bfef95601890afd80709" - path: "" - vcs_processed: - type: "" - url: "" - revision: "da39a3ee5e6b4b0d3255bfef95601890afd80709" - path: "" + provenance: + vcs_info: + type: "" + url: "" + revision: "" + path: "" + resolved_revision: "da39a3ee5e6b4b0d3255bfef95601890afd80709" config: {} analyzer: start_time: "1970-01-01T00:00:00Z" diff --git a/scanner/src/funTest/resources/scanner-integration-subset-pkgs-expected-ort-result.yml b/scanner/src/funTest/resources/scanner-integration-subset-pkgs-expected-ort-result.yml index 051963d923741..03dbd276fa8a6 100644 --- a/scanner/src/funTest/resources/scanner-integration-subset-pkgs-expected-ort-result.yml +++ b/scanner/src/funTest/resources/scanner-integration-subset-pkgs-expected-ort-result.yml @@ -1,15 +1,12 @@ --- repository: - vcs: - type: "" - url: "" - revision: "da39a3ee5e6b4b0d3255bfef95601890afd80709" - path: "" - vcs_processed: - type: "" - url: "" - revision: "da39a3ee5e6b4b0d3255bfef95601890afd80709" - path: "" + provenance: + vcs_info: + type: "" + url: "" + revision: "" + path: "" + resolved_revision: "da39a3ee5e6b4b0d3255bfef95601890afd80709" config: {} analyzer: start_time: "1970-01-01T00:00:00Z" From c4a330182d90452307e687fefe5b9ad2459139d9 Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Thu, 18 Sep 2025 13:34:52 +0200 Subject: [PATCH 07/12] fix(EvaluatedModelReporterFunTest): Update `evaluator-output` files Since these files are just parsed as plain text instead of deserialized into ORT data structures, updating them to the syntax appears to be the only way to fix the tests from here on out. Signed-off-by: Jens Keim --- ...orter-test-deduplicate-expected-output.yml | 17 +++++++---------- ...d-model-reporter-test-expected-output.json | 19 ++++++++----------- ...ed-model-reporter-test-expected-output.yml | 17 +++++++---------- 3 files changed, 22 insertions(+), 31 deletions(-) diff --git a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-deduplicate-expected-output.yml b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-deduplicate-expected-output.yml index 32f1672d38deb..aea00d9666992 100644 --- a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-deduplicate-expected-output.yml +++ b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-deduplicate-expected-output.yml @@ -1166,16 +1166,13 @@ statistics: MIT: 1 execution_duration_in_seconds: 3125 repository: - vcs: - type: "" - url: "" - revision: "" - path: "" - vcs_processed: - type: "Git" - url: "https://github.com/oss-review-toolkit/ort.git" - revision: "master" - path: "analyzer/src/funTest/assets/projects/synthetic/gradle/lib" + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "master" + path: "analyzer/src/funTest/assets/projects/synthetic/gradle/lib" + resolved_revision: "master" nested_repositories: sub/module: type: "Git" diff --git a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.json b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.json index 56e4e607635be..98cf9133f8757 100644 --- a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.json +++ b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.json @@ -1261,17 +1261,14 @@ "execution_duration_in_seconds" : 3125 }, "repository" : { - "vcs" : { - "type" : "", - "url" : "", - "revision" : "", - "path" : "" - }, - "vcs_processed" : { - "type" : "Git", - "url" : "https://github.com/oss-review-toolkit/ort.git", - "revision" : "master", - "path" : "analyzer/src/funTest/assets/projects/synthetic/gradle/lib" + "provenance" : { + "vcs_info" : { + "type" : "Git", + "url" : "https://github.com/oss-review-toolkit/ort.git", + "revision" : "master", + "path" : "analyzer/src/funTest/assets/projects/synthetic/gradle/lib" + }, + "resolved_revision" : "master" }, "nested_repositories" : { "sub/module" : { diff --git a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.yml b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.yml index 32f1672d38deb..aea00d9666992 100644 --- a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.yml +++ b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.yml @@ -1166,16 +1166,13 @@ statistics: MIT: 1 execution_duration_in_seconds: 3125 repository: - vcs: - type: "" - url: "" - revision: "" - path: "" - vcs_processed: - type: "Git" - url: "https://github.com/oss-review-toolkit/ort.git" - revision: "master" - path: "analyzer/src/funTest/assets/projects/synthetic/gradle/lib" + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "master" + path: "analyzer/src/funTest/assets/projects/synthetic/gradle/lib" + resolved_revision: "master" nested_repositories: sub/module: type: "Git" From 3a465cab8af22b521d8fd498cf7f21262864e323 Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Thu, 25 Sep 2025 12:01:54 +0200 Subject: [PATCH 08/12] fix(OrtResultTest): Avoid setting `resolvedRevision` after the fact Signed-off-by: Jens Keim --- model/src/test/kotlin/OrtResultTest.kt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/model/src/test/kotlin/OrtResultTest.kt b/model/src/test/kotlin/OrtResultTest.kt index d24a65c899d72..4331b7509573e 100644 --- a/model/src/test/kotlin/OrtResultTest.kt +++ b/model/src/test/kotlin/OrtResultTest.kt @@ -162,8 +162,12 @@ class OrtResultTest : WordSpec({ "getDefinitionFilePathRelativeToAnalyzerRoot()" should { "use the correct vcs" { - val vcs = VcsInfo(type = VcsType.GIT, url = "https://example.com/git", revision = "") - val provenance = RepositoryProvenance(vcsInfo = vcs, resolvedRevision = HashAlgorithm.SHA1.emptyValue) + val vcs = VcsInfo( + type = VcsType.GIT, + url = "https://example.com/git", + revision = HashAlgorithm.SHA1.emptyValue + ) + val provenance = RepositoryProvenance(vcsInfo = vcs, resolvedRevision = vcs.revision) val nestedVcs1 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git1", revision = "") val nestedVcs2 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git2", revision = "") val project1 = Project.EMPTY.copy( @@ -203,8 +207,12 @@ class OrtResultTest : WordSpec({ } "fail if no vcs matches" { - val vcs = VcsInfo(type = VcsType.GIT, url = "https://example.com/git", revision = "") - val provenance = RepositoryProvenance(vcsInfo = vcs, resolvedRevision = HashAlgorithm.SHA1.emptyValue) + val vcs = VcsInfo( + type = VcsType.GIT, + url = "https://example.com/git", + revision = HashAlgorithm.SHA1.emptyValue + ) + val provenance = RepositoryProvenance(vcsInfo = vcs, resolvedRevision = vcs.revision) val nestedVcs1 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git1", revision = "") val nestedVcs2 = VcsInfo(type = VcsType.GIT, url = "https://example.com/git2", revision = "") val project = Project.EMPTY.copy( From 9590fc0479f0148240a19a61e4374dfe8d2cd88e Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Thu, 25 Sep 2025 12:32:34 +0200 Subject: [PATCH 09/12] fix(KDoc): Reference `Repository.provenance` now `Repository.provenance.vcsInfo` would be even better, but KDoc appears to not be able to follow at this attribute depth. Signed-off-by: Jens Keim --- model/src/main/kotlin/Repository.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/model/src/main/kotlin/Repository.kt b/model/src/main/kotlin/Repository.kt index 5a23ea806ad2a..ae854691c5cee 100644 --- a/model/src/main/kotlin/Repository.kt +++ b/model/src/main/kotlin/Repository.kt @@ -68,8 +68,8 @@ data class Repository( } /** - * Return the path of [vcs] relative to [Repository.vcs], or null if [vcs] is neither [Repository.vcs] nor contained - * in [nestedRepositories]. + * Return the path of [vcs] relative to [Repository.provenance], or null if [vcs] is neither [Repository.provenance] + * nor contained in [nestedRepositories]. */ fun getRelativePath(vcs: VcsInfo): String? { fun VcsInfo.matches(other: VcsInfo) = type == other.type && url == other.url && revision == other.revision From b9c4e681b079f2a303390553e27434dcd7f5dae7 Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Thu, 25 Sep 2025 12:17:50 +0200 Subject: [PATCH 10/12] refactor(Analyzer): Always pass `vcs.normalize()` to `Repository` Signed-off-by: Jens Keim --- analyzer/src/main/kotlin/Analyzer.kt | 2 +- cli-helper/src/main/kotlin/utils/Extensions.kt | 2 +- evaluator/src/main/kotlin/ProjectSourceRule.kt | 2 +- evaluator/src/main/kotlin/RuleSet.kt | 2 +- model/src/main/kotlin/Repository.kt | 4 ++-- .../reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt | 4 ++-- .../static-html/src/main/kotlin/TablesReportModelMapper.kt | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/analyzer/src/main/kotlin/Analyzer.kt b/analyzer/src/main/kotlin/Analyzer.kt index a661eb10e7c9a..ef24cef685c1a 100644 --- a/analyzer/src/main/kotlin/Analyzer.kt +++ b/analyzer/src/main/kotlin/Analyzer.kt @@ -155,7 +155,7 @@ class Analyzer(private val config: AnalyzerConfiguration, private val labels: Ma } else { Repository( provenance = RepositoryProvenance( - vcsInfo = vcs, + vcsInfo = vcs.normalize(), resolvedRevision = vcs.revision ), nestedRepositories = nestedVcs, diff --git a/cli-helper/src/main/kotlin/utils/Extensions.kt b/cli-helper/src/main/kotlin/utils/Extensions.kt index 6d2be9c5b207c..118047e8866d9 100644 --- a/cli-helper/src/main/kotlin/utils/Extensions.kt +++ b/cli-helper/src/main/kotlin/utils/Extensions.kt @@ -716,7 +716,7 @@ internal fun OrtResult.getScanResultFor(packageConfiguration: PackageConfigurati * tree. */ internal fun OrtResult.getRepositoryPaths(): Map> { - val result = mutableMapOf(repository.provenance.vcsInfo.normalize().url to mutableSetOf("")) + val result = mutableMapOf(repository.provenance.vcsInfo.url to mutableSetOf("")) repository.nestedRepositories.mapValues { (path, vcsInfo) -> result.getOrPut(vcsInfo.url) { mutableSetOf() } += path diff --git a/evaluator/src/main/kotlin/ProjectSourceRule.kt b/evaluator/src/main/kotlin/ProjectSourceRule.kt index af503c45baa18..3989fbac7fa31 100644 --- a/evaluator/src/main/kotlin/ProjectSourceRule.kt +++ b/evaluator/src/main/kotlin/ProjectSourceRule.kt @@ -93,7 +93,7 @@ open class ProjectSourceRule( /** * Return the [VcsType] of the project's code repository. */ - fun projectSourceGetVcsType(): VcsType = ortResult.repository.provenance.vcsInfo.normalize().type + fun projectSourceGetVcsType(): VcsType = ortResult.repository.provenance.vcsInfo.type /** * Return the file paths matching any of the given [glob expressions][patterns] with its file content matching diff --git a/evaluator/src/main/kotlin/RuleSet.kt b/evaluator/src/main/kotlin/RuleSet.kt index fd9331f34de36..c34579a8d1dd0 100644 --- a/evaluator/src/main/kotlin/RuleSet.kt +++ b/evaluator/src/main/kotlin/RuleSet.kt @@ -159,7 +159,7 @@ fun ruleSet( licenseInfoResolver: LicenseInfoResolver = ortResult.createLicenseInfoResolver(), resolutionProvider: ResolutionProvider = DefaultResolutionProvider.create(), projectSourceResolver: SourceTreeResolver = SourceTreeResolver.forRemoteRepository( - ortResult.repository.provenance.vcsInfo.normalize() + ortResult.repository.provenance.vcsInfo ), configure: RuleSet.() -> Unit = {} ) = RuleSet(ortResult, licenseInfoResolver, resolutionProvider, projectSourceResolver).apply(configure) diff --git a/model/src/main/kotlin/Repository.kt b/model/src/main/kotlin/Repository.kt index ae854691c5cee..5c0c8315840b0 100644 --- a/model/src/main/kotlin/Repository.kt +++ b/model/src/main/kotlin/Repository.kt @@ -76,7 +76,7 @@ data class Repository( val normalizedVcs = vcs.normalize() - if (provenance.vcsInfo.normalize().matches(normalizedVcs)) return "" + if (provenance.vcsInfo.matches(normalizedVcs)) return "" return nestedRepositories.entries.find { (_, nestedVcs) -> nestedVcs.normalize().matches(normalizedVcs) }?.key } @@ -95,7 +95,7 @@ private class RepositoryDeserializer : StdDeserializer(Repository::c val vcsProcess = jsonMapper.treeToValue(node["vcs_processed"]) // Fall back to [vcsProcessed], if [vcs] is empty. - val vcsInfo = if (vcs != VcsInfo.EMPTY) vcs else vcsProcess + val vcsInfo = vcsProcess // Get the [vcs]'s revision. // Fall back to [vcsProcessed], if [vcs] has empty revision. diff --git a/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt b/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt index a068b4e35b251..477c7a895d476 100644 --- a/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt +++ b/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt @@ -154,7 +154,7 @@ class CycloneDxReporter( // There is no component type for repositories. type = Component.Type.FILE - with(input.ortResult.repository.provenance.vcsInfo.normalize()) { + with(input.ortResult.repository.provenance.vcsInfo) { bomRef = "$url@$revision" name = url @@ -178,7 +178,7 @@ class CycloneDxReporter( // distributable), just create a single BOM for all projects in that case for now. As there also is no // single correct project to pick for adding external references in that case, simply only use the global // repository VCS information here. - val vcs = input.ortResult.repository.provenance.vcsInfo.normalize() + val vcs = input.ortResult.repository.provenance.vcsInfo bom.addExternalReference( ExternalReference.Type.VCS, vcs.url, diff --git a/plugins/reporters/static-html/src/main/kotlin/TablesReportModelMapper.kt b/plugins/reporters/static-html/src/main/kotlin/TablesReportModelMapper.kt index b686ed3d23004..79b566085dae2 100644 --- a/plugins/reporters/static-html/src/main/kotlin/TablesReportModelMapper.kt +++ b/plugins/reporters/static-html/src/main/kotlin/TablesReportModelMapper.kt @@ -48,7 +48,7 @@ internal object TablesReportModelMapper { .sortedBy { it.id } return TablesReport( - input.ortResult.repository.provenance.vcsInfo.normalize(), + input.ortResult.repository.provenance.vcsInfo, input.ortResult.repository.config, ruleViolations, getAnalyzerIssueSummaryTable(input), From dc3e808ab45215dc274b5ca27d5c2ac1b2f1f9f7 Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Thu, 25 Sep 2025 13:31:05 +0200 Subject: [PATCH 11/12] fix(EvaluatedModelReporterFunTest): Set correct `resolved_revision` Signed-off-by: Jens Keim --- ...valuated-model-reporter-test-deduplicate-expected-output.yml | 2 +- .../evaluated-model-reporter-test-expected-output.json | 2 +- .../resources/evaluated-model-reporter-test-expected-output.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-deduplicate-expected-output.yml b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-deduplicate-expected-output.yml index aea00d9666992..4b912feb13324 100644 --- a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-deduplicate-expected-output.yml +++ b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-deduplicate-expected-output.yml @@ -1172,7 +1172,7 @@ repository: url: "https://github.com/oss-review-toolkit/ort.git" revision: "master" path: "analyzer/src/funTest/assets/projects/synthetic/gradle/lib" - resolved_revision: "master" + resolved_revision: "3dcca3e6ee0dea120922f90495bf04b4e09ae455" nested_repositories: sub/module: type: "Git" diff --git a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.json b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.json index 98cf9133f8757..5ae1c997bb667 100644 --- a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.json +++ b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.json @@ -1268,7 +1268,7 @@ "revision" : "master", "path" : "analyzer/src/funTest/assets/projects/synthetic/gradle/lib" }, - "resolved_revision" : "master" + "resolved_revision" : "3dcca3e6ee0dea120922f90495bf04b4e09ae455" }, "nested_repositories" : { "sub/module" : { diff --git a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.yml b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.yml index aea00d9666992..4b912feb13324 100644 --- a/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.yml +++ b/plugins/reporters/evaluated-model/src/funTest/resources/evaluated-model-reporter-test-expected-output.yml @@ -1172,7 +1172,7 @@ repository: url: "https://github.com/oss-review-toolkit/ort.git" revision: "master" path: "analyzer/src/funTest/assets/projects/synthetic/gradle/lib" - resolved_revision: "master" + resolved_revision: "3dcca3e6ee0dea120922f90495bf04b4e09ae455" nested_repositories: sub/module: type: "Git" From c45f7ba72e8caafdc3aaf376b7fcc8811e07d0e4 Mon Sep 17 00:00:00 2001 From: Jens Keim Date: Thu, 25 Sep 2025 13:30:56 +0200 Subject: [PATCH 12/12] fix(Analyzer): Populate `resolvedRevision` with `Worktree.getRevision()` Signed-off-by: Jens Keim --- analyzer/src/main/kotlin/Analyzer.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/analyzer/src/main/kotlin/Analyzer.kt b/analyzer/src/main/kotlin/Analyzer.kt index ef24cef685c1a..4fd01f7e0ad75 100644 --- a/analyzer/src/main/kotlin/Analyzer.kt +++ b/analyzer/src/main/kotlin/Analyzer.kt @@ -145,18 +145,19 @@ class Analyzer(private val config: AnalyzerConfiguration, private val labels: Ma val workingTree = VersionControlSystem.forDirectory(info.absoluteProjectPath) val vcs = workingTree?.getInfo().orEmpty() + val resolvedRevision = workingTree?.getRevision().orEmpty() val nestedVcs = workingTree?.getNested()?.filter { (path, _) -> // Only include nested VCS if they are part of the analyzed directory. workingTree.getRootPath().resolve(path).startsWith(info.absoluteProjectPath) }.orEmpty() - val repository = if (vcs == VcsInfo.EMPTY) { + val repository = if (vcs == VcsInfo.EMPTY || resolvedRevision.isEmpty()) { Repository.EMPTY } else { Repository( provenance = RepositoryProvenance( vcsInfo = vcs.normalize(), - resolvedRevision = vcs.revision + resolvedRevision = resolvedRevision ), nestedRepositories = nestedVcs, config = info.repositoryConfiguration