From 54b6bb615617f795d8ed278518ee95c800e5daaf Mon Sep 17 00:00:00 2001 From: Sebastian Schuberth Date: Fri, 9 Apr 2021 12:16:45 +0200 Subject: [PATCH] Use sane fallbacks when reading empty files Fixes #3861. Signed-off-by: Sebastian Schuberth --- advisor/src/main/kotlin/Advisor.kt | 12 ++++++-- .../kotlin/advisors/VulnerableCodeTest.kt | 9 ++++-- analyzer/src/main/kotlin/Analyzer.kt | 2 +- .../curation/FilePackageCurationProvider.kt | 2 +- analyzer/src/main/kotlin/managers/Npm.kt | 2 +- .../main/kotlin/managers/utils/NodeSupport.kt | 7 ++--- cli/src/funTest/kotlin/ExamplesFunTest.kt | 29 ++++++++++--------- .../main/kotlin/commands/DownloaderCommand.kt | 16 ++++++++-- .../main/kotlin/commands/EvaluatorCommand.kt | 10 ++++--- .../main/kotlin/commands/ReporterCommand.kt | 11 +++++-- .../kotlin/commands/UploadCurationsCommand.kt | 2 +- .../commands/UploadResultToPostgresCommand.kt | 13 ++++++--- .../commands/UploadResultToSw360Command.kt | 13 ++++++--- .../ExportLicenseFindingCurationsCommand.kt | 15 +++++----- .../commands/ExportPathExcludesCommand.kt | 13 ++++----- .../ExtractRepositoryConfigurationCommand.kt | 9 +++--- .../FormatRepositoryConfigurationCommand.kt | 9 ++++-- .../GenerateProjectExcludesCommand.kt | 13 ++++----- ...GenerateRuleViolationResolutionsCommand.kt | 7 +++-- .../commands/GenerateScopeExcludesCommand.kt | 15 ++++++---- .../GenerateTimeoutErrorResolutionsCommand.kt | 8 +++-- .../commands/ImportCopyrightGarbageCommand.kt | 7 ++--- .../ImportLicenseFindingCurationsCommand.kt | 15 +++++----- .../commands/ImportPathExcludesCommand.kt | 7 ++--- .../commands/ImportScanResultsCommand.kt | 5 +++- .../kotlin/commands/ListCopyrightsCommand.kt | 5 +++- .../commands/ListLicenseCategoriesCommand.kt | 2 +- .../kotlin/commands/ListLicensesCommand.kt | 4 ++- .../kotlin/commands/ListPackagesCommand.kt | 4 ++- .../kotlin/commands/MapCopyrightsCommand.kt | 8 +++-- .../MergeRepositoryConfigurationsCommand.kt | 2 +- .../RemoveConfigurationEntriesCommand.kt | 7 +++-- .../SortRepositoryConfigurationCommand.kt | 6 ++-- .../commands/SubtractScanResultsCommand.kt | 25 ++++++++++++---- .../VerifySourceArtifactCurationsCommand.kt | 2 +- .../commands/packageconfig/FindCommand.kt | 2 +- .../commands/packageconfig/FormatCommand.kt | 5 ++-- .../ImportLicenseFindingCurationsCommand.kt | 8 +++-- .../ImportPathExcludesCommand.kt | 4 ++- .../packageconfig/RemoveEntriesCommand.kt | 10 +++++-- .../commands/packageconfig/SortCommand.kt | 5 +--- helper-cli/src/main/kotlin/common/Utils.kt | 4 +-- model/src/main/kotlin/FileFormat.kt | 7 +++-- .../SimplePackageConfigurationProvider.kt | 4 +-- .../test/kotlin/AdvisorResultContainerTest.kt | 4 +-- model/src/test/kotlin/ProjectTest.kt | 2 +- .../kotlin/config/NexusIqConfigurationTest.kt | 2 +- .../kotlin/config/ScannerConfigurationTest.kt | 2 +- scanner/src/main/kotlin/Scanner.kt | 12 ++++++-- 49 files changed, 237 insertions(+), 150 deletions(-) diff --git a/advisor/src/main/kotlin/Advisor.kt b/advisor/src/main/kotlin/Advisor.kt index d65541b104e4..c85aa0c5e6b6 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 d6fd669fce2a..393d005d6914 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 675746fde7d2..0655d2fd60ec 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 31413d541b8c..4ab1a8e28b80 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 93869123d50d..df8a9f4fa267 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 58303b52b221..a9b1e628842b 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 14cae6770116..0cf7f120a95d 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,20 @@ 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() - 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") + ortResult shouldNotBeNull { + val evaluator = Evaluator( + ortResult = this, + licenseInfoResolver = createLicenseInfoResolver(), + licenseClassifications = licenseFile.readValue() ?: LicenseClassifications() + ) + 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") + } } "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 0a7f5f9f9b66..e9f483b7b8cf 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 04fc7c9132ad..41c784522f9f 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 16ee75834759..6767e69b9016 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 4e388a2a94e5..bfc4c31d2941 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 c733e0286b50..8b9d78969dcc 100644 --- a/cli/src/main/kotlin/commands/UploadResultToPostgresCommand.kt +++ b/cli/src/main/kotlin/commands/UploadResultToPostgresCommand.kt @@ -60,8 +60,8 @@ class UploadResultToPostgresCommand : CliktCommand( epilog = "EXPERIMENTAL: The command is still in development and usage will likely change in the near future. The " + "command expects that a PostgresStorage for the scanner is configured." ) { - private val ortFile by option( - "--ort-file", "-i", + private val ortResultFile by option( + "--ort-result-file", "-i", help = "The ORT result file to read as input." ).convert { it.expandTilde() } .file(mustExist = true, canBeFile = true, canBeDir = false, mustBeWritable = false, mustBeReadable = true) @@ -87,10 +87,15 @@ class UploadResultToPostgresCommand : CliktCommand( private val globalOptionsForSubcommands by requireObject() override fun run() { - val (ortResult, duration) = measureTimedValue { ortFile.readValue() } + val (ortResult, duration) = measureTimedValue { ortResultFile.readValue() } log.perf { - "Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms." + "Read ORT result from '${ortResultFile.name}' (${ortResultFile.formatSizeInMib}) in " + + "${duration.inMilliseconds}ms." + } + + requireNotNull(ortResult) { + "The provided ORT result file '${ortResultFile.canonicalPath}' has no content." } val postgresConfig = globalOptionsForSubcommands.config.scanner.storages?.values diff --git a/cli/src/main/kotlin/commands/UploadResultToSw360Command.kt b/cli/src/main/kotlin/commands/UploadResultToSw360Command.kt index dc7b7040420f..bd3372e460ab 100644 --- a/cli/src/main/kotlin/commands/UploadResultToSw360Command.kt +++ b/cli/src/main/kotlin/commands/UploadResultToSw360Command.kt @@ -64,8 +64,8 @@ class UploadResultToSw360Command : CliktCommand( epilog = "EXPERIMENTAL: The command is still in development and usage will likely change in the near future. The " + "command expects that a Sw360Storage for the scanner is configured." ) { - private val ortFile by option( - "--ort-file", "-i", + private val ortResultFile by option( + "--ort-result-file", "-i", help = "The ORT result file to read as input." ).convert { it.expandTilde() } .file(mustExist = true, canBeFile = true, canBeDir = false, mustBeWritable = false, mustBeReadable = true) @@ -76,10 +76,15 @@ class UploadResultToSw360Command : CliktCommand( private val globalOptionsForSubcommands by requireObject() override fun run() { - val (ortResult, duration) = measureTimedValue { ortFile.readValue() } + val (ortResult, duration) = measureTimedValue { ortResultFile.readValue() } log.perf { - "Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms." + "Read ORT result from '${ortResultFile.name}' (${ortResultFile.formatSizeInMib}) in " + + "${duration.inMilliseconds}ms." + } + + requireNotNull(ortResult) { + "The provided ORT result file '${ortResultFile.canonicalPath}' has no content." } val sw360Config = globalOptionsForSubcommands.config.scanner.storages?.values diff --git a/helper-cli/src/main/kotlin/commands/ExportLicenseFindingCurationsCommand.kt b/helper-cli/src/main/kotlin/commands/ExportLicenseFindingCurationsCommand.kt index c14972334a34..6e25ee01bcae 100644 --- a/helper-cli/src/main/kotlin/commands/ExportLicenseFindingCurationsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ExportLicenseFindingCurationsCommand.kt @@ -71,16 +71,17 @@ 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 2e0ba771741e..c71cd4d591f5 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 7263fda67e07..52f239b021f1 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 b47fa1b638f4..4e71105b85e8 100644 --- a/helper-cli/src/main/kotlin/commands/FormatRepositoryConfigurationCommand.kt +++ b/helper-cli/src/main/kotlin/commands/FormatRepositoryConfigurationCommand.kt @@ -25,6 +25,7 @@ import com.github.ajalt.clikt.parameters.arguments.convert import com.github.ajalt.clikt.parameters.types.file import org.ossreviewtoolkit.helper.common.writeAsYaml +import org.ossreviewtoolkit.model.OrtResult import org.ossreviewtoolkit.model.config.RepositoryConfiguration import org.ossreviewtoolkit.model.readValue import org.ossreviewtoolkit.utils.expandTilde @@ -41,8 +42,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 3d7613f3ff65..c2e557d65a9b 100644 --- a/helper-cli/src/main/kotlin/commands/GenerateProjectExcludesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/GenerateProjectExcludesCommand.kt @@ -57,14 +57,13 @@ 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 6fb6f7509a55..c30ae04a1904 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 07cf02330598..ad06746d3afb 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 9325d905ae4c..48191fc5ee39 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 68a17e0a195f..3076084cc54d 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 f20a25420024..3b34f7da8af8 100644 --- a/helper-cli/src/main/kotlin/commands/ImportLicenseFindingCurationsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ImportLicenseFindingCurationsCommand.kt @@ -76,13 +76,14 @@ 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 +103,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 55310090acfb..c1e72c5a2e73 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 1950d09481f9..e7dd513e476a 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 0f82ace73e8f..8af1f4054999 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 cfe3446abd55..831315fb39e3 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 46601cfb7753..277a91813228 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 68ebd0a0e252..8be506ddb454 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 f8c5427700fb..155e8f3f50a0 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 b190b800a548..c4527b64ec7c 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 f93c4c33ae2b..fd741f74b3ac 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 3080199319d8..ac2858069031 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 39f3b1b87400..8c441bfa86f3 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 b004ac1cf2b9..217aecf89623 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/FindCommand.kt b/helper-cli/src/main/kotlin/commands/packageconfig/FindCommand.kt index cdf0240b8d2d..90c8182a46b1 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 0572d157ef66..910c5106294e 100644 --- a/helper-cli/src/main/kotlin/commands/packageconfig/FormatCommand.kt +++ b/helper-cli/src/main/kotlin/commands/packageconfig/FormatCommand.kt @@ -41,8 +41,7 @@ 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 583668e9d731..5bc603e323f5 100644 --- a/helper-cli/src/main/kotlin/commands/packageconfig/ImportLicenseFindingCurationsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/packageconfig/ImportLicenseFindingCurationsCommand.kt @@ -82,10 +82,14 @@ class ImportLicenseFindingCurationsCommand : CliktCommand( private val findingCurationMatcher = FindingCurationMatcher() override fun run() { - val ortResult = ortFile.readValue() + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + val packageConfiguration = packageConfigurationFile.readValue() - val allLicenseFindings = ortResult.getScanResultFor(packageConfiguration)?.summary?.licenseFindings.orEmpty() + val allLicenseFindings = packageConfiguration?.let { ortResult.getScanResultFor(it) } + ?.summary?.licenseFindings.orEmpty() val importedCurations = importLicenseFindingCurations(sourceCodeDir, licenseFindingCurationsFile) .filter { curation -> diff --git a/helper-cli/src/main/kotlin/commands/packageconfig/ImportPathExcludesCommand.kt b/helper-cli/src/main/kotlin/commands/packageconfig/ImportPathExcludesCommand.kt index 06a131bb3a3f..959d4e77a73b 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 8ec371e325f7..d8c37dbdf2ae 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 6701dc6cd3e5..308a570488d8 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 c93ae64db531..20a828e399fd 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 ee006ac87a02..3097e2ce15f4 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,7 @@ 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 { mapper().treeToValue(it) } diff --git a/model/src/main/kotlin/utils/SimplePackageConfigurationProvider.kt b/model/src/main/kotlin/utils/SimplePackageConfigurationProvider.kt index f3e758734a33..ae70baf9bd29 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 64d883be1af0..b5bc7136a332 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 76c4cb991be4..2628c934cd2e 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 562d20a81c4b..f34b23beffdc 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 285bf9853773..6b5ab84746a5 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 a1dd59e2b212..1c518cd461be 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.