diff --git a/advisor/src/main/kotlin/Advisor.kt b/advisor/src/main/kotlin/Advisor.kt index d65541b104e42..c85aa0c5e6b6b 100644 --- a/advisor/src/main/kotlin/Advisor.kt +++ b/advisor/src/main/kotlin/Advisor.kt @@ -66,8 +66,16 @@ class Advisor( "Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms." } - requireNotNull(ortResult.analyzer) { - "The provided ORT result file '${ortFile.canonicalPath}' does not contain an analyzer result." + requireNotNull(ortResult) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + + if (ortResult.analyzer == null) { + log.warn { + "The provided ORT result file '${ortFile.canonicalPath}' does not contain an analyzer result." + } + + return ortResult } val providers = providerFactories.map { it.create(config) } diff --git a/advisor/src/test/kotlin/advisors/VulnerableCodeTest.kt b/advisor/src/test/kotlin/advisors/VulnerableCodeTest.kt index d6fd669fce2a0..393d005d69144 100644 --- a/advisor/src/test/kotlin/advisors/VulnerableCodeTest.kt +++ b/advisor/src/test/kotlin/advisors/VulnerableCodeTest.kt @@ -92,7 +92,8 @@ class VulnerableCodeTest : WordSpec({ stubVulnerability("v3", "CVE-2019-CoV19", 77.0f) val vulnerableCode = createVulnerableCode(wiremock) - val packagesToAdvise = resultFile().readValue().getPackages(false).map { it.pkg } + val ortResult = resultFile().readValue() + val packagesToAdvise = ortResult?.getPackages(false)?.map { it.pkg }.orEmpty() val result = vulnerableCode.retrievePackageVulnerabilities(packagesToAdvise).mapKeys { it.key.id } @@ -145,7 +146,8 @@ class VulnerableCodeTest : WordSpec({ ) val vulnerableCode = createVulnerableCode(wiremock) - val packagesToAdvise = resultFile().readValue().getPackages(false).map { it.pkg } + val ortResult = resultFile().readValue() + val packagesToAdvise = ortResult?.getPackages(false)?.map { it.pkg }.orEmpty() vulnerableCode.retrievePackageVulnerabilities(packagesToAdvise).mapKeys { it.key.id } shouldNotBeNull { val strutsResults = getValue(idStruts) @@ -235,7 +237,8 @@ private val vulnerabilityDetailsTemplate = File(TEST_FILES_ROOT).resolve(VULNERA */ private fun expectErrorResult(wiremock: WireMockServer) { val vulnerableCode = createVulnerableCode(wiremock) - val packagesToAdvise = resultFile().readValue().getPackages(false).map { it.pkg } + val ortResult = resultFile().readValue() + val packagesToAdvise = ortResult?.getPackages(false)?.map { it.pkg }.orEmpty() val result = runBlocking { vulnerableCode.retrievePackageVulnerabilities(packagesToAdvise).mapKeys { it.key.id } diff --git a/analyzer/src/main/kotlin/Analyzer.kt b/analyzer/src/main/kotlin/Analyzer.kt index 675746fde7d2f..0655d2fd60ecd 100644 --- a/analyzer/src/main/kotlin/Analyzer.kt +++ b/analyzer/src/main/kotlin/Analyzer.kt @@ -60,7 +60,7 @@ class Analyzer(private val config: AnalyzerConfiguration) { val repositoryConfiguration = if (actualRepositoryConfigurationFile.isFile) { log.info { "Using configuration file '${actualRepositoryConfigurationFile.absolutePath}'." } - actualRepositoryConfigurationFile.readValue() + actualRepositoryConfigurationFile.readValue() ?: RepositoryConfiguration() } else { RepositoryConfiguration() } diff --git a/analyzer/src/main/kotlin/curation/FilePackageCurationProvider.kt b/analyzer/src/main/kotlin/curation/FilePackageCurationProvider.kt index 31413d541b8cc..4ab1a8e28b802 100644 --- a/analyzer/src/main/kotlin/curation/FilePackageCurationProvider.kt +++ b/analyzer/src/main/kotlin/curation/FilePackageCurationProvider.kt @@ -33,7 +33,7 @@ import org.ossreviewtoolkit.model.readValue */ class FilePackageCurationProvider(curationFile: File) : PackageCurationProvider { internal val packageCurations: List by lazy { - curationFile.readValue>() + curationFile.readValue>().orEmpty() } override fun getCurationsFor(pkgId: Identifier) = packageCurations.filter { it.isApplicable(pkgId) } diff --git a/analyzer/src/main/kotlin/managers/Npm.kt b/analyzer/src/main/kotlin/managers/Npm.kt index 93869123d50de..df8a9f4fa267c 100644 --- a/analyzer/src/main/kotlin/managers/Npm.kt +++ b/analyzer/src/main/kotlin/managers/Npm.kt @@ -226,7 +226,7 @@ open class Npm( log.debug { "Found a 'package.json' file in '$packageDir'." } - val json = it.readValue() + val json = it.readValue() ?: return@forEach val rawName = json["name"].textValue() val (namespace, name) = splitNamespaceAndName(rawName) val version = json["version"].textValue() diff --git a/analyzer/src/main/kotlin/managers/utils/NodeSupport.kt b/analyzer/src/main/kotlin/managers/utils/NodeSupport.kt index 58303b52b2211..a9b1e628842b6 100644 --- a/analyzer/src/main/kotlin/managers/utils/NodeSupport.kt +++ b/analyzer/src/main/kotlin/managers/utils/NodeSupport.kt @@ -23,13 +23,12 @@ package org.ossreviewtoolkit.analyzer.managers.utils import com.fasterxml.jackson.core.JsonProcessingException import com.fasterxml.jackson.databind.node.ArrayNode -import com.fasterxml.jackson.databind.node.ObjectNode import java.io.File import java.nio.file.FileSystems import java.nio.file.PathMatcher -import org.ossreviewtoolkit.model.readValue +import org.ossreviewtoolkit.model.readJsonFile import org.ossreviewtoolkit.utils.AuthenticatedProxy import org.ossreviewtoolkit.utils.ProtocolProxyMap import org.ossreviewtoolkit.utils.collectMessagesAsString @@ -176,7 +175,7 @@ private fun getPackageJsonInfo(definitionFiles: Set): Collection()["workspaces"] != null + readJsonFile(definitionFile).has("workspaces") } catch (e: JsonProcessingException) { e.showStackTrace() @@ -211,7 +210,7 @@ private fun getYarnWorkspaceSubmodules(definitionFiles: Set): Set { private fun getWorkspaceMatchers(definitionFile: File): List { var workspaces = try { - definitionFile.readValue()["workspaces"] + readJsonFile(definitionFile).get("workspaces") } catch (e: JsonProcessingException) { e.showStackTrace() diff --git a/cli/src/funTest/kotlin/ExamplesFunTest.kt b/cli/src/funTest/kotlin/ExamplesFunTest.kt index 14cae6770116e..18de6e1410a35 100644 --- a/cli/src/funTest/kotlin/ExamplesFunTest.kt +++ b/cli/src/funTest/kotlin/ExamplesFunTest.kt @@ -93,8 +93,8 @@ class ExamplesFunTest : StringSpec() { "license-classifications.yml can be deserialized" { shouldNotThrow { - val classifications = - takeExampleFile("license-classifications.yml").readValue() + val classifications = takeExampleFile("license-classifications.yml").readValue() + ?: LicenseClassifications() classifications.categories.filter { it.description.isNotEmpty() } shouldNot beEmpty() classifications.categoryNames shouldContain "public-domain" @@ -130,19 +130,21 @@ class ExamplesFunTest : StringSpec() { val resultFile = File("src/funTest/assets/semver4j-analyzer-result.yml") val licenseFile = File("../examples/license-classifications.yml") val ortResult = resultFile.readValue() - val evaluator = Evaluator( - ortResult = ortResult, - licenseInfoResolver = ortResult.createLicenseInfoResolver(), - licenseClassifications = licenseFile.readValue() - ) - val script = takeExampleFile("rules.kts").readText() + ortResult shouldNotBeNull { + val evaluator = Evaluator( + ortResult = this, + licenseInfoResolver = createLicenseInfoResolver(), + licenseClassifications = licenseFile.readValue() ?: LicenseClassifications() + ) - val result = evaluator.run(script) + val script = takeExampleFile("rules.kts").readText() + val result = evaluator.run(script) - result.violations shouldHaveSize 2 - val failedRules = result.violations.map { it.rule } - failedRules shouldContainExactlyInAnyOrder listOf("UNHANDLED_LICENSE", "COPYLEFT_LIMITED_IN_SOURCE") + result.violations shouldHaveSize 2 + val failedRules = result.violations.map { it.rule } + failedRules shouldContainExactlyInAnyOrder listOf("UNHANDLED_LICENSE", "COPYLEFT_LIMITED_IN_SOURCE") + } } "asciidoctor-pdf-theme.yml is a valid asciidoctor-pdf theme" { diff --git a/cli/src/main/kotlin/commands/DownloaderCommand.kt b/cli/src/main/kotlin/commands/DownloaderCommand.kt index 0a7f5f9f9b66c..e9f483b7b8cf5 100644 --- a/cli/src/main/kotlin/commands/DownloaderCommand.kt +++ b/cli/src/main/kotlin/commands/DownloaderCommand.kt @@ -180,15 +180,25 @@ class DownloaderCommand : CliktCommand(name = "download", help = "Fetch source c when (input) { is FileType -> { val ortFile = (input as FileType).file - val (analyzerResult, duration) = measureTimedValue { ortFile.readValue().analyzer?.result } + val (ortResult, duration) = measureTimedValue { ortFile.readValue() } log.perf { "Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in " + "${duration.inMilliseconds}ms." } - requireNotNull(analyzerResult) { - "The provided ORT result file '${ortFile.canonicalPath}' does not contain an analyzer result." + requireNotNull(ortResult) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + + val analyzerResult = ortResult.analyzer?.result + + if (analyzerResult == null) { + log.warn { + "The provided ORT result file '${ortFile.canonicalPath}' does not contain an analyzer result." + } + + throw ProgramResult(0) } val packages = mutableListOf().apply { diff --git a/cli/src/main/kotlin/commands/EvaluatorCommand.kt b/cli/src/main/kotlin/commands/EvaluatorCommand.kt index 04fc7c9132ad3..41c784522f9f2 100644 --- a/cli/src/main/kotlin/commands/EvaluatorCommand.kt +++ b/cli/src/main/kotlin/commands/EvaluatorCommand.kt @@ -45,9 +45,11 @@ import org.ossreviewtoolkit.GroupTypes.StringType import org.ossreviewtoolkit.evaluator.Evaluator import org.ossreviewtoolkit.model.FileFormat import org.ossreviewtoolkit.model.OrtResult +import org.ossreviewtoolkit.model.PackageCuration import org.ossreviewtoolkit.model.Severity import org.ossreviewtoolkit.model.config.CopyrightGarbage import org.ossreviewtoolkit.model.config.LicenseFilenamePatterns +import org.ossreviewtoolkit.model.config.RepositoryConfiguration import org.ossreviewtoolkit.model.config.createFileArchiver import org.ossreviewtoolkit.model.config.orEmpty import org.ossreviewtoolkit.model.licenses.DefaultLicenseInfoProvider @@ -239,12 +241,12 @@ class EvaluatorCommand : CliktCommand(name = "evaluate", help = "Evaluate ORT re } } - repositoryConfigurationFile?.let { - ortResultInput = ortResultInput?.replaceConfig(it.readValue()) + repositoryConfigurationFile?.readValue()?.let { + ortResultInput = ortResultInput?.replaceConfig(it) } - packageCurationsFile?.let { - ortResultInput = ortResultInput?.replacePackageCurations(it.readValue()) + packageCurationsFile?.readValue>()?.let { + ortResultInput = ortResultInput?.replacePackageCurations(it) } val finalOrtResult = requireNotNull(ortResultInput) { diff --git a/cli/src/main/kotlin/commands/ReporterCommand.kt b/cli/src/main/kotlin/commands/ReporterCommand.kt index 16ee758347596..6767e69b90169 100644 --- a/cli/src/main/kotlin/commands/ReporterCommand.kt +++ b/cli/src/main/kotlin/commands/ReporterCommand.kt @@ -45,6 +45,7 @@ import org.ossreviewtoolkit.GlobalOptions import org.ossreviewtoolkit.model.OrtResult import org.ossreviewtoolkit.model.config.CopyrightGarbage import org.ossreviewtoolkit.model.config.LicenseFilenamePatterns +import org.ossreviewtoolkit.model.config.RepositoryConfiguration import org.ossreviewtoolkit.model.config.Resolutions import org.ossreviewtoolkit.model.config.createFileArchiver import org.ossreviewtoolkit.model.config.orEmpty @@ -200,14 +201,18 @@ class ReporterCommand : CliktCommand( private val globalOptionsForSubcommands by requireObject() override fun run() { - var (ortResult, duration) = measureTimedValue { ortFile.readValue() } + var (originalOrtResult, duration) = measureTimedValue { ortFile.readValue() } log.perf { "Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms." } - repositoryConfigurationFile?.let { - ortResult = ortResult.replaceConfig(it.readValue()) + repositoryConfigurationFile?.readValue()?.let { + originalOrtResult = originalOrtResult?.replaceConfig(it) + } + + val ortResult = requireNotNull(originalOrtResult) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." } val resolutionProvider = DefaultResolutionProvider() diff --git a/cli/src/main/kotlin/commands/UploadCurationsCommand.kt b/cli/src/main/kotlin/commands/UploadCurationsCommand.kt index 4e388a2a94e54..bfc4c31d29413 100644 --- a/cli/src/main/kotlin/commands/UploadCurationsCommand.kt +++ b/cli/src/main/kotlin/commands/UploadCurationsCommand.kt @@ -95,7 +95,7 @@ class UploadCurationsCommand : CliktCommand( } override fun run() { - val curations = inputFile.readValue>() + val curations = inputFile.readValue>().orEmpty() val curationsToCoordinates = curations.associateWith { it.id.toClearlyDefinedCoordinates().toString() } val definitions = service.call { getDefinitions(curationsToCoordinates.values) } diff --git a/cli/src/main/kotlin/commands/UploadResultToPostgresCommand.kt b/cli/src/main/kotlin/commands/UploadResultToPostgresCommand.kt index c733e0286b500..9b2043d0da7e8 100644 --- a/cli/src/main/kotlin/commands/UploadResultToPostgresCommand.kt +++ b/cli/src/main/kotlin/commands/UploadResultToPostgresCommand.kt @@ -93,6 +93,10 @@ class UploadResultToPostgresCommand : CliktCommand( "Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms." } + requireNotNull(ortResult) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + val postgresConfig = globalOptionsForSubcommands.config.scanner.storages?.values ?.filterIsInstance()?.singleOrNull() diff --git a/cli/src/main/kotlin/commands/UploadResultToSw360Command.kt b/cli/src/main/kotlin/commands/UploadResultToSw360Command.kt index dc7b7040420f8..d7f13f1cc6dac 100644 --- a/cli/src/main/kotlin/commands/UploadResultToSw360Command.kt +++ b/cli/src/main/kotlin/commands/UploadResultToSw360Command.kt @@ -82,6 +82,10 @@ class UploadResultToSw360Command : CliktCommand( "Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms." } + requireNotNull(ortResult) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + val sw360Config = globalOptionsForSubcommands.config.scanner.storages?.values ?.filterIsInstance()?.singleOrNull() diff --git a/helper-cli/src/main/kotlin/commands/ExportLicenseFindingCurationsCommand.kt b/helper-cli/src/main/kotlin/commands/ExportLicenseFindingCurationsCommand.kt index c14972334a342..277c80348c9ee 100644 --- a/helper-cli/src/main/kotlin/commands/ExportLicenseFindingCurationsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ExportLicenseFindingCurationsCommand.kt @@ -71,16 +71,16 @@ internal class ExportLicenseFindingCurationsCommand : CliktCommand( ).flag() override fun run() { - val localLicenseFindingCurations = ortFile - .readValue() + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + + val localLicenseFindingCurations = ortResult .replaceConfig(repositoryConfigurationFile) .getRepositoryLicenseFindingCurations() - val globalLicenseFindingCurations = if (licenseFindingCurationsFile.isFile) { - licenseFindingCurationsFile.readValue() - } else { - mapOf() - } + val globalLicenseFindingCurations = licenseFindingCurationsFile.takeIf { it.isFile } + ?.readValue().orEmpty() globalLicenseFindingCurations .mergeLicenseFindingCurations(localLicenseFindingCurations, updateOnlyExisting = updateOnlyExisting) diff --git a/helper-cli/src/main/kotlin/commands/ExportPathExcludesCommand.kt b/helper-cli/src/main/kotlin/commands/ExportPathExcludesCommand.kt index 2e0ba771741e4..c71cd4d591f50 100644 --- a/helper-cli/src/main/kotlin/commands/ExportPathExcludesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ExportPathExcludesCommand.kt @@ -71,16 +71,15 @@ internal class ExportPathExcludesCommand : CliktCommand( ).flag() override fun run() { - val localPathExcludes = ortFile - .readValue() + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + + val localPathExcludes = ortResult .replaceConfig(repositoryConfigurationFile) .getRepositoryPathExcludes() - val globalPathExcludes = if (pathExcludesFile.isFile) { - pathExcludesFile.readValue() - } else { - mapOf() - } + val globalPathExcludes = pathExcludesFile.takeIf { it.isFile }?.readValue().orEmpty() globalPathExcludes .mergePathExcludes(localPathExcludes, updateOnlyExisting = updateOnlyExisting) diff --git a/helper-cli/src/main/kotlin/commands/ExtractRepositoryConfigurationCommand.kt b/helper-cli/src/main/kotlin/commands/ExtractRepositoryConfigurationCommand.kt index 7263fda67e07a..52f239b021f10 100644 --- a/helper-cli/src/main/kotlin/commands/ExtractRepositoryConfigurationCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ExtractRepositoryConfigurationCommand.kt @@ -50,9 +50,10 @@ class ExtractRepositoryConfigurationCommand : CliktCommand( .required() override fun run() { - ortFile - .readValue() - .repository - .config.writeAsYaml(repositoryConfigurationFile) + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + + ortResult.repository.config.writeAsYaml(repositoryConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/commands/FormatRepositoryConfigurationCommand.kt b/helper-cli/src/main/kotlin/commands/FormatRepositoryConfigurationCommand.kt index b47fa1b638f4e..42baa04e81438 100644 --- a/helper-cli/src/main/kotlin/commands/FormatRepositoryConfigurationCommand.kt +++ b/helper-cli/src/main/kotlin/commands/FormatRepositoryConfigurationCommand.kt @@ -41,8 +41,10 @@ internal class FormatRepositoryConfigurationCommand : CliktCommand( .convert { it.absoluteFile.normalize() } override fun run() { - repositoryConfigurationFile - .readValue() - .writeAsYaml(repositoryConfigurationFile) + val repoConfig = requireNotNull(repositoryConfigurationFile.readValue()) { + "The provided ORT result file '${repositoryConfigurationFile.canonicalPath}' has no content." + } + + repoConfig.writeAsYaml(repositoryConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/commands/GenerateProjectExcludesCommand.kt b/helper-cli/src/main/kotlin/commands/GenerateProjectExcludesCommand.kt index 3d7613f3ff652..a8bb2c02b08d3 100644 --- a/helper-cli/src/main/kotlin/commands/GenerateProjectExcludesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/GenerateProjectExcludesCommand.kt @@ -57,14 +57,12 @@ internal class GenerateProjectExcludesCommand : CliktCommand( .required() override fun run() { - val repositoryConfiguration = if (repositoryConfigurationFile.isFile) { - repositoryConfigurationFile.readValue() - } else { - RepositoryConfiguration() - } + val repositoryConfiguration = repositoryConfigurationFile.takeIf { it.isFile }?.readValue() + ?: RepositoryConfiguration() - val ortResult = ortFile.readValue() - .replaceConfig(repositoryConfiguration) + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + }.replaceConfig(repositoryConfiguration) val generatedPathExcludes = ortResult .getProjects() diff --git a/helper-cli/src/main/kotlin/commands/GenerateRuleViolationResolutionsCommand.kt b/helper-cli/src/main/kotlin/commands/GenerateRuleViolationResolutionsCommand.kt index 6fb6f7509a551..c30ae04a19041 100644 --- a/helper-cli/src/main/kotlin/commands/GenerateRuleViolationResolutionsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/GenerateRuleViolationResolutionsCommand.kt @@ -66,8 +66,11 @@ internal class GenerateRuleViolationResolutionsCommand : CliktCommand( ).enum().split(",").default(enumValues().asList()) override fun run() { - val repositoryConfiguration = repositoryConfigurationFile.readValue() - val ortResult = ortFile.readValue().replaceConfig(repositoryConfiguration) + val repositoryConfiguration = repositoryConfigurationFile.readValue() ?: RepositoryConfiguration() + + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + }.replaceConfig(repositoryConfiguration) val generatedResolutions = ortResult .getUnresolvedRuleViolations() diff --git a/helper-cli/src/main/kotlin/commands/GenerateScopeExcludesCommand.kt b/helper-cli/src/main/kotlin/commands/GenerateScopeExcludesCommand.kt index 07cf02330598b..ad06746d3afb7 100644 --- a/helper-cli/src/main/kotlin/commands/GenerateScopeExcludesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/GenerateScopeExcludesCommand.kt @@ -57,14 +57,17 @@ internal class GenerateScopeExcludesCommand : CliktCommand( .required() override fun run() { - val ortResult = ortFile.readValue() + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + val scopeExcludes = ortResult.generateScopeExcludes() - repositoryConfigurationFile - .readValue() - .replaceScopeExcludes(scopeExcludes) - .sortScopeExcludes() - .writeAsYaml(repositoryConfigurationFile) + val repoConfig = requireNotNull(repositoryConfigurationFile.readValue()) { + "The provided ORT result file '${repositoryConfigurationFile.canonicalPath}' has no content." + } + + repoConfig.replaceScopeExcludes(scopeExcludes).sortScopeExcludes().writeAsYaml(repositoryConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/commands/GenerateTimeoutErrorResolutionsCommand.kt b/helper-cli/src/main/kotlin/commands/GenerateTimeoutErrorResolutionsCommand.kt index 9325d905ae4c5..48191fc5ee396 100644 --- a/helper-cli/src/main/kotlin/commands/GenerateTimeoutErrorResolutionsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/GenerateTimeoutErrorResolutionsCommand.kt @@ -68,13 +68,15 @@ internal class GenerateTimeoutErrorResolutionsCommand : CliktCommand( ).flag() override fun run() { - val ortResult = ortFile.readValue().replaceConfig(repositoryConfigurationFile) + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + }.replaceConfig(repositoryConfigurationFile) val resolutionProvider = DefaultResolutionProvider().apply { var resolutions = Resolutions() - resolutionsFile?.let { - resolutions = resolutions.merge(it.readValue()) + resolutionsFile?.readValue()?.let { + resolutions = resolutions.merge(it) } resolutions = resolutions.merge(ortResult.getResolutions()) diff --git a/helper-cli/src/main/kotlin/commands/ImportCopyrightGarbageCommand.kt b/helper-cli/src/main/kotlin/commands/ImportCopyrightGarbageCommand.kt index 68a17e0a195f5..3076084cc54db 100644 --- a/helper-cli/src/main/kotlin/commands/ImportCopyrightGarbageCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ImportCopyrightGarbageCommand.kt @@ -59,11 +59,8 @@ internal class ImportCopyrightGarbageCommand : CliktCommand( override fun run() { val entriesToImport = inputCopyrightGarbageFile.readLines().filterNot { it.isBlank() } - val existingCopyrightGarbage = if (outputCopyrightGarbageFile.isFile) { - outputCopyrightGarbageFile.readValue().items - } else { - emptySet() - } + val existingCopyrightGarbage = outputCopyrightGarbageFile.takeIf { it.isFile } + ?.readValue()?.items.orEmpty() val collator = Collator.getInstance(Locale("en", "US.utf-8", "POSIX")) CopyrightGarbage((entriesToImport + existingCopyrightGarbage).toSortedSet(collator)).let { diff --git a/helper-cli/src/main/kotlin/commands/ImportLicenseFindingCurationsCommand.kt b/helper-cli/src/main/kotlin/commands/ImportLicenseFindingCurationsCommand.kt index f20a254200249..bd1ec5ba8b153 100644 --- a/helper-cli/src/main/kotlin/commands/ImportLicenseFindingCurationsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ImportLicenseFindingCurationsCommand.kt @@ -76,13 +76,13 @@ internal class ImportLicenseFindingCurationsCommand : CliktCommand( private val findingCurationMatcher = FindingCurationMatcher() override fun run() { - val ortResult = ortFile.readValue() - val repositoryConfiguration = if (repositoryConfigurationFile.isFile) { - repositoryConfigurationFile.readValue() - } else { - RepositoryConfiguration() + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." } + val repositoryConfiguration = repositoryConfigurationFile.takeIf { it.isFile }?.readValue() + ?: RepositoryConfiguration() + val allLicenseFindings = ortResult.getLicenseFindingsForAllProjects() val importedCurations = importLicenseFindingCurations(ortResult) @@ -102,12 +102,12 @@ internal class ImportLicenseFindingCurationsCommand : CliktCommand( private fun importLicenseFindingCurations(ortResult: OrtResult): Set { val repositoryPaths = ortResult.getRepositoryPaths() - val licenseFindingCurations = licenseFindingCurationsFile.readValue() + val curations = licenseFindingCurationsFile.readValue().orEmpty() val result = mutableSetOf() repositoryPaths.forEach { (vcsUrl, relativePaths) -> - licenseFindingCurations[vcsUrl]?.let { curationsForRepository -> + curations[vcsUrl]?.let { curationsForRepository -> curationsForRepository.forEach { curation -> relativePaths.forEach { path -> result += curation.copy(path = path + '/' + curation.path) diff --git a/helper-cli/src/main/kotlin/commands/ImportPathExcludesCommand.kt b/helper-cli/src/main/kotlin/commands/ImportPathExcludesCommand.kt index 55310090acfb6..c1e72c5a2e739 100644 --- a/helper-cli/src/main/kotlin/commands/ImportPathExcludesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ImportPathExcludesCommand.kt @@ -72,11 +72,8 @@ internal class ImportPathExcludesCommand : CliktCommand( override fun run() { val allFiles = findFilesRecursive(sourceCodeDir) - val repositoryConfiguration = if (repositoryConfigurationFile.isFile) { - repositoryConfigurationFile.readValue() - } else { - RepositoryConfiguration() - } + val repositoryConfiguration = repositoryConfigurationFile.takeIf { it.isFile }?.readValue() + ?: RepositoryConfiguration() val existingPathExcludes = repositoryConfiguration.excludes.paths val importedPathExcludes = importPathExcludes(sourceCodeDir, pathExcludesFile).filter { pathExclude -> diff --git a/helper-cli/src/main/kotlin/commands/ImportScanResultsCommand.kt b/helper-cli/src/main/kotlin/commands/ImportScanResultsCommand.kt index 1950d09481f9e..e7dd513e476aa 100644 --- a/helper-cli/src/main/kotlin/commands/ImportScanResultsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ImportScanResultsCommand.kt @@ -51,7 +51,10 @@ internal class ImportScanResultsCommand : CliktCommand( .required() override fun run() { - val ortResult = ortFile.readValue() + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + val scanResultsStorage = FileBasedStorage(LocalFileStorage(scanResultsStorageDir)) val ids = ortResult.getProjects().map { it.id } + ortResult.getPackages().map { it.pkg.id } diff --git a/helper-cli/src/main/kotlin/commands/ListCopyrightsCommand.kt b/helper-cli/src/main/kotlin/commands/ListCopyrightsCommand.kt index 0f82ace73e8f1..8af1f4054999c 100644 --- a/helper-cli/src/main/kotlin/commands/ListCopyrightsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ListCopyrightsCommand.kt @@ -88,7 +88,10 @@ internal class ListCopyrightsCommand : CliktCommand( ).single() override fun run() { - val ortResult = ortFile.readValue() + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + val copyrightGarbage = copyrightGarbageFile?.readValue().orEmpty() val packageConfigurationProvider = packageConfigurationOption.createProvider() diff --git a/helper-cli/src/main/kotlin/commands/ListLicenseCategoriesCommand.kt b/helper-cli/src/main/kotlin/commands/ListLicenseCategoriesCommand.kt index cfe3446abd558..831315fb39e32 100644 --- a/helper-cli/src/main/kotlin/commands/ListLicenseCategoriesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ListLicenseCategoriesCommand.kt @@ -48,7 +48,7 @@ class ListLicenseCategoriesCommand : CliktCommand( ).flag() override fun run() { - val licenseClassifications = licenseClassificationsFile.readValue() + val licenseClassifications = licenseClassificationsFile.readValue() ?: LicenseClassifications() println(licenseClassifications.summary()) diff --git a/helper-cli/src/main/kotlin/commands/ListLicensesCommand.kt b/helper-cli/src/main/kotlin/commands/ListLicensesCommand.kt index 46601cfb77535..277a918132287 100644 --- a/helper-cli/src/main/kotlin/commands/ListLicensesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ListLicensesCommand.kt @@ -155,7 +155,9 @@ internal class ListLicensesCommand : CliktCommand( }.default(emptyList()) override fun run() { - val ortResult = ortFile.readValue().replaceConfig(repositoryConfigurationFile) + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + }.replaceConfig(repositoryConfigurationFile) if (ortResult.getPackageOrProject(packageId) == null) { throw UsageError("Could not find the package for the given id '${packageId.toCoordinates()}'.") diff --git a/helper-cli/src/main/kotlin/commands/ListPackagesCommand.kt b/helper-cli/src/main/kotlin/commands/ListPackagesCommand.kt index 68ebd0a0e252c..8be506ddb4541 100644 --- a/helper-cli/src/main/kotlin/commands/ListPackagesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ListPackagesCommand.kt @@ -51,7 +51,9 @@ class ListPackagesCommand : CliktCommand( ).split(",").default(emptyList()) override fun run() { - val ortResult = ortFile.readValue() + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } val licenseInfoResolver = ortResult.createLicenseInfoResolver() diff --git a/helper-cli/src/main/kotlin/commands/MapCopyrightsCommand.kt b/helper-cli/src/main/kotlin/commands/MapCopyrightsCommand.kt index f8c5427700fbe..155e8f3f50a01 100644 --- a/helper-cli/src/main/kotlin/commands/MapCopyrightsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/MapCopyrightsCommand.kt @@ -61,9 +61,11 @@ internal class MapCopyrightsCommand : CliktCommand( override fun run() { val processedCopyrightStatements = inputCopyrightGarbageFile.readLines().filterNot { it.isBlank() } - val unprocessedCopyrightStatements = ortFile - .readValue() - .getUnprocessedCopyrightStatements(processedCopyrightStatements) + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + + val unprocessedCopyrightStatements = ortResult.getUnprocessedCopyrightStatements(processedCopyrightStatements) outputCopyrightsFile.writeText(unprocessedCopyrightStatements.joinToString(separator = "\n")) } diff --git a/helper-cli/src/main/kotlin/commands/MergeRepositoryConfigurationsCommand.kt b/helper-cli/src/main/kotlin/commands/MergeRepositoryConfigurationsCommand.kt index b190b800a5486..c4527b64ec7cf 100644 --- a/helper-cli/src/main/kotlin/commands/MergeRepositoryConfigurationsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/MergeRepositoryConfigurationsCommand.kt @@ -55,7 +55,7 @@ internal class MergeRepositoryConfigurationsCommand : CliktCommand( var result = RepositoryConfiguration() inputRepositoryConfigurationFiles.forEach { file -> - val repositoryConfiguration = file.readValue() + val repositoryConfiguration = file.readValue() ?: RepositoryConfiguration() result = result.merge(repositoryConfiguration) } diff --git a/helper-cli/src/main/kotlin/commands/RemoveConfigurationEntriesCommand.kt b/helper-cli/src/main/kotlin/commands/RemoveConfigurationEntriesCommand.kt index f93c4c33ae2b9..fd741f74b3aca 100644 --- a/helper-cli/src/main/kotlin/commands/RemoveConfigurationEntriesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/RemoveConfigurationEntriesCommand.kt @@ -78,8 +78,11 @@ internal class RemoveConfigurationEntriesCommand : CliktCommand( .convert { it.absoluteFile.normalize() } override fun run() { - val repositoryConfiguration = repositoryConfigurationFile.readValue() - val ortResult = ortFile.readValue().replaceConfig(repositoryConfiguration) + val repositoryConfiguration = repositoryConfigurationFile.readValue() ?: RepositoryConfiguration() + + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + }.replaceConfig(repositoryConfiguration) val pathExcludes = findFilesRecursive(sourceCodeDir).let { allFiles -> ortResult.getExcludes().paths.filter { pathExclude -> diff --git a/helper-cli/src/main/kotlin/commands/SortRepositoryConfigurationCommand.kt b/helper-cli/src/main/kotlin/commands/SortRepositoryConfigurationCommand.kt index 3080199319d8f..ac28580690317 100644 --- a/helper-cli/src/main/kotlin/commands/SortRepositoryConfigurationCommand.kt +++ b/helper-cli/src/main/kotlin/commands/SortRepositoryConfigurationCommand.kt @@ -42,9 +42,7 @@ internal class SortRepositoryConfigurationCommand : CliktCommand( .convert { it.absoluteFile.normalize() } override fun run() { - repositoryConfigurationFile - .readValue() - .sortEntries() - .writeAsYaml(repositoryConfigurationFile) + repositoryConfigurationFile.readValue() + ?.sortEntries()?.writeAsYaml(repositoryConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/commands/SubtractScanResultsCommand.kt b/helper-cli/src/main/kotlin/commands/SubtractScanResultsCommand.kt index 39f3b1b87400f..8c441bfa86f33 100644 --- a/helper-cli/src/main/kotlin/commands/SubtractScanResultsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/SubtractScanResultsCommand.kt @@ -64,15 +64,28 @@ internal class SubtractScanResultsCommand : CliktCommand( .required() override fun run() { - val lhsOrtResult = lhsOrtFile.readValue() - val rhsOrtResult = rhsOrtFile.readValue() + val lhsOrtResult = requireNotNull(lhsOrtFile.readValue()) { + "The provided ORT result file '${lhsOrtFile.canonicalPath}' has no content." + } + + val lhsScannerRun = requireNotNull(lhsOrtResult.scanner) { + "The ORT result file '${lhsOrtFile.canonicalPath}' does not contain a scanner run." + } + + val rhsOrtResult = requireNotNull(rhsOrtFile.readValue()) { + "The provided ORT result file '${rhsOrtFile.canonicalPath}' has no content." + } + + val rhsScannerRun = requireNotNull(rhsOrtResult.scanner) { + "The ORT result file '${rhsOrtFile.canonicalPath}' does not contain a scanner run." + } - val rhsScanSummaries = rhsOrtResult.scanner!!.results.scanResults.flatMap { it.value }.associateBy( + val rhsScanSummaries = rhsScannerRun.results.scanResults.flatMap { it.value }.associateBy( keySelector = { it.provenance.key() }, valueTransform = { it.summary } ) - val scanResults = lhsOrtResult.scanner!!.results.scanResults.mapValuesTo(sortedMapOf()) { (_, results) -> + val scanResults = lhsScannerRun.results.scanResults.mapValuesTo(sortedMapOf()) { (_, results) -> results.map { lhsScanResult -> val lhsSummary = lhsScanResult.summary val rhsSummary = rhsScanSummaries[lhsScanResult.provenance.key()] @@ -82,8 +95,8 @@ internal class SubtractScanResultsCommand : CliktCommand( } val result = lhsOrtResult.copy( - scanner = lhsOrtResult.scanner!!.copy( - results = lhsOrtResult.scanner!!.results.copy( + scanner = lhsScannerRun.copy( + results = lhsScannerRun.results.copy( scanResults = scanResults ) ) diff --git a/helper-cli/src/main/kotlin/commands/VerifySourceArtifactCurationsCommand.kt b/helper-cli/src/main/kotlin/commands/VerifySourceArtifactCurationsCommand.kt index b004ac1cf2b90..217aecf89623e 100644 --- a/helper-cli/src/main/kotlin/commands/VerifySourceArtifactCurationsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/VerifySourceArtifactCurationsCommand.kt @@ -44,7 +44,7 @@ internal class VerifySourceArtifactCurationsCommand : CliktCommand( .convert { it.absoluteFile.normalize() } override fun run() { - val curations = packageCurationsFile.readValue>() + val curations = packageCurationsFile.readValue>().orEmpty() val failed = curations.filterNot { curation -> curation.data.sourceArtifact?.let { sourceArtifact -> diff --git a/helper-cli/src/main/kotlin/commands/packageconfig/ExportPathExcludesCommand.kt b/helper-cli/src/main/kotlin/commands/packageconfig/ExportPathExcludesCommand.kt index b07c3b8bcc7e0..087f0add8031d 100644 --- a/helper-cli/src/main/kotlin/commands/packageconfig/ExportPathExcludesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/packageconfig/ExportPathExcludesCommand.kt @@ -69,14 +69,10 @@ class ExportPathExcludesCommand : CliktCommand( ).flag() override fun run() { - val globalPathExcludes = if (pathExcludesFile.isFile) { - pathExcludesFile.readValue() - } else { - mapOf() - } + val globalPathExcludes = pathExcludesFile.takeIf { it.isFile }?.readValue().orEmpty() val localPathExcludes = getPathExcludesByRepository( - pathExcludes = packageConfigurationFile.readValue().pathExcludes, + pathExcludes = packageConfigurationFile.readValue()?.pathExcludes.orEmpty(), nestedRepositories = findRepositories(sourceCodeDir) ) diff --git a/helper-cli/src/main/kotlin/commands/packageconfig/FindCommand.kt b/helper-cli/src/main/kotlin/commands/packageconfig/FindCommand.kt index cdf0240b8d2d4..90c8182a46b17 100644 --- a/helper-cli/src/main/kotlin/commands/packageconfig/FindCommand.kt +++ b/helper-cli/src/main/kotlin/commands/packageconfig/FindCommand.kt @@ -52,7 +52,7 @@ internal class FindCommand : CliktCommand( override fun run() { // TODO: There could be multiple package configurations matching the given identifier which is not handled. findPackageConfigurationFiles(packageConfigurationDir).find { - it.readValue().id == packageId + it.readValue()?.id == packageId }?.let { println(it.absolutePath) } diff --git a/helper-cli/src/main/kotlin/commands/packageconfig/FormatCommand.kt b/helper-cli/src/main/kotlin/commands/packageconfig/FormatCommand.kt index 0572d157ef66c..e77c343f28518 100644 --- a/helper-cli/src/main/kotlin/commands/packageconfig/FormatCommand.kt +++ b/helper-cli/src/main/kotlin/commands/packageconfig/FormatCommand.kt @@ -41,8 +41,6 @@ internal class FormatCommand : CliktCommand( .convert { it.absoluteFile.normalize() } override fun run() { - packageConfigurationFile - .readValue() - .writeAsYaml(packageConfigurationFile) + packageConfigurationFile.readValue()?.writeAsYaml(packageConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/commands/packageconfig/ImportLicenseFindingCurationsCommand.kt b/helper-cli/src/main/kotlin/commands/packageconfig/ImportLicenseFindingCurationsCommand.kt index 2fe3afec6d648..361c69969ca70 100644 --- a/helper-cli/src/main/kotlin/commands/packageconfig/ImportLicenseFindingCurationsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/packageconfig/ImportLicenseFindingCurationsCommand.kt @@ -82,8 +82,13 @@ class ImportLicenseFindingCurationsCommand : CliktCommand( private val findingCurationMatcher = FindingCurationMatcher() override fun run() { - val ortResult = ortFile.readValue() - val packageConfiguration = packageConfigurationFile.readValue() + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + + val packageConfiguration = requireNotNull(packageConfigurationFile.readValue()) { + "The provided package configuration file '${packageConfigurationFile.canonicalPath}' has no content." + } val allLicenseFindings = ortResult.getScanResultFor(packageConfiguration)?.summary?.licenseFindings.orEmpty() diff --git a/helper-cli/src/main/kotlin/commands/packageconfig/ImportPathExcludesCommand.kt b/helper-cli/src/main/kotlin/commands/packageconfig/ImportPathExcludesCommand.kt index 06a131bb3a3f0..959d4e77a73b8 100644 --- a/helper-cli/src/main/kotlin/commands/packageconfig/ImportPathExcludesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/packageconfig/ImportPathExcludesCommand.kt @@ -70,7 +70,9 @@ class ImportPathExcludesCommand : CliktCommand( override fun run() { val allFiles = findFilesRecursive(sourceCodeDir) - val packageConfiguration = packageConfigurationFile.readValue() + val packageConfiguration = requireNotNull(packageConfigurationFile.readValue()) { + "The provided package configuration file '${packageConfigurationFile.canonicalPath}' has no content." + } val existingPathExcludes = packageConfiguration.pathExcludes val importedPathExcludes = importPathExcludes(sourceCodeDir, pathExcludesFile).filter { pathExclude -> diff --git a/helper-cli/src/main/kotlin/commands/packageconfig/RemoveEntriesCommand.kt b/helper-cli/src/main/kotlin/commands/packageconfig/RemoveEntriesCommand.kt index 8ec371e325f79..d8c37dbdf2aeb 100644 --- a/helper-cli/src/main/kotlin/commands/packageconfig/RemoveEntriesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/packageconfig/RemoveEntriesCommand.kt @@ -57,8 +57,14 @@ internal class RemoveEntriesCommand : CliktCommand( private val findingsMatcher = FindingCurationMatcher() override fun run() { - val packageConfiguration = packageConfigurationFile.readValue() - val ortResult = ortFile.readValue() + val packageConfiguration = requireNotNull(packageConfigurationFile.readValue()) { + "The provided package configuration file '${packageConfigurationFile.canonicalPath}' has no content." + } + + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + val scanResult = ortResult.getScanResultFor(packageConfiguration) if (scanResult == null) { diff --git a/helper-cli/src/main/kotlin/commands/packageconfig/SortCommand.kt b/helper-cli/src/main/kotlin/commands/packageconfig/SortCommand.kt index 6701dc6cd3e5b..308a570488d80 100644 --- a/helper-cli/src/main/kotlin/commands/packageconfig/SortCommand.kt +++ b/helper-cli/src/main/kotlin/commands/packageconfig/SortCommand.kt @@ -42,9 +42,6 @@ internal class SortCommand : CliktCommand( .convert { it.absoluteFile.normalize() } override fun run() { - packageConfigurationFile - .readValue() - .sortEntries() - .writeAsYaml(packageConfigurationFile) + packageConfigurationFile.readValue()?.sortEntries()?.writeAsYaml(packageConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/common/Utils.kt b/helper-cli/src/main/kotlin/common/Utils.kt index c93ae64db531e..20a828e399fd8 100644 --- a/helper-cli/src/main/kotlin/common/Utils.kt +++ b/helper-cli/src/main/kotlin/common/Utils.kt @@ -809,7 +809,7 @@ internal fun importPathExcludes(sourceCodeDir: File, pathExcludesFile: File): Li println("Found ${repositoryPaths.size} repositories in ${repositoryPaths.values.sumBy { it.size }} locations.") println("Loading $pathExcludesFile...") - val pathExcludes = pathExcludesFile.readValue() + val pathExcludes = pathExcludesFile.readValue().orEmpty() println("Found ${pathExcludes.values.sumBy { it.size }} excludes for ${pathExcludes.size} repositories.") val result = mutableListOf() @@ -836,7 +836,7 @@ internal fun importLicenseFindingCurations( println("Found ${repositoryPaths.size} repositories in ${repositoryPaths.values.sumBy { it.size }} locations.") println("Loading $licenseFindingCurationsFile...") - val curations = licenseFindingCurationsFile.readValue() + val curations = licenseFindingCurationsFile.readValue().orEmpty() println("Found ${curations.values.sumBy { it.size }} curations for ${curations.size} repositories.") val result = mutableListOf() diff --git a/model/src/main/kotlin/FileFormat.kt b/model/src/main/kotlin/FileFormat.kt index ee006ac87a02f..c757e95bc50ba 100644 --- a/model/src/main/kotlin/FileFormat.kt +++ b/model/src/main/kotlin/FileFormat.kt @@ -20,7 +20,7 @@ package org.ossreviewtoolkit.model import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.readValue +import com.fasterxml.jackson.module.kotlin.treeToValue import java.io.File @@ -77,6 +77,12 @@ enum class FileFormat(val mapper: ObjectMapper, val fileExtension: String, varar fun File.mapper() = FileFormat.forFile(this).mapper /** - * Use the Jackson mapper returned from [File.mapper] to read an object of type [T] from this file. + * Use the Jackson mapper returned from [File.mapper] to read an object of type [T] from this file, or return null if + * the file has no content. */ -inline fun File.readValue(): T = mapper().readValue(this) +inline fun File.readValue(): T? = + mapper().readTree(this)?.let { + // Parse the file in a two-step process to avoid readValue() throwing an exception on empty files. Also see + // https://github.com/FasterXML/jackson-databind/issues/1406#issuecomment-252676674. + mapper().treeToValue(it) + } diff --git a/model/src/main/kotlin/utils/SimplePackageConfigurationProvider.kt b/model/src/main/kotlin/utils/SimplePackageConfigurationProvider.kt index f3e758734a332..ae70baf9bd292 100644 --- a/model/src/main/kotlin/utils/SimplePackageConfigurationProvider.kt +++ b/model/src/main/kotlin/utils/SimplePackageConfigurationProvider.kt @@ -48,7 +48,7 @@ class SimplePackageConfigurationProvider( * configuration per [Identifier] and [Provenance]. */ fun forDirectory(directory: File): SimplePackageConfigurationProvider { - val entries = findPackageConfigurationFiles(directory).mapTo(mutableListOf()) { file -> + val entries = findPackageConfigurationFiles(directory).mapNotNullTo(mutableListOf()) { file -> try { file.readValue() } catch (e: IOException) { @@ -67,7 +67,7 @@ class SimplePackageConfigurationProvider( * file. Throws an exception if there is more than one configuration per [Identifier] and [Provenance]. */ fun forFile(file: File): SimplePackageConfigurationProvider { - val entries = file.readValue>() + val entries = file.readValue>().orEmpty() return SimplePackageConfigurationProvider(entries) } diff --git a/model/src/test/kotlin/AdvisorResultContainerTest.kt b/model/src/test/kotlin/AdvisorResultContainerTest.kt index 64d883be1af08..b5bc7136a3323 100644 --- a/model/src/test/kotlin/AdvisorResultContainerTest.kt +++ b/model/src/test/kotlin/AdvisorResultContainerTest.kt @@ -99,7 +99,7 @@ class AdvisorResultContainerTest : WordSpec() { val result = resultsFile.readValue() - result.advisor shouldNot beNull() + result?.advisor shouldNot beNull() } "be deserialized with vulnerabilities in format with references" { @@ -107,7 +107,7 @@ class AdvisorResultContainerTest : WordSpec() { val result = resultsFile.readValue() - result.advisor shouldNot beNull() + result?.advisor shouldNot beNull() } } } diff --git a/model/src/test/kotlin/ProjectTest.kt b/model/src/test/kotlin/ProjectTest.kt index 76c4cb991be4d..2628c934cd2ee 100644 --- a/model/src/test/kotlin/ProjectTest.kt +++ b/model/src/test/kotlin/ProjectTest.kt @@ -39,7 +39,7 @@ import org.ossreviewtoolkit.utils.test.containExactly private fun readAnalyzerResult(analyzerResultFilename: String): Project = File("../analyzer/src/funTest/assets/projects/synthetic") .resolve(analyzerResultFilename) - .readValue().project + .readValue()?.project ?: Project.EMPTY private const val MANAGER = "MyManager" diff --git a/model/src/test/kotlin/config/NexusIqConfigurationTest.kt b/model/src/test/kotlin/config/NexusIqConfigurationTest.kt index 562d20a81c4bb..f34b23beffdc9 100644 --- a/model/src/test/kotlin/config/NexusIqConfigurationTest.kt +++ b/model/src/test/kotlin/config/NexusIqConfigurationTest.kt @@ -40,7 +40,7 @@ class NexusIqConfigurationTest : WordSpec({ }.readValue() val expectedNexusIqConfig = referenceOrtConfig.advisor.nexusIq - val actualNexusIqConfiguration = rereadOrtConfig.advisor.nexusIq + val actualNexusIqConfiguration = rereadOrtConfig?.advisor?.nexusIq expectedNexusIqConfig.shouldBeInstanceOf() actualNexusIqConfiguration.shouldBeInstanceOf() diff --git a/model/src/test/kotlin/config/ScannerConfigurationTest.kt b/model/src/test/kotlin/config/ScannerConfigurationTest.kt index 285bf98537732..6b5ab84746a5e 100644 --- a/model/src/test/kotlin/config/ScannerConfigurationTest.kt +++ b/model/src/test/kotlin/config/ScannerConfigurationTest.kt @@ -40,7 +40,7 @@ class ScannerConfigurationTest : WordSpec({ val file = createTempFile(suffix = ".yml").toFile().apply { deleteOnExit() } file.mapper().writeValue(file, ortConfig.scanner) - val loadedConfig = file.readValue() + val loadedConfig = file.readValue() ?: ScannerConfiguration() // Note: loadedConfig cannot be directly compared to the original one, as there have been some changes: // Relative paths have been normalized, passwords do not get serialized, etc. diff --git a/scanner/src/main/kotlin/Scanner.kt b/scanner/src/main/kotlin/Scanner.kt index a1dd59e2b212e..1c518cd461be3 100644 --- a/scanner/src/main/kotlin/Scanner.kt +++ b/scanner/src/main/kotlin/Scanner.kt @@ -108,8 +108,16 @@ abstract class Scanner( "Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms." } - requireNotNull(ortResult.analyzer) { - "The provided ORT result file '${ortFile.canonicalPath}' does not contain an analyzer result." + requireNotNull(ortResult) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + + if (ortResult.analyzer == null) { + log.warn { + "The provided ORT result file '${ortFile.canonicalPath}' does not contain an analyzer result." + } + + return ortResult } // Add the projects as packages to scan.