From a580823a797347bb5d8769bcda3eb112a33cfb7e Mon Sep 17 00:00:00 2001 From: Joan Goyeau Date: Tue, 26 Sep 2023 09:17:21 -0400 Subject: [PATCH] Ability to lift a ScalaVersion from a String --- .../scalacoptions/ScalaVersion.scala | 11 ++++ .../scalacoptions/ScalaVersionSuite.scala | 56 +++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 lib/src/test/scala/org/typelevel/scalacoptions/ScalaVersionSuite.scala diff --git a/lib/src/main/scala/org/typelevel/scalacoptions/ScalaVersion.scala b/lib/src/main/scala/org/typelevel/scalacoptions/ScalaVersion.scala index 74b577e..d2bedf1 100644 --- a/lib/src/main/scala/org/typelevel/scalacoptions/ScalaVersion.scala +++ b/lib/src/main/scala/org/typelevel/scalacoptions/ScalaVersion.scala @@ -44,6 +44,17 @@ object ScalaVersion { val V3_3_0 = ScalaVersion(3, 3, 0) val V3_3_1 = ScalaVersion(3, 3, 1) + private val versionRegex = raw"""(\d+)\.(\d+)\.(\d+)(?:-.*)?""".r + def fromString(version: String): Either[IllegalArgumentException, ScalaVersion] = + version match { + case versionRegex(major, minor, patch) => + Right(ScalaVersion(major.toLong, minor.toLong, patch.toLong)) + case _ => Left(new IllegalArgumentException(s"Scala version $version not recognized")) + } + + def unsafeFromString(version: String): ScalaVersion = + fromString(version).fold(throw _, identity) + implicit val scalaVersionOrdering: Ordering[ScalaVersion] = Ordering.by(version => (version.major, version.minor, version.patch)) } diff --git a/lib/src/test/scala/org/typelevel/scalacoptions/ScalaVersionSuite.scala b/lib/src/test/scala/org/typelevel/scalacoptions/ScalaVersionSuite.scala new file mode 100644 index 0000000..20476e8 --- /dev/null +++ b/lib/src/test/scala/org/typelevel/scalacoptions/ScalaVersionSuite.scala @@ -0,0 +1,56 @@ +/* + * Copyright 2022 Typelevel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.typelevel.scalacoptions + +import org.scalacheck.Gen +import org.scalacheck.Prop.forAll + +class ScalaVersionSuite extends munit.ScalaCheckSuite { + val versionGen = Gen.chooseNum(0L, 20L) + + property("fromString parse a version") { + forAll(versionGen, versionGen, versionGen) { + (currentMaj: Long, currentMin: Long, currentPatch: Long) => + val version = ScalaVersion.fromString(s"$currentMaj.$currentMin.$currentPatch") + assertEquals(version, Right(ScalaVersion(currentMaj, currentMin, currentPatch))) + } + } + + property("fromString parse an RC version") { + forAll(versionGen, versionGen, versionGen) { + (currentMaj: Long, currentMin: Long, currentPatch: Long) => + val version = ScalaVersion.fromString(s"$currentMaj.$currentMin.$currentPatch-RC3") + assertEquals(version, Right(ScalaVersion(currentMaj, currentMin, currentPatch))) + } + } + + property("fromString parse a NIGHTLY version") { + forAll(versionGen, versionGen, versionGen) { + (currentMaj: Long, currentMin: Long, currentPatch: Long) => + val version = ScalaVersion.fromString(s"$currentMaj.$currentMin.$currentPatch-RC1-bin-20231106-f61026d-NIGHTLY") + assertEquals(version, Right(ScalaVersion(currentMaj, currentMin, currentPatch))) + } + } + + property("fromString parse a commit version") { + forAll(versionGen, versionGen, versionGen) { + (currentMaj: Long, currentMin: Long, currentPatch: Long) => + val version = ScalaVersion.fromString(s"$currentMaj.$currentMin.$currentPatch-bin-80514f7") + assertEquals(version, Right(ScalaVersion(currentMaj, currentMin, currentPatch))) + } + } +}