From 8142cdc06a871bc1e66d4b2df82ffcf0fbd20ee5 Mon Sep 17 00:00:00 2001 From: Sebastian Schuberth Date: Thu, 1 Dec 2022 18:49:16 +0100 Subject: [PATCH] Switch from the unmaintained vdurmont/semver4j to semver4j/semver4j The new semver4j GitHub organization contains a maintained fork / copy [1] of the original semver4j library by @vdurmont [2]. However, the API changed quite significantly. Catch up with those changes in order to (partly) fix issue #6153. [1]: https://github.com/semver4j/semver4j [2]: https://github.com/vdurmont/semver4j Signed-off-by: Sebastian Schuberth --- analyzer/src/main/kotlin/managers/Bower.kt | 7 ++++--- analyzer/src/main/kotlin/managers/CocoaPods.kt | 7 ++++--- analyzer/src/main/kotlin/managers/Composer.kt | 7 ++++--- analyzer/src/main/kotlin/managers/Conan.kt | 7 ++++--- analyzer/src/main/kotlin/managers/Npm.kt | 7 ++++--- analyzer/src/main/kotlin/managers/Pipenv.kt | 9 +++++---- analyzer/src/main/kotlin/managers/Pnpm.kt | 7 ++++--- analyzer/src/main/kotlin/managers/Pub.kt | 7 ++++--- analyzer/src/main/kotlin/managers/Sbt.kt | 13 +++++++------ analyzer/src/main/kotlin/managers/Stack.kt | 7 ++++--- analyzer/src/main/kotlin/managers/Yarn.kt | 7 ++++--- analyzer/src/main/kotlin/managers/Yarn2.kt | 7 ++++--- .../main/kotlin/managers/utils/PythonInspector.kt | 7 ++++--- .../main/kotlin/commands/RequirementsCommand.kt | 8 +++++--- downloader/src/main/kotlin/VersionControlSystem.kt | 8 ++++---- downloader/src/main/kotlin/vcs/Git.kt | 7 ++++--- gradle/libs.versions.toml | 4 ++-- model/src/main/kotlin/PackageCuration.kt | 10 +++------- .../AbstractProvenanceBasedStorageFunTest.kt | 4 ++-- .../kotlin/storages/AbstractStorageFunTest.kt | 4 ++-- scanner/src/main/kotlin/ScannerCriteria.kt | 13 +++++++------ .../scanners/scancode/ScanCodeResultParser.kt | 4 ++-- scanner/src/test/kotlin/ScannerCriteriaTest.kt | 14 +++++++------- .../kotlin/storages/ClearlyDefinedStorageTest.kt | 4 ++-- utils/common/src/main/kotlin/CommandLineTool.kt | 12 +++++++----- 25 files changed, 103 insertions(+), 88 deletions(-) diff --git a/analyzer/src/main/kotlin/managers/Bower.kt b/analyzer/src/main/kotlin/managers/Bower.kt index e5dd9aed3deed..272412308d93c 100644 --- a/analyzer/src/main/kotlin/managers/Bower.kt +++ b/analyzer/src/main/kotlin/managers/Bower.kt @@ -21,8 +21,6 @@ package org.ossreviewtoolkit.analyzer.managers import com.fasterxml.jackson.databind.JsonNode -import com.vdurmont.semver4j.Requirement - import java.io.File import java.util.SortedSet import java.util.Stack @@ -50,6 +48,9 @@ import org.ossreviewtoolkit.utils.common.fieldsOrEmpty import org.ossreviewtoolkit.utils.common.stashDirectories import org.ossreviewtoolkit.utils.common.textValueOrEmpty +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + /** * The [Bower](https://bower.io/) package manager for JavaScript. */ @@ -225,7 +226,7 @@ class Bower( override fun command(workingDir: File?) = if (Os.isWindows) "bower.cmd" else "bower" - override fun getVersionRequirement(): Requirement = Requirement.buildIvy("[1.8.8,)") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("[1.8.8,)") override fun beforeResolution(definitionFiles: List) = checkVersion() diff --git a/analyzer/src/main/kotlin/managers/CocoaPods.kt b/analyzer/src/main/kotlin/managers/CocoaPods.kt index d0030e5a09195..977b39630983e 100644 --- a/analyzer/src/main/kotlin/managers/CocoaPods.kt +++ b/analyzer/src/main/kotlin/managers/CocoaPods.kt @@ -27,8 +27,6 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize import com.fasterxml.jackson.databind.deser.std.StdDeserializer import com.fasterxml.jackson.databind.node.ObjectNode -import com.vdurmont.semver4j.Requirement - import java.io.File import java.util.SortedSet @@ -60,6 +58,9 @@ import org.ossreviewtoolkit.utils.common.collectMessages import org.ossreviewtoolkit.utils.common.stashDirectories import org.ossreviewtoolkit.utils.common.textValueOrEmpty +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + /** * The [CocoaPods](https://cocoapods.org/) package manager for Objective-C. * @@ -93,7 +94,7 @@ class CocoaPods( override fun command(workingDir: File?) = "pod" - override fun getVersionRequirement(): Requirement = Requirement.buildIvy("[1.11.0,)") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("[1.11.0,)") override fun getVersionArguments() = "--version --allow-root" diff --git a/analyzer/src/main/kotlin/managers/Composer.kt b/analyzer/src/main/kotlin/managers/Composer.kt index 3dd51176e0b5e..485ecd57d1888 100644 --- a/analyzer/src/main/kotlin/managers/Composer.kt +++ b/analyzer/src/main/kotlin/managers/Composer.kt @@ -22,8 +22,6 @@ package org.ossreviewtoolkit.analyzer.managers import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.node.ObjectNode -import com.vdurmont.semver4j.Requirement - import java.io.File import java.io.IOException import java.util.SortedSet @@ -58,6 +56,9 @@ import org.ossreviewtoolkit.utils.common.stashDirectories import org.ossreviewtoolkit.utils.common.textValueOrEmpty import org.ossreviewtoolkit.utils.ort.showStackTrace +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + const val COMPOSER_PHAR_BINARY = "composer.phar" const val COMPOSER_LOCK_FILE = "composer.lock" @@ -108,7 +109,7 @@ class Composer( // Composer version @package_branch_alias_version@ (1.0.0-beta2) 2016-03-27 16:00:34 output.splitOnWhitespace().dropLast(2).last().removeSurrounding("(", ")") - override fun getVersionRequirement(): Requirement = Requirement.buildIvy("[1.5,)") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("[1.5,)") override fun beforeResolution(definitionFiles: List) { // If all directories we are analyzing contain a composer.phar, no global installation of Composer is required diff --git a/analyzer/src/main/kotlin/managers/Conan.kt b/analyzer/src/main/kotlin/managers/Conan.kt index f1a945e4348f4..68b1ad260ed17 100644 --- a/analyzer/src/main/kotlin/managers/Conan.kt +++ b/analyzer/src/main/kotlin/managers/Conan.kt @@ -22,8 +22,6 @@ package org.ossreviewtoolkit.analyzer.managers import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.module.kotlin.readValue -import com.vdurmont.semver4j.Requirement - import java.io.File import java.util.SortedSet @@ -57,6 +55,9 @@ import org.ossreviewtoolkit.utils.common.toUri import org.ossreviewtoolkit.utils.ort.createOrtTempDir import org.ossreviewtoolkit.utils.ort.requestPasswordAuthentication +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + /** * The [Conan](https://conan.io/) package manager for C / C++. * @@ -114,7 +115,7 @@ class Conan( // Conan version 1.18.0 output.removePrefix("Conan version ") - override fun getVersionRequirement(): Requirement = Requirement.buildIvy("[1.18.0,)") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("[1.18.0,)") override fun beforeResolution(definitionFiles: List) = checkVersion() diff --git a/analyzer/src/main/kotlin/managers/Npm.kt b/analyzer/src/main/kotlin/managers/Npm.kt index 666f729cbe6c6..a436c48a5321f 100644 --- a/analyzer/src/main/kotlin/managers/Npm.kt +++ b/analyzer/src/main/kotlin/managers/Npm.kt @@ -24,8 +24,6 @@ package org.ossreviewtoolkit.analyzer.managers import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.databind.node.ObjectNode -import com.vdurmont.semver4j.Requirement - import java.io.File import java.util.concurrent.ConcurrentHashMap @@ -81,6 +79,9 @@ import org.ossreviewtoolkit.utils.common.realFile import org.ossreviewtoolkit.utils.common.stashDirectories import org.ossreviewtoolkit.utils.common.textValueOrEmpty +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + /** * The [Node package manager](https://www.npmjs.com/) for JavaScript. * @@ -145,7 +146,7 @@ open class Npm( override fun command(workingDir: File?) = if (Os.isWindows) "npm.cmd" else "npm" - override fun getVersionRequirement(): Requirement = Requirement.buildNPM("6.* - 8.*") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("6.* - 8.*") override fun mapDefinitionFiles(definitionFiles: List) = mapDefinitionFilesForNpm(definitionFiles).toList() diff --git a/analyzer/src/main/kotlin/managers/Pipenv.kt b/analyzer/src/main/kotlin/managers/Pipenv.kt index 2b9cffc77eb66..14f3bab40e5e7 100644 --- a/analyzer/src/main/kotlin/managers/Pipenv.kt +++ b/analyzer/src/main/kotlin/managers/Pipenv.kt @@ -19,9 +19,6 @@ package org.ossreviewtoolkit.analyzer.managers -import com.vdurmont.semver4j.Requirement -import com.vdurmont.semver4j.Semver - import java.io.File import org.apache.logging.log4j.kotlin.Logging @@ -34,6 +31,10 @@ import org.ossreviewtoolkit.model.config.RepositoryConfiguration import org.ossreviewtoolkit.utils.common.CommandLineTool import org.ossreviewtoolkit.utils.common.ProcessCapture +import org.semver4j.RangesList +import org.semver4j.RangesListFactory +import org.semver4j.Semver + /** * The version that introduced the requirements command. */ @@ -64,7 +65,7 @@ class Pipenv( // pipenv, version 2018.11.26 output.removePrefix("pipenv, version ") - override fun getVersionRequirement(): Requirement = Requirement.buildIvy("[2018.10.9,)") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("[2018.10.9,)") override fun beforeResolution(definitionFiles: List) = checkVersion() diff --git a/analyzer/src/main/kotlin/managers/Pnpm.kt b/analyzer/src/main/kotlin/managers/Pnpm.kt index 022ad458f055e..8bd58041f0146 100644 --- a/analyzer/src/main/kotlin/managers/Pnpm.kt +++ b/analyzer/src/main/kotlin/managers/Pnpm.kt @@ -19,8 +19,6 @@ package org.ossreviewtoolkit.analyzer.managers -import com.vdurmont.semver4j.Requirement - import java.io.File import org.ossreviewtoolkit.analyzer.AbstractPackageManagerFactory @@ -31,6 +29,9 @@ import org.ossreviewtoolkit.model.config.RepositoryConfiguration import org.ossreviewtoolkit.utils.common.Os import org.ossreviewtoolkit.utils.common.realFile +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + /** * The [fast, disk space efficient package manager](https://pnpm.io/). */ @@ -69,7 +70,7 @@ class Pnpm( override fun command(workingDir: File?) = if (Os.isWindows) "pnpm.cmd" else "pnpm" - override fun getVersionRequirement(): Requirement = Requirement.buildNPM("5.* - 7.*") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("5.* - 7.*") override fun mapDefinitionFiles(definitionFiles: List) = mapDefinitionFilesForPnpm(definitionFiles).toList() diff --git a/analyzer/src/main/kotlin/managers/Pub.kt b/analyzer/src/main/kotlin/managers/Pub.kt index da6f9e2ec1fdd..3b285f92118f0 100644 --- a/analyzer/src/main/kotlin/managers/Pub.kt +++ b/analyzer/src/main/kotlin/managers/Pub.kt @@ -22,8 +22,6 @@ package org.ossreviewtoolkit.analyzer.managers import com.fasterxml.jackson.databind.JsonNode import com.fasterxml.jackson.dataformat.yaml.JacksonYAMLParseException -import com.vdurmont.semver4j.Requirement - import java.io.File import java.io.IOException import java.util.SortedSet @@ -68,6 +66,9 @@ import org.ossreviewtoolkit.utils.ort.OkHttpClientHelper import org.ossreviewtoolkit.utils.ort.ortToolsDirectory import org.ossreviewtoolkit.utils.ort.showStackTrace +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + private const val GRADLE_VERSION = "7.3" private const val PUBSPEC_YAML = "pubspec.yaml" private const val PUB_LOCK_FILE = "pubspec.lock" @@ -121,7 +122,7 @@ class Pub( override fun transformVersion(output: String) = output.removePrefix("Dart SDK version: ").substringBefore(' ') - override fun getVersionRequirement(): Requirement = Requirement.buildIvy("[2.10,)") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("[2.10,)") override fun beforeResolution(definitionFiles: List) { gradleDefinitionFilesForPubDefinitionFiles.clear() diff --git a/analyzer/src/main/kotlin/managers/Sbt.kt b/analyzer/src/main/kotlin/managers/Sbt.kt index 285cdd7a6fa50..3ea0e95707695 100644 --- a/analyzer/src/main/kotlin/managers/Sbt.kt +++ b/analyzer/src/main/kotlin/managers/Sbt.kt @@ -19,9 +19,6 @@ package org.ossreviewtoolkit.analyzer.managers -import com.vdurmont.semver4j.Requirement -import com.vdurmont.semver4j.Semver - import java.io.File import java.io.IOException import java.nio.file.StandardCopyOption @@ -43,6 +40,10 @@ import org.ossreviewtoolkit.utils.common.searchUpwardsForSubdirectory import org.ossreviewtoolkit.utils.common.suppressInput import org.ossreviewtoolkit.utils.ort.createOrtTempDir +import org.semver4j.RangesList +import org.semver4j.RangesListFactory +import org.semver4j.Semver + /** * The [SBT](https://www.scala-sbt.org/) package manager for Scala. */ @@ -121,11 +122,11 @@ class Sbt( return checkForSameSbtVersion(versions) } - override fun getVersionRequirement(): Requirement = + override fun getVersionRequirement(): RangesList = // We need at least sbt version 0.13.0 to be able to use "makePom" instead of the deprecated hyphenated // form "make-pom" and to support declaring Maven-style repositories, see // http://www.scala-sbt.org/0.13/docs/Publishing.html#Modifying+the+generated+POM. - Requirement.buildIvy("[0.13.0,)") + RangesListFactory.create("[0.13.0,)") private fun checkForSameSbtVersion(versions: List): String { val uniqueVersions = versions.toSortedSet() @@ -202,7 +203,7 @@ class Sbt( val sbtVersionRequirement = getVersionRequirement() val lowestSbtVersion = checkForSameSbtVersion(versions) - if (!sbtVersionRequirement.isSatisfiedBy(lowestSbtVersion)) { + if (!Semver(lowestSbtVersion).satisfies(sbtVersionRequirement)) { throw IOException( "Unsupported $managerName version $lowestSbtVersion does not fulfill " + "$sbtVersionRequirement." diff --git a/analyzer/src/main/kotlin/managers/Stack.kt b/analyzer/src/main/kotlin/managers/Stack.kt index 0bf8e7069a96c..b14c6aa71f94f 100644 --- a/analyzer/src/main/kotlin/managers/Stack.kt +++ b/analyzer/src/main/kotlin/managers/Stack.kt @@ -22,8 +22,6 @@ package org.ossreviewtoolkit.analyzer.managers import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.module.kotlin.readValue -import com.vdurmont.semver4j.Requirement - import java.io.File import java.io.IOException import java.util.SortedSet @@ -52,6 +50,9 @@ import org.ossreviewtoolkit.utils.common.ProcessCapture import org.ossreviewtoolkit.utils.common.safeDeleteRecursively import org.ossreviewtoolkit.utils.ort.OkHttpClientHelper +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + /** * The [Stack](https://haskellstack.org/) package manager for Haskell. */ @@ -103,7 +104,7 @@ class Stack( // Version 2.1.1, Git revision f612ea85316bbc327a64e4ad8d9f0b150dc12d4b (7648 commits) x86_64 hpack-0.31.2 output.removePrefix("Version ").substringBefore(',').substringBefore(' ') - override fun getVersionRequirement(): Requirement = Requirement.buildIvy("[2.1.1,)") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("[2.1.1,)") override fun beforeResolution(definitionFiles: List) = checkVersion() diff --git a/analyzer/src/main/kotlin/managers/Yarn.kt b/analyzer/src/main/kotlin/managers/Yarn.kt index 064582e255ae7..380c639bfface 100644 --- a/analyzer/src/main/kotlin/managers/Yarn.kt +++ b/analyzer/src/main/kotlin/managers/Yarn.kt @@ -21,8 +21,6 @@ package org.ossreviewtoolkit.analyzer.managers import com.fasterxml.jackson.databind.JsonNode -import com.vdurmont.semver4j.Requirement - import java.io.File import kotlin.time.Duration.Companion.days @@ -40,6 +38,9 @@ import org.ossreviewtoolkit.utils.common.Os import org.ossreviewtoolkit.utils.common.mebibytes import org.ossreviewtoolkit.utils.ort.ortDataDirectory +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + private val yarnInfoCache = DiskCache( directory = ortDataDirectory.resolve("cache/analyzer/yarn/info"), maxCacheSizeInBytes = 100.mebibytes, @@ -71,7 +72,7 @@ class Yarn( override fun command(workingDir: File?) = if (Os.isWindows) "yarn.cmd" else "yarn" - override fun getVersionRequirement(): Requirement = Requirement.buildNPM("1.3.* - 1.22.*") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("1.3.* - 1.22.*") override fun mapDefinitionFiles(definitionFiles: List) = mapDefinitionFilesForYarn(definitionFiles).toList() diff --git a/analyzer/src/main/kotlin/managers/Yarn2.kt b/analyzer/src/main/kotlin/managers/Yarn2.kt index 1534fa4e1f6e2..edbdc0d810013 100644 --- a/analyzer/src/main/kotlin/managers/Yarn2.kt +++ b/analyzer/src/main/kotlin/managers/Yarn2.kt @@ -25,8 +25,6 @@ import com.fasterxml.jackson.databind.node.NullNode import com.fasterxml.jackson.databind.node.ObjectNode import com.fasterxml.jackson.module.kotlin.readValues -import com.vdurmont.semver4j.Requirement - import java.io.File import kotlinx.coroutines.Dispatchers @@ -72,6 +70,9 @@ import org.ossreviewtoolkit.utils.common.ProcessCapture import org.ossreviewtoolkit.utils.common.textValueOrEmpty import org.ossreviewtoolkit.utils.ort.showStackTrace +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + internal const val OPTION_DISABLE_REGISTRY_CERTIFICATE_VERIFICATION = "disableRegistryCertificateVerification" // The various Yarn dependency types supported by this package manager. @@ -189,7 +190,7 @@ class Yarn2( // TODO: An alternative would be to collate the versions of all tools in `yarn2CommandsByPath`. if (workingDir == null) "" else super.getVersion(workingDir) - override fun getVersionRequirement(): Requirement = Requirement.buildNPM(">=2.0.0") + override fun getVersionRequirement(): RangesList = RangesListFactory.create(">=2.0.0") override fun mapDefinitionFiles(definitionFiles: List) = mapDefinitionFilesForYarn2(definitionFiles).toList() diff --git a/analyzer/src/main/kotlin/managers/utils/PythonInspector.kt b/analyzer/src/main/kotlin/managers/utils/PythonInspector.kt index a31add3bf3c17..433cdd566d6f0 100644 --- a/analyzer/src/main/kotlin/managers/utils/PythonInspector.kt +++ b/analyzer/src/main/kotlin/managers/utils/PythonInspector.kt @@ -19,8 +19,6 @@ package org.ossreviewtoolkit.analyzer.managers.utils -import com.vdurmont.semver4j.Requirement - import java.io.File import java.util.SortedSet @@ -48,6 +46,9 @@ import org.ossreviewtoolkit.utils.ort.ProcessedDeclaredLicense import org.ossreviewtoolkit.utils.ort.createOrtTempFile import org.ossreviewtoolkit.utils.spdx.SpdxLicenseIdExpression +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + private const val GENERIC_BSD_LICENSE = "BSD License" private const val SHORT_STRING_MAX_CHARS = 200 @@ -58,7 +59,7 @@ internal object PythonInspector : CommandLineTool, Logging { override fun transformVersion(output: String) = output.removePrefix("Python-inspector version: ") - override fun getVersionRequirement(): Requirement = Requirement.buildIvy("[0.9.2,)") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("[0.9.2,)") fun run( workingDir: File, diff --git a/cli/src/main/kotlin/commands/RequirementsCommand.kt b/cli/src/main/kotlin/commands/RequirementsCommand.kt index 53f0e9830f7b0..24b31d79b8485 100644 --- a/cli/src/main/kotlin/commands/RequirementsCommand.kt +++ b/cli/src/main/kotlin/commands/RequirementsCommand.kt @@ -37,6 +37,8 @@ import org.ossreviewtoolkit.utils.spdx.scanCodeLicenseTextDir import org.reflections.Reflections +import org.semver4j.Semver + class RequirementsCommand : OrtCommand( name = "requirements", help = "Check for the command line tools required by ORT." @@ -120,7 +122,7 @@ class RequirementsCommand : OrtCommand( val actualVersion = tool.getVersion() runCatching { val isRequiredVersion = tool.getVersionRequirement().let { - it == CommandLineTool.ANY_VERSION || it.isSatisfiedBy(actualVersion) + Semver.coerce(actualVersion).satisfies(it) } if (isRequiredVersion) { @@ -134,7 +136,7 @@ class RequirementsCommand : OrtCommand( Pair("\t+ ", "Found version '$actualVersion'.") } }.getOrElse { - if (tool.getVersionRequirement() != CommandLineTool.ANY_VERSION) { + if (!tool.getVersionRequirement().isSatisfiedByAny) { statusCode = statusCode or 2 } @@ -155,7 +157,7 @@ class RequirementsCommand : OrtCommand( append(prefix) append("${tool.javaClass.simpleName}: Requires '${tool.command()}' in ") - if (tool.getVersionRequirement() == CommandLineTool.ANY_VERSION) { + if (tool.getVersionRequirement().isSatisfiedByAny) { append("no specific version. ") } else { append("version ${tool.getVersionRequirement()}. ") diff --git a/downloader/src/main/kotlin/VersionControlSystem.kt b/downloader/src/main/kotlin/VersionControlSystem.kt index 99e719ec9bb0d..483fa186b19c1 100644 --- a/downloader/src/main/kotlin/VersionControlSystem.kt +++ b/downloader/src/main/kotlin/VersionControlSystem.kt @@ -19,8 +19,6 @@ package org.ossreviewtoolkit.downloader -import com.vdurmont.semver4j.Semver - import java.io.File import java.io.IOException import java.util.ServiceLoader @@ -38,6 +36,8 @@ import org.ossreviewtoolkit.utils.common.uppercaseFirstChar import org.ossreviewtoolkit.utils.ort.ORT_REPO_CONFIG_FILENAME import org.ossreviewtoolkit.utils.ort.showStackTrace +import org.semver4j.Semver + abstract class VersionControlSystem { companion object : Logging { private val LOADER = ServiceLoader.load(VersionControlSystem::class.java) @@ -404,7 +404,7 @@ abstract class VersionControlSystem { * Check whether the VCS tool is at least of the specified [expectedVersion], e.g. to check for features. */ fun isAtLeastVersion(expectedVersion: String): Boolean { - val actualVersion = Semver(getVersion(), Semver.SemverType.LOOSE) - return actualVersion.isGreaterThanOrEqualTo(expectedVersion) + val actualVersion = Semver.coerce(getVersion()) + return actualVersion.isGreaterThanOrEqualTo(Semver.coerce(expectedVersion)) } } diff --git a/downloader/src/main/kotlin/vcs/Git.kt b/downloader/src/main/kotlin/vcs/Git.kt index 2656aac4e3bc1..18d9a33c57f58 100644 --- a/downloader/src/main/kotlin/vcs/Git.kt +++ b/downloader/src/main/kotlin/vcs/Git.kt @@ -19,8 +19,6 @@ package org.ossreviewtoolkit.downloader.vcs -import com.vdurmont.semver4j.Requirement - import java.io.File import java.io.IOException import java.net.Authenticator @@ -57,6 +55,9 @@ import org.ossreviewtoolkit.utils.common.safeMkdirs import org.ossreviewtoolkit.utils.ort.requestPasswordAuthentication import org.ossreviewtoolkit.utils.ort.showStackTrace +import org.semver4j.RangesList +import org.semver4j.RangesListFactory + // TODO: Make this configurable. const val GIT_HISTORY_DEPTH = 50 @@ -108,7 +109,7 @@ class Git : VersionControlSystem(), CommandLineTool { override fun getVersion() = getVersion(null) // Require at least Git 2.29 on the client side as it has protocol "v2" enabled by default. - override fun getVersionRequirement(): Requirement = Requirement.buildIvy("[2.29,)") + override fun getVersionRequirement(): RangesList = RangesListFactory.create("[2.29,)") override fun getDefaultBranchName(url: String): String { val refs = Git.lsRemoteRepository().setRemote(url).callAsMap() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1a26d705fa817..b9c83b0816861 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -54,7 +54,7 @@ retrofit = "2.9.0" retrofitConverterKotlinxSerialization = "0.8.0" saxonHe = "11.4" scanoss = "1.1.6" -semver4j = "3.1.0" +semver4j = "4.1.1" springCore = "5.3.24" svnkit = "1.10.9" sw360Client = "16.0.0-m1" @@ -144,7 +144,7 @@ retrofitConverterKotlinxSerialization = { module = "com.jakewharton.retrofit:ret retrofitConverterScalars = { module = "com.squareup.retrofit2:converter-scalars", version.ref = "retrofit" } saxonHe = { module = "net.sf.saxon:Saxon-HE", version.ref = "saxonHe" } scanoss = { module = "com.scanoss:scanner", version.ref = "scanoss" } -semver4j = { module = "com.vdurmont:semver4j", version.ref = "semver4j" } +semver4j = { module = "org.semver4j:semver4j", version.ref = "semver4j" } springCore = { module = "org.springframework:spring-core", version.ref = "springCore" } svnkit = { module = "org.tmatesoft.svnkit:svnkit", version.ref = "svnkit" } sw360Client = { module = "org.eclipse.sw360:client", version.ref = "sw360Client" } diff --git a/model/src/main/kotlin/PackageCuration.kt b/model/src/main/kotlin/PackageCuration.kt index 57931bf2e81ba..3eb2f975d0137 100644 --- a/model/src/main/kotlin/PackageCuration.kt +++ b/model/src/main/kotlin/PackageCuration.kt @@ -21,13 +21,12 @@ package org.ossreviewtoolkit.model import com.fasterxml.jackson.annotation.JsonProperty -import com.vdurmont.semver4j.Requirement -import com.vdurmont.semver4j.Semver - import org.apache.logging.log4j.kotlin.Logging import org.ossreviewtoolkit.utils.ort.showStackTrace +import org.semver4j.Semver + /** * Return true if this string equals the [other] string, or if either string is blank. */ @@ -65,10 +64,7 @@ data class PackageCuration( */ private fun isApplicableIvyVersion(pkgId: Identifier) = runCatching { - // TODO: This check does not completely comply to the Ivy version-matchers specification. E.g. the version - // '1.0' does not satisfy the version range [1.0,2.0], see - // https://github.com/vdurmont/semver4j/issues/67. - Requirement.buildIvy(id.version).isSatisfiedBy(Semver(pkgId.version, Semver.SemverType.LOOSE)) + Semver.coerce(pkgId.version).satisfies(id.version) }.onFailure { logger.warn { "Failed to check if package curation version '${id.version}' is applicable to package version " + diff --git a/scanner/src/funTest/kotlin/storages/AbstractProvenanceBasedStorageFunTest.kt b/scanner/src/funTest/kotlin/storages/AbstractProvenanceBasedStorageFunTest.kt index abf2b1b23ad41..0abae62c62871 100644 --- a/scanner/src/funTest/kotlin/storages/AbstractProvenanceBasedStorageFunTest.kt +++ b/scanner/src/funTest/kotlin/storages/AbstractProvenanceBasedStorageFunTest.kt @@ -19,8 +19,6 @@ package org.ossreviewtoolkit.scanner.storages -import com.vdurmont.semver4j.Semver - import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.listeners.TestListener import io.kotest.core.spec.style.WordSpec @@ -47,6 +45,8 @@ import org.ossreviewtoolkit.scanner.ProvenanceBasedScanStorage import org.ossreviewtoolkit.scanner.ScanStorageException import org.ossreviewtoolkit.scanner.ScannerCriteria +import org.semver4j.Semver + abstract class AbstractProvenanceBasedStorageFunTest(vararg listeners: TestListener) : WordSpec() { private lateinit var storage: ProvenanceBasedScanStorage diff --git a/scanner/src/funTest/kotlin/storages/AbstractStorageFunTest.kt b/scanner/src/funTest/kotlin/storages/AbstractStorageFunTest.kt index dea2c15569ebc..2674b2ef800be 100644 --- a/scanner/src/funTest/kotlin/storages/AbstractStorageFunTest.kt +++ b/scanner/src/funTest/kotlin/storages/AbstractStorageFunTest.kt @@ -19,8 +19,6 @@ package org.ossreviewtoolkit.scanner.storages -import com.vdurmont.semver4j.Semver - import io.kotest.core.listeners.TestListener import io.kotest.core.spec.style.WordSpec import io.kotest.matchers.collections.beEmpty @@ -52,6 +50,8 @@ import org.ossreviewtoolkit.model.VcsType import org.ossreviewtoolkit.scanner.ScanResultsStorage import org.ossreviewtoolkit.scanner.ScannerCriteria +import org.semver4j.Semver + private val DUMMY_TEXT_LOCATION = TextLocation("fakepath", 13, 21) abstract class AbstractStorageFunTest(vararg listeners: TestListener) : WordSpec() { diff --git a/scanner/src/main/kotlin/ScannerCriteria.kt b/scanner/src/main/kotlin/ScannerCriteria.kt index 5b32b27584583..788ed6b4993a4 100644 --- a/scanner/src/main/kotlin/ScannerCriteria.kt +++ b/scanner/src/main/kotlin/ScannerCriteria.kt @@ -19,11 +19,12 @@ package org.ossreviewtoolkit.scanner -import com.vdurmont.semver4j.Semver - import org.ossreviewtoolkit.model.ScannerDetails import org.ossreviewtoolkit.model.config.ScannerConfiguration +import org.semver4j.Semver +import org.semver4j.Semver.VersionDiff + /** * Definition of a predicate to check whether the configuration of a scanner is compatible with the requirements * specified by a [ScannerCriteria]. @@ -106,14 +107,14 @@ data class ScannerCriteria( */ fun forDetails( details: ScannerDetails, - versionDiff: Semver.VersionDiff = Semver.VersionDiff.NONE + versionDiff: VersionDiff = VersionDiff.NONE ): ScannerCriteria { val minVersion = Semver(details.version) val maxVersion = when (versionDiff) { - Semver.VersionDiff.NONE, Semver.VersionDiff.SUFFIX, Semver.VersionDiff.BUILD -> minVersion.nextPatch() - Semver.VersionDiff.PATCH -> minVersion.nextMinor() - Semver.VersionDiff.MINOR -> minVersion.nextMajor() + VersionDiff.NONE, VersionDiff.PRE_RELEASE, VersionDiff.BUILD -> minVersion.nextPatch() + VersionDiff.PATCH -> minVersion.nextMinor() + VersionDiff.MINOR -> minVersion.nextMajor() else -> throw IllegalArgumentException("Invalid version difference $versionDiff") } diff --git a/scanner/src/main/kotlin/scanners/scancode/ScanCodeResultParser.kt b/scanner/src/main/kotlin/scanners/scancode/ScanCodeResultParser.kt index c0b3fec8e3c2c..7ba999b693db2 100644 --- a/scanner/src/main/kotlin/scanners/scancode/ScanCodeResultParser.kt +++ b/scanner/src/main/kotlin/scanners/scancode/ScanCodeResultParser.kt @@ -23,8 +23,6 @@ package org.ossreviewtoolkit.scanner.scanners.scancode import com.fasterxml.jackson.databind.JsonNode -import com.vdurmont.semver4j.Semver - import java.io.File import java.time.Instant import java.time.ZoneId @@ -43,6 +41,8 @@ import org.ossreviewtoolkit.utils.spdx.SpdxConstants.LICENSE_REF_PREFIX import org.ossreviewtoolkit.utils.spdx.calculatePackageVerificationCode import org.ossreviewtoolkit.utils.spdx.toSpdxId +import org.semver4j.Semver + internal val SCANCODE_TIMESTAMP_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HHmmss.n").withZone(ZoneId.of("UTC")) diff --git a/scanner/src/test/kotlin/ScannerCriteriaTest.kt b/scanner/src/test/kotlin/ScannerCriteriaTest.kt index 3e8a78acc5ed5..2fdbbb6238ac7 100644 --- a/scanner/src/test/kotlin/ScannerCriteriaTest.kt +++ b/scanner/src/test/kotlin/ScannerCriteriaTest.kt @@ -19,8 +19,6 @@ package org.ossreviewtoolkit.scanner -import com.vdurmont.semver4j.Semver - import io.kotest.core.spec.style.WordSpec import io.kotest.matchers.shouldBe @@ -28,6 +26,8 @@ import org.ossreviewtoolkit.model.ScannerDetails import org.ossreviewtoolkit.model.config.Options import org.ossreviewtoolkit.model.config.ScannerConfiguration +import org.semver4j.Semver + class ScannerCriteriaTest : WordSpec({ "ScannerCriteria" should { "provide a config matcher that accepts every configuration" { @@ -75,7 +75,7 @@ class ScannerCriteriaTest : WordSpec({ val criteria = ScannerCriteria.fromConfig(testDetails, config) criteria.regScannerName shouldBe SCANNER_NAME - criteria.minVersion.originalValue shouldBe SCANNER_VERSION + criteria.minVersion.version shouldBe SCANNER_VERSION criteria.maxVersion shouldBe Semver(SCANNER_VERSION).nextMinor() } @@ -91,8 +91,8 @@ class ScannerCriteriaTest : WordSpec({ val criteria = ScannerCriteria.fromConfig(testDetails, config) criteria.regScannerName shouldBe "foo" - criteria.minVersion.originalValue shouldBe "1.2.3" - criteria.maxVersion.originalValue shouldBe "4.5.6" + criteria.minVersion.version shouldBe "1.2.3" + criteria.maxVersion.version shouldBe "4.5.6" } "parse versions in a lenient way" { @@ -105,8 +105,8 @@ class ScannerCriteriaTest : WordSpec({ val criteria = ScannerCriteria.fromConfig(testDetails, config) - criteria.minVersion.originalValue shouldBe "1.0.0" - criteria.maxVersion.originalValue shouldBe "3.7.0" + criteria.minVersion.version shouldBe "1.0.0" + criteria.maxVersion.version shouldBe "3.7.0" } "use an exact configuration matcher" { diff --git a/scanner/src/test/kotlin/storages/ClearlyDefinedStorageTest.kt b/scanner/src/test/kotlin/storages/ClearlyDefinedStorageTest.kt index 0b137e642f6c2..b07eb908a5d6d 100644 --- a/scanner/src/test/kotlin/storages/ClearlyDefinedStorageTest.kt +++ b/scanner/src/test/kotlin/storages/ClearlyDefinedStorageTest.kt @@ -29,8 +29,6 @@ import com.github.tomakehurst.wiremock.client.WireMock.post import com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo import com.github.tomakehurst.wiremock.core.WireMockConfiguration -import com.vdurmont.semver4j.Semver - import io.kotest.core.spec.style.WordSpec import io.kotest.matchers.collections.beEmpty import io.kotest.matchers.collections.shouldHaveSize @@ -63,6 +61,8 @@ import org.ossreviewtoolkit.model.VcsType import org.ossreviewtoolkit.model.config.ClearlyDefinedStorageConfiguration import org.ossreviewtoolkit.scanner.ScannerCriteria +import org.semver4j.Semver + private const val PACKAGE_TYPE = "Maven" private const val NAMESPACE = "someNamespace" private const val NAME = "somePackage" diff --git a/utils/common/src/main/kotlin/CommandLineTool.kt b/utils/common/src/main/kotlin/CommandLineTool.kt index 5908eff11b274..b2a9d68a3fe88 100644 --- a/utils/common/src/main/kotlin/CommandLineTool.kt +++ b/utils/common/src/main/kotlin/CommandLineTool.kt @@ -19,12 +19,14 @@ package org.ossreviewtoolkit.utils.common -import com.vdurmont.semver4j.Requirement - import java.io.File import org.apache.logging.log4j.kotlin.Logging +import org.semver4j.RangesList +import org.semver4j.RangesListFactory +import org.semver4j.Semver + /** * An interface to implement by classes that are backed by a command line tool. */ @@ -33,7 +35,7 @@ interface CommandLineTool { /** * A convenience property to require any version. */ - val ANY_VERSION: Requirement = Requirement.buildNPM("*") + val ANY_VERSION: RangesList = RangesListFactory.create("*") } /** @@ -99,10 +101,10 @@ interface CommandLineTool { * Run a [command] to check its version against the [required version][getVersionRequirement]. */ fun checkVersion(workingDir: File? = null) { - val actualVersion = getVersion(workingDir) + val actualVersion = Semver.coerce(getVersion(workingDir)) val requiredVersion = getVersionRequirement() - if (!requiredVersion.isSatisfiedBy(actualVersion)) { + if (!actualVersion.satisfies(requiredVersion)) { logger.warn { "The command is required in version $requiredVersion, but you are using version $actualVersion. This " + "could lead to problems."