From a527e5fec6b6f39a3963ccfe900c36482d658f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cardoso?= Date: Sun, 28 Apr 2024 12:50:41 +0100 Subject: [PATCH 1/7] Drop support for old unsupported scala versions --- .github/workflows/scala.yml | 2 +- build.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/scala.yml b/.github/workflows/scala.yml index ef15a35..4a90141 100644 --- a/.github/workflows/scala.yml +++ b/.github/workflows/scala.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - scala-version: [2.10.7, 2.11.12, 2.12.19, 2.13.13, 3.1.1] + scala-version: [2.12.19, 2.13.13, 3.1.1] steps: - name: Checkout repository and submodules uses: actions/checkout@v2 diff --git a/build.sbt b/build.sbt index 34c48ec..e4f75ad 100644 --- a/build.sbt +++ b/build.sbt @@ -28,7 +28,7 @@ scalacOptions := { } scalaVersion := "2.13.13" -crossScalaVersions := Seq("2.10.7", "2.11.12", "2.12.19", "2.13.13", "3.1.1") +crossScalaVersions := Seq("2.12.19", "2.13.13", "3.1.1") libraryDependencies += "org.yaml" % "snakeyaml" % "2.2" From 29395a58f9b326c0ddff145cd67b7616ec883a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cardoso?= Date: Sun, 28 Apr 2024 13:12:56 +0100 Subject: [PATCH 2/7] Avoid some compilation warnings --- .../org/uaparser/scala/YamlUtil.scala | 23 ++++++++++++++++++ .../org/uaparser/scala/YamlUtil.scala | 23 ++++++++++++++++++ .../scala-3/org/uaparser/scala/YamlUtil.scala | 24 +++++++++++++++++++ .../scala/org/uaparser/scala/Parser.scala | 10 +------- .../org/uaparser/scala/ParserSpecBase.scala | 7 ++---- 5 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala create mode 100644 src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala create mode 100644 src/main/scala-3/org/uaparser/scala/YamlUtil.scala diff --git a/src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala b/src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala new file mode 100644 index 0000000..28d4749 --- /dev/null +++ b/src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala @@ -0,0 +1,23 @@ +package org.uaparser.scala + +import org.yaml.snakeyaml.{LoaderOptions, Yaml} +import org.yaml.snakeyaml.constructor.SafeConstructor +import java.io.InputStream +import scala.collection.JavaConverters._ +import scala.util.Try +import org.yaml.snakeyaml.{LoaderOptions, Yaml} +import org.yaml.snakeyaml.constructor.SafeConstructor +import java.util.{List => JList, Map => JMap} + +private[scala] object YamlUtil { + def loadYamlAsMap(yamlStream: InputStream, loader: Yaml): Map[String, List[Map[String, String]]] = { + val javaConfig = loader.load[JMap[String, JList[JMap[String, String]]]](yamlStream) + javaConfig.asScala.map { case (k, v) => + k -> v.asScala.map(_.asScala.filter{case (_, v) => v != null}.toMap).toList + }.toMap + } + + def loadYamlAsMap(yamlStream: InputStream): Map[String, List[Map[String, String]]] = { + loadYamlAsMap(yamlStream, new Yaml(new SafeConstructor(new LoaderOptions))) + } +} diff --git a/src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala b/src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala new file mode 100644 index 0000000..bc2d613 --- /dev/null +++ b/src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala @@ -0,0 +1,23 @@ +package org.uaparser.scala + +import org.yaml.snakeyaml.{LoaderOptions, Yaml} +import org.yaml.snakeyaml.constructor.SafeConstructor +import java.io.InputStream +import scala.jdk.CollectionConverters._ +import org.yaml.snakeyaml.{LoaderOptions, Yaml} +import org.yaml.snakeyaml.constructor.SafeConstructor +import java.util.{List => JList, Map => JMap} + +private[scala] object YamlUtil { + + def loadYamlAsMap(yamlStream: InputStream, loader: Yaml): Map[String, List[Map[String, String]]] = { + val javaConfig = loader.load[JMap[String, JList[JMap[String, String]]]](yamlStream) + javaConfig.asScala.map { case (k, v) => + k -> v.asScala.map(_.asScala.filter{case (_, v) => v != null}.toMap).toList + }.toMap + } + + def loadYamlAsMap(yamlStream: InputStream): Map[String, List[Map[String, String]]] = { + loadYamlAsMap(yamlStream, new Yaml(new SafeConstructor(new LoaderOptions))) + } +} diff --git a/src/main/scala-3/org/uaparser/scala/YamlUtil.scala b/src/main/scala-3/org/uaparser/scala/YamlUtil.scala new file mode 100644 index 0000000..5f14d86 --- /dev/null +++ b/src/main/scala-3/org/uaparser/scala/YamlUtil.scala @@ -0,0 +1,24 @@ +package org.uaparser.scala + +import org.yaml.snakeyaml.{LoaderOptions, Yaml} +import org.yaml.snakeyaml.constructor.SafeConstructor +import java.io.InputStream +import scala.jdk.CollectionConverters._ +import scala.util.Try +import org.yaml.snakeyaml.{LoaderOptions, Yaml} +import org.yaml.snakeyaml.constructor.SafeConstructor +import java.util.{List => JList, Map => JMap} +import scala.collection.MapView + +private[scala] object YamlUtil { + def loadYamlAsMap(yamlStream: InputStream, loader: Yaml): Map[String, List[Map[String, String]]] = { + val javaConfig = loader.load[JMap[String, JList[JMap[String, String]]]](yamlStream) + javaConfig.asScala.map { case (k, v) => + k -> v.asScala.map(_.asScala.filter{case (_, v) => v != null}.toMap).toList + }.toMap + } + + def loadYamlAsMap(yamlStream: InputStream): Map[String, List[Map[String, String]]] = { + loadYamlAsMap(yamlStream, new Yaml(new SafeConstructor(new LoaderOptions)) ) + } +} diff --git a/src/main/scala/org/uaparser/scala/Parser.scala b/src/main/scala/org/uaparser/scala/Parser.scala index 17746e7..63a1820 100644 --- a/src/main/scala/org/uaparser/scala/Parser.scala +++ b/src/main/scala/org/uaparser/scala/Parser.scala @@ -1,13 +1,9 @@ package org.uaparser.scala import java.io.InputStream -import java.util.{List => JList, Map => JMap} import org.uaparser.scala.Device.DeviceParser import org.uaparser.scala.OS.OSParser import org.uaparser.scala.UserAgent.UserAgentParser -import org.yaml.snakeyaml.{LoaderOptions, Yaml} -import org.yaml.snakeyaml.constructor.SafeConstructor -import scala.collection.JavaConverters._ import scala.util.Try case class Parser(userAgentParser: UserAgentParser, osParser: OSParser, deviceParser: DeviceParser) @@ -18,11 +14,7 @@ case class Parser(userAgentParser: UserAgentParser, osParser: OSParser, devicePa object Parser { def fromInputStream(source: InputStream): Try[Parser] = Try { - val yaml = new Yaml(new SafeConstructor(new LoaderOptions)) - val javaConfig = yaml.load[JMap[String, JList[JMap[String, String]]]](source) - val config = javaConfig.asScala.toMap.mapValues(_.asScala.toList.map(_.asScala.toMap.filterNot { - case (_ , value) => value eq null - })) + val config = YamlUtil.loadYamlAsMap(source) val userAgentParser = UserAgentParser.fromList(config.getOrElse("user_agent_parsers", Nil)) val osParser = OSParser.fromList(config.getOrElse("os_parsers", Nil)) val deviceParser = DeviceParser.fromList(config.getOrElse("device_parsers", Nil)) diff --git a/src/test/scala/org/uaparser/scala/ParserSpecBase.scala b/src/test/scala/org/uaparser/scala/ParserSpecBase.scala index 39eb8e5..6d1a9c3 100644 --- a/src/test/scala/org/uaparser/scala/ParserSpecBase.scala +++ b/src/test/scala/org/uaparser/scala/ParserSpecBase.scala @@ -4,9 +4,6 @@ import org.specs2.mutable.Specification import org.yaml.snakeyaml.{LoaderOptions, Yaml} import java.io.{ByteArrayInputStream, InputStream} import java.nio.charset.StandardCharsets -import java.util.{List => JList, Map => JMap} - -import scala.collection.JavaConverters._ trait ParserSpecBase extends Specification { sequential @@ -24,8 +21,8 @@ trait ParserSpecBase extends Specification { def readCasesConfig(resource: String): List[Map[String, String]] = { val stream = this.getClass.getResourceAsStream(resource) - val cases = yaml.load[JMap[String, JList[JMap[String, String]]]](stream) - .asScala.toMap.mapValues(_.asScala.toList.map(_.asScala.toMap)) + val cases = YamlUtil.loadYamlAsMap(stream, yaml) + cases.getOrElse("test_cases", List()).filterNot(_.contains("js_ua")).map { config => config.filterNot { case (_, value) => value eq null } } From ab4803b772d6d266e6a06fb21c7ae3ef01af02d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cardoso?= Date: Wed, 1 May 2024 17:26:49 +0100 Subject: [PATCH 3/7] Remove unused imports and empty line --- src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala | 1 - src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala b/src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala index 28d4749..d25e42f 100644 --- a/src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala +++ b/src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala @@ -4,7 +4,6 @@ import org.yaml.snakeyaml.{LoaderOptions, Yaml} import org.yaml.snakeyaml.constructor.SafeConstructor import java.io.InputStream import scala.collection.JavaConverters._ -import scala.util.Try import org.yaml.snakeyaml.{LoaderOptions, Yaml} import org.yaml.snakeyaml.constructor.SafeConstructor import java.util.{List => JList, Map => JMap} diff --git a/src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala b/src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala index bc2d613..272e4e2 100644 --- a/src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala +++ b/src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala @@ -4,12 +4,9 @@ import org.yaml.snakeyaml.{LoaderOptions, Yaml} import org.yaml.snakeyaml.constructor.SafeConstructor import java.io.InputStream import scala.jdk.CollectionConverters._ -import org.yaml.snakeyaml.{LoaderOptions, Yaml} -import org.yaml.snakeyaml.constructor.SafeConstructor import java.util.{List => JList, Map => JMap} private[scala] object YamlUtil { - def loadYamlAsMap(yamlStream: InputStream, loader: Yaml): Map[String, List[Map[String, String]]] = { val javaConfig = loader.load[JMap[String, JList[JMap[String, String]]]](yamlStream) javaConfig.asScala.map { case (k, v) => From 192fed2c100f67304f7e1b0f60acfe19ee6f66a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cardoso?= Date: Wed, 1 May 2024 17:27:16 +0100 Subject: [PATCH 4/7] Make warnings fatal --- build.sbt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index e4f75ad..38b4c8c 100644 --- a/build.sbt +++ b/build.sbt @@ -4,6 +4,7 @@ name := "uap-scala" organization := "org.uaparser" scalacOptions ++= Seq( + "-Xfatal-warnings", "-deprecation", "-encoding", "UTF-8", "-feature", @@ -13,7 +14,7 @@ scalacOptions ++= Seq( val scala2Flags = Seq( "-Ywarn-dead-code", "-Ywarn-numeric-widen", - "-Xfuture" + "-Ywarn-unused:imports" ) scalacOptions := { From b0405bbea10d1c07723df16f78f90b6576f2b91e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cardoso?= Date: Sat, 4 May 2024 15:43:06 +0100 Subject: [PATCH 5/7] Avoid cross compiling different yaml loading logic Instead, create a shim for standard convert utilities. --- .../org/uaparser/scala/YamlUtil.scala | 22 ----------------- .../scala-2.12/org/uaparser/scala/scala.scala | 7 ++++++ .../scala-2.13/org/uaparser/scala/scala.scala | 7 ++++++ .../scala-3/org/uaparser/scala/YamlUtil.scala | 24 ------------------- .../scala-3/org/uaparser/scala/scala.scala | 7 ++++++ .../org/uaparser/scala/YamlUtil.scala | 6 ++--- 6 files changed, 24 insertions(+), 49 deletions(-) delete mode 100644 src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala create mode 100644 src/main/scala-2.12/org/uaparser/scala/scala.scala create mode 100644 src/main/scala-2.13/org/uaparser/scala/scala.scala delete mode 100644 src/main/scala-3/org/uaparser/scala/YamlUtil.scala create mode 100644 src/main/scala-3/org/uaparser/scala/scala.scala rename src/main/{scala-2.13 => scala}/org/uaparser/scala/YamlUtil.scala (94%) diff --git a/src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala b/src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala deleted file mode 100644 index d25e42f..0000000 --- a/src/main/scala-2.12/org/uaparser/scala/YamlUtil.scala +++ /dev/null @@ -1,22 +0,0 @@ -package org.uaparser.scala - -import org.yaml.snakeyaml.{LoaderOptions, Yaml} -import org.yaml.snakeyaml.constructor.SafeConstructor -import java.io.InputStream -import scala.collection.JavaConverters._ -import org.yaml.snakeyaml.{LoaderOptions, Yaml} -import org.yaml.snakeyaml.constructor.SafeConstructor -import java.util.{List => JList, Map => JMap} - -private[scala] object YamlUtil { - def loadYamlAsMap(yamlStream: InputStream, loader: Yaml): Map[String, List[Map[String, String]]] = { - val javaConfig = loader.load[JMap[String, JList[JMap[String, String]]]](yamlStream) - javaConfig.asScala.map { case (k, v) => - k -> v.asScala.map(_.asScala.filter{case (_, v) => v != null}.toMap).toList - }.toMap - } - - def loadYamlAsMap(yamlStream: InputStream): Map[String, List[Map[String, String]]] = { - loadYamlAsMap(yamlStream, new Yaml(new SafeConstructor(new LoaderOptions))) - } -} diff --git a/src/main/scala-2.12/org/uaparser/scala/scala.scala b/src/main/scala-2.12/org/uaparser/scala/scala.scala new file mode 100644 index 0000000..5faaaac --- /dev/null +++ b/src/main/scala-2.12/org/uaparser/scala/scala.scala @@ -0,0 +1,7 @@ +package org.uaparser + +package object scala { + object jdk { + val CollectionConverters = _root_.scala.collection.JavaConverters + } +} diff --git a/src/main/scala-2.13/org/uaparser/scala/scala.scala b/src/main/scala-2.13/org/uaparser/scala/scala.scala new file mode 100644 index 0000000..3b862ed --- /dev/null +++ b/src/main/scala-2.13/org/uaparser/scala/scala.scala @@ -0,0 +1,7 @@ +package org.uaparser + +package object scala { + object jdk { + val CollectionConverters = _root_.scala.jdk.CollectionConverters + } +} diff --git a/src/main/scala-3/org/uaparser/scala/YamlUtil.scala b/src/main/scala-3/org/uaparser/scala/YamlUtil.scala deleted file mode 100644 index 5f14d86..0000000 --- a/src/main/scala-3/org/uaparser/scala/YamlUtil.scala +++ /dev/null @@ -1,24 +0,0 @@ -package org.uaparser.scala - -import org.yaml.snakeyaml.{LoaderOptions, Yaml} -import org.yaml.snakeyaml.constructor.SafeConstructor -import java.io.InputStream -import scala.jdk.CollectionConverters._ -import scala.util.Try -import org.yaml.snakeyaml.{LoaderOptions, Yaml} -import org.yaml.snakeyaml.constructor.SafeConstructor -import java.util.{List => JList, Map => JMap} -import scala.collection.MapView - -private[scala] object YamlUtil { - def loadYamlAsMap(yamlStream: InputStream, loader: Yaml): Map[String, List[Map[String, String]]] = { - val javaConfig = loader.load[JMap[String, JList[JMap[String, String]]]](yamlStream) - javaConfig.asScala.map { case (k, v) => - k -> v.asScala.map(_.asScala.filter{case (_, v) => v != null}.toMap).toList - }.toMap - } - - def loadYamlAsMap(yamlStream: InputStream): Map[String, List[Map[String, String]]] = { - loadYamlAsMap(yamlStream, new Yaml(new SafeConstructor(new LoaderOptions)) ) - } -} diff --git a/src/main/scala-3/org/uaparser/scala/scala.scala b/src/main/scala-3/org/uaparser/scala/scala.scala new file mode 100644 index 0000000..3b862ed --- /dev/null +++ b/src/main/scala-3/org/uaparser/scala/scala.scala @@ -0,0 +1,7 @@ +package org.uaparser + +package object scala { + object jdk { + val CollectionConverters = _root_.scala.jdk.CollectionConverters + } +} diff --git a/src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala b/src/main/scala/org/uaparser/scala/YamlUtil.scala similarity index 94% rename from src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala rename to src/main/scala/org/uaparser/scala/YamlUtil.scala index 272e4e2..368758d 100644 --- a/src/main/scala-2.13/org/uaparser/scala/YamlUtil.scala +++ b/src/main/scala/org/uaparser/scala/YamlUtil.scala @@ -1,10 +1,10 @@ package org.uaparser.scala -import org.yaml.snakeyaml.{LoaderOptions, Yaml} -import org.yaml.snakeyaml.constructor.SafeConstructor import java.io.InputStream -import scala.jdk.CollectionConverters._ import java.util.{List => JList, Map => JMap} +import jdk.CollectionConverters._ +import org.yaml.snakeyaml.{LoaderOptions, Yaml} +import org.yaml.snakeyaml.constructor.SafeConstructor private[scala] object YamlUtil { def loadYamlAsMap(yamlStream: InputStream, loader: Yaml): Map[String, List[Map[String, String]]] = { From f92ea70ecd52d18de9b1cde49220f8684e260129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cardoso?= Date: Sat, 4 May 2024 16:04:22 +0100 Subject: [PATCH 6/7] Recover Xfuture/Xsource setting --- build.sbt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/build.sbt b/build.sbt index 38b4c8c..6fadf62 100644 --- a/build.sbt +++ b/build.sbt @@ -3,6 +3,9 @@ import ReleaseTransformations._ name := "uap-scala" organization := "org.uaparser" +scalaVersion := "2.13.13" +crossScalaVersions := Seq("2.12.19", "2.13.13", "3.1.1") + scalacOptions ++= Seq( "-Xfatal-warnings", "-deprecation", @@ -12,6 +15,8 @@ scalacOptions ++= Seq( ) val scala2Flags = Seq( + "-Xlint:adapted-args", + "-Xsource:2.13.13", "-Ywarn-dead-code", "-Ywarn-numeric-widen", "-Ywarn-unused:imports" @@ -21,16 +26,13 @@ scalacOptions := { CrossVersion.partialVersion(scalaVersion.value) match { case Some((3, _)) => scalacOptions.value :+ "-language:implicitConversions" - case Some((2, scalaMajor)) if scalaMajor >= 11 => - scalacOptions.value ++ scala2Flags :+ "-Xlint:adapted-args" + case Some((2, _)) => + scalacOptions.value ++ scala2Flags case _ => - scalacOptions.value ++ scala2Flags :+ "-Yno-adapted-args" + scalacOptions.value } } -scalaVersion := "2.13.13" -crossScalaVersions := Seq("2.12.19", "2.13.13", "3.1.1") - libraryDependencies += "org.yaml" % "snakeyaml" % "2.2" libraryDependencies := { From c8d87f10f487eacdafa96fcdd03253bf24b72df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Cardoso?= Date: Fri, 23 Aug 2024 15:58:58 +0100 Subject: [PATCH 7/7] Use -Xsource:3 --- build.sbt | 2 +- src/test/scala/org/uaparser/scala/CachingParserSpec.scala | 2 +- src/test/scala/org/uaparser/scala/ParserSpec.scala | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 5fa8f89..978c34d 100644 --- a/build.sbt +++ b/build.sbt @@ -16,7 +16,7 @@ scalacOptions ++= Seq( val scala2Flags = Seq( "-Xlint:adapted-args", - "-Xsource:2.13.13", + "-Xsource:3", "-Ywarn-dead-code", "-Ywarn-numeric-widen", "-Ywarn-unused:imports" diff --git a/src/test/scala/org/uaparser/scala/CachingParserSpec.scala b/src/test/scala/org/uaparser/scala/CachingParserSpec.scala index 500b13c..d7cc7b7 100644 --- a/src/test/scala/org/uaparser/scala/CachingParserSpec.scala +++ b/src/test/scala/org/uaparser/scala/CachingParserSpec.scala @@ -3,6 +3,6 @@ package org.uaparser.scala import java.io.InputStream class CachingParserSpec extends ParserSpecBase { - val parser = CachingParser.default() + val parser: CachingParser = CachingParser.default() def createFromStream(stream: InputStream): UserAgentStringParser = CachingParser.fromInputStream(stream).get } diff --git a/src/test/scala/org/uaparser/scala/ParserSpec.scala b/src/test/scala/org/uaparser/scala/ParserSpec.scala index 2258ec2..1451643 100644 --- a/src/test/scala/org/uaparser/scala/ParserSpec.scala +++ b/src/test/scala/org/uaparser/scala/ParserSpec.scala @@ -3,6 +3,6 @@ package org.uaparser.scala import java.io.InputStream class ParserSpec extends ParserSpecBase { - val parser = Parser.default + val parser: Parser = Parser.default def createFromStream(stream: InputStream): UserAgentStringParser = Parser.fromInputStream(stream).get }