diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9586137..b93dc6cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,12 +9,17 @@ name: Continuous Integration on: pull_request: - branches: ['*'] + branches: ['**'] push: - branches: ['*'] + branches: ['**'] tags: [v*] env: + PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_CREDENTIAL_HOST: ${{ secrets.SONATYPE_CREDENTIAL_HOST }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + PGP_SECRET: ${{ secrets.PGP_SECRET }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} jobs: @@ -23,9 +28,9 @@ jobs: strategy: matrix: os: [ubuntu-latest] - scala: [2.12.15, 2.13.8, 3.1.0] - java: [adopt@1.8] - ci: [test] + scala: [2.12.15, 2.13.8, 3.1.1] + java: [temurin@8] + project: [rootJS, rootJVM] runs-on: ${{ matrix.os }} steps: - name: Checkout current branch (full) @@ -33,10 +38,12 @@ jobs: with: fetch-depth: 0 - - name: Setup Java and Scala - uses: olafurpg/setup-scala@v10 + - name: Setup Java (temurin@8) + if: matrix.java == 'temurin@8' + uses: actions/setup-java@v2 with: - java-version: ${{ matrix.java }} + distribution: temurin + java-version: 8 - name: Cache sbt uses: actions/cache@v2 @@ -51,20 +58,50 @@ jobs: key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} - name: Check that workflows are up to date - run: sbt ++${{ matrix.scala }} githubWorkflowCheck + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' 'project /' githubWorkflowCheck - - name: Validation - run: sbt ++${{ matrix.scala }} '${{ matrix.ci }}' + - name: Check formatting + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' scalafmtCheckAll root/scalafmtSbtCheck + + - name: scalaJSLink + if: matrix.project == 'rootJS' + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' Test/scalaJSLinkerResult + + - name: Test + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' test + + - name: Check binary compatibility + if: matrix.java == 'temurin@8' + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' mimaReportBinaryIssues + + - name: Generate API documentation + if: matrix.java == 'temurin@8' + run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' doc + + - name: Make target directories + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/dotty') + run: mkdir -p target .js/target core/.js/target core/.jvm/target .jvm/target .native/target project/target + + - name: Compress target directories + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/dotty') + run: tar cf targets.tar target .js/target core/.js/target core/.jvm/target .jvm/target .native/target project/target + + - name: Upload target directories + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/dotty') + uses: actions/upload-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-${{ matrix.scala }}-${{ matrix.project }} + path: targets.tar publish: name: Publish Artifacts needs: [build] - if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v')) + if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/dotty') strategy: matrix: os: [ubuntu-latest] - scala: [3.1.0] - java: [adopt@1.8] + scala: [3.1.1] + java: [temurin@8] runs-on: ${{ matrix.os }} steps: - name: Checkout current branch (full) @@ -72,10 +109,12 @@ jobs: with: fetch-depth: 0 - - name: Setup Java and Scala - uses: olafurpg/setup-scala@v10 + - name: Setup Java (temurin@8) + if: matrix.java == 'temurin@8' + uses: actions/setup-java@v2 with: - java-version: ${{ matrix.java }} + distribution: temurin + java-version: 8 - name: Cache sbt uses: actions/cache@v2 @@ -89,11 +128,76 @@ jobs: ~/Library/Caches/Coursier/v1 key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} - - uses: olafurpg/setup-gpg@v3 + - name: Download target directories (2.12.15, rootJS) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.15-rootJS + + - name: Inflate target directories (2.12.15, rootJS) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.12.15, rootJVM) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.15-rootJVM + + - name: Inflate target directories (2.12.15, rootJVM) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.13.8, rootJS) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13.8-rootJS + + - name: Inflate target directories (2.13.8, rootJS) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (2.13.8, rootJVM) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-2.13.8-rootJVM + + - name: Inflate target directories (2.13.8, rootJVM) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (3.1.1, rootJS) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-3.1.1-rootJS + + - name: Inflate target directories (3.1.1, rootJS) + run: | + tar xf targets.tar + rm targets.tar + + - name: Download target directories (3.1.1, rootJVM) + uses: actions/download-artifact@v2 + with: + name: target-${{ matrix.os }}-${{ matrix.java }}-3.1.1-rootJVM + + - name: Inflate target directories (3.1.1, rootJVM) + run: | + tar xf targets.tar + rm targets.tar + + - name: Import signing key + if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE == '' + run: echo $PGP_SECRET | base64 -di | gpg --import + + - name: Import signing key and strip passphrase + if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE != '' + run: | + echo "$PGP_SECRET" | base64 -di > /tmp/signing-key.gpg + echo "$PGP_PASSPHRASE" | gpg --pinentry-mode loopback --passphrase-fd 0 --import /tmp/signing-key.gpg + (echo "$PGP_PASSPHRASE"; echo; echo) | gpg --command-fd 0 --pinentry-mode loopback --change-passphrase $(gpg --list-secret-keys --with-colons 2> /dev/null | grep '^sec:' | cut --delimiter ':' --fields 5 | tail -n 1) - - env: - PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} - PGP_SECRET: ${{ secrets.PGP_SECRET }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - run: sbt ++${{ matrix.scala }} ci-release \ No newline at end of file + - name: Publish + run: sbt '++${{ matrix.scala }}' tlRelease diff --git a/.github/workflows/clean.yml b/.github/workflows/clean.yml index b535fcc1..547aaa43 100644 --- a/.github/workflows/clean.yml +++ b/.github/workflows/clean.yml @@ -56,4 +56,4 @@ jobs: printf "Deleting '%s' #%d, %'d bytes\n" $name ${ARTCOUNT[$name]} $size ghapi -X DELETE $REPO/actions/artifacts/$id done - done \ No newline at end of file + done diff --git a/.gitignore b/.gitignore index 99aa4a29..0b5fc9b7 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,13 @@ target/ *.iml *.iws +# Ignore project files for VSCode +.bloop +.bsp +.metals +.vscode +metals.sbt + # Ignore OS X metadata .DS_Store diff --git a/.sbtrc b/.sbtrc deleted file mode 100644 index 741a9b6e..00000000 --- a/.sbtrc +++ /dev/null @@ -1 +0,0 @@ -alias boot = ;reload ;project kittens ;iflast shell diff --git a/.scalafmt.conf b/.scalafmt.conf index b4486c93..32e7cfeb 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,5 +1,5 @@ -version = "3.0.0" -runner.dialect = "scala3" +version = "3.4.3" +runner.dialect = scala3 align.preset = none maxColumn = 120 includeNoParensInSelectChains = false @@ -10,3 +10,4 @@ rewrite.redundantBraces.stringInterpolation = true rewrite.redundantBraces.methodBodies = true rewrite.redundantBraces.generalExpressions = true rewriteTokens = { "⇒": "=>", "→": "->", "←": "<-" } +fileOverride { "glob:**/*.sbt" { runner.dialect = scala212 } } diff --git a/build.sbt b/build.sbt index ea1adaba..5e23b87a 100644 --- a/build.sbt +++ b/build.sbt @@ -2,23 +2,22 @@ import sbt._ val scala212 = "2.12.15" val scala213 = "2.13.8" -val scala3 = "3.1.0" +val scala3 = "3.1.1" ThisBuild / crossScalaVersions := Seq(scala212, scala213, scala3) ThisBuild / scalaVersion := scala3 - -lazy val buildSettings = Seq( - organization := "org.typelevel" -) +ThisBuild / tlBaseVersion := "3.0" +ThisBuild / organization := "org.typelevel" val catsVersion = "2.7.0" +val munitVersion = "0.7.29" val disciplineMunitVersion = "1.0.9" val kindProjectorVersion = "0.13.2" -val shapeless2Version = "2.3.7" +val shapeless2Version = "2.3.8" val shapeless3Version = "3.0.4" lazy val commonSettings = Seq( - scalacOptions := Seq( + scalacOptions ++= Seq( "-feature", "-language:higherKinds", "-language:implicitConversions", @@ -39,7 +38,8 @@ lazy val commonSettings = Seq( "org.typelevel" %%% "cats-core" % catsVersion, "org.typelevel" %%% "alleycats-core" % catsVersion, "org.typelevel" %%% "cats-testkit" % catsVersion % Test, - "org.typelevel" %%% "discipline-munit" % disciplineMunitVersion % Test + "org.typelevel" %%% "discipline-munit" % disciplineMunitVersion % Test, + "org.scalameta" %%% "munit" % munitVersion % Test ), libraryDependencies ++= (CrossVersion.partialVersion(scalaVersion.value) match { case Some((3, _)) => @@ -51,36 +51,19 @@ lazy val commonSettings = Seq( compilerPlugin(("org.typelevel" %% "kind-projector" % kindProjectorVersion).cross(CrossVersion.full)) ) }), - Test / parallelExecution := false, - versionScheme := Some("semver-spec"), - mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "2.2.1") + Test / parallelExecution := false ) console / initialCommands := """import shapeless._, cats._, cats.derived._""" -lazy val commonJsSettings = Seq( - Global / scalaJSStage := FastOptStage, - Test / scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.CommonJSModule)) -) - -lazy val coreSettings = - Seq.concat(buildSettings, commonSettings, crossVersionSharedSources, publishSettings) - -lazy val kittens = project - .in(file(".")) - .aggregate(coreJVM) - .dependsOn(coreJVM) - .settings(coreSettings: _*) - .settings(noPublishSettings) +lazy val root = tlCrossRootProject.aggregate(core) -lazy val core = crossProject(JVMPlatform) +lazy val core = crossProject(JVMPlatform, JSPlatform) .crossType(CrossType.Pure) .settings(moduleName := "kittens") - .settings(coreSettings: _*) - -lazy val coreJVM = core.jvm + .settings(commonSettings: _*) -addCommandAlias("root", ";project kittens") +addCommandAlias("root", ";project /") addCommandAlias("jvm", ";project coreJVM") addCommandAlias("js", ";project coreJS") addCommandAlias("native", ";project coreNative") @@ -95,43 +78,17 @@ addCommandAlias("mima", "coreJVM/mimaReportBinaryIssues") addCommandAlias("fmt", "all scalafmtSbt scalafmtAll") addCommandAlias("fmtCheck", "all scalafmtSbtCheck scalafmtCheckAll") -lazy val crossVersionSharedSources: Seq[Setting[_]] = Seq(Compile, Test).map { sc => - (sc / unmanagedSourceDirectories) ++= (sc / unmanagedSourceDirectories).value.map { dir: File => - new File(dir.getPath + "-" + scalaBinaryVersion.value.head) - } -} - -lazy val publishSettings = Seq( - Test / publishArtifact := false, - pomIncludeRepository := (_ => false), - homepage := Some(url("https://github.com/typelevel/kittens")), - licenses := Seq("Apache 2" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt")), - scmInfo := Some(ScmInfo(url("https://github.com/typelevel/kittens"), "scm:git:git@github.com:typelevel/kittens.git")), - developers := List( - Developer("milessabin", "Miles Sabin", "", url("http://milessabin.com/blog")), - Developer("kailuowang", "Kai(luo) Wang", "kailuo.wang@gmail.com", url("http://kailuowang.com/")), - Developer("joroKr21", "Georgi Krastev", "joro.kr.21@gmail.com", url("https://twitter.com/Joro_Kr")) - ) +ThisBuild / licenses := Seq(License.Apache2) +ThisBuild / developers := List( + Developer("milessabin", "Miles Sabin", "", url("http://milessabin.com/blog")), + Developer("kailuowang", "Kai(luo) Wang", "kailuo.wang@gmail.com", url("http://kailuowang.com/")), + Developer("joroKr21", "Georgi Krastev", "joro.kr.21@gmail.com", url("https://twitter.com/Joro_Kr")) ) -lazy val noPublishSettings = - publish / skip := true - -ThisBuild / githubWorkflowJavaVersions := Seq("adopt@1.8") -ThisBuild / githubWorkflowArtifactUpload := false -ThisBuild / githubWorkflowBuildMatrixAdditions += "ci" -> List("test") -ThisBuild / githubWorkflowBuild := List(WorkflowStep.Sbt(List("${{ matrix.ci }}"), name = Some("Validation"))) -ThisBuild / githubWorkflowTargetTags ++= Seq("v*") -ThisBuild / githubWorkflowPublishTargetBranches := Seq(RefPredicate.StartsWith(Ref.Tag("v"))) -ThisBuild / githubWorkflowPublishPreamble += WorkflowStep.Use(UseRef.Public("olafurpg", "setup-gpg", "v3")) -ThisBuild / githubWorkflowPublish := Seq( +ThisBuild / tlCiReleaseBranches := Seq("dotty") +ThisBuild / githubWorkflowBuild ~= { steps => WorkflowStep.Sbt( - List("ci-release"), - env = Map( - "PGP_PASSPHRASE" -> "${{ secrets.PGP_PASSPHRASE }}", - "PGP_SECRET" -> "${{ secrets.PGP_SECRET }}", - "SONATYPE_PASSWORD" -> "${{ secrets.SONATYPE_PASSWORD }}", - "SONATYPE_USERNAME" -> "${{ secrets.SONATYPE_USERNAME }}" - ) - ) -) + List("scalafmtCheckAll", "root/scalafmtSbtCheck"), + name = Some("Check formatting") + ) +: steps +} diff --git a/core/src/main/scala-2.12/cats/derived/semiauto.scala b/core/src/main/scala-2.12/cats/derived/semiauto.scala index 84f3ec56..ed8d0a14 100644 --- a/core/src/main/scala-2.12/cats/derived/semiauto.scala +++ b/core/src/main/scala-2.12/cats/derived/semiauto.scala @@ -1,7 +1,7 @@ package cats.derived -/** allows semi automatically derive each instance. The derivation might need help when - * there are fields with a type constructor that comes with instances, e.g. +/** allows semi automatically derive each instance. The derivation might need help when there are fields with a type + * constructor that comes with instances, e.g. * {{{ * scala> case class Bar(a: String) * scala> case class Foo(bars: List[Bar]) @@ -25,9 +25,9 @@ package cats.derived * scala> implicit val fooShow: Show[Foo] = { | * import cats.derived.auto.show._ | * cats.derived.semiauto.show | - * } - * scala> Foo(List(Bar("a"))).show - * res3: String = Foo(bars = List(Bar(a = a))) + * } + * scala> Foo(List(Bar("a"))).show + * res3: String = Foo(bars = List(Bar(a = a))) * }}} */ object semiauto extends SemiAutoInstances diff --git a/core/src/main/scala-2.13/cats/derived/semiauto.scala b/core/src/main/scala-2.13/cats/derived/semiauto.scala index b096422b..4bc63587 100644 --- a/core/src/main/scala-2.13/cats/derived/semiauto.scala +++ b/core/src/main/scala-2.13/cats/derived/semiauto.scala @@ -4,8 +4,8 @@ package derived import alleycats.{ConsK, Empty, EmptyK, Pure} import cats.kernel.{CommutativeMonoid, CommutativeSemigroup} -/** allows semi automatically derive each instance. The derivation might need help when - * there are fields with a type constructor that comes with instances, e.g. +/** allows semi automatically derive each instance. The derivation might need help when there are fields with a type + * constructor that comes with instances, e.g. * {{{ * scala> case class Bar(a: String) * scala> case class Foo(bars: List[Bar]) @@ -29,9 +29,9 @@ import cats.kernel.{CommutativeMonoid, CommutativeSemigroup} * scala> implicit val fooShow: Show[Foo] = { | * import cats.derived.auto.show._ | * cats.derived.semiauto.show | - * } - * scala> Foo(List(Bar("a"))).show - * res3: String = Foo(bars = List(Bar(a = a))) + * } + * scala> Foo(List(Bar("a"))).show + * res3: String = Foo(bars = List(Bar(a = a))) * }}} */ object semiauto { diff --git a/core/src/main/scala-2/cats/derived/package.scala b/core/src/main/scala-2/cats/derived/package.scala index 6ec9fa08..005ad2a9 100644 --- a/core/src/main/scala-2/cats/derived/package.scala +++ b/core/src/main/scala-2/cats/derived/package.scala @@ -6,9 +6,8 @@ import cats.derived.util.VersionSpecific.Lazy import cats.kernel.{CommutativeMonoid, CommutativeSemigroup} import shapeless.{Cached, Refute} -/** Fully automatically derive the instance, note that this derivation is not cached, so it - * will re-derive every time an instance is needed in the application, which could - * significantly impact the compilation time. +/** Fully automatically derive the instance, note that this derivation is not cached, so it will re-derive every time an + * instance is needed in the application, which could significantly impact the compilation time. */ object auto { @@ -277,8 +276,8 @@ object auto { } } -/** cached cache the derived instance but this cache are global, so be cautious only use it - * when there is only one instance globally in your application. +/** cached cache the derived instance but this cache are global, so be cautious only use it when there is only one + * instance globally in your application. */ object cached { @@ -495,8 +494,8 @@ abstract private[derived] class SemiAutoInstances { def iterable[F[_], A](fa: F[A])(implicit F: MkIterable[F]): Iterable[A] = F.iterable(fa) } -/** allows semi automatically derive each instance. The derivation might need help when - * there are fields with a type constructor that comes with instances, e.g. +/** allows semi automatically derive each instance. The derivation might need help when there are fields with a type + * constructor that comes with instances, e.g. * {{{ * scala> case class Bar(a: String) * scala> case class Foo(bars: List[Bar]) @@ -520,9 +519,9 @@ abstract private[derived] class SemiAutoInstances { * scala> implicit val fooShow: Show[Foo] = { | * import cats.derived.auto.show._ | * cats.derived.semi.show | - * } - * scala> Foo(List(Bar("a"))).show - * res3: String = Foo(bars = List(Bar(a = a))) + * } + * scala> Foo(List(Bar("a"))).show + * res3: String = Foo(bars = List(Bar(a = a))) * }}} */ @deprecated(message = "Use semiauto instead.", since = "2.1.0") diff --git a/core/src/main/scala-2/cats/derived/show.scala b/core/src/main/scala-2/cats/derived/show.scala index 1af55e90..0994808f 100644 --- a/core/src/main/scala-2/cats/derived/show.scala +++ b/core/src/main/scala-2/cats/derived/show.scala @@ -8,16 +8,12 @@ import util.VersionSpecific.{Lazy, OrElse} import scala.annotation.implicitNotFound import scala.reflect.ClassTag -/** Due to a limitation in the way Shapeless' `describe` is currently - * implemented, `Show` can't be derived for ADTs which are _both_ - * recursive _and_ generic in one or more type parameters. +/** Due to a limitation in the way Shapeless' `describe` is currently implemented, `Show` can't be derived for ADTs + * which are _both_ recursive _and_ generic in one or more type parameters. * - * See: - * https://github.com/typelevel/kittens/pull/48#issue-249836267 - * https://github.com/milessabin/shapeless/issues/750 + * See: https://github.com/typelevel/kittens/pull/48#issue-249836267 https://github.com/milessabin/shapeless/issues/750 * - * See the test suite for more precise examples of what can and cannot - * be derived. + * See the test suite for more precise examples of what can and cannot be derived. */ @implicitNotFound("""Could not derive an instance of Show[A] where A = ${A}. Make sure that A satisfies one of the following conditions: diff --git a/core/src/main/scala-2/cats/derived/util/liftSome.scala b/core/src/main/scala-2/cats/derived/util/liftSome.scala index da63115a..35d59337 100644 --- a/core/src/main/scala-2/cats/derived/util/liftSome.scala +++ b/core/src/main/scala-2/cats/derived/util/liftSome.scala @@ -18,8 +18,8 @@ package cats.derived.util import shapeless._ -/** Summons all available instances of the typeclass `F` for members of the coproduct `C`. - * Unlike `LiftAll` members of the coproduct without an instance will be skipped in the result. +/** Summons all available instances of the typeclass `F` for members of the coproduct `C`. Unlike `LiftAll` members of + * the coproduct without an instance will be skipped in the result. */ sealed trait LiftSome[F[_], C <: Coproduct] extends Serializable { type Out <: HList diff --git a/core/src/main/scala-3/cats/derived/Derived.scala b/core/src/main/scala-3/cats/derived/Derived.scala index 6c6c0ddc..ccbd0683 100644 --- a/core/src/main/scala-3/cats/derived/Derived.scala +++ b/core/src/main/scala-3/cats/derived/Derived.scala @@ -19,15 +19,15 @@ object Derived: object Or extends OrInstances: def apply[A](instance: A): Or[A] = instance extension [A](or: Or[A]) def unify: A = or - extension [I[f[_], t] <: K0.Instances[f, t], F[_], T] - (inst: I[Or0[F], T]) @targetName("unifyK0") def unify: I[F, T] = inst - extension [I[f[_[_]], t[_]] <: K1.Instances[f, t], F[_[_]], T[_]] - (inst: I[Or1[F], T]) @targetName("unifyK1") def unify: I[F, T] = inst - extension [I[f[_[_[_]]], t[_[_]]] <: K11.Instances[f, t], F[_[_[_]]], T[_[_]]] - (inst: I[Or11[F], T]) @targetName("unifyK11") def unify: I[F, T] = inst - extension [I[f[_[_, _]], t[_, _]] <: K2.Instances[f, t], F[_[_, _]], T[_, _]] - (inst: I[Or2[F], T]) @targetName("unifyK2") def unify: I[F, T] = inst - + extension [I[f[_], t] <: K0.Instances[f, t], F[_], T](inst: I[Or0[F], T]) + @targetName("unifyK0") def unify: I[F, T] = inst + extension [I[f[_[_]], t[_]] <: K1.Instances[f, t], F[_[_]], T[_]](inst: I[Or1[F], T]) + @targetName("unifyK1") def unify: I[F, T] = inst + extension [I[f[_[_[_]]], t[_[_]]] <: K11.Instances[f, t], F[_[_[_]]], T[_[_]]](inst: I[Or11[F], T]) + @targetName("unifyK11") def unify: I[F, T] = inst + extension [I[f[_[_, _]], t[_, _]] <: K2.Instances[f, t], F[_[_, _]], T[_, _]](inst: I[Or2[F], T]) + @targetName("unifyK2") def unify: I[F, T] = inst + sealed abstract class OrInstances: inline given [A]: Derived.Or[A] = summonFrom { case instance: A => Derived.Or(instance) diff --git a/core/src/main/scala-3/cats/derived/DerivedShow.scala b/core/src/main/scala-3/cats/derived/DerivedShow.scala index fa5379d5..747acae3 100644 --- a/core/src/main/scala-3/cats/derived/DerivedShow.scala +++ b/core/src/main/scala-3/cats/derived/DerivedShow.scala @@ -21,13 +21,13 @@ object DerivedShow: given K0.CoproductInstances[Show, A] = inst.unify new Coproduct[Show, A] {} - trait Product[F[x] <: Show[x], A](using inst: K0.ProductInstances[F, A], labelling: Labelling[A]) - extends Show[A]: + trait Product[F[x] <: Show[x], A](using inst: K0.ProductInstances[F, A], labelling: Labelling[A]) extends Show[A]: def show(a: A): String = val prefix = labelling.label val labels = labelling.elemLabels val n = labels.size - if n <= 0 then prefix else + if n <= 0 then prefix + else val sb = new StringBuilder(prefix) sb.append('(') var i = 0 @@ -43,7 +43,6 @@ object DerivedShow: sb.append(')') sb.toString - trait Coproduct[F[x] <: Show[x], A](using inst: K0.CoproductInstances[F, A]) - extends Show[A]: + trait Coproduct[F[x] <: Show[x], A](using inst: K0.CoproductInstances[F, A]) extends Show[A]: def show(a: A): String = inst.fold(a)([t] => (st: F[t], t: t) => st.show(t)) diff --git a/core/src/main/scala-3/cats/derived/contravariant.scala b/core/src/main/scala-3/cats/derived/contravariant.scala index 82d42e75..e55af0c3 100644 --- a/core/src/main/scala-3/cats/derived/contravariant.scala +++ b/core/src/main/scala-3/cats/derived/contravariant.scala @@ -3,8 +3,7 @@ package cats.derived import cats.Contravariant import shapeless3.deriving.K1 -trait GenericContravariant[T[x[_]] <: Contravariant[x], F[_]](using inst: K1.Instances[T, F]) - extends Contravariant[F]: +trait GenericContravariant[T[x[_]] <: Contravariant[x], F[_]](using inst: K1.Instances[T, F]) extends Contravariant[F]: def contramap[A, B](fa: F[A])(f: B => A): F[B] = inst.map(fa)( [t[_]] => (contra: T[t], t0: t[A]) => contra.contramap(t0)(f) @@ -13,4 +12,4 @@ trait GenericContravariant[T[x[_]] <: Contravariant[x], F[_]](using inst: K1.Ins trait ContravariantDerivation: extension (F: Contravariant.type) inline def derived[F[_]](using gen: K1.Generic[F]): Contravariant[F] = - new GenericContravariant[Contravariant, F]{} + new GenericContravariant[Contravariant, F] {} diff --git a/core/src/main/scala-3/cats/derived/emptyk.scala b/core/src/main/scala-3/cats/derived/emptyk.scala index 39cac71b..f30221ba 100644 --- a/core/src/main/scala-3/cats/derived/emptyk.scala +++ b/core/src/main/scala-3/cats/derived/emptyk.scala @@ -3,12 +3,12 @@ package cats.derived import alleycats.{Empty, EmptyK} import shapeless3.deriving.{Const, K1} -trait ProductEmptyK[T[x[_]] <: EmptyK[x], F[_]]( - using inst: K1.ProductInstances[T, F] +trait ProductEmptyK[T[x[_]] <: EmptyK[x], F[_]](using + inst: K1.ProductInstances[T, F] ) extends EmptyK[F]: def empty[A]: F[A] = inst.construct([t[_]] => (emp: T[t]) => emp.empty[A]) trait EmptyKDerivation: extension (E: EmptyK.type) inline def derived[F[_]](using gen: K1.ProductGeneric[F]): EmptyK[F] = - new ProductEmptyK[EmptyK, F]{} + new ProductEmptyK[EmptyK, F] {} diff --git a/core/src/main/scala-3/cats/derived/invariant.scala b/core/src/main/scala-3/cats/derived/invariant.scala index 801b0dab..74d9dcc4 100644 --- a/core/src/main/scala-3/cats/derived/invariant.scala +++ b/core/src/main/scala-3/cats/derived/invariant.scala @@ -3,13 +3,12 @@ package cats.derived import cats.Invariant import shapeless3.deriving.K1 -trait GenericInvariant[T[x[_]] <: Invariant[x], F[_]](using inst: K1.Instances[T, F]) - extends Invariant[F]: - def imap[A, B](fa: F[A])(f: A => B)(g: B => A): F[B] = inst.map(fa)( - [t[_]] => (inv: T[t], t0: t[A]) => inv.imap(t0)(f)(g) - ) +trait GenericInvariant[T[x[_]] <: Invariant[x], F[_]](using inst: K1.Instances[T, F]) extends Invariant[F]: + def imap[A, B](fa: F[A])(f: A => B)(g: B => A): F[B] = inst.map(fa)( + [t[_]] => (inv: T[t], t0: t[A]) => inv.imap(t0)(f)(g) + ) trait InvariantDerivation: extension (F: Invariant.type) inline def derived[F[_]](using gen: K1.Generic[F]): Invariant[F] = - new GenericInvariant[Invariant, F]{} + new GenericInvariant[Invariant, F] {} diff --git a/core/src/main/scala-3/cats/derived/monoidk.scala b/core/src/main/scala-3/cats/derived/monoidk.scala index a8be9c91..cc5e878c 100644 --- a/core/src/main/scala-3/cats/derived/monoidk.scala +++ b/core/src/main/scala-3/cats/derived/monoidk.scala @@ -4,9 +4,9 @@ import cats.{Monoid, MonoidK} import shapeless3.deriving.{Const, K1} trait ProductMonoidK[T[x[_]] <: MonoidK[x], F[_]](using inst: K1.ProductInstances[T, F]) - extends ProductSemigroupK[T, F], MonoidK[F]: - def empty[A]: F[A] = inst.construct([t[_]] => (emp: T[t]) => emp.empty[A]) + extends ProductSemigroupK[T, F], + MonoidK[F]: + def empty[A]: F[A] = inst.construct([t[_]] => (emp: T[t]) => emp.empty[A]) trait MonoidKDerivation: - extension (F: MonoidK.type) - inline def derived[F[_]](using gen: K1.Generic[F]): MonoidK[F] = ??? + extension (F: MonoidK.type) inline def derived[F[_]](using gen: K1.Generic[F]): MonoidK[F] = ??? diff --git a/core/src/main/scala-3/cats/derived/partialOrder.scala b/core/src/main/scala-3/cats/derived/partialOrder.scala index 29cb75e9..aa82a43a 100644 --- a/core/src/main/scala-3/cats/derived/partialOrder.scala +++ b/core/src/main/scala-3/cats/derived/partialOrder.scala @@ -3,14 +3,14 @@ package cats.derived import cats.PartialOrder import shapeless3.deriving.{K0, Complete} -trait ProductPartialOrder[T[x] <: PartialOrder[x], A](using inst: K0.ProductInstances[T, A]) - extends PartialOrder[A]: +trait ProductPartialOrder[T[x] <: PartialOrder[x], A](using inst: K0.ProductInstances[T, A]) extends PartialOrder[A]: def partialCompare(x: A, y: A): Double = inst.foldLeft2(x, y)(0: Double)( - [t] => (acc: Double, ord: T[t], t0: t, t1: t) => { - val cmp = ord.partialCompare(t0, t1) - Complete(cmp != 0)(cmp)(acc) + [t] => + (acc: Double, ord: T[t], t0: t, t1: t) => { + val cmp = ord.partialCompare(t0, t1) + Complete(cmp != 0)(cmp)(acc) } ) @@ -18,7 +18,7 @@ trait CoproductPartialOrder[T[x] <: PartialOrder[x], A](using inst: K0.Coproduct extends PartialOrder[A]: def partialCompare(x: A, y: A): Double = - inst.fold2(x, y)(Double.NaN : Double)( + inst.fold2(x, y)(Double.NaN: Double)( [t] => (ord: T[t], t0: t, t1: t) => ord.partialCompare(t0, t1) ) @@ -28,7 +28,7 @@ trait PartialOrderDerivation: gen.derive(productPartialOrder, coproductPartialOrder) given productPartialOrder[A](using K0.ProductInstances[PartialOrder, A]): PartialOrder[A] = - new ProductPartialOrder[PartialOrder, A]{} + new ProductPartialOrder[PartialOrder, A] {} given coproductPartialOrder[A](using K0.CoproductInstances[PartialOrder, A]): PartialOrder[A] = - new CoproductPartialOrder[PartialOrder, A]{} + new CoproductPartialOrder[PartialOrder, A] {} diff --git a/core/src/main/scala-3/cats/derived/semigroupk.scala b/core/src/main/scala-3/cats/derived/semigroupk.scala index 22e8d1f1..c9b000f3 100644 --- a/core/src/main/scala-3/cats/derived/semigroupk.scala +++ b/core/src/main/scala-3/cats/derived/semigroupk.scala @@ -3,13 +3,12 @@ package cats.derived import cats.{Semigroup, SemigroupK} import shapeless3.deriving.{Const, K1} -trait ProductSemigroupK[T[x[_]] <: SemigroupK[x], F[_]](using inst: K1.ProductInstances[T, F]) - extends SemigroupK[F]: - def combineK[A](x: F[A], y: F[A]): F[A] = inst.map2[A, A, A](x,y)( - [t[_]] => (smgrpk: T[t], t0: t[A], t1: t[A]) => smgrpk.combineK(t0, t1) - ) +trait ProductSemigroupK[T[x[_]] <: SemigroupK[x], F[_]](using inst: K1.ProductInstances[T, F]) extends SemigroupK[F]: + def combineK[A](x: F[A], y: F[A]): F[A] = inst.map2[A, A, A](x, y)( + [t[_]] => (smgrpk: T[t], t0: t[A], t1: t[A]) => smgrpk.combineK(t0, t1) + ) trait SemigroupKDerivation: extension (F: SemigroupK.type) inline def derived[F[_]](using gen: K1.ProductGeneric[F]): SemigroupK[F] = - new ProductSemigroupK[SemigroupK, F]{} + new ProductSemigroupK[SemigroupK, F] {} diff --git a/core/src/test/scala-2/cats/derived/KittensSuite.scala b/core/src/test/scala-2/cats/derived/KittensSuite.scala index 924f256a..0f631bfd 100644 --- a/core/src/test/scala-2/cats/derived/KittensSuite.scala +++ b/core/src/test/scala-2/cats/derived/KittensSuite.scala @@ -21,10 +21,8 @@ import cats.syntax.AllSyntax import munit.DisciplineSuite import org.scalacheck.Test.Parameters -/** An opinionated stack of traits to improve consistency and reduce - * boilerplate in Kittens tests. Note that unlike the corresponding - * CatsSuite in the Cat project, this trait does not mix in any - * instances. +/** An opinionated stack of traits to improve consistency and reduce boilerplate in Kittens tests. Note that unlike the + * corresponding CatsSuite in the Cat project, this trait does not mix in any instances. */ abstract class KittensSuite extends DisciplineSuite with AllSyntax { override val scalaCheckTestParameters: Parameters = super.scalaCheckTestParameters diff --git a/core/src/test/scala-2/cats/derived/adtdefns.scala b/core/src/test/scala-2/cats/derived/adtdefns.scala index fa638819..9c678d9b 100644 --- a/core/src/test/scala-2/cats/derived/adtdefns.scala +++ b/core/src/test/scala-2/cats/derived/adtdefns.scala @@ -258,7 +258,7 @@ object TestDefns { Arbitrary(Arbitrary.arbitrary[Option[A]].map(GenericAdtCase.apply)) implicit def cogen[A: Cogen]: Cogen[GenericAdt[A]] = - Cogen[Option[A]].contramap({ case GenericAdtCase(value) => value }) + Cogen[Option[A]].contramap { case GenericAdtCase(value) => value } } final case class CaseClassWOption[A](value: Option[A]) diff --git a/core/src/test/scala-2/cats/derived/commutativeSemigroup.scala b/core/src/test/scala-2/cats/derived/commutativeSemigroup.scala index 3d03ac7a..d96945dd 100644 --- a/core/src/test/scala-2/cats/derived/commutativeSemigroup.scala +++ b/core/src/test/scala-2/cats/derived/commutativeSemigroup.scala @@ -66,23 +66,12 @@ class CommutativeSemigroupSuite extends KittensSuite { } object CommutativeSemigroupSuite { - - // can be removed once kittens depends on a version of cats that includes https://github.com/typelevel/cats/pull/2834 - implicit def commutativeSemigroupOption[A](implicit sa: CommutativeSemigroup[A]): CommutativeSemigroup[Option[A]] = - new CommutativeSemigroup[Option[A]] { - def combine(x: Option[A], y: Option[A]): Option[A] = - cats.instances.option.catsKernelStdMonoidForOption(sa).combine(x, y) - } - final case class Mul(value: Int) object Mul { - implicit val eqv: Eq[Mul] = Eq.fromUniversalEquals - implicit val arbitrary: Arbitrary[Mul] = Arbitrary(Arbitrary.arbitrary[Int].map(apply)) - implicit val commutativeSemigroup: CommutativeSemigroup[Mul] = CommutativeSemigroup.instance((x, y) => Mul(x.value * y.value)) } diff --git a/core/src/test/scala-3/cats/derived/CommutativeMonoidSuite.scala b/core/src/test/scala-3/cats/derived/CommutativeMonoidSuite.scala index 2f6d8002..b423ea0d 100644 --- a/core/src/test/scala-3/cats/derived/CommutativeMonoidSuite.scala +++ b/core/src/test/scala-3/cats/derived/CommutativeMonoidSuite.scala @@ -33,7 +33,7 @@ class CommutativeMonoidSuite extends KittensSuite: inline def testCommutativeMonoid(inline context: String): Unit = checkAll(s"$context.CommutativeMonoid[Foo]", commutativeMonoidTests[CommutativeFoo].commutativeMonoid) // FIXME: Doesn't work - //checkAll(s"$context.CommutativeMonoid[Recursive]", commutativeMonoidTests[Recursive].commutativeMonoid) + // checkAll(s"$context.CommutativeMonoid[Recursive]", commutativeMonoidTests[Recursive].commutativeMonoid) checkAll(s"$context.CommutativeMonoid[Box[Mul]]", commutativeMonoidTests[Box[Mul]].commutativeMonoid) checkAll( s"$context.CommutativeMonoid is Serializable", diff --git a/core/src/test/scala-3/cats/derived/CommutativeSemigroupSuite.scala b/core/src/test/scala-3/cats/derived/CommutativeSemigroupSuite.scala index f261f29c..2adaf003 100644 --- a/core/src/test/scala-3/cats/derived/CommutativeSemigroupSuite.scala +++ b/core/src/test/scala-3/cats/derived/CommutativeSemigroupSuite.scala @@ -36,7 +36,7 @@ class CommutativeSemigroupSuite extends KittensSuite: commutativeSemigroupTests[CommutativeFoo].commutativeSemigroup ) // FIXME: Doesn't work - //checkAll(s"$context.CommutativeSemigroup[Recursive]", commutativeSemigroupTests[Recursive].commutativeSemigroup) + // checkAll(s"$context.CommutativeSemigroup[Recursive]", commutativeSemigroupTests[Recursive].commutativeSemigroup) checkAll(s"$context.CommutativeSemigroup[Box[Mul]]", commutativeSemigroupTests[Box[Mul]].commutativeSemigroup) checkAll( s"$context.CommutativeSemigroup is Serializable", diff --git a/core/src/test/scala-3/cats/derived/MonoidSuite.scala b/core/src/test/scala-3/cats/derived/MonoidSuite.scala index bab92c9b..8822d8e2 100644 --- a/core/src/test/scala-3/cats/derived/MonoidSuite.scala +++ b/core/src/test/scala-3/cats/derived/MonoidSuite.scala @@ -34,7 +34,7 @@ class MonoidSuite extends KittensSuite: checkAll(s"$context.Monoid[Interleaved[Int]]", monoidTests[Interleaved[Int]].monoid) checkAll(s"$context.Monoid[Box[Mul]]", monoidTests[Box[Mul]].monoid) // FIXME: Doesn't work - //checkAll(s"$context.Monoid[Recursive]", monoidTests[Recursive].monoid) + // checkAll(s"$context.Monoid[Recursive]", monoidTests[Recursive].monoid) checkAll(s"$context.Monoid is Serializable", SerializableTests.serializable(summonInline[Monoid[Foo]])) test(s"$context.Monoid respects existing instances") { val box = summonInline[Monoid[Box[Mul]]] diff --git a/core/src/test/scala-3/cats/derived/ReducibleTests.scala b/core/src/test/scala-3/cats/derived/ReducibleTests.scala index 11055315..b0595b3e 100644 --- a/core/src/test/scala-3/cats/derived/ReducibleTests.scala +++ b/core/src/test/scala-3/cats/derived/ReducibleTests.scala @@ -33,4 +33,6 @@ object ReducibleTests: DerivedReducible[NonEmptyTree] @main def run() = - println(DerivedFunctor[ReducibleTests.MyList].map(ReducibleTests.MyList.Con(42, ReducibleTests.MyList.Non))(_.toString)) + println( + DerivedFunctor[ReducibleTests.MyList].map(ReducibleTests.MyList.Con(42, ReducibleTests.MyList.Non))(_.toString) + ) diff --git a/core/src/test/scala-3/cats/derived/SemigroupSuite.scala b/core/src/test/scala-3/cats/derived/SemigroupSuite.scala index 0e2a764c..571685b5 100644 --- a/core/src/test/scala-3/cats/derived/SemigroupSuite.scala +++ b/core/src/test/scala-3/cats/derived/SemigroupSuite.scala @@ -34,7 +34,7 @@ class SemigroupSuite extends KittensSuite: checkAll(s"$context.Semigroup[Interleaved[Int]]", semigroupTests[Interleaved[Int]].semigroup) checkAll(s"$context.Semigroup[Box[Mul]]", semigroupTests[Box[Mul]].semigroup) // FIXME: Doesn't work - //checkAll(s"$context.Semigroup[Recursive]", semigroupTests[Recursive].semigroup) + // checkAll(s"$context.Semigroup[Recursive]", semigroupTests[Recursive].semigroup) checkAll(s"$context.Semigroup is Serializable", SerializableTests.serializable(summonInline[Semigroup[Foo]])) test(s"$context.Semigroup respects existing instances") { val box = summonInline[Semigroup[Box[Mul]]] diff --git a/core/src/test/scala-3/cats/derived/adtdefns.scala b/core/src/test/scala-3/cats/derived/adtdefns.scala index 43ded5b5..86e67b30 100644 --- a/core/src/test/scala-3/cats/derived/adtdefns.scala +++ b/core/src/test/scala-3/cats/derived/adtdefns.scala @@ -261,7 +261,7 @@ object TestDefns { Arbitrary(Arbitrary.arbitrary[Option[A]].map(GenericAdtCase.apply)) implicit def cogen[A: Cogen]: Cogen[GenericAdt[A]] = - Cogen[Option[A]].contramap({ case GenericAdtCase(value) => value }) + Cogen[Option[A]].contramap { case GenericAdtCase(value) => value } } final case class CaseClassWOption[A](value: Option[A]) diff --git a/project/build.properties b/project/build.properties index 67d27a1d..c8fcab54 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.5.3 +sbt.version=1.6.2 diff --git a/project/plugins.sbt b/project/plugins.sbt index 0c193570..07a17558 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,9 +1,7 @@ -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.5.1") -addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.0") -addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.0.0") -addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.0.0") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.9.0") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.3") +addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.1.0") +addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.1.0") addSbtPlugin("com.thoughtworks.sbt-api-mappings" % "sbt-api-mappings" % "3.0.0") -addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.10.1") -addSbtPlugin("com.geirsson" % "sbt-ci-release" % "1.5.7") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.9.0") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2") +addSbtPlugin("org.typelevel" % "sbt-typelevel-ci-release" % "0.4.5") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6")