From dac23e37fba3c10438b0f63ca83fb581bbdb1d33 Mon Sep 17 00:00:00 2001 From: Erlend Hamnaberg Date: Mon, 29 Jul 2024 22:27:25 +0200 Subject: [PATCH] Upgrade deps and add Scala 3 support * Upgrade all deps * Split sources in scala-2 and scala-3 for required compat changes * Mostly bincompat, but had to remove a few functions in Resources object --- .github/workflows/ci.yml | 28 ++++++++++- .gitignore | 4 ++ .scalafmt.conf | 8 +++- build.sbt | 29 +++++++---- .../golden/GoldenCodecTestsCompanion.scala | 39 +++++++++++++++ ...ResourceFileGoldenCodecLawsCompanion.scala | 46 ++++++++++++++++++ .../circe/testing/golden/Scala2Naming.scala | 47 ++++++++++++++++++ .../golden/GoldenCodecTestsCompanion.scala | 38 +++++++++++++++ ...ResourceFileGoldenCodecLawsCompanion.scala | 46 ++++++++++++++++++ .../circe/testing/golden/Scala3Naming.scala | 48 +++++++++++++++++++ .../testing/golden/GoldenCodecTests.scala | 21 ++------ .../golden/ResourceFileGoldenCodecLaws.scala | 15 +----- .../io/circe/testing/golden/Resources.scala | 32 ++----------- project/build.properties | 2 +- project/plugins.sbt | 2 +- 15 files changed, 330 insertions(+), 75 deletions(-) create mode 100644 golden/src/main/scala-2/io/circe/testing/golden/GoldenCodecTestsCompanion.scala create mode 100644 golden/src/main/scala-2/io/circe/testing/golden/ResourceFileGoldenCodecLawsCompanion.scala create mode 100644 golden/src/main/scala-2/io/circe/testing/golden/Scala2Naming.scala create mode 100644 golden/src/main/scala-3/io/circe/testing/golden/GoldenCodecTestsCompanion.scala create mode 100644 golden/src/main/scala-3/io/circe/testing/golden/ResourceFileGoldenCodecLawsCompanion.scala create mode 100644 golden/src/main/scala-3/io/circe/testing/golden/Scala3Naming.scala diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a35aa1..138f6e6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,15 +28,21 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.12, 2.13] + scala: [2.12, 2.13, 3] java: [temurin@11, temurin@17] project: [rootJVM] exclude: - scala: 2.12 java: temurin@17 + - scala: 3 + java: temurin@17 runs-on: ${{ matrix.os }} timeout-minutes: 60 steps: + - name: Install sbt + if: contains(runner.os, 'macos') + run: brew install sbt + - name: Checkout current branch (full) uses: actions/checkout@v4 with: @@ -115,6 +121,10 @@ jobs: java: [temurin@11] runs-on: ${{ matrix.os }} steps: + - name: Install sbt + if: contains(runner.os, 'macos') + run: brew install sbt + - name: Checkout current branch (full) uses: actions/checkout@v4 with: @@ -166,6 +176,16 @@ jobs: tar xf targets.tar rm targets.tar + - name: Download target directories (3, rootJVM) + uses: actions/download-artifact@v4 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-3-rootJVM + + - name: Inflate target directories (3, rootJVM) + run: | + tar xf targets.tar + rm targets.tar + - name: Import signing key if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE == '' env: @@ -199,6 +219,10 @@ jobs: java: [temurin@11] runs-on: ${{ matrix.os }} steps: + - name: Install sbt + if: contains(runner.os, 'macos') + run: brew install sbt + - name: Checkout current branch (full) uses: actions/checkout@v4 with: @@ -233,5 +257,5 @@ jobs: - name: Submit Dependencies uses: scalacenter/sbt-dependency-submission@v2 with: - modules-ignore: rootjs_2.12 rootjs_2.13 rootjvm_2.12 rootjvm_2.13 rootnative_2.12 rootnative_2.13 example1_2.12 example1_2.13 + 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 example1_2.12 example1_2.13 example1_3 configs-ignore: test scala-tool scala-doc-tool test-internal diff --git a/.gitignore b/.gitignore index a90a026..5efecf8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ target/ .classpath tmp/ .bsp/ +.metals/ +.vscode/ +.jvm/ +*.semanticdb diff --git a/.scalafmt.conf b/.scalafmt.conf index 103c862..11802f9 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,5 +1,5 @@ version = 3.5.0 -runner.dialect = scala213 +runner.dialect = scala3 continuationIndent.defnSite = 2 docstrings.style = Asterisk includeCurlyBraceInSelectChains = false @@ -15,3 +15,9 @@ rewrite.rules = [ AsciiSortImports, PreferCurlyFors ] + +fileOverride { + "glob:**/scala-3/**/*.scala" { + runner.dialect = scala3 + } +} \ No newline at end of file diff --git a/build.sbt b/build.sbt index 29cac6d..b050661 100644 --- a/build.sbt +++ b/build.sbt @@ -4,14 +4,15 @@ ThisBuild / circeRootOfCodeCoverage := None ThisBuild / startYear := Some(2016) val scala212 = "2.12.19" -val scala213 = "2.13.11" +val scala213 = "2.13.14" +val scala3 = "3.3.3" ThisBuild / scalaVersion := scala213 -ThisBuild / crossScalaVersions := Seq(scala212, scala213) +ThisBuild / crossScalaVersions := Seq(scala212, scala213, scala3) -val circeVersion = "0.14.6" -val scalacheckVersion = "1.17.0" -val disciplineScalatestVersion = "2.2.0" -val scalacheckScalaTestVersion = "3.2.18.0" +val circeVersion = "0.14.9" +val scalacheckVersion = "1.18.0" +val disciplineScalatestVersion = "2.3.0" +val scalacheckScalaTestVersion = "3.2.19.0" val root = tlCrossRootProject.aggregate(golden, example1) @@ -21,15 +22,23 @@ lazy val golden = crossProject(JVMPlatform) .settings( moduleName := "circe-golden", libraryDependencies ++= Seq( - "org.scalatestplus" %%% "scalacheck-1-17" % scalacheckScalaTestVersion, + "org.scalatestplus" %%% "scalacheck-1-18" % scalacheckScalaTestVersion, "io.circe" %%% "circe-core" % circeVersion, "io.circe" %%% "circe-parser" % circeVersion, "io.circe" %%% "circe-testing" % circeVersion, "io.circe" %%% "circe-generic" % circeVersion % Test, "org.scalacheck" %% "scalacheck" % scalacheckVersion, - "org.typelevel" %%% "discipline-scalatest" % disciplineScalatestVersion % Test, - scalaOrganization.value % "scala-reflect" % scalaVersion.value % Provided - ) + "org.typelevel" %%% "discipline-scalatest" % disciplineScalatestVersion % Test + ), + libraryDependencies ++= { + if (tlIsScala3.value) Nil + else + Seq( + scalaOrganization.value % "scala-reflect" % scalaVersion.value % Provided + ) + }, + Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat, + tlVersionIntroduced := Map("2.13" -> "0.14.0", "2.12" -> "0.4.0", "3" -> "0.4.1") ) lazy val example1 = crossProject(JVMPlatform) diff --git a/golden/src/main/scala-2/io/circe/testing/golden/GoldenCodecTestsCompanion.scala b/golden/src/main/scala-2/io/circe/testing/golden/GoldenCodecTestsCompanion.scala new file mode 100644 index 0000000..283569d --- /dev/null +++ b/golden/src/main/scala-2/io/circe/testing/golden/GoldenCodecTestsCompanion.scala @@ -0,0 +1,39 @@ +/* + * 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.testing.golden + +import io.circe.Decoder +import io.circe.Encoder +import io.circe.Printer +import org.scalacheck.Arbitrary + +import scala.reflect.runtime.universe.TypeTag + +trait GoldenCodecTestsCompanion { self: GoldenCodecTests.type => + def apply[A: Decoder: Encoder: Arbitrary: TypeTag]: GoldenCodecTests[A] = + fromLaws[A](ResourceFileGoldenCodecLaws[A]()) + + def apply[A: Decoder: Encoder: Arbitrary: TypeTag](printer: Printer): GoldenCodecTests[A] = + fromLaws[A](ResourceFileGoldenCodecLaws[A](printer = printer)) + + def apply[A: Decoder: Encoder: Arbitrary: TypeTag](count: Int): GoldenCodecTests[A] = + fromLaws[A](ResourceFileGoldenCodecLaws[A](count = count)) + + def apply[A: Decoder: Encoder: Arbitrary: TypeTag](count: Int, printer: Printer): GoldenCodecTests[A] = + fromLaws[A](ResourceFileGoldenCodecLaws[A](count = count, printer = printer)) + +} diff --git a/golden/src/main/scala-2/io/circe/testing/golden/ResourceFileGoldenCodecLawsCompanion.scala b/golden/src/main/scala-2/io/circe/testing/golden/ResourceFileGoldenCodecLawsCompanion.scala new file mode 100644 index 0000000..8410840 --- /dev/null +++ b/golden/src/main/scala-2/io/circe/testing/golden/ResourceFileGoldenCodecLawsCompanion.scala @@ -0,0 +1,46 @@ +/* + * 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.testing.golden + +import io.circe.Decoder +import io.circe.Encoder +import io.circe.Printer +import org.scalacheck.Arbitrary + +import scala.reflect.runtime.universe.TypeTag + +trait ResourceFileGoldenCodecLawsCompanion { self: ResourceFileGoldenCodecLaws.type => + + def apply[A]( + size: Int = 100, + count: Int = 1, + printer: Printer = Printer.spaces2 + )(implicit + decodeA: Decoder[A], + encodeA: Encoder[A], + arbitraryA: Arbitrary[A], + typeTagA: TypeTag[A] + ): GoldenCodecLaws[A] = + self.apply[A]( + Scala2Naming.inferName[A], + Resources.inferRootDir(typeTagA.mirror.runtimeClass(typeTagA.tpe)), + Scala2Naming.inferPackage[A], + size, + count, + printer + ) +} diff --git a/golden/src/main/scala-2/io/circe/testing/golden/Scala2Naming.scala b/golden/src/main/scala-2/io/circe/testing/golden/Scala2Naming.scala new file mode 100644 index 0000000..0c2818a --- /dev/null +++ b/golden/src/main/scala-2/io/circe/testing/golden/Scala2Naming.scala @@ -0,0 +1,47 @@ +/* + * 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.testing.golden + +import scala.reflect.runtime.universe.Symbol +import scala.reflect.runtime.universe.Type +import scala.reflect.runtime.universe.TypeTag + +object Scala2Naming { + + /** + * Attempt to guess the packaging of the type indicated by the provided type tag. + */ + def inferPackage[A](implicit A: TypeTag[A]): List[String] = + owners(A.tpe).collectFirst { case s if s.isPackage => s.fullName.split('.').toList }.getOrElse(List.empty) + + private def owners(tpe: Type): Iterator[Symbol] = + Iterator.iterate(tpe.typeSymbol)(_.owner) + + /** + * Attempt to guess the name of the type indicated by the provided type tag. + */ + def inferName[A](implicit A: TypeTag[A]): String = inferNameForType(A.tpe) + + private def baseSymbols(tpe: Type): List[Symbol] = + owners(tpe).takeWhile(!_.isPackage).toList.reverse + + private def inferNameForType(tpe: Type): String = { + val baseNames = baseSymbols(tpe).map(_.name.decodedName.toString) + + (baseNames ::: tpe.typeArgs.map(inferNameForType)).mkString("_") + } +} diff --git a/golden/src/main/scala-3/io/circe/testing/golden/GoldenCodecTestsCompanion.scala b/golden/src/main/scala-3/io/circe/testing/golden/GoldenCodecTestsCompanion.scala new file mode 100644 index 0000000..c8d043a --- /dev/null +++ b/golden/src/main/scala-3/io/circe/testing/golden/GoldenCodecTestsCompanion.scala @@ -0,0 +1,38 @@ +/* + * 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.testing.golden + +import io.circe.Decoder +import io.circe.Encoder +import io.circe.Printer +import org.scalacheck.Arbitrary + +import scala.reflect.ClassTag + +trait GoldenCodecTestsCompanion { self: GoldenCodecTests.type => + inline def apply[A: Decoder: Encoder: Arbitrary: ClassTag]: GoldenCodecTests[A] = + fromLaws[A](ResourceFileGoldenCodecLaws[A]()) + + inline def apply[A: Decoder: Encoder: Arbitrary: ClassTag](printer: Printer): GoldenCodecTests[A] = + fromLaws[A](ResourceFileGoldenCodecLaws[A](printer = printer)) + + inline def apply[A: Decoder: Encoder: Arbitrary: ClassTag](count: Int): GoldenCodecTests[A] = + fromLaws[A](ResourceFileGoldenCodecLaws[A](count = count)) + + inline def apply[A: Decoder: Encoder: Arbitrary: ClassTag](count: Int, printer: Printer): GoldenCodecTests[A] = + fromLaws[A](ResourceFileGoldenCodecLaws[A](count = count, printer = printer)) +} diff --git a/golden/src/main/scala-3/io/circe/testing/golden/ResourceFileGoldenCodecLawsCompanion.scala b/golden/src/main/scala-3/io/circe/testing/golden/ResourceFileGoldenCodecLawsCompanion.scala new file mode 100644 index 0000000..535209e --- /dev/null +++ b/golden/src/main/scala-3/io/circe/testing/golden/ResourceFileGoldenCodecLawsCompanion.scala @@ -0,0 +1,46 @@ +/* + * 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.testing.golden + +import io.circe.Decoder +import io.circe.Encoder +import io.circe.Printer +import org.scalacheck.Arbitrary + +import scala.reflect.ClassTag + +trait ResourceFileGoldenCodecLawsCompanion { self: ResourceFileGoldenCodecLaws.type => + + inline def apply[A]( + size: Int = 100, + count: Int = 1, + printer: Printer = Printer.spaces2 + )(using + decodeA: Decoder[A], + encodeA: Encoder[A], + arbitraryA: Arbitrary[A], + classT: ClassTag[A] + ): GoldenCodecLaws[A] = + self.apply[A]( + Scala3Naming.name[A], + Resources.inferRootDir(classT.runtimeClass), + Scala3Naming.pkg[A], + size, + count, + printer + ) +} diff --git a/golden/src/main/scala-3/io/circe/testing/golden/Scala3Naming.scala b/golden/src/main/scala-3/io/circe/testing/golden/Scala3Naming.scala new file mode 100644 index 0000000..2b65bce --- /dev/null +++ b/golden/src/main/scala-3/io/circe/testing/golden/Scala3Naming.scala @@ -0,0 +1,48 @@ +/* + * 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.testing.golden + +import scala.quoted.* +object Scala3Naming { + + inline def name[T]: String = ${ Scala3Naming.nameImpl[T] } + inline def pkg[T]: List[String] = ${ Scala3Naming.packageImpl[T] } + + def nameImpl[T: Type](using Quotes): Expr[String] = { + import quotes.reflect.* + + val typeRepr = TypeRepr.of[T] + + def expandName(repr: TypeRepr, names: List[String]): List[String] = { + val args = repr.typeArgs + repr.typeSymbol.name :: (if args.isEmpty then names else args.flatMap(x => expandName(x, names))) + } + + Expr(expandName(typeRepr, Nil).reverse.mkString("_")) + } + + def packageImpl[T: Type](using q: Quotes): Expr[List[String]] = { + import q.reflect.* + val repr = TypeRepr.of[T] + val symbol = repr.typeSymbol + + def expandPkg(s: Symbol, names: List[String]): List[String] = + if s.isNoSymbol || s.name == "" then names + else expandPkg(s.maybeOwner, if s.isPackageDef then s.name :: names else names) + Expr(expandPkg(symbol, Nil)) + } +} diff --git a/golden/src/main/scala/io/circe/testing/golden/GoldenCodecTests.scala b/golden/src/main/scala/io/circe/testing/golden/GoldenCodecTests.scala index 56452b6..472290c 100644 --- a/golden/src/main/scala/io/circe/testing/golden/GoldenCodecTests.scala +++ b/golden/src/main/scala/io/circe/testing/golden/GoldenCodecTests.scala @@ -20,16 +20,12 @@ import cats.instances.string._ import cats.kernel.Eq import cats.laws.IsEq import cats.laws.discipline.catsLawsIsEqToProp -import io.circe.Decoder -import io.circe.Encoder import io.circe.Json -import io.circe.Printer import io.circe.testing.CodecTests import org.scalacheck.Arbitrary import org.scalacheck.Prop import org.scalacheck.Shrink -import scala.reflect.runtime.universe.TypeTag import scala.util.Failure import scala.util.Success import scala.util.Try @@ -69,20 +65,11 @@ trait GoldenCodecTests[A] extends CodecTests[A] { ) } -object GoldenCodecTests { - def apply[A: Decoder: Encoder: Arbitrary: TypeTag]: GoldenCodecTests[A] = - apply[A](ResourceFileGoldenCodecLaws[A]()) +object GoldenCodecTests extends GoldenCodecTestsCompanion { - def apply[A: Decoder: Encoder: Arbitrary: TypeTag](printer: Printer): GoldenCodecTests[A] = - apply[A](ResourceFileGoldenCodecLaws[A](printer = printer)) - - def apply[A: Decoder: Encoder: Arbitrary: TypeTag](count: Int): GoldenCodecTests[A] = - apply[A](ResourceFileGoldenCodecLaws[A](count = count)) - - def apply[A: Decoder: Encoder: Arbitrary: TypeTag](count: Int, printer: Printer): GoldenCodecTests[A] = - apply[A](ResourceFileGoldenCodecLaws[A](count = count, printer = printer)) - - def apply[A](laws0: GoldenCodecLaws[A]): GoldenCodecTests[A] = + // for binary compat + protected def apply[A](laws0: GoldenCodecLaws[A]): GoldenCodecTests[A] = fromLaws(laws0) + def fromLaws[A](laws0: GoldenCodecLaws[A]): GoldenCodecTests[A] = new GoldenCodecTests[A] { val laws: GoldenCodecLaws[A] = laws0 } diff --git a/golden/src/main/scala/io/circe/testing/golden/ResourceFileGoldenCodecLaws.scala b/golden/src/main/scala/io/circe/testing/golden/ResourceFileGoldenCodecLaws.scala index f1a977e..33355e1 100644 --- a/golden/src/main/scala/io/circe/testing/golden/ResourceFileGoldenCodecLaws.scala +++ b/golden/src/main/scala/io/circe/testing/golden/ResourceFileGoldenCodecLaws.scala @@ -28,7 +28,6 @@ import org.scalacheck.Gen import java.io.File import java.io.PrintWriter -import scala.reflect.runtime.universe.TypeTag import scala.util.Failure import scala.util.Try import scala.util.matching.Regex @@ -98,7 +97,7 @@ abstract class ResourceFileGoldenCodecLaws[A]( loadGoldenFiles.flatMap(fs => if (fs.isEmpty) generateGoldenFiles else loadGoldenFiles) } -object ResourceFileGoldenCodecLaws { +object ResourceFileGoldenCodecLaws extends ResourceFileGoldenCodecLawsCompanion { def apply[A]( name: String, resourceRootDir: File, @@ -112,16 +111,4 @@ object ResourceFileGoldenCodecLaws { val encode: Encoder[A] = encodeA val gen: Gen[A] = arbitraryA.arbitrary } - - def apply[A]( - size: Int = 100, - count: Int = 1, - printer: Printer = Printer.spaces2 - )(implicit - decodeA: Decoder[A], - encodeA: Encoder[A], - arbitraryA: Arbitrary[A], - typeTagA: TypeTag[A] - ): GoldenCodecLaws[A] = - apply[A](Resources.inferName[A], Resources.inferRootDir, Resources.inferPackage[A], size, count, printer) } diff --git a/golden/src/main/scala/io/circe/testing/golden/Resources.scala b/golden/src/main/scala/io/circe/testing/golden/Resources.scala index d41040c..1444522 100644 --- a/golden/src/main/scala/io/circe/testing/golden/Resources.scala +++ b/golden/src/main/scala/io/circe/testing/golden/Resources.scala @@ -18,21 +18,18 @@ package io.circe.testing.golden import java.io.File import scala.io.Source -import scala.reflect.runtime.universe.Symbol -import scala.reflect.runtime.universe.Type -import scala.reflect.runtime.universe.TypeTag import scala.util.Try /** - * Miscellaneous utilities for guessing resource locations, names, etc. + * Miscellaneous utilities for guessing resource locations */ object Resources { /** * Attempt to guess the test resource root directory for the current project, creating it if it does not exist. */ - lazy val inferRootDir: File = { - var current = new File(getClass.getResource("/").toURI) + def inferRootDir(cls: Class[_]): File = { + var current = new File(cls.getProtectionDomain.getCodeSource.getLocation.getFile) while (current.ne(null) && current.getName != "target") current = current.getParentFile @@ -43,29 +40,6 @@ object Resources { resourceDir } - /** - * Attempt to guess the packaging of the type indicated by the provided type tag. - */ - def inferPackage[A](implicit A: TypeTag[A]): List[String] = - owners(A.tpe).collectFirst { case s if s.isPackage => s.fullName.split('.').toList }.getOrElse(List.empty) - - private def owners(tpe: Type): Iterator[Symbol] = - Iterator.iterate(tpe.typeSymbol)(_.owner) - - /** - * Attempt to guess the name of the type indicated by the provided type tag. - */ - def inferName[A](implicit A: TypeTag[A]): String = inferNameForType(A.tpe) - - private def baseSymbols(tpe: Type): List[Symbol] = - owners(tpe).takeWhile(!_.isPackage).toList.reverse - - private def inferNameForType(tpe: Type): String = { - val baseNames = baseSymbols(tpe).map(_.name.decodedName.toString) - - (baseNames ::: tpe.typeArgs.map(inferNameForType)).mkString("_") - } - def open(path: String): Try[Source] = Try( Source.fromInputStream(getClass.getResourceAsStream(path)) ) diff --git a/project/build.properties b/project/build.properties index 04267b1..ee4c672 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.9.9 +sbt.version=1.10.1 diff --git a/project/plugins.sbt b/project/plugins.sbt index 50c0653..26771e3 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1 +1 @@ -addSbtPlugin("io.circe" % "sbt-circe-org" % "0.3.1") +addSbtPlugin("io.circe" % "sbt-circe-org" % "0.4.2")