From 4d103f5a0fc12bc3645cd74b0fb36304428ea789 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 | 4 +++ .../kotlin/advisors/VulnerableCodeTest.kt | 2 +- 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 | 26 ++++++++++--------- .../main/kotlin/commands/DownloaderCommand.kt | 4 +++ .../main/kotlin/commands/EvaluatorCommand.kt | 10 ++++--- .../main/kotlin/commands/ReporterCommand.kt | 11 +++++--- .../kotlin/commands/UploadCurationsCommand.kt | 2 +- .../commands/UploadResultToPostgresCommand.kt | 4 +++ .../commands/UploadResultToSw360Command.kt | 4 +++ .../ExportLicenseFindingCurationsCommand.kt | 11 ++++---- .../commands/ExportPathExcludesCommand.kt | 13 +++++----- .../ExtractRepositoryConfigurationCommand.kt | 9 ++++--- .../FormatRepositoryConfigurationCommand.kt | 8 +++--- .../GenerateProjectExcludesCommand.kt | 12 ++++----- ...GenerateRuleViolationResolutionsCommand.kt | 7 +++-- .../commands/GenerateScopeExcludesCommand.kt | 15 ++++++----- .../GenerateTimeoutErrorResolutionsCommand.kt | 8 +++--- .../commands/ImportCopyrightGarbageCommand.kt | 7 ++--- .../ImportLicenseFindingCurationsCommand.kt | 14 +++++----- .../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 +- .../ExportPathExcludesCommand.kt | 8 ++---- .../commands/packageconfig/FindCommand.kt | 2 +- .../commands/packageconfig/FormatCommand.kt | 4 +-- .../ImportLicenseFindingCurationsCommand.kt | 9 +++++-- .../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 | 12 ++++++--- .../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 | 4 +++ 50 files changed, 201 insertions(+), 136 deletions(-) diff --git a/advisor/src/main/kotlin/Advisor.kt b/advisor/src/main/kotlin/Advisor.kt index 1a2e82b33161b..a85d5bba484c6 100644 --- a/advisor/src/main/kotlin/Advisor.kt +++ b/advisor/src/main/kotlin/Advisor.kt @@ -66,6 +66,10 @@ class Advisor( "Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms." } + requireNotNull(ortResult) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + if (ortResult.analyzer == null) { log.warn { "Cannot run the advisor as the provided ORT result file '${ortFile.canonicalPath}' does not contain " + diff --git a/advisor/src/test/kotlin/advisors/VulnerableCodeTest.kt b/advisor/src/test/kotlin/advisors/VulnerableCodeTest.kt index 4f01a7bc90bdf..e09026a8781fd 100644 --- a/advisor/src/test/kotlin/advisors/VulnerableCodeTest.kt +++ b/advisor/src/test/kotlin/advisors/VulnerableCodeTest.kt @@ -268,7 +268,7 @@ private fun resultFile(): File = File(TEST_FILES_ROOT).resolve(TEST_RESULT_NAME) * Return a list with [Package]s from the analyzer result file that serve as input for the [VulnerableCode] advisor. */ private fun inputPackages(): List = - resultFile().readValue().getPackages(false).map { it.pkg } + resultFile().readValue()?.getPackages(false)?.map { it.pkg }.orEmpty() /** * Generate the JSON body of the request to query information about packages. It mainly consists of an array with the 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 f2f1a70342b5d..a217774bf218c 100644 --- a/analyzer/src/main/kotlin/managers/Npm.kt +++ b/analyzer/src/main/kotlin/managers/Npm.kt @@ -223,7 +223,7 @@ open class Npm( log.debug { "Found a 'package.json' file in '$packageDir'." } - val json = file.readValue() + val json = file.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 56d20fb63123c..b218458c5fb52 100644 --- a/cli/src/main/kotlin/commands/DownloaderCommand.kt +++ b/cli/src/main/kotlin/commands/DownloaderCommand.kt @@ -187,6 +187,10 @@ class DownloaderCommand : CliktCommand(name = "download", help = "Fetch source c "${duration.inMilliseconds}ms." } + requireNotNull(ortResult) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + val analyzerResult = ortResult.analyzer?.result if (analyzerResult == null) { diff --git a/cli/src/main/kotlin/commands/EvaluatorCommand.kt b/cli/src/main/kotlin/commands/EvaluatorCommand.kt index 99fa47abba11f..c068aa209dbfb 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 ea99dcbdf438b..bf0354a3679e5 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.mapNotNull { curation -> curation.id.toClearlyDefinedCoordinates()?.let { coordinates -> curation to coordinates 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 da37cdae6255b..710ad01e3e0fe 100644 --- a/helper-cli/src/main/kotlin/commands/ExportLicenseFindingCurationsCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ExportLicenseFindingCurationsCommand.kt @@ -68,18 +68,17 @@ internal class ExportLicenseFindingCurationsCommand : 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 localLicenseFindingCurations = getLicenseFindingCurationsByRepository( curations = ortResult.repository.config.curations.licenseFindings, nestedRepositories = ortResult.repository.nestedRepositories ) - 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 f5e8dfa886db0..5edde8eec8863 100644 --- a/helper-cli/src/main/kotlin/commands/ExportPathExcludesCommand.kt +++ b/helper-cli/src/main/kotlin/commands/ExportPathExcludesCommand.kt @@ -68,16 +68,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 f21d180253459..cf3b81daeff71 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.write(repositoryConfigurationFile) + val ortResult = requireNotNull(ortFile.readValue()) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + + ortResult.repository.config.write(repositoryConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/commands/FormatRepositoryConfigurationCommand.kt b/helper-cli/src/main/kotlin/commands/FormatRepositoryConfigurationCommand.kt index 908edebc57f45..5e735aad05aff 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() - .write(repositoryConfigurationFile) + val repoConfig = requireNotNull(repositoryConfigurationFile.readValue()) { + "The provided ORT result file '${repositoryConfigurationFile.canonicalPath}' has no content." + } + + repoConfig.write(repositoryConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/commands/GenerateProjectExcludesCommand.kt b/helper-cli/src/main/kotlin/commands/GenerateProjectExcludesCommand.kt index 6ac037e5c6ebf..d732902f77c17 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 3428443c90d86..0aeeae9508cb0 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 4e1d7cab60152..47adde15ed389 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() - .write(repositoryConfigurationFile) + val repoConfig = requireNotNull(repositoryConfigurationFile.readValue()) { + "The provided ORT result file '${repositoryConfigurationFile.canonicalPath}' has no content." + } + + repoConfig.replaceScopeExcludes(scopeExcludes).sortScopeExcludes().write(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 f3739cfcf4899..739d7013dd49c 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 bbf3e836bb32b..7da28a6a6ec80 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 da27d1def21c0..598229415b6da 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 5b6466d36a2b1..ab3863fb16a2a 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 f5c3013801c3d..52f1ee86a36d7 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() - .write(repositoryConfigurationFile) + repositoryConfigurationFile.readValue() + ?.sortEntries()?.write(repositoryConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/commands/SubtractScanResultsCommand.kt b/helper-cli/src/main/kotlin/commands/SubtractScanResultsCommand.kt index dd51d97dc846c..5a2afacd29170 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 99294021378e2..60321820ca184 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 d3de4bad6d68f..a873fd97f52ab 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() - .write(packageConfigurationFile) + packageConfigurationFile.readValue()?.write(packageConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/commands/packageconfig/ImportLicenseFindingCurationsCommand.kt b/helper-cli/src/main/kotlin/commands/packageconfig/ImportLicenseFindingCurationsCommand.kt index 39f80503dd6ee..0d5a452919753 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 cbac7462a4742..8194d76f4efe2 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 ccbe4d367d38b..4f960403407e8 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 5319af9040fc0..b727a5c8185d7 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() - .write(packageConfigurationFile) + packageConfigurationFile.readValue()?.sortEntries()?.write(packageConfigurationFile) } } diff --git a/helper-cli/src/main/kotlin/common/Utils.kt b/helper-cli/src/main/kotlin/common/Utils.kt index ea823bf409fe7..a0bc9a9ebe26b 100644 --- a/helper-cli/src/main/kotlin/common/Utils.kt +++ b/helper-cli/src/main/kotlin/common/Utils.kt @@ -835,7 +835,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() @@ -862,7 +862,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 58257d60aacce..1214accd79249 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 @@ -79,9 +79,15 @@ 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) + } /** * Use the Jackson mapper returned from [File.mapper] to write an object of type [T] to this file. [prettyPrint] 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 8b6e5f2e31fb1..fadc934cbcc75 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 5968f263e3c7f..b7da3ed94dc97 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 d2732184531bf..3f43bfa9946f2 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.writeValue(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 4a26c650866bd..4f04e3f20e397 100644 --- a/scanner/src/main/kotlin/Scanner.kt +++ b/scanner/src/main/kotlin/Scanner.kt @@ -108,6 +108,10 @@ abstract class Scanner( "Read ORT result from '${ortFile.name}' (${ortFile.formatSizeInMib}) in ${duration.inMilliseconds}ms." } + requireNotNull(ortResult) { + "The provided ORT result file '${ortFile.canonicalPath}' has no content." + } + if (ortResult.analyzer == null) { log.warn { "Cannot run the scanner as the provided ORT result file '${ortFile.canonicalPath}' does not contain " +