diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1e06957..63e1b5b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,19 +7,27 @@ on: branches: [ main ] jobs: - build: - name: Build and Test + test: strategy: + fail-fast: false matrix: - os: [ubuntu-latest] - scala: [2.13.11, 2.12.18] - java: [zulu@1.8, zulu@1.11, zulu@1.17] + include: + - os: ubuntu-latest + java: 11 + - os: ubuntu-latest + java: 17 + - os: ubuntu-latest + java: 21 runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3.0.2 - - name: Set up Java - uses: olafurpg/setup-scala@v13 - with: - java-version: ${{ matrix.java }} - - name: Run tests - run: sbt ++${{ matrix.scala }} test \ No newline at end of file + - name: Checkout + uses: actions/checkout@v4 + - name: Setup JDK + uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: ${{ matrix.java }} + cache: sbt + - name: Build and test + shell: bash + run: sbt -v +test \ No newline at end of file diff --git a/avrohugger-core/src/main/scala/input/parsers/FileInputParser.scala b/avrohugger-core/src/main/scala/input/parsers/FileInputParser.scala index f52e9fbe..53986c66 100644 --- a/avrohugger-core/src/main/scala/input/parsers/FileInputParser.scala +++ b/avrohugger-core/src/main/scala/input/parsers/FileInputParser.scala @@ -7,10 +7,10 @@ import stores.ClassStore import org.apache.avro.{Protocol, Schema} import org.apache.avro.Schema.Parser import org.apache.avro.Schema.Type.{ENUM, FIXED, RECORD, UNION} -import org.apache.avro.compiler.idl.Idl -import org.apache.avro.generic.{GenericDatumReader, GenericRecord} import org.apache.avro.file.DataFileReader -import org.apache.avro.SchemaParseException +import org.apache.avro.generic.{GenericDatumReader, GenericRecord} +import org.apache.avro.idl.IdlReader +import org.apache.avro.{AvroTypeException, SchemaParseException} import java.io.File import scala.jdk.CollectionConverters._ @@ -48,19 +48,24 @@ class FileInputParser { sys.error(s"Can't redefine: ${nonEqualElements.mkString(",")} in $infile") } else { if (commonElements.isEmpty) { - val _ = parser.addTypes(tempParser.getTypes) + val _ = parser.addTypes(tempParser.getTypes.values) } else { val missingTypes = tempParser.getTypes().keySet().asScala.diff(parser.getTypes().keySet().asScala) val _ = parser.addTypes(missingTypes.map { t => t -> tempParser.getTypes().get(t) - }.toMap.asJava) + }.toMap.asJava.values) } } } def mightBeRecoverable(e: SchemaParseException): Boolean = { val msg = e.getMessage - msg.contains("Undefined name:") || msg.contains("is not a defined name") + msg.contains("Undefined name:") || msg.contains("is not a defined name") + } + + def mightBeRecoverableType(e: AvroTypeException): Boolean = { + val msg = e.getMessage + msg.contains("Undefined schema:") } def tryParse(inFile: File, parser: Schema.Parser): List[Schema] = { @@ -68,8 +73,11 @@ class FileInputParser { val parsed = Try(tempParser.parse(inFile)).map(schema => { copySchemas(tempParser, parser) schema - }).recoverWith { case e: SchemaParseException if mightBeRecoverable(e) => - Try(parser.parse(inFile)) + }).recoverWith { + case e: AvroTypeException if mightBeRecoverableType(e) => + Try(parser.parse(inFile)) + case e: SchemaParseException if mightBeRecoverable(e) => + Try(parser.parse(inFile)) } unUnion(parsed.get)// throw the avro parse exception if Failure } @@ -89,8 +97,8 @@ class FileInputParser { val protocol = Protocol.parse(infile) List(Right(protocol)) case "avdl" => - val idlParser = new Idl(infile, classLoader) - val protocol = idlParser.CompilationUnit() + val idl = new IdlReader().parse(infile.toPath()) + val protocol = idl.getProtocol() /** * IDLs may refer to types imported from another file. When converted * to protocols, the imported types that share the IDL's namespace diff --git a/avrohugger-core/src/main/scala/input/parsers/StringInputParser.scala b/avrohugger-core/src/main/scala/input/parsers/StringInputParser.scala index 55e48be0..26f75ff1 100644 --- a/avrohugger-core/src/main/scala/input/parsers/StringInputParser.scala +++ b/avrohugger-core/src/main/scala/input/parsers/StringInputParser.scala @@ -8,7 +8,7 @@ import org.apache.avro.Protocol import org.apache.avro.Schema import org.apache.avro.Schema.Parser import org.apache.avro.SchemaParseException -import org.apache.avro.compiler.idl.Idl +import org.apache.avro.idl.IdlReader import org.apache.avro.compiler.idl.ParseException import scala.jdk.CollectionConverters._ @@ -22,7 +22,8 @@ class StringInputParser { def getSchemaOrProtocols( inputString: String, - schemaStore: SchemaStore): List[Either[Schema, Protocol]] = { + schemaStore: SchemaStore + ): List[Either[Schema, Protocol]] = { def trySchema(str: String): List[Either[Schema, Protocol]] = { try { @@ -48,13 +49,13 @@ class StringInputParser { try { val bytes = str.getBytes(Charset.forName("UTF-8")) val inStream = new java.io.ByteArrayInputStream(bytes) - val idlParser = new Idl(inStream) - val protocol = idlParser.CompilationUnit() + val idlParser = new IdlReader().parse(inStream) + val protocol = idlParser.getProtocol() List(Right(protocol)) } catch { case e: ParseException => sys.error(s"Unable to parse: ${e}") - case npe: NullPointerException => sys.error("Imports not supported in String IDLs, only avdl files.") + case e: SchemaParseException => sys.error("Imports not supported in String IDLs, only avdl files.") case unknown: Throwable => sys.error("Unexpected exception: " + unknown) } } diff --git a/build.sbt b/build.sbt index 3c989e22..0c30afbc 100644 --- a/build.sbt +++ b/build.sbt @@ -1,15 +1,16 @@ -lazy val avroVersion = "1.11.3" +lazy val avroVersion = "1.12.0" lazy val commonSettings = Seq( organization := "com.julianpeeters", - version := "2.8.3", + version := "2.9.0-SNAPSHOT", ThisBuild / versionScheme := Some("semver-spec"), scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature"), Test / scalacOptions ++= Seq("-Yrangepos"), - scalaVersion := "3.3.1", - crossScalaVersions := Seq("2.12.18", "2.13.12", scalaVersion.value), + scalaVersion := "3.3.3", + crossScalaVersions := Seq("2.12.19", "2.13.14", scalaVersion.value), libraryDependencies += "org.apache.avro" % "avro" % avroVersion, libraryDependencies += "org.apache.avro" % "avro-compiler" % avroVersion, + libraryDependencies += "org.apache.avro" % "avro-idl" % avroVersion, libraryDependencies := { CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, scalaMinor)) if scalaMinor < 13 => // for implementing SpecificRecord from standard case class definitions @@ -20,7 +21,7 @@ lazy val commonSettings = Seq( }}, libraryDependencies := { CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, scalaMinor)) if scalaMinor < 13 => - libraryDependencies.value ++ Seq("org.scala-lang.modules" %% "scala-collection-compat" % "2.11.0") + libraryDependencies.value ++ Seq("org.scala-lang.modules" %% "scala-collection-compat" % "2.12.0") case _ => libraryDependencies.value }}, diff --git a/project/build.properties b/project/build.properties index 8cf07b7c..cb409aac 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.8 \ No newline at end of file +sbt.version=1.10.1 \ No newline at end of file