From eaec152e191af2f653cc199473ee88aca62d7f6f Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Thu, 1 Sep 2022 11:34:38 +0100 Subject: [PATCH 1/2] Reenable Scala 3 Native build Additionally, fix errors on newer Scala 3 --- .github/workflows/ci.yml | 4 +- build.sbt | 41 ++++--------------- .../yaml/YamlDecoderCrossCompat.scala | 18 ++++---- .../yaml/YamlEncoderCrossCompat.scala | 15 +++---- project/plugin.sbt | 2 +- 5 files changed, 28 insertions(+), 52 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bee68f9c3..2aaeced6b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: strategy: fail-fast: false matrix: - platform: ['jvm', 'js'] # TODO restore native + platform: ['jvm', 'js', 'native'] steps: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 @@ -86,4 +86,4 @@ jobs: with: personal_token: ${{ secrets.DOC_TOKEN }} publish_dir: generated-docs/ - publish_branch: gh-pages \ No newline at end of file + publish_branch: gh-pages diff --git a/build.sbt b/build.sbt index 7c20afb43..6d320549d 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,8 @@ import BuildHelper._ -def scala3Version = "3.2.0-RC2" +def scala3Version = "3.1.3" +def scala2Version = "2.13.9" +def munitVersion = "1.0.0-M6" def projectName = "scala-yaml" def localSnapshotVersion = "0.0.5-SNAPSHOT" def isCI = System.getenv("CI") != null @@ -8,7 +10,7 @@ def isCI = System.getenv("CI") != null inThisBuild( List( organization := "org.virtuslab", - crossScalaVersions := Seq("2.13.8", scala3Version), + crossScalaVersions := Seq(scala2Version, scala3Version), scalaVersion := scala3Version, version ~= { dynVer => if (isCI) dynVer @@ -37,46 +39,17 @@ inThisBuild( ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.6.0" -lazy val core = crossProject(JSPlatform, JVMPlatform /*, NativePlatform*/ ) +lazy val core = crossProject(JSPlatform, JVMPlatform, NativePlatform) .crossType(CrossType.Full) .withoutSuffixFor(JVMPlatform) .settings( name := projectName, libraryDependencies ++= Seq(Deps.pprint % Test), - - // see https://github.com/scala-native/scala-native/blob/master/docs/changelog/0.4.3-RC1.md#cannot-create-documentation-using-scaladoc-in-scala-native-sbt-project - Compile / doc / scalacOptions ~= { options => - options.filterNot(_.startsWith("-Xplugin")) - } - ) - .jsSettings( libraryDependencies ++= List( - "org.scalameta" %%% "munit" % "0.7.29" % Test, - ("org.scala-js" %% "scalajs-test-interface" % scalaJSVersion % Test) - .cross(CrossVersion.for3Use2_13), - ("org.scala-js" %% "scalajs-junit-test-runtime" % scalaJSVersion % Test) - .cross(CrossVersion.for3Use2_13) + "org.scalameta" %%% "munit" % munitVersion % Test ) ) - // .nativeSettings( - // // skip native tests for now since upstream changes in munit are required - // Test / compile / skip := true, - // Test / test / skip := true, - - // // set dummy directory with tests to avoid unnecessary errors - // Test / unmanagedSourceDirectories := Nil - - // // libraryDependencies ++= List( - // // ("org.scalameta" %% "munit" % "0.7.29" % Test).cross(CrossVersion.for3Use2_13), - // // ("org.scala-native" %%% "test-interface" % nativeVersion % Test).cross(CrossVersion.for3Use2_13), - // // ), - // ) .settings(docsSettings) - .jvmSettings( - libraryDependencies ++= List( - "org.scalameta" %% "munit" % "0.7.29" % Test - ) - ) lazy val integration = project .in(file("integration-tests")) @@ -86,7 +59,7 @@ lazy val integration = project moduleName := "integration", publish / skip := true, libraryDependencies ++= List( - "org.scalameta" %% "munit" % "0.7.29", + "org.scalameta" %% "munit" % munitVersion, "com.lihaoyi" %% "os-lib" % "0.8.1", "com.lihaoyi" %% "pprint" % "0.7.3" ) diff --git a/core/shared/src/main/scala-3/org/virtuslab/yaml/YamlDecoderCrossCompat.scala b/core/shared/src/main/scala-3/org/virtuslab/yaml/YamlDecoderCrossCompat.scala index 71c5b7725..c9579b4e8 100644 --- a/core/shared/src/main/scala-3/org/virtuslab/yaml/YamlDecoderCrossCompat.scala +++ b/core/shared/src/main/scala-3/org/virtuslab/yaml/YamlDecoderCrossCompat.scala @@ -5,12 +5,14 @@ import org.virtuslab.yaml.Node.* import scala.compiletime.* import scala.deriving.Mirror -private[yaml] trait YamlDecoderCompanionCrossCompat { +private[yaml] trait YamlDecoderCompanionCrossCompat extends DecoderMacros { inline def derived[T](using m: Mirror.Of[T]): YamlDecoder[T] = inline m match case p: Mirror.ProductOf[T] => deriveProduct(p) case s: Mirror.SumOf[T] => sumOf(s) +} - private def extractKeyValues( +private[yaml] trait DecoderMacros { + protected def extractKeyValues( mappings: Map[Node, Node] ): Either[ConstructError, Map[String, Node]] = { val keyValueMap = mappings @@ -26,7 +28,7 @@ private[yaml] trait YamlDecoderCompanionCrossCompat { else Right(valuesSeq.toMap) } - private def constructValues[T]( + protected def constructValues[T]( elemLabels: List[String], instances: List[YamlDecoder[_]], valuesMap: Map[String, Node], @@ -42,7 +44,7 @@ private[yaml] trait YamlDecoderCompanionCrossCompat { else Right(p.fromProduct(Tuple.fromArray(right.toArray))) } - private inline def deriveProduct[T](p: Mirror.ProductOf[T]) = + protected inline def deriveProduct[T](p: Mirror.ProductOf[T]) = val instances = summonAll[p.MirroredElemTypes] val elemLabels = getElemLabels[p.MirroredElemLabels] new YamlDecoder[T] { @@ -59,7 +61,7 @@ private[yaml] trait YamlDecoderCompanionCrossCompat { Left(ConstructError(s"Expected MappingNode, got ${node.getClass.getSimpleName}")) } - private inline def sumOf[T](s: Mirror.SumOf[T]) = + protected inline def sumOf[T](s: Mirror.SumOf[T]) = val instances = summonSumOf[s.MirroredElemTypes].asInstanceOf[List[YamlDecoder[T]]] new YamlDecoder[T]: override def construct( @@ -70,18 +72,18 @@ private[yaml] trait YamlDecoderCompanionCrossCompat { .collectFirst { case r @ Right(_) => r } .getOrElse(Left(ConstructError(s"Cannot parse $node"))) - private inline def summonSumOf[T <: Tuple]: List[YamlDecoder[_]] = inline erasedValue[T] match + protected inline def summonSumOf[T <: Tuple]: List[YamlDecoder[_]] = inline erasedValue[T] match case _: (t *: ts) => summonFrom { case p: Mirror.ProductOf[`t`] => deriveProduct(p) :: summonSumOf[ts] } case _: EmptyTuple => Nil - private inline def summonAll[T <: Tuple]: List[YamlDecoder[_]] = inline erasedValue[T] match + protected inline def summonAll[T <: Tuple]: List[YamlDecoder[_]] = inline erasedValue[T] match case _: EmptyTuple => Nil case _: (t *: ts) => summonInline[YamlDecoder[t]] :: summonAll[ts] - private inline def getElemLabels[T <: Tuple]: List[String] = inline erasedValue[T] match + protected inline def getElemLabels[T <: Tuple]: List[String] = inline erasedValue[T] match case _: EmptyTuple => Nil case _: (head *: tail) => constValue[head].toString :: getElemLabels[tail] diff --git a/core/shared/src/main/scala-3/org/virtuslab/yaml/YamlEncoderCrossCompat.scala b/core/shared/src/main/scala-3/org/virtuslab/yaml/YamlEncoderCrossCompat.scala index 770814847..630576b8f 100644 --- a/core/shared/src/main/scala-3/org/virtuslab/yaml/YamlEncoderCrossCompat.scala +++ b/core/shared/src/main/scala-3/org/virtuslab/yaml/YamlEncoderCrossCompat.scala @@ -3,12 +3,14 @@ package org.virtuslab.yaml import scala.deriving.Mirror import scala.compiletime.* -private[yaml] trait YamlEncoderCrossCompanionCompat { +private[yaml] trait YamlEncoderCrossCompanionCompat extends EncoderMacros { inline def derived[T](using m: Mirror.Of[T]): YamlEncoder[T] = inline m match case p: Mirror.ProductOf[T] => deriveProduct(p) case s: Mirror.SumOf[T] => deriveSum(s) +} - private inline def deriveProduct[T](p: Mirror.ProductOf[T]): YamlEncoder[T] = +private[yaml] trait EncoderMacros: + protected inline def deriveProduct[T](p: Mirror.ProductOf[T]): YamlEncoder[T] = new YamlEncoder[T] { val yamlEncoders = summonAll[p.MirroredElemTypes] val elemLabels = getElemLabels[p.MirroredElemLabels] @@ -27,7 +29,7 @@ private[yaml] trait YamlEncoderCrossCompanionCompat { Node.MappingNode(nodes) } - private inline def deriveSum[T](s: Mirror.SumOf[T]) = + protected inline def deriveSum[T](s: Mirror.SumOf[T]) = new YamlEncoder[T]: val yamlEncoders = summonSumOf[s.MirroredElemTypes].asInstanceOf[List[YamlEncoder[T]]] override def asNode(t: T): Node = { @@ -35,20 +37,19 @@ private[yaml] trait YamlEncoderCrossCompanionCompat { yamlEncoders(index).asInstanceOf[YamlEncoder[Any]].asNode(t) } - private inline def summonSumOf[T <: Tuple]: List[YamlEncoder[_]] = inline erasedValue[T] match + protected inline def summonSumOf[T <: Tuple]: List[YamlEncoder[_]] = inline erasedValue[T] match case _: (t *: ts) => summonFrom { case p: Mirror.ProductOf[`t`] => deriveProduct(p) :: summonSumOf[ts] } case _: EmptyTuple => Nil - private inline def summonAll[T <: Tuple]: List[YamlEncoder[_]] = inline erasedValue[T] match { + inline def summonAll[T <: Tuple]: List[YamlEncoder[_]] = inline erasedValue[T] match { case _: EmptyTuple => Nil case _: (t *: ts) => summonInline[YamlEncoder[t]] :: summonAll[ts] } - private inline def getElemLabels[T <: Tuple]: List[String] = inline erasedValue[T] match { + protected inline def getElemLabels[T <: Tuple]: List[String] = inline erasedValue[T] match { case _: EmptyTuple => Nil case _: (head *: tail) => constValue[head].toString :: getElemLabels[tail] } -} diff --git a/project/plugin.sbt b/project/plugin.sbt index df9530553..ff69d5328 100644 --- a/project/plugin.sbt +++ b/project/plugin.sbt @@ -6,4 +6,4 @@ addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0") addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.2.0") addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.0") -addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.4") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.5") From 21bf5d02d27c0fb3925a52334b900e5a7a7b2657 Mon Sep 17 00:00:00 2001 From: Anton Sviridov Date: Thu, 1 Sep 2022 12:11:31 +0100 Subject: [PATCH 2/2] Run cross-build, don't break Scala 2 docs --- .github/workflows/ci.yml | 6 +++--- build.sbt | 2 +- project/BuildHelper.scala | 43 ++++++++++++++++++++++----------------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2aaeced6b..cd0f53be4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,13 +36,13 @@ jobs: java-version: 8 - name: JVM tests if: matrix.platform == 'jvm' - run: sbt core/test + run: sbt +core/test - name: JS tests if: matrix.platform == 'js' - run: sbt coreJS/test + run: sbt +coreJS/test - name: Native tests if: matrix.platform == 'native' - run: sbt coreNative/test + run: sbt +coreNative/test publish: needs: test diff --git a/build.sbt b/build.sbt index 6d320549d..24922e1c6 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,7 @@ import BuildHelper._ def scala3Version = "3.1.3" -def scala2Version = "2.13.9" +def scala2Version = "2.13.8" def munitVersion = "1.0.0-M6" def projectName = "scala-yaml" def localSnapshotVersion = "0.0.5-SNAPSHOT" diff --git a/project/BuildHelper.scala b/project/BuildHelper.scala index efabf876a..28b91462f 100644 --- a/project/BuildHelper.scala +++ b/project/BuildHelper.scala @@ -3,27 +3,32 @@ import sbt.Keys._ object BuildHelper { lazy val docsSettings = Seq( - Compile / doc / scalacOptions ++= Seq( - "-project", - "Scala-yaml", - "-siteroot", - "docs", - "-project-version", - version.value, - "-project-logo", - "docs/logo.svg", - "-social-links:" + - "github::https://github.com/VirtusLab/scala-yaml," + - "twitter::https://twitter.com/VirtusLab", - "-project-footer", - s"Copyright (c) 2021, VirtusLab", - "-source-links:github://VirtusLab/scala-yaml", - "-revision", - "master" - ), + Compile / doc / scalacOptions ++= { + if (scalaBinaryVersion.value.startsWith("3")) { + Seq( + "-project", + "Scala-yaml", + "-siteroot", + "docs", + "-project-version", + version.value, + "-project-logo", + "docs/logo.svg", + "-social-links:" + + "github::https://github.com/VirtusLab/scala-yaml," + + "twitter::https://twitter.com/VirtusLab", + "-project-footer", + s"Copyright (c) 2021, VirtusLab", + "-source-links:github://VirtusLab/scala-yaml", + "-revision", + "master" + ) + } else Seq.empty + }, Compile / doc := { val out = (Compile / doc).value - IO.copyDirectory((Compile / doc / target).value, file("generated-docs")) + if (scalaBinaryVersion.value.startsWith("3")) + IO.copyDirectory((Compile / doc / target).value, file("generated-docs")) out } )