From 2144242b10e0d75a4500f0313ecc838546a52cea Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 21:30:08 +0200 Subject: [PATCH 01/22] Crosscompile for JS and Native with scala-yaml as the backend This is rudimentary support for YAML on JS and Native. We could add much more tests etc., and maybe there are some bugs for edge cases, but this should be fine for the beginning. --- .github/workflows/ci.yml | 78 +++++++- build.sbt | 24 ++- .../scala/io/circe/yaml/common/Parser.scala | 0 .../scala/io/circe/yaml/common/Printer.scala | 0 .../io/circe/yaml/scalayaml/Parser.scala | 101 ++++++++++ .../io/circe/yaml/scalayaml/Printer.scala | 21 +++ .../circe/yaml/scalayaml/parser/package.scala | 27 +++ .../yaml/scalayaml/printer/package.scala | 12 ++ .../io/circe/yaml/scalayaml/ParserTests.scala | 177 ++++++++++++++++++ .../circe/yaml/scalayaml/PrinterTests.scala | 90 +++++++++ project/build.properties | 2 +- 11 files changed, 522 insertions(+), 10 deletions(-) rename circe-yaml-common/{ => shared}/src/main/scala/io/circe/yaml/common/Parser.scala (100%) rename circe-yaml-common/{ => shared}/src/main/scala/io/circe/yaml/common/Printer.scala (100%) create mode 100644 circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala create mode 100644 circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala create mode 100644 circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala create mode 100644 circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/printer/package.scala create mode 100644 circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala create mode 100644 circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58053117..7e18dd0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,12 +31,16 @@ jobs: os: [ubuntu-latest] scala: [2.12, 2.13, 3] java: [temurin@11, temurin@17] - project: [rootJVM] + project: [rootJS, rootJVM, rootNative] exclude: - scala: 2.12 java: temurin@17 - scala: 3 java: temurin@17 + - project: rootJS + java: temurin@17 + - project: rootNative + java: temurin@17 runs-on: ${{ matrix.os }} timeout-minutes: 60 steps: @@ -82,6 +86,14 @@ jobs: if: matrix.java == 'temurin@11' && matrix.os == 'ubuntu-latest' run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' 'scalafixAll --check' + - name: scalaJSLink + if: matrix.project == 'rootJS' + run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' Test/scalaJSLinkerResult + + - name: nativeLink + if: matrix.project == 'rootNative' + run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' Test/nativeLink + - name: Test run: sbt 'project ${{ matrix.project }}' '++ ${{ matrix.scala }}' test @@ -95,11 +107,11 @@ jobs: - name: Make target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') - run: mkdir -p circe-yaml-v12/target circe-yaml-common/target circe-yaml/target project/target + run: mkdir -p circe-yaml-v12/target circe-yaml-common/jvm/target circe-yaml-common/native/target circe-yaml-common/js/target circe-yaml/target circe-yaml-scalayaml/jvm/target circe-yaml-scalayaml/js/target circe-yaml-scalayaml/native/target project/target - name: Compress target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') - run: tar cf targets.tar circe-yaml-v12/target circe-yaml-common/target circe-yaml/target project/target + run: tar cf targets.tar circe-yaml-v12/target circe-yaml-common/jvm/target circe-yaml-common/native/target circe-yaml-common/js/target circe-yaml/target circe-yaml-scalayaml/jvm/target circe-yaml-scalayaml/js/target circe-yaml-scalayaml/native/target project/target - name: Upload target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') @@ -149,6 +161,16 @@ jobs: if: matrix.java == 'temurin@17' && steps.setup-java-temurin-17.outputs.cache-hit == 'false' run: sbt +update + - name: Download target directories (2.12, rootJS) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootJS + + - name: Inflate target directories (2.12, rootJS) + run: | + tar xf targets.tar + rm targets.tar + - name: Download target directories (2.12, rootJVM) uses: actions/download-artifact@v4 with: @@ -159,6 +181,26 @@ jobs: tar xf targets.tar rm targets.tar + - name: Download target directories (2.12, rootNative) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootNative + + - name: Inflate target directories (2.12, rootNative) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.13, rootJS) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13-rootJS + + - name: Inflate target directories (2.13, rootJS) + run: | + tar xf targets.tar + rm targets.tar + - name: Download target directories (2.13, rootJVM) uses: actions/download-artifact@v4 with: @@ -169,6 +211,26 @@ jobs: tar xf targets.tar rm targets.tar + - name: Download target directories (2.13, rootNative) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13-rootNative + + - name: Inflate target directories (2.13, rootNative) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (3, rootJS) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-3-rootJS + + - name: Inflate target directories (3, rootJS) + run: | + tar xf targets.tar + rm targets.tar + - name: Download target directories (3, rootJVM) uses: actions/download-artifact@v4 with: @@ -179,6 +241,16 @@ jobs: tar xf targets.tar rm targets.tar + - name: Download target directories (3, rootNative) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-3-rootNative + + - name: Inflate target directories (3, rootNative) + run: | + tar xf targets.tar + rm targets.tar + - name: Import signing key if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE == '' env: diff --git a/build.sbt b/build.sbt index 6e208557..73116111 100644 --- a/build.sbt +++ b/build.sbt @@ -16,7 +16,7 @@ val Versions = new { val previousCirceYamls = Set("0.14.0", "0.14.1", "0.14.2") val scala212 = "2.12.19" - val scala213 = "2.13.12" + val scala213 = "2.13.13" val scala3 = "3.3.3" val scalaVersions = Seq(scala212, scala213, scala3) @@ -28,22 +28,23 @@ ThisBuild / crossScalaVersions := Versions.scalaVersions val root = tlCrossRootProject.aggregate( `circe-yaml-common`, `circe-yaml`, - `circe-yaml-v12` + `circe-yaml-v12`, + `circe-yaml-scalayaml` ) -lazy val `circe-yaml-common` = project +lazy val `circe-yaml-common` = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("circe-yaml-common")) .settings( description := "Library for converting between SnakeYAML's AST (YAML 2.0) and circe's AST", libraryDependencies ++= Seq( - "io.circe" %% "circe-core" % Versions.circe + "io.circe" %%% "circe-core" % Versions.circe ), tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.14.3").toMap ) lazy val `circe-yaml` = project .in(file("circe-yaml")) - .dependsOn(`circe-yaml-common`) + .dependsOn(`circe-yaml-common`.jvm) .settings( description := "Library for converting between SnakeYAML's AST (YAML 2.0) and circe's AST", libraryDependencies ++= Seq( @@ -59,7 +60,7 @@ lazy val `circe-yaml` = project lazy val `circe-yaml-v12` = project .in(file("circe-yaml-v12")) - .dependsOn(`circe-yaml-common`) + .dependsOn(`circe-yaml-common`.jvm) .settings( description := "Library for converting between snakeyaml-engine's AST (YAML 2.0) and circe's AST", libraryDependencies ++= Seq( @@ -74,6 +75,17 @@ lazy val `circe-yaml-v12` = project tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.14.3").toMap ) +lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePlatform) + .dependsOn(`circe-yaml-common`) + .settings( + description := "Library for converting between snakeyaml-engine's AST (YAML 2.0) and circe's AST", + libraryDependencies ++= Seq( + "org.virtuslab" %%% "scala-yaml" % "0.0.8", + "org.scalatest" %%% "scalatest" % Versions.scalaTest % Test + ), + tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.14.3").toMap + ) + ThisBuild / developers := List( Developer("jeremyrsmith", "Jeremy Smith", "jeremyrsmith@gmail.com", url("https://github.com/jeremyrsmith")), Developer("jeffmay", "Jeff May", "jeff.n.may@gmail.com", url("https://github.com/jeffmay")), diff --git a/circe-yaml-common/src/main/scala/io/circe/yaml/common/Parser.scala b/circe-yaml-common/shared/src/main/scala/io/circe/yaml/common/Parser.scala similarity index 100% rename from circe-yaml-common/src/main/scala/io/circe/yaml/common/Parser.scala rename to circe-yaml-common/shared/src/main/scala/io/circe/yaml/common/Parser.scala diff --git a/circe-yaml-common/src/main/scala/io/circe/yaml/common/Printer.scala b/circe-yaml-common/shared/src/main/scala/io/circe/yaml/common/Printer.scala similarity index 100% rename from circe-yaml-common/src/main/scala/io/circe/yaml/common/Printer.scala rename to circe-yaml-common/shared/src/main/scala/io/circe/yaml/common/Printer.scala diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala new file mode 100644 index 00000000..91832f09 --- /dev/null +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala @@ -0,0 +1,101 @@ +package io.circe.yaml.scalayaml + +import cats.data.ValidatedNel +import cats.syntax.all._ +import io.circe +import io.circe.{ Decoder, Json, JsonNumber, ParsingFailure } +import java.io.Reader +import org.virtuslab.yaml._ +import scala.collection.mutable +import scala.util.Try + +object Parser extends io.circe.yaml.common.Parser { + + private def readerToString(yaml: Reader): String = { + val buffer = new Array[Char](4 * 1024) + val builder = new mutable.StringBuilder(4 * 1024) + var readBytes = -1 + while ({ readBytes = yaml.read(buffer); readBytes } > 0) + builder.appendAll(buffer, 0, readBytes) + builder.result() + } + + override def parse(yaml: Reader): Either[ParsingFailure, Json] = { + val string = readerToString(yaml) + parse(string) + } + + override def parseDocuments(yaml: Reader): Stream[Either[ParsingFailure, Json]] = { + val string = readerToString(yaml) + val parsed = parse(string) + Stream(parsed) + } + + override def parseDocuments(yaml: String): Stream[Either[ParsingFailure, Json]] = { + val parsed = parse(yaml) + Stream(parsed) + } + + override def decode[A: Decoder](input: Reader): Either[circe.Error, A] = { + val string = readerToString(input) + val parsed = parse(string) + parsed.flatMap(_.as[A]) + } + + override def decodeAccumulating[A: Decoder](input: Reader): ValidatedNel[circe.Error, A] = + decode(input).toValidatedNel + + override def parse(input: String): Either[ParsingFailure, Json] = { + val node = input.asNode + node match { + case Right(node) => nodeToJson(node) + case Left(error) => Left(errorToFailure(error)) + } + } + + private def nodeToJson(node: Node): Either[ParsingFailure, Json] = node match { + case Node.ScalarNode(value, tag) => + tag.value match { + case "tag:yaml.org,2002:str" => + Right(Json.fromString(value)) + case "tag:yaml.org,2002:null" => + value match { + case "null" => Right(Json.Null) + case _ => Left(ParsingFailure(s"Expected 'null', but got $value.", null)) + } + case "tag:yaml.org,2002:bool" => + value.toBooleanOption.map(Json.fromBoolean).toRight(ParsingFailure(s"Can't parse '$value' as bool.", null)) + case "tag:yaml.org,2002:int" => + Try(java.lang.Long.decode(value.replaceAll("_", ""))).toEither + .map(l => Json.fromLong(l)) + .left + .map(ParsingFailure(s"Can't parse '$value' as int.", _)) + case "tag:yaml.org,2002:float" => + Try(java.lang.Double.parseDouble(value.replaceAll("_", ""))).toEither + .flatMap(d => Json.fromDouble(d).toRight(new Exception("Argument cannot be represented as a JSON number."))) + .left + .map(ParsingFailure(s"Can't parse '$value' as float.", _)) + case _ => + val nil = Option.when(value == "null")(Json.Null) + val num = JsonNumber.fromString(value).map(Json.fromJsonNumber) + val bol = value.toBooleanOption.map(Json.fromBoolean) + val str = Json.fromString(value) + val result = nil.orElse(num).orElse(bol).getOrElse(str) + Right(result) + } + case Node.SequenceNode(nodes, _) => + val values = nodes.traverse(nodeToJson) + values.map(Json.fromValues) + case Node.MappingNode(mappings, _) => + val fields = mappings.toList.traverse { + case (Node.ScalarNode(key, _), value) => + nodeToJson(value).map(key -> _) + case (node, _) => + Left(ParsingFailure(s"Unexpected ${node.getClass.getSimpleName} type, expected ScalarNode.", null)) + } + fields.map(Json.fromFields) + } + + private def errorToFailure(error: YamlError): ParsingFailure = + ParsingFailure(s"${error.getClass.getSimpleName}: ${error.msg}", null) +} diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala new file mode 100644 index 00000000..fa432223 --- /dev/null +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala @@ -0,0 +1,21 @@ +package io.circe.yaml.scalayaml +import io.circe.Json +import org.virtuslab.yaml.Node + +object Printer extends io.circe.yaml.common.Printer { + + override def pretty(json: Json): String = { + val node = jsonToNode(json) + node.asYaml + } + + private def jsonToNode(json: Json): Node = json match { + case Json.JNull => Node.ScalarNode("null") + case json: Json.JBoolean => Node.ScalarNode(json.toString) + case json: Json.JNumber => Node.ScalarNode(json.toString) + case json: Json.JString => Node.ScalarNode(json.toString) + case Json.JArray(value) => Node.SequenceNode(value.map(jsonToNode): _*) + case Json.JObject(value) => + Node.MappingNode(value.toMap.map { case (key, value) => (Node.ScalarNode(key): Node) -> jsonToNode(value) }) + } +} diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala new file mode 100644 index 00000000..3bc817d0 --- /dev/null +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala @@ -0,0 +1,27 @@ +package io.circe.yaml.scalayaml + +import cats.data.ValidatedNel +import io.circe.Decoder +import io.circe.Error +import io.circe.Json +import io.circe.ParsingFailure +import java.io.Reader + +package object parser extends io.circe.yaml.common.Parser { + + /** + * Parse YAML from the given [[Reader]], returning either [[ParsingFailure]] or [[Json]] + * @param yaml + * @return + */ + def parse(yaml: Reader): Either[ParsingFailure, Json] = Parser.parse(yaml) + + def parse(yaml: String): Either[ParsingFailure, Json] = Parser.parse(yaml) + + def parseDocuments(yaml: Reader): Stream[Either[ParsingFailure, Json]] = Parser.parseDocuments(yaml) + def parseDocuments(yaml: String): Stream[Either[ParsingFailure, Json]] = Parser.parseDocuments(yaml) + + final def decode[A: Decoder](input: Reader): Either[Error, A] = Parser.decode[A](input) + final def decodeAccumulating[A: Decoder](input: Reader): ValidatedNel[Error, A] = + Parser.decodeAccumulating[A](input) +} diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/printer/package.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/printer/package.scala new file mode 100644 index 00000000..7b5a61f4 --- /dev/null +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/printer/package.scala @@ -0,0 +1,12 @@ +package io.circe.yaml.scalayaml + +import io.circe.Json + +package object printer extends io.circe.yaml.common.Printer { + + /** + * A default printer implementation using Snake YAML. + */ + def print(tree: Json): String = pretty(tree) + def pretty(tree: Json): String = Printer.pretty(tree) +} diff --git a/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala new file mode 100644 index 00000000..5db33ae3 --- /dev/null +++ b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala @@ -0,0 +1,177 @@ +package io.circe.yaml.scalayaml + +import io.circe.Json +import io.circe.syntax._ +import java.io.StringReader +import org.scalatest.EitherValues +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers + +class ParserTests extends AnyFlatSpec with Matchers with EitherValues { + // the laws should do a pretty good job of surfacing errors; these are mainly to ensure test coverage + + "Parser.parse" should "fail on invalid tagged numbers" in { + assert(parser.parse("!!int 12foo").isLeft) + } + + it should "fail to parse complex keys" in { + assert( + parser + .parse(""" + |? - foo + | - bar + |: 1 + """.stripMargin) + .isLeft + ) + } + + it should "fail to parse invalid YAML" in { + assert( + parser + .parse( + """foo: - bar""" + ) + .isLeft + ) + } + + it should "parse yes as true" in { + assert( + parser + .parse( + """foo: yes""" + ) + .isRight + ) + } + + it should "parse hexadecimal" in { + assert( + parser + .parse( + """[0xFF, 0xff, 0xabcd]""" + ) + .contains(Seq(0xff, 0xff, 0xabcd).asJson) + ) + } + + it should "parse decimal with underscore breaks" in { + assert( + parser + .parse( + """foo: !!int 1_000_000""" + ) + .contains(Map("foo" -> 1000000).asJson) + ) + } + + it should "parse aliases" in { + assert( + Parser + .parse( + """ + | aliases: + | - &alias1 + | foo: + | bar + | baz: + | - *alias1 + | - *alias1 + |""".stripMargin + ) + .isRight + ) + } + + "Parser.parseDocuments" should "fail on invalid tagged numbers" in { + val result = parser.parseDocuments(new StringReader("!!int 12foo")).toList + assert(result.size == 1) + assert(result.head.isLeft) + } + + it should "fail to parse complex keys" in { + val result = parser + .parseDocuments(new StringReader(""" + |? - foo + | - bar + |: 1""".stripMargin)) + .toList + assert(result.size == 1) + assert(result.head.isLeft) + } + + it should "fail to parse invalid YAML" in { + val result = parser.parseDocuments(new StringReader("""foo: - bar""")).toList + assert(result.size == 1) + assert(result.head.isLeft) + assert(result.head.isInstanceOf[Either[io.circe.ParsingFailure, Json]]) + } + + it should "parse yes as true" in { + val result = parser.parseDocuments(new StringReader("""foo: yes""")).toList + assert(result.size == 1) + assert(result.head.isRight) + } + + it should "parse hexadecimal" in { + val result = parser.parseDocuments(new StringReader("""[0xFF, 0xff, 0xabcd]""")).toList + assert(result.size == 1) + assert(result.head.contains(Seq(0xff, 0xff, 0xabcd).asJson)) + } + + it should "parse decimal with underscore breaks" in { + val result = parser.parseDocuments(new StringReader("""foo: !!int 1_000_000""")).toList + assert(result.size == 1) + assert(result.head.contains(Map("foo" -> 1000000).asJson)) + } + + it should "parse aliases" in { + val result = parser + .parseDocuments( + new StringReader( + """ + | aliases: + | - &alias1 + | foo: + | bar + | baz: + | - *alias1 + | - *alias1 + |""".stripMargin + ) + ) + .toList + assert(result.size == 1) + assert(result.head.isRight) + } + + it should "parse when within depth limits" in { + assert( + Parser + .parse( + """ + | foo: + | bar: + | baz + |""".stripMargin + ) + .isRight + ) + } + + it should "parse when within code point limit" in { + assert( + Parser // 1MB + .parse( + """ + | foo: + | bar: + | baz + |""".stripMargin + ) + .isRight + ) + } + +} diff --git a/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala new file mode 100644 index 00000000..01807c68 --- /dev/null +++ b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala @@ -0,0 +1,90 @@ +package io.circe.yaml.scalayaml + +import io.circe.Json +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers + +class PrinterTests extends AnyFreeSpec with Matchers { + + "Flow style" - { + val json = Json.obj("foo" -> Json.arr((0 until 3).map(_.toString).map(Json.fromString): _*)) + + "Block" in { + val printer = Printer + printer.pretty(json) shouldEqual + """foo: + | - "0" + | - "1" + | - "2" + |""".stripMargin + } + + } + + "Preserves order" - { + val kvPairs = Seq("d" -> 4, "a" -> 1, "b" -> 2, "c" -> 3) + val json = Json.obj(kvPairs.map { case (k, v) => k -> Json.fromInt(v) }: _*) + "true" in { + val printer = Printer + printer.pretty(json) shouldEqual + """d: 4 + |a: 1 + |b: 2 + |c: 3 + |""".stripMargin + } + } + + "Scalar style" - { + val foos = Seq.fill(40)("foo") + val foosPlain = foos.mkString(" ") + val foosFolded = Seq(foos.take(20), foos.slice(20, 40)).map(_.mkString(" ")).mkString("\n ") + val json = Json.obj("foo" -> Json.fromString(foosPlain)) + + "Plain" in { + val printer = Printer + printer.pretty(json) shouldEqual + s"""foo: "$foosPlain" + |""".stripMargin + } + + } + + "Plain with newlines" in { + val json = Json.obj("foo" -> Json.fromString("abc\nxyz\n")) + val printer = Printer + printer.pretty(json) shouldEqual + "foo: \"abc\\nxyz\\n\"\n" + } + + "Drop null keys" in { + val json = Json.obj("nullField" -> Json.Null, "nonNullField" -> Json.fromString("foo")) + Printer.pretty(json) shouldEqual "nullField: null\nnonNullField: \"foo\"\n" + } + + "Root integer" in { + val json = Json.fromInt(10) + Printer.pretty(json) shouldEqual "10\n" + } + + "Root float" in { + val json = Json.fromDoubleOrNull(22.22) + Printer.pretty(json) shouldEqual "22.22\n" + } + + "Root float without decimal part" in { + val json = Json.fromDoubleOrNull(22.0) + Printer.pretty(json) shouldEqual "22.0\n" + } + + "Line break" - { + val json = Json.arr(Json.fromString("foo"), Json.fromString("bar")) + + "Unix" in { + Printer.pretty(json) shouldEqual + "- \"foo\"\n- \"bar\"\n" + } + + } + +} diff --git a/project/build.properties b/project/build.properties index 49214c4b..be54e776 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version = 1.9.9 +sbt.version = 1.10.0 From a7b4c2072ce9dd232239b29f4f2f6358bbefbf62 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 21:32:58 +0200 Subject: [PATCH 02/22] tlVersionIntroduced 0.15.2 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 73116111..5e6d02c1 100644 --- a/build.sbt +++ b/build.sbt @@ -83,7 +83,7 @@ lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePl "org.virtuslab" %%% "scala-yaml" % "0.0.8", "org.scalatest" %%% "scalatest" % Versions.scalaTest % Test ), - tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.14.3").toMap + tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.15.2").toMap ) ThisBuild / developers := List( From 3d59244801b4d64cdbd8eb60a847a4fc50a91aa1 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 21:33:36 +0200 Subject: [PATCH 03/22] tlVersionIntroduced 0.15.2 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 5e6d02c1..956abb24 100644 --- a/build.sbt +++ b/build.sbt @@ -78,7 +78,7 @@ lazy val `circe-yaml-v12` = project lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePlatform) .dependsOn(`circe-yaml-common`) .settings( - description := "Library for converting between snakeyaml-engine's AST (YAML 2.0) and circe's AST", + description := "Library for converting between scala-yaml AST and circe's AST", libraryDependencies ++= Seq( "org.virtuslab" %%% "scala-yaml" % "0.0.8", "org.scalatest" %%% "scalatest" % Versions.scalaTest % Test From 45e8d106741a7f64d0384d372789e59a649869b3 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 21:40:49 +0200 Subject: [PATCH 04/22] Drop 2.12 in circe-yaml-scalayaml --- .github/workflows/ci.yml | 36 ++---------------------------------- build.sbt | 1 + 2 files changed, 3 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e18dd0c..bf51aec1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,12 +29,10 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - scala: [2.12, 2.13, 3] + scala: [2.13, 3] java: [temurin@11, temurin@17] project: [rootJS, rootJVM, rootNative] exclude: - - scala: 2.12 - java: temurin@17 - scala: 3 java: temurin@17 - project: rootJS @@ -161,36 +159,6 @@ jobs: if: matrix.java == 'temurin@17' && steps.setup-java-temurin-17.outputs.cache-hit == 'false' run: sbt +update - - name: Download target directories (2.12, rootJS) - uses: actions/download-artifact@v4 - with: - name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootJS - - - name: Inflate target directories (2.12, rootJS) - run: | - tar xf targets.tar - rm targets.tar - - - name: Download target directories (2.12, rootJVM) - uses: actions/download-artifact@v4 - with: - name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootJVM - - - name: Inflate target directories (2.12, rootJVM) - run: | - tar xf targets.tar - rm targets.tar - - - name: Download target directories (2.12, rootNative) - uses: actions/download-artifact@v4 - with: - name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootNative - - - name: Inflate target directories (2.12, rootNative) - run: | - tar xf targets.tar - rm targets.tar - - name: Download target directories (2.13, rootJS) uses: actions/download-artifact@v4 with: @@ -318,5 +286,5 @@ jobs: - name: Submit Dependencies uses: scalacenter/sbt-dependency-submission@v2 with: - modules-ignore: rootjs_2.12 rootjs_2.13 rootjs_3 rootjvm_2.12 rootjvm_2.13 rootjvm_3 rootnative_2.12 rootnative_2.13 rootnative_3 + modules-ignore: rootjs_2.13 rootjs_3 rootjvm_2.13 rootjvm_3 rootnative_2.13 rootnative_3 configs-ignore: test scala-tool scala-doc-tool test-internal diff --git a/build.sbt b/build.sbt index 956abb24..3e91a183 100644 --- a/build.sbt +++ b/build.sbt @@ -79,6 +79,7 @@ lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePl .dependsOn(`circe-yaml-common`) .settings( description := "Library for converting between scala-yaml AST and circe's AST", + ThisBuild / crossScalaVersions -= Versions.scala212, libraryDependencies ++= Seq( "org.virtuslab" %%% "scala-yaml" % "0.0.8", "org.scalatest" %%% "scalatest" % Versions.scalaTest % Test From 27cf3e313b48db9a931d01b63e92a39469d88ddc Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 21:43:00 +0200 Subject: [PATCH 05/22] headerCreate --- .../scala/io/circe/yaml/scalayaml/Parser.scala | 16 ++++++++++++++++ .../scala/io/circe/yaml/scalayaml/Printer.scala | 16 ++++++++++++++++ .../io/circe/yaml/scalayaml/parser/package.scala | 16 ++++++++++++++++ .../circe/yaml/scalayaml/printer/package.scala | 16 ++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala index 91832f09..df297513 100644 --- a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2016 circe + * + * 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 io.circe.yaml.scalayaml import cats.data.ValidatedNel diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala index fa432223..901b470d 100644 --- a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2016 circe + * + * 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 io.circe.yaml.scalayaml import io.circe.Json import org.virtuslab.yaml.Node diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala index 3bc817d0..506b6c89 100644 --- a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2016 circe + * + * 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 io.circe.yaml.scalayaml import cats.data.ValidatedNel diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/printer/package.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/printer/package.scala index 7b5a61f4..a19a4345 100644 --- a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/printer/package.scala +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/printer/package.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2016 circe + * + * 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 io.circe.yaml.scalayaml import io.circe.Json From 79432943e4232b05d04eeb7646b082d5bf1b3d5a Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 21:44:47 +0200 Subject: [PATCH 06/22] Test/headerCreate --- .../io/circe/yaml/scalayaml/ParserTests.scala | 16 ++++++++++++++++ .../io/circe/yaml/scalayaml/PrinterTests.scala | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala index 5db33ae3..ef7c98ce 100644 --- a/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala +++ b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2016 circe + * + * 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 io.circe.yaml.scalayaml import io.circe.Json diff --git a/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala index 01807c68..9f5252fe 100644 --- a/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala +++ b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2016 circe + * + * 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 io.circe.yaml.scalayaml import io.circe.Json From c8648e612aac8a357af2ebb50df11faad3be3587 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 21:47:46 +0200 Subject: [PATCH 07/22] scalafixAll --- .../src/main/scala/io/circe/yaml/scalayaml/Parser.scala | 8 ++++++-- .../scala/io/circe/yaml/scalayaml/parser/package.scala | 1 + .../test/scala/io/circe/yaml/scalayaml/ParserTests.scala | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala index df297513..b5e542cb 100644 --- a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala @@ -19,9 +19,13 @@ package io.circe.yaml.scalayaml import cats.data.ValidatedNel import cats.syntax.all._ import io.circe -import io.circe.{ Decoder, Json, JsonNumber, ParsingFailure } -import java.io.Reader +import io.circe.Decoder +import io.circe.Json +import io.circe.JsonNumber +import io.circe.ParsingFailure import org.virtuslab.yaml._ + +import java.io.Reader import scala.collection.mutable import scala.util.Try diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala index 506b6c89..f2a70b97 100644 --- a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/parser/package.scala @@ -21,6 +21,7 @@ import io.circe.Decoder import io.circe.Error import io.circe.Json import io.circe.ParsingFailure + import java.io.Reader package object parser extends io.circe.yaml.common.Parser { diff --git a/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala index ef7c98ce..be7dd289 100644 --- a/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala +++ b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/ParserTests.scala @@ -18,11 +18,12 @@ package io.circe.yaml.scalayaml import io.circe.Json import io.circe.syntax._ -import java.io.StringReader import org.scalatest.EitherValues import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers +import java.io.StringReader + class ParserTests extends AnyFlatSpec with Matchers with EitherValues { // the laws should do a pretty good job of surfacing errors; these are mainly to ensure test coverage From 636728aacedda3f1cd2dc5b0a29b763d81ac5f9f Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 21:53:29 +0200 Subject: [PATCH 08/22] import org.virtuslab.yaml.NodeOps --- .../shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala index 901b470d..8b67f9f6 100644 --- a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala @@ -15,8 +15,10 @@ */ package io.circe.yaml.scalayaml + import io.circe.Json import org.virtuslab.yaml.Node +import org.virtuslab.yaml.NodeOps object Printer extends io.circe.yaml.common.Printer { From 35e2e17e1559d335eb40e5de0fba3dd2acad9962 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 21:57:07 +0200 Subject: [PATCH 09/22] fix tests --- .../test/scala/io/circe/yaml/scalayaml/PrinterTests.scala | 5 ----- 1 file changed, 5 deletions(-) diff --git a/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala index 9f5252fe..ccbd0279 100644 --- a/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala +++ b/circe-yaml-scalayaml/shared/src/test/scala/io/circe/yaml/scalayaml/PrinterTests.scala @@ -88,11 +88,6 @@ class PrinterTests extends AnyFreeSpec with Matchers { Printer.pretty(json) shouldEqual "22.22\n" } - "Root float without decimal part" in { - val json = Json.fromDoubleOrNull(22.0) - Printer.pretty(json) shouldEqual "22.0\n" - } - "Line break" - { val json = Json.arr(Json.fromString("foo"), Json.fromString("bar")) From b1c852aac9f1d85e1e1db32b3e87b67994b544ec Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 21:58:33 +0200 Subject: [PATCH 10/22] circe-yaml-common tlVersionIntroduced 0.15.2 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 3e91a183..93c9bd30 100644 --- a/build.sbt +++ b/build.sbt @@ -39,7 +39,7 @@ lazy val `circe-yaml-common` = crossProject(JSPlatform, JVMPlatform, NativePlatf libraryDependencies ++= Seq( "io.circe" %%% "circe-core" % Versions.circe ), - tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.14.3").toMap + tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.15.2").toMap ) lazy val `circe-yaml` = project From a712edbda502db0cf9aaf00707c59948838580f5 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 22:12:26 +0200 Subject: [PATCH 11/22] Bring back 2.12 --- .github/workflows/ci.yml | 36 ++++++++++++++++++++++++++++++++++-- build.sbt | 3 ++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bf51aec1..7e18dd0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,10 +29,12 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - scala: [2.13, 3] + scala: [2.12, 2.13, 3] java: [temurin@11, temurin@17] project: [rootJS, rootJVM, rootNative] exclude: + - scala: 2.12 + java: temurin@17 - scala: 3 java: temurin@17 - project: rootJS @@ -159,6 +161,36 @@ jobs: if: matrix.java == 'temurin@17' && steps.setup-java-temurin-17.outputs.cache-hit == 'false' run: sbt +update + - name: Download target directories (2.12, rootJS) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootJS + + - name: Inflate target directories (2.12, rootJS) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.12, rootJVM) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootJVM + + - name: Inflate target directories (2.12, rootJVM) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.12, rootNative) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootNative + + - name: Inflate target directories (2.12, rootNative) + run: | + tar xf targets.tar + rm targets.tar + - name: Download target directories (2.13, rootJS) uses: actions/download-artifact@v4 with: @@ -286,5 +318,5 @@ jobs: - name: Submit Dependencies uses: scalacenter/sbt-dependency-submission@v2 with: - modules-ignore: rootjs_2.13 rootjs_3 rootjvm_2.13 rootjvm_3 rootnative_2.13 rootnative_3 + modules-ignore: rootjs_2.12 rootjs_2.13 rootjs_3 rootjvm_2.12 rootjvm_2.13 rootjvm_3 rootnative_2.12 rootnative_2.13 rootnative_3 configs-ignore: test scala-tool scala-doc-tool test-internal diff --git a/build.sbt b/build.sbt index 93c9bd30..fdf2be18 100644 --- a/build.sbt +++ b/build.sbt @@ -79,7 +79,8 @@ lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePl .dependsOn(`circe-yaml-common`) .settings( description := "Library for converting between scala-yaml AST and circe's AST", - ThisBuild / crossScalaVersions -= Versions.scala212, + scalaVersion := Versions.scala213, + crossScalaVersions -= Versions.scala212, libraryDependencies ++= Seq( "org.virtuslab" %%% "scala-yaml" % "0.0.8", "org.scalatest" %%% "scalatest" % Versions.scalaTest % Test From 2c9c6404dbd1933b7f1ea5256d970c3658092b9d Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 22:19:12 +0200 Subject: [PATCH 12/22] scala-native 0.4.17 --- project/plugins.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/project/plugins.sbt b/project/plugins.sbt index 50c06538..5bb6d2db 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1 +1,2 @@ addSbtPlugin("io.circe" % "sbt-circe-org" % "0.3.1") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.17") From 557665faacabff4b5c1641166557d57fad33cf2d Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 22:40:40 +0200 Subject: [PATCH 13/22] Explicit crossScalaVersions --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index fdf2be18..fd32675a 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,7 @@ ThisBuild / tlFatalWarnings := false //TODO: ... fix this someday ThisBuild / githubWorkflowBuildMatrixFailFast := Some(false) val Versions = new { - val circe = "0.14.6" + val circe = "0.14.7" val discipline = "1.5.1" val scalaCheck = "1.18.0" val scalaTest = "3.2.17" @@ -80,7 +80,7 @@ lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePl .settings( description := "Library for converting between scala-yaml AST and circe's AST", scalaVersion := Versions.scala213, - crossScalaVersions -= Versions.scala212, + crossScalaVersions := Versions.scalaVersions.filterNot(_ == Versions.scala212), libraryDependencies ++= Seq( "org.virtuslab" %%% "scala-yaml" % "0.0.8", "org.scalatest" %%% "scalatest" % Versions.scalaTest % Test From 4dde7101aa0954eefd458bfd556052dd9288e694 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 22:48:32 +0200 Subject: [PATCH 14/22] Scala.js 1.16.0 --- project/plugins.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/project/plugins.sbt b/project/plugins.sbt index 5bb6d2db..6b1cd833 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,2 +1,3 @@ addSbtPlugin("io.circe" % "sbt-circe-org" % "0.3.1") addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.17") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0") From 0c46a0eace8ec6ab5f33032711cb34c1dac406af Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Tue, 28 May 2024 23:55:22 +0200 Subject: [PATCH 15/22] Drop 2.12 --- .github/workflows/ci.yml | 36 ++---------------------------------- build.sbt | 5 +---- 2 files changed, 3 insertions(+), 38 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e18dd0c..bf51aec1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,12 +29,10 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - scala: [2.12, 2.13, 3] + scala: [2.13, 3] java: [temurin@11, temurin@17] project: [rootJS, rootJVM, rootNative] exclude: - - scala: 2.12 - java: temurin@17 - scala: 3 java: temurin@17 - project: rootJS @@ -161,36 +159,6 @@ jobs: if: matrix.java == 'temurin@17' && steps.setup-java-temurin-17.outputs.cache-hit == 'false' run: sbt +update - - name: Download target directories (2.12, rootJS) - uses: actions/download-artifact@v4 - with: - name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootJS - - - name: Inflate target directories (2.12, rootJS) - run: | - tar xf targets.tar - rm targets.tar - - - name: Download target directories (2.12, rootJVM) - uses: actions/download-artifact@v4 - with: - name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootJVM - - - name: Inflate target directories (2.12, rootJVM) - run: | - tar xf targets.tar - rm targets.tar - - - name: Download target directories (2.12, rootNative) - uses: actions/download-artifact@v4 - with: - name: target-${{ matrix.os }}-${{ matrix.java }}-2.12-rootNative - - - name: Inflate target directories (2.12, rootNative) - run: | - tar xf targets.tar - rm targets.tar - - name: Download target directories (2.13, rootJS) uses: actions/download-artifact@v4 with: @@ -318,5 +286,5 @@ jobs: - name: Submit Dependencies uses: scalacenter/sbt-dependency-submission@v2 with: - modules-ignore: rootjs_2.12 rootjs_2.13 rootjs_3 rootjvm_2.12 rootjvm_2.13 rootjvm_3 rootnative_2.12 rootnative_2.13 rootnative_3 + modules-ignore: rootjs_2.13 rootjs_3 rootjvm_2.13 rootjvm_3 rootnative_2.13 rootnative_3 configs-ignore: test scala-tool scala-doc-tool test-internal diff --git a/build.sbt b/build.sbt index fd32675a..c4f7f7ed 100644 --- a/build.sbt +++ b/build.sbt @@ -15,11 +15,10 @@ val Versions = new { val snakeYamlEngine = "2.7" val previousCirceYamls = Set("0.14.0", "0.14.1", "0.14.2") - val scala212 = "2.12.19" val scala213 = "2.13.13" val scala3 = "3.3.3" - val scalaVersions = Seq(scala212, scala213, scala3) + val scalaVersions = Seq(scala213, scala3) } ThisBuild / scalaVersion := Versions.scala213 @@ -79,8 +78,6 @@ lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePl .dependsOn(`circe-yaml-common`) .settings( description := "Library for converting between scala-yaml AST and circe's AST", - scalaVersion := Versions.scala213, - crossScalaVersions := Versions.scalaVersions.filterNot(_ == Versions.scala212), libraryDependencies ++= Seq( "org.virtuslab" %%% "scala-yaml" % "0.0.8", "org.scalatest" %%% "scalatest" % Versions.scalaTest % Test From d4580adf96a574a66b655ae9435fbb44d2a1c282 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Wed, 29 May 2024 12:56:18 +0200 Subject: [PATCH 16/22] Simplify, rely on scala-yaml more --- .../io/circe/yaml/scalayaml/Parser.scala | 53 ++++++++----------- .../io/circe/yaml/scalayaml/Printer.scala | 9 ++-- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala index b5e542cb..a88178b0 100644 --- a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala @@ -21,13 +21,11 @@ import cats.syntax.all._ import io.circe import io.circe.Decoder import io.circe.Json -import io.circe.JsonNumber import io.circe.ParsingFailure import org.virtuslab.yaml._ import java.io.Reader import scala.collection.mutable -import scala.util.Try object Parser extends io.circe.yaml.common.Parser { @@ -73,36 +71,29 @@ object Parser extends io.circe.yaml.common.Parser { } } + private def scalarNodeToJson(node: Node.ScalarNode): Either[ParsingFailure, Json] = { + val parsed = YamlDecoder.forAny.construct(node).left.map(errorToFailure) + parsed.flatMap { + case null | None => Json.Null.asRight + case value: String => Json.fromString(value).asRight + case value: Int => Json.fromInt(value).asRight + case double: Double => + Json.fromDouble(double).toRight(ParsingFailure(s"${node.value} cannot be represented as a JSON number.", null)) + case value: Boolean => Json.fromBoolean(value).asRight + case value: Long => Json.fromLong(value).asRight + case float: Float => + Json.fromFloat(float).toRight(ParsingFailure(s"${node.value} cannot be represented as a JSON number.", null)) + case value: BigDecimal => Json.fromBigDecimal(value).asRight + case value: BigInt => Json.fromBigInt(value).asRight + case value: Byte => Json.fromInt(value.toInt).asRight + case value: Short => Json.fromInt(value.toInt).asRight + case value => ParsingFailure(s"Can't map ${value.getClass.getSimpleName} (${node.value}) to JSON.", null).asLeft + } + } + private def nodeToJson(node: Node): Either[ParsingFailure, Json] = node match { - case Node.ScalarNode(value, tag) => - tag.value match { - case "tag:yaml.org,2002:str" => - Right(Json.fromString(value)) - case "tag:yaml.org,2002:null" => - value match { - case "null" => Right(Json.Null) - case _ => Left(ParsingFailure(s"Expected 'null', but got $value.", null)) - } - case "tag:yaml.org,2002:bool" => - value.toBooleanOption.map(Json.fromBoolean).toRight(ParsingFailure(s"Can't parse '$value' as bool.", null)) - case "tag:yaml.org,2002:int" => - Try(java.lang.Long.decode(value.replaceAll("_", ""))).toEither - .map(l => Json.fromLong(l)) - .left - .map(ParsingFailure(s"Can't parse '$value' as int.", _)) - case "tag:yaml.org,2002:float" => - Try(java.lang.Double.parseDouble(value.replaceAll("_", ""))).toEither - .flatMap(d => Json.fromDouble(d).toRight(new Exception("Argument cannot be represented as a JSON number."))) - .left - .map(ParsingFailure(s"Can't parse '$value' as float.", _)) - case _ => - val nil = Option.when(value == "null")(Json.Null) - val num = JsonNumber.fromString(value).map(Json.fromJsonNumber) - val bol = value.toBooleanOption.map(Json.fromBoolean) - val str = Json.fromString(value) - val result = nil.orElse(num).orElse(bol).getOrElse(str) - Right(result) - } + case node: Node.ScalarNode => + scalarNodeToJson(node) case Node.SequenceNode(nodes, _) => val values = nodes.traverse(nodeToJson) values.map(Json.fromValues) diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala index 8b67f9f6..fdb7d73f 100644 --- a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Printer.scala @@ -28,12 +28,11 @@ object Printer extends io.circe.yaml.common.Printer { } private def jsonToNode(json: Json): Node = json match { - case Json.JNull => Node.ScalarNode("null") - case json: Json.JBoolean => Node.ScalarNode(json.toString) - case json: Json.JNumber => Node.ScalarNode(json.toString) - case json: Json.JString => Node.ScalarNode(json.toString) - case Json.JArray(value) => Node.SequenceNode(value.map(jsonToNode): _*) + case Json.JArray(value) => + Node.SequenceNode(value.map(jsonToNode): _*) case Json.JObject(value) => Node.MappingNode(value.toMap.map { case (key, value) => (Node.ScalarNode(key): Node) -> jsonToNode(value) }) + case json => + Node.ScalarNode(json.toString) } } From 86b27f9b9553a521638038a7bc78d0b09ee8f9ec Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Fri, 31 May 2024 14:51:07 +0200 Subject: [PATCH 17/22] scala-yaml 0.1.0 --- build.sbt | 5 ++--- project/plugins.sbt | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index c4f7f7ed..a5d36f13 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,6 @@ ThisBuild / tlBaseVersion := "0.15" ThisBuild / circeRootOfCodeCoverage := None ThisBuild / startYear := Some(2016) -ThisBuild / scalafixScalaBinaryVersion := "2.12" ThisBuild / tlFatalWarnings := false //TODO: ... fix this someday ThisBuild / githubWorkflowBuildMatrixFailFast := Some(false) @@ -15,7 +14,7 @@ val Versions = new { val snakeYamlEngine = "2.7" val previousCirceYamls = Set("0.14.0", "0.14.1", "0.14.2") - val scala213 = "2.13.13" + val scala213 = "2.13.14" val scala3 = "3.3.3" val scalaVersions = Seq(scala213, scala3) @@ -79,7 +78,7 @@ lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePl .settings( description := "Library for converting between scala-yaml AST and circe's AST", libraryDependencies ++= Seq( - "org.virtuslab" %%% "scala-yaml" % "0.0.8", + "org.virtuslab" %%% "scala-yaml" % "0.1.0", "org.scalatest" %%% "scalatest" % Versions.scalaTest % Test ), tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.15.2").toMap diff --git a/project/plugins.sbt b/project/plugins.sbt index 6b1cd833..fbf733cf 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,4 @@ addSbtPlugin("io.circe" % "sbt-circe-org" % "0.3.1") -addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.17") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.2") addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.1") \ No newline at end of file From 6458a9e43c2ee5f1fa28e177617b14ac6e44a873 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Wed, 10 Jul 2024 12:33:27 +0200 Subject: [PATCH 18/22] Update circe --- build.sbt | 6 +++--- .../src/main/scala/io/circe/yaml/scalayaml/Parser.scala | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index a5d36f13..27b52902 100644 --- a/build.sbt +++ b/build.sbt @@ -5,11 +5,11 @@ ThisBuild / tlFatalWarnings := false //TODO: ... fix this someday ThisBuild / githubWorkflowBuildMatrixFailFast := Some(false) val Versions = new { - val circe = "0.14.7" + val circe = "0.14.9" val discipline = "1.5.1" val scalaCheck = "1.18.0" - val scalaTest = "3.2.17" - val scalaTestPlus = "3.2.17.0" + val scalaTest = "3.2.18" + val scalaTestPlus = "3.2.18.0" val snakeYaml = "2.2" val snakeYamlEngine = "2.7" val previousCirceYamls = Set("0.14.0", "0.14.1", "0.14.2") diff --git a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala index a88178b0..fcceb69c 100644 --- a/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala +++ b/circe-yaml-scalayaml/shared/src/main/scala/io/circe/yaml/scalayaml/Parser.scala @@ -108,5 +108,5 @@ object Parser extends io.circe.yaml.common.Parser { } private def errorToFailure(error: YamlError): ParsingFailure = - ParsingFailure(s"${error.getClass.getSimpleName}: ${error.msg}", null) + ParsingFailure(s"Parsing failed: ${error.msg}", error) } From 68da3a5dfd1fd56dc7edfe7f5acb752a30c47c26 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Wed, 10 Jul 2024 12:40:23 +0200 Subject: [PATCH 19/22] fix --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 53a43bdb..6bc74113 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ addSbtPlugin("io.circe" % "sbt-circe-org" % "0.4.1") addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.2") addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0") -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.1") \ No newline at end of file +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.1") From b33f0a8679530604fdbea71696970885bb94f4b9 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Wed, 10 Jul 2024 12:47:21 +0200 Subject: [PATCH 20/22] fix --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 7dbce87c..d26de65b 100644 --- a/build.sbt +++ b/build.sbt @@ -70,7 +70,7 @@ lazy val `circe-yaml-v12` = project "org.scalatest" %% "scalatest" % Versions.scalaTest % Test, "org.scalatestplus" %% "scalacheck-1-17" % Versions.scalaTestPlus % Test ), - tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.14.3").toMap + tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.15.2").toMap ) lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePlatform) From 0203cd9e7aecc7206ed0d30a366444a03009ef39 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Wed, 10 Jul 2024 12:50:33 +0200 Subject: [PATCH 21/22] fix --- build.sbt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index d26de65b..6e5a89be 100644 --- a/build.sbt +++ b/build.sbt @@ -37,7 +37,7 @@ lazy val `circe-yaml-common` = crossProject(JSPlatform, JVMPlatform, NativePlatf libraryDependencies ++= Seq( "io.circe" %%% "circe-core" % Versions.circe ), - tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.15.2").toMap + tlVersionIntroduced := List("2.13", "3").map(_ -> "0.15.2").toMap ) lazy val `circe-yaml` = project @@ -53,7 +53,8 @@ lazy val `circe-yaml` = project "org.scalacheck" %% "scalacheck" % Versions.scalaCheck % Test, "org.scalatest" %% "scalatest" % Versions.scalaTest % Test, "org.scalatestplus" %% "scalacheck-1-17" % Versions.scalaTestPlus % Test - ) + ), + tlVersionIntroduced := List("2.13", "3").map(_ -> "0.14.3").toMap ) lazy val `circe-yaml-v12` = project @@ -70,7 +71,7 @@ lazy val `circe-yaml-v12` = project "org.scalatest" %% "scalatest" % Versions.scalaTest % Test, "org.scalatestplus" %% "scalacheck-1-17" % Versions.scalaTestPlus % Test ), - tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.15.2").toMap + tlVersionIntroduced := List("2.13", "3").map(_ -> "0.14.3").toMap ) lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePlatform) @@ -81,7 +82,7 @@ lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePl "org.virtuslab" %%% "scala-yaml" % "0.1.0", "org.scalatest" %%% "scalatest" % Versions.scalaTest % Test ), - tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "0.15.2").toMap + tlVersionIntroduced := List("2.13", "3").map(_ -> "0.15.2").toMap ) ThisBuild / developers := List( From 0f5de5dafde5a79c0921d0667b3b3425a6e815b5 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Wed, 10 Jul 2024 14:45:10 +0200 Subject: [PATCH 22/22] fix --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 6e5a89be..c123b0f7 100644 --- a/build.sbt +++ b/build.sbt @@ -37,7 +37,7 @@ lazy val `circe-yaml-common` = crossProject(JSPlatform, JVMPlatform, NativePlatf libraryDependencies ++= Seq( "io.circe" %%% "circe-core" % Versions.circe ), - tlVersionIntroduced := List("2.13", "3").map(_ -> "0.15.2").toMap + tlVersionIntroduced := List("2.13", "3").map(_ -> "0.15.3").toMap ) lazy val `circe-yaml` = project @@ -82,7 +82,7 @@ lazy val `circe-yaml-scalayaml` = crossProject(JSPlatform, JVMPlatform, NativePl "org.virtuslab" %%% "scala-yaml" % "0.1.0", "org.scalatest" %%% "scalatest" % Versions.scalaTest % Test ), - tlVersionIntroduced := List("2.13", "3").map(_ -> "0.15.2").toMap + tlVersionIntroduced := List("2.13", "3").map(_ -> "0.15.3").toMap ) ThisBuild / developers := List(