From 7c3d6517a62f3d062452b3664da59d4a0af9b058 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Fri, 1 Jul 2022 20:58:57 +0200 Subject: [PATCH 1/8] Scala Native: compile and package as JS and JVM (#7027) * Scala Native: compile and package as JS and JVM * -Xmx5G * -Xmx6G * -Xss8M * -Xmx8G * -Xmx5G * revert --- project/BuildHelper.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/project/BuildHelper.scala b/project/BuildHelper.scala index 6485f47fc447..00b1ef08500f 100644 --- a/project/BuildHelper.scala +++ b/project/BuildHelper.scala @@ -258,9 +258,7 @@ object BuildHelper { ) def nativeSettings = Seq( - Test / test := (Test / compile).value, - doc / skip := true, - Compile / doc / sources := Seq.empty + Test / test := (Test / compile).value ) def welcomeMessage = onLoadMessage := { From 2633569be88d617dd97d655a72d659f1d5c1e548 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Fri, 1 Jul 2022 23:33:45 +0200 Subject: [PATCH 2/8] izumi-reflect 2.1.3 (series/1.x) (#7025) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 1b6c2948463b..12329dc7b431 100644 --- a/build.sbt +++ b/build.sbt @@ -139,7 +139,7 @@ lazy val core = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(stdSettings("zio")) .settings(crossProjectSettings) .settings(buildInfoSettings("zio")) - .settings(libraryDependencies += "dev.zio" %%% "izumi-reflect" % "2.1.1") + .settings(libraryDependencies += "dev.zio" %%% "izumi-reflect" % "2.1.3") .enablePlugins(BuildInfoPlugin) lazy val coreJVM = core.jvm From a120ede091732864ecb23589bdb3b6100f9c4924 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Thu, 7 Jul 2022 16:37:33 +0200 Subject: [PATCH 3/8] Build all projects for Scala Native (#7048) * Build all projects for Scala Native * fix * Magnolia isn't for Scala Native * fix * No Native Refined because depends on Magnolia * refined 0.9.27 --- .github/workflows/ci.yml | 8 ++++++-- build.sbt | 18 ++++++++++++++---- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9bf41a9ca0be..88772303018c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: compile: runs-on: ubuntu-20.04 - timeout-minutes: 60 + timeout-minutes: 120 steps: - name: Checkout current branch uses: actions/checkout@v3.0.2 @@ -48,8 +48,12 @@ jobs: uses: coursier/cache-action@v6 - name: Install libuv run: sudo apt-get update && sudo apt-get install -y libuv1-dev + - name: Set Swap Space + uses: pierotofy/set-swap-space@master + with: + swap-size-gb: 10 - name: Check generation of ScalaDoc - run: ./sbt +Test/compile + run: free -h -s 1 & ./sbt +Test/compile publishLocal: runs-on: ubuntu-20.04 diff --git a/build.sbt b/build.sbt index 12329dc7b431..e332db188460 100644 --- a/build.sbt +++ b/build.sbt @@ -36,7 +36,7 @@ addCommandAlias( ) addCommandAlias( "testNative", - ";coreTestsNative/test;stacktracerNative/test;streamsTestsNative/test;testTestsNative/test;concurrentNative/test" // `test` currently executes only compilation, see `nativeSettings` in `BuildHelper` + ";coreTestsNative/test;stacktracerNative/test;streamsTestsNative/test;testTestsNative/test;examplesNative/Test/compile;macrosTestsNative/test;concurrentNative/test" // `test` currently executes only compilation, see `nativeSettings` in `BuildHelper` ) addCommandAlias( "testJVM", @@ -97,10 +97,13 @@ lazy val root = project docs, examplesJS, examplesJVM, + examplesNative, macrosJS, macrosJVM, + macrosNative, macrosTestsJS, macrosTestsJVM, + macrosTestsNative, stacktracerJS, stacktracerJVM, stacktracerNative, @@ -200,7 +203,7 @@ lazy val coreTestsJS = coreTests.js lazy val coreTestsNative = coreTests.native .settings(nativeSettings) -lazy val macros = crossProject(JSPlatform, JVMPlatform) +lazy val macros = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("macros")) .dependsOn(core) .settings(stdSettings("zio-macros")) @@ -210,8 +213,10 @@ lazy val macros = crossProject(JSPlatform, JVMPlatform) lazy val macrosJVM = macros.jvm lazy val macrosJS = macros.js +lazy val macrosNative = macros.native + .settings(nativeSettings) -lazy val macrosTests = crossProject(JSPlatform, JVMPlatform) +lazy val macrosTests = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("macros-tests")) .dependsOn(macros) .settings(stdSettings("macros-tests")) @@ -226,6 +231,8 @@ lazy val macrosTests = crossProject(JSPlatform, JVMPlatform) lazy val macrosTestsJVM = macrosTests.jvm lazy val macrosTestsJS = macrosTests.js +lazy val macrosTestsNative = macrosTests.native + .settings(nativeSettings) lazy val streams = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("streams")) @@ -526,7 +533,7 @@ lazy val concurrentNative = concurrent.native * * To run tests: `sbt "examplesJVM/test"` */ -lazy val examples = crossProject(JVMPlatform, JSPlatform) +lazy val examples = crossProject(JVMPlatform, JSPlatform, NativePlatform) .in(file("examples")) .settings(stdSettings("examples")) .settings(crossProjectSettings) @@ -541,6 +548,9 @@ lazy val examplesJS = examples.js lazy val examplesJVM = examples.jvm .dependsOn(testJunitRunnerJVM) +lazy val examplesNative = examples.native + .settings(nativeSettings) + lazy val benchmarks = project.module .dependsOn(coreJVM, streamsJVM, testJVM) .enablePlugins(JmhPlugin) From b9bfff0f505c392df46b720489b25e550ce80bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Mon, 11 Jul 2022 16:12:40 +0200 Subject: [PATCH 4/8] Backport #6743 to 1.x (#6991) * Backport DeriveDiff fix from #6743 * Update test example to show diff in recursive structure * Fix compilation * empty commit Co-authored-by: Kit Langton --- .../zio/test/magnolia/DeriveDiffSpec.scala | 24 +++++++++++++++---- .../src/main/scala/zio/test/diff/Diff.scala | 3 ++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/test-magnolia-tests/shared/src/test/scala/zio/test/magnolia/DeriveDiffSpec.scala b/test-magnolia-tests/shared/src/test/scala/zio/test/magnolia/DeriveDiffSpec.scala index 7ca64bda0a81..7dc697eb03ee 100644 --- a/test-magnolia-tests/shared/src/test/scala/zio/test/magnolia/DeriveDiffSpec.scala +++ b/test-magnolia-tests/shared/src/test/scala/zio/test/magnolia/DeriveDiffSpec.scala @@ -1,13 +1,13 @@ package zio.test.magnolia import zio.test._ -import zio.test.magnolia.diff._ +import zio.test.magnolia.diff._ import java.time.Instant object DeriveDiffSpec extends DefaultRunnableSpec { final case class Pet(name: String, hasBone: Boolean, favoriteFoods: List[String], birthday: Instant) - final case class Person(name: String, nickname: Option[String], age: Int, pet: Pet) + final case class Person(name: String, nickname: Option[String], age: Int, pet: Pet, person: Option[Person] = None) sealed trait Color @@ -27,13 +27,29 @@ object DeriveDiffSpec extends DefaultRunnableSpec { "Boboo", Some("Babbo\nThe\nBibber"), 300, - Pet("The Beautiful Crumb", false, l1, Instant.MIN) + Pet("The Beautiful Crumb", false, l1, Instant.MIN), + Some( + Person( + "Boboo", + Some("Babbo\nThe\nBibber"), + 300, + Pet("The Beautiful Crumb", false, l1, Instant.MIN) + ) + ) ) val p2 = Person( "Bibi", Some("Bibbo\nThe\nBibber\nBobber"), 300, - Pet("The Beautiful Destroyer", false, l2, Instant.now) + Pet("The Beautiful Destroyer", false, l2, Instant.now), + Some( + Person( + "Bibi", + Some("Bibbo\nThe\nBibber\nBobber"), + 300, + Pet("The Beautiful Destroyer", false, l2, Instant.now) + ) + ) ) assertTrue(p1 == p2) } @@ TestAspect.failing, diff --git a/test/shared/src/main/scala/zio/test/diff/Diff.scala b/test/shared/src/main/scala/zio/test/diff/Diff.scala index 95d2a26d5042..ebf7c7021263 100644 --- a/test/shared/src/main/scala/zio/test/diff/Diff.scala +++ b/test/shared/src/main/scala/zio/test/diff/Diff.scala @@ -107,8 +107,9 @@ trait DiffInstances extends LowPriDiff { trait LowPriDiff { - implicit def anyDiff[A]: Diff[A] = new Diff[A] { + implicit def anyValDiff[A <: AnyVal]: Diff[A] = anyDiff[A] + def anyDiff[A]: Diff[A] = new Diff[A] { override def diff(x: A, y: A): DiffResult = if (x == y) DiffResult.Identical(x) else DiffResult.Different(x, y) From f6fbc6c1c343dd80a229c5742078ecbcb9e86228 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Wed, 13 Jul 2022 06:19:49 +0200 Subject: [PATCH 5/8] CI: split compile step by Scala version (#7049) * CI: split compile step by Scala version * CI: split compile step by Scala version * CI: split compile step by Scala version * CI: split compile step by Scala version * CI: split compile step by Scala version * Update ci.yml * CI: split compile step by Scala version * Use only binary versions for compile job * change the names to 2.11 (with the dot) * ci.yaml: manual selection of Scala version root project :( * fix * fix * fix * Run tests as rootJVM/test * Run tests as rootJVM/test * Run tests as rootJVM/test * Don't run testJunitRunnerTests test on Scala 3 * Split publishLocal * Split publishLocal * Split publishLocal * Split publishLocal * Split publishLocal * Split publishLocal * simplify roots * Update build.sbt * Update build.properties --- .github/workflows/ci.yml | 69 +++++-- build.sbt | 420 +++++++++++++++++++++------------------ project/build.properties | 2 +- 3 files changed, 278 insertions(+), 213 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 88772303018c..be87c083c73b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,8 +1,8 @@ name: CI env: - JDK_JAVA_OPTIONS: -XX:+PrintCommandLineFlags -Xmx4G # JDK_JAVA_OPTIONS is _the_ env. variable to use for modern Java - JVM_OPTS: -XX:+PrintCommandLineFlags -Xmx4G # for Java 8 only (sadly, it is not modern enough for JDK_JAVA_OPTIONS) + JDK_JAVA_OPTIONS: -XX:+PrintCommandLineFlags -Xmx4G -Xss4M # JDK_JAVA_OPTIONS is _the_ env. variable to use for modern Java + JVM_OPTS: -XX:+PrintCommandLineFlags -Xmx4G -Xss4M # for Java 8 only (sadly, it is not modern enough for JDK_JAVA_OPTIONS) on: pull_request: @@ -35,6 +35,10 @@ jobs: compile: runs-on: ubuntu-20.04 timeout-minutes: 120 + strategy: + fail-fast: false + matrix: + scala: ['2.11.*', '2.12.*', '2.13.*', '3.*'] steps: - name: Checkout current branch uses: actions/checkout@v3.0.2 @@ -51,13 +55,27 @@ jobs: - name: Set Swap Space uses: pierotofy/set-swap-space@master with: - swap-size-gb: 10 - - name: Check generation of ScalaDoc - run: free -h -s 1 & ./sbt +Test/compile + swap-size-gb: 7 + - name: Test/compile 2.11 + if: ${{ startsWith(matrix.scala, '2.11.') }} + run: free --si -tmws 10 & ./sbt ++${{ matrix.scala }} root211/Test/compile + - name: Test/compile 2.12 + if: ${{ startsWith(matrix.scala, '2.12.') }} + run: free --si -tmws 10 & ./sbt ++${{ matrix.scala }} root212/Test/compile + - name: Test/compile 2.13 + if: ${{ startsWith(matrix.scala, '2.13.') }} + run: free --si -tmws 10 & ./sbt ++${{ matrix.scala }} root213/Test/compile + - name: Test/compile 3 + if: ${{ startsWith(matrix.scala, '3.') }} + run: free --si -tmws 10 & ./sbt ++${{ matrix.scala }} root3/Test/compile publishLocal: runs-on: ubuntu-20.04 timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + scala: ['2.11.*', '2.12.*', '2.13.*', '3.*'] steps: - name: Checkout current branch uses: actions/checkout@v3.0.2 @@ -71,8 +89,18 @@ jobs: uses: coursier/cache-action@v6 - name: Install libuv run: sudo apt-get update && sudo apt-get install -y libuv1-dev - - name: Check that building packages works - run: ./sbt +publishLocal + - name: publishLocal 2.11 + if: ${{ startsWith(matrix.scala, '2.11.') }} + run: ./sbt ++${{ matrix.scala }} root211/publishLocal + - name: publishLocal 2.12 + if: ${{ startsWith(matrix.scala, '2.12.') }} + run: ./sbt ++${{ matrix.scala }} root212/publishLocal + - name: publishLocal 2.13 + if: ${{ startsWith(matrix.scala, '2.13.') }} + run: ./sbt ++${{ matrix.scala }} root213/publishLocal + - name: publishLocal 3 + if: ${{ startsWith(matrix.scala, '3.') }} + run: ./sbt ++${{ matrix.scala }} root3/publishLocal website: runs-on: ubuntu-20.04 @@ -100,6 +128,7 @@ jobs: fail-fast: false matrix: scala: ['2.11.12', '2.12.15', '2.13.8', '3.1.2'] + java: ['17'] platform: ['JVM'] steps: - name: Checkout current branch @@ -108,22 +137,25 @@ jobs: uses: actions/setup-java@v2.5.0 with: distribution: temurin - java-version: 17 + java-version: ${{ matrix.java }} check-latest: true - name: Cache scala dependencies uses: coursier/cache-action@v6 - name: Mima Checks if: ${{ !startsWith(matrix.scala, '3.') }} run: ./sbt ++${{ matrix.scala }}! mimaChecks - - name: Test 2.11.x + - name: Test 2.11 if: ${{ startsWith(matrix.scala, '2.11.') }} - run: ./sbt ++${{ matrix.scala }}! test${{ matrix.platform }}211 - - name: Test 2.12.x and 2.13.x - if: ${{ !startsWith(matrix.scala, '2.11.') && !startsWith(matrix.scala, '3.') }} - run: ./sbt ++${{ matrix.scala }}! test${{ matrix.platform }} - - name: Test 3.x + run: ./sbt ++${{ matrix.scala }}! root${{ matrix.platform }}211/test + - name: Test 2.12 + if: ${{ startsWith(matrix.scala, '2.12.') }} + run: ./sbt ++${{ matrix.scala }}! root${{ matrix.platform }}212/test + - name: Test 2.13 + if: ${{ startsWith(matrix.scala, '2.13.') }} + run: ./sbt ++${{ matrix.scala }}! root${{ matrix.platform }}213/test + - name: Test 3 if: ${{ startsWith(matrix.scala, '3.') }} - run: ./sbt ++${{ matrix.scala }}! test${{ matrix.platform }}Dotty + run: ./sbt ++${{ matrix.scala }}! root${{ matrix.platform }}3/test testJvms: runs-on: ubuntu-20.04 @@ -145,7 +177,7 @@ jobs: - name: Cache scala dependencies uses: coursier/cache-action@v6 - name: Test on different JVM versions - run: ./sbt test${{ matrix.platform }} + run: ./sbt root${{ matrix.platform }}/test testPlatforms: runs-on: ubuntu-20.04 @@ -153,6 +185,7 @@ jobs: strategy: fail-fast: false matrix: + java: ['17'] platform: ['JS', 'Native'] steps: - name: Checkout current branch @@ -161,14 +194,14 @@ jobs: uses: actions/setup-java@v2.5.0 with: distribution: temurin - java-version: 17 + java-version: ${{ matrix.java }} check-latest: true - name: Cache scala dependencies uses: coursier/cache-action@v6 - name: Install libuv run: sudo apt-get update && sudo apt-get install -y libuv1-dev - name: Test on different Scala target platforms - run: ./sbt test${{ matrix.platform }} + run: ./sbt root${{ matrix.platform }}/test ci: runs-on: ubuntu-20.04 diff --git a/build.sbt b/build.sbt index e332db188460..31257b0044c9 100644 --- a/build.sbt +++ b/build.sbt @@ -23,13 +23,14 @@ inThisBuild( ) ) -addCommandAlias("build", "; fmt; testJVM") +addCommandAlias("build", "; fmt; rootJVM/test") addCommandAlias("fmt", "all root/scalafmtSbt root/scalafmtAll") addCommandAlias("fmtCheck", "all root/scalafmtSbtCheck root/scalafmtCheckAll") addCommandAlias( "check", - "; scalafmtSbtCheck; scalafmtCheckAll; Test/compile" + "; scalafmtSbtCheck; scalafmtCheckAll" ) +// Legacy command aliases ahead, may be removed in future. Consider using the one of the `root*` projects, like `rootJVM/test` instead of `testJVM` addCommandAlias( "compileJVM", ";coreTestsJVM/test:compile;stacktracerJVM/test:compile;streamsTestsJVM/test:compile;testTestsJVM/test:compile;testMagnoliaTestsJVM/test:compile;testRefinedJVM/test:compile;testRunnerJVM/test:compile;examplesJVM/test:compile;macrosTestsJVM/test:compile;concurrentJVM/test:compile" @@ -68,72 +69,158 @@ addCommandAlias( ) addCommandAlias( "mimaChecks", - "all coreJVM/mimaReportBinaryIssues streamsJVM/mimaReportBinaryIssues testJVM/mimaReportBinaryIssues" + "all coreJVM/mimaReportBinaryIssues streamsJVM/mimaReportBinaryIssues testsJVM/mimaReportBinaryIssues" ) +lazy val projectsCommon = List( + concurrent, + core, + coreTests, + examples, + macros, + macrosTests, + stacktracer, + streams, + streamsTests, + tests, + testRunner, + testTests +) + +lazy val rootJVM = project.in(file("target/rootJVM")).settings(publish / skip := true).aggregate(rootJVM213) + +lazy val rootJVM211 = project + .in(file("target/rootJVM211")) + .settings(publish / skip := true) + .aggregate(projectsCommon.map(p => p.jvm: ProjectReference): _*) + .aggregate( + List[ProjectReference]( + testJunitRunner + ): _* + ) + +lazy val rootJVM212 = project.in(file("target/rootJVM212")).settings(publish / skip := true).aggregate(rootJVM213) + +lazy val rootJVM213 = project + .in(file("target/rootJVM213")) + .settings(publish / skip := true) + .aggregate(projectsCommon.map(p => p.jvm: ProjectReference): _*) + .aggregate( + List[ProjectReference]( + benchmarks, + docs, + testJunitRunner, + testJunitRunnerTests, + testMagnolia.jvm, + testMagnoliaTests.jvm, + testRefined.jvm, + testScalaCheck.jvm + ): _* + ) + +lazy val rootJVM3 = project + .in(file("target/rootJVM3")) + .settings(publish / skip := true) + .aggregate(projectsCommon.map(p => p.jvm: ProjectReference): _*) + .aggregate( + List[ProjectReference]( + testJunitRunner, +// testJunitRunnerTests, TODO: fix test + testMagnolia.jvm, + testMagnoliaTests.jvm, + testRefined.jvm, + testScalaCheck.jvm + ): _* + ) + +lazy val rootJS = project + .in(file("target/rootJS")) + .settings(publish / skip := true) + .aggregate(projectsCommon.map(p => p.js: ProjectReference): _*) + .aggregate( + List[ProjectReference]( + testMagnolia.js, + testMagnoliaTests.js, + testRefined.js, + testScalaCheck.js + ): _* + ) + +lazy val rootNative = project + .in(file("target/rootNative")) + .settings(publish / skip := true) + .aggregate(projectsCommon.map(_.native: ProjectReference): _*) + .aggregate( + List[ProjectReference]( + testScalaCheck.native + ): _* + ) + +lazy val root211 = project + .in(file("target/root211")) + .settings(publish / skip := true) + .aggregate( + (projectsCommon.flatMap(p => List[ProjectReference](p.jvm, p.js, p.native)) ++ + List[ProjectReference]( + testJunitRunner + )): _* + ) + +lazy val root212 = project.in(file("target/root212")).settings(publish / skip := true).aggregate(root213) + +lazy val root213 = project + .in(file("target/root213")) + .settings(publish / skip := true) + .aggregate( + (projectsCommon.flatMap(p => List[ProjectReference](p.jvm, p.js, p.native)) ++ + List( + testScalaCheck + ).flatMap(p => List[ProjectReference](p.jvm, p.js, p.native)) ++ + List( + testMagnolia, + testMagnoliaTests, + testRefined + ).flatMap(p => List[ProjectReference](p.jvm, p.js)) ++ + List[ProjectReference]( + benchmarks, + docs, + testJunitRunner, + testJunitRunnerTests + )): _* + ) + +lazy val root3 = project + .in(file("target/root3")) + .settings(publish / skip := true) + .aggregate( + (projectsCommon.flatMap(p => List[ProjectReference](p.jvm, p.js, p.native)) ++ + List( + testScalaCheck + ).flatMap(p => List[ProjectReference](p.jvm, p.js, p.native)) ++ + List( + testMagnolia, + testMagnoliaTests, + testRefined + ).flatMap(p => List[ProjectReference](p.jvm, p.js)) ++ + List[ProjectReference]( + testJunitRunner, + testJunitRunnerTests + )): _* + ) + lazy val root = project .in(file(".")) .settings( name := "zio", publish / skip := true, - console := (coreJVM / Compile / console).value, + console := (core.jvm / Compile / console).value, unusedCompileDependenciesFilter -= moduleFilter( "org.scala-js", "scalajs-library" ), welcomeMessage ) - .aggregate( - benchmarks, - concurrentJS, - concurrentJVM, - concurrentNative, - coreJS, - coreJVM, - coreNative, - coreTestsJS, - coreTestsJVM, - coreTestsNative, - docs, - examplesJS, - examplesJVM, - examplesNative, - macrosJS, - macrosJVM, - macrosNative, - macrosTestsJS, - macrosTestsJVM, - macrosTestsNative, - stacktracerJS, - stacktracerJVM, - stacktracerNative, - streamsJS, - streamsJVM, - streamsNative, - streamsTestsJS, - streamsTestsJVM, - streamsTestsNative, - testJS, - testJVM, - testNative, - testJunitRunnerJVM, - testJunitRunnerTestsJVM, - testMagnoliaJS, - testMagnoliaJVM, - testMagnoliaTestsJS, - testMagnoliaTestsJVM, - testRefinedJS, - testRefinedJVM, - testRunnerJS, - testRunnerJVM, - testRunnerNative, - testScalaCheckJS, - testScalaCheckJVM, - testScalaCheckNative, - testTestsJS, - testTestsJVM, - testTestsNative - ) + .aggregate(root213) .enablePlugins(ScalaJSPlugin) lazy val core = crossProject(JSPlatform, JVMPlatform, NativePlatform) @@ -144,14 +231,12 @@ lazy val core = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(buildInfoSettings("zio")) .settings(libraryDependencies += "dev.zio" %%% "izumi-reflect" % "2.1.3") .enablePlugins(BuildInfoPlugin) - -lazy val coreJVM = core.jvm - .settings(replSettings) - .settings(mimaSettings(failOnProblem = true)) - -lazy val coreJS = core.js - .settings(libraryDependencies += "org.scala-js" %%% "scala-js-macrotask-executor" % "1.0.0") - .settings( + .jvmSettings( + replSettings, + mimaSettings(failOnProblem = true) + ) + .jsSettings( + libraryDependencies += "org.scala-js" %%% "scala-js-macrotask-executor" % "1.0.0", scalacOptions ++= { if (scalaVersion.value == Scala3) { List() @@ -161,10 +246,8 @@ lazy val coreJS = core.js } } ) - -lazy val coreNative = core.native - .settings(nativeSettings) - .settings( + .nativeSettings( + nativeSettings, libraryDependencies ++= Seq( "com.github.lolgab" %%% "native-loop-core" % "0.2.1" ) @@ -173,7 +256,7 @@ lazy val coreNative = core.native lazy val coreTests = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("core-tests")) .dependsOn(core) - .dependsOn(test) + .dependsOn(tests) .settings(stdSettings("core-tests")) .settings(crossProjectSettings) .settings(testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")) @@ -184,13 +267,9 @@ lazy val coreTests = crossProject(JSPlatform, JVMPlatform, NativePlatform) Compile / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat ) .enablePlugins(BuildInfoPlugin) - -lazy val coreTestsJVM = coreTests.jvm - .configure(_.enablePlugins(JCStressPlugin)) - .settings(replSettings) - -lazy val coreTestsJS = coreTests.js - .settings( + .jvmConfigure(_.enablePlugins(JCStressPlugin)) + .jvmSettings(replSettings) + .jsSettings( scalacOptions ++= { if (scalaVersion.value == Scala3) { List() @@ -199,9 +278,7 @@ lazy val coreTestsJS = coreTests.js } } ) - -lazy val coreTestsNative = coreTests.native - .settings(nativeSettings) + .nativeSettings(nativeSettings) lazy val macros = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("macros")) @@ -210,11 +287,7 @@ lazy val macros = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(crossProjectSettings) .settings(macroDefinitionSettings) .settings(macroExpansionSettings) - -lazy val macrosJVM = macros.jvm -lazy val macrosJS = macros.js -lazy val macrosNative = macros.native - .settings(nativeSettings) + .nativeSettings(nativeSettings) lazy val macrosTests = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("macros-tests")) @@ -228,11 +301,7 @@ lazy val macrosTests = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(buildInfoSettings("zio")) .settings(publish / skip := true) .enablePlugins(BuildInfoPlugin) - -lazy val macrosTestsJVM = macrosTests.jvm -lazy val macrosTestsJS = macrosTests.js -lazy val macrosTestsNative = macrosTests.native - .settings(nativeSettings) + .nativeSettings(nativeSettings) lazy val streams = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("streams")) @@ -242,15 +311,8 @@ lazy val streams = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(buildInfoSettings("zio.stream")) .settings(streamReplSettings) .enablePlugins(BuildInfoPlugin) - -lazy val streamsJVM = streams.jvm - // No bincompat on streams yet - .settings(mimaSettings(failOnProblem = false)) - -lazy val streamsJS = streams.js - -lazy val streamsNative = streams.native - .settings(nativeSettings) + .jvmSettings(mimaSettings(failOnProblem = false)) + .nativeSettings(nativeSettings) lazy val streamsTests = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("streams-tests")) @@ -266,12 +328,8 @@ lazy val streamsTests = crossProject(JSPlatform, JVMPlatform, NativePlatform) Compile / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.AllLibraryJars ) .enablePlugins(BuildInfoPlugin) - -lazy val streamsTestsJVM = streamsTests.jvm - .dependsOn(coreTestsJVM % "test->compile") - -lazy val streamsTestsJS = streamsTests.js - .settings( + .jvmConfigure(_.dependsOn(coreTests.jvm % "test->compile")) + .jsSettings( scalacOptions ++= { if (scalaVersion.value == Scala3) { List() @@ -280,11 +338,9 @@ lazy val streamsTestsJS = streamsTests.js } } ) + .nativeSettings(nativeSettings) -lazy val streamsTestsNative = streamsTests.native - .settings(nativeSettings) - -lazy val test = crossProject(JSPlatform, JVMPlatform, NativePlatform) +lazy val tests = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("test")) .dependsOn(core, streams) .settings(stdSettings("zio-test")) @@ -297,20 +353,15 @@ lazy val test = crossProject(JSPlatform, JVMPlatform, NativePlatform) .cross(CrossVersion.for3Use2_13) ) ) - -lazy val testJVM = test.jvm - // No bincompat on zio-test yet - .settings(mimaSettings(failOnProblem = false)) -lazy val testJS = test.js - .settings( + .jvmSettings(mimaSettings(failOnProblem = false)) + .jsSettings( libraryDependencies ++= List( "io.github.cquiroz" %%% "scala-java-time" % "2.4.0-M3", "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.4.0-M3" ) ) -lazy val testNative = test.native - .settings(nativeSettings) - .settings( + .nativeSettings( + nativeSettings, libraryDependencies ++= List( "io.github.cquiroz" %%% "scala-java-time" % "2.4.0-M3", "io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.4.0-M3" @@ -319,7 +370,7 @@ lazy val testNative = test.native lazy val testTests = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("test-tests")) - .dependsOn(test) + .dependsOn(tests) .settings(stdSettings("test-tests")) .settings(crossProjectSettings) .settings(testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")) @@ -328,20 +379,16 @@ lazy val testTests = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(publish / skip := true) .settings(macroExpansionSettings) .enablePlugins(BuildInfoPlugin) - -lazy val testTestsJVM = testTests.jvm -lazy val testTestsJS = testTests.js - .settings( + .jsSettings( libraryDependencies ++= List( ("org.scala-js" %%% "scalajs-java-securerandom" % "1.0.0").cross(CrossVersion.for3Use2_13) ) ) -lazy val testTestsNative = testTests.native - .settings(nativeSettings) + .nativeSettings(nativeSettings) lazy val testMagnolia = crossProject(JVMPlatform, JSPlatform) .in(file("test-magnolia")) - .dependsOn(test) + .dependsOn(tests) .settings(stdSettings("zio-test-magnolia")) .settings(crossProjectSettings) .settings(macroDefinitionSettings) @@ -366,9 +413,6 @@ lazy val testMagnolia = crossProject(JVMPlatform, JSPlatform) } ) -lazy val testMagnoliaJVM = testMagnolia.jvm -lazy val testMagnoliaJS = testMagnolia.js - lazy val testMagnoliaTests = crossProject(JVMPlatform, JSPlatform) .in(file("test-magnolia-tests")) .dependsOn(testMagnolia) @@ -384,9 +428,6 @@ lazy val testMagnoliaTests = crossProject(JVMPlatform, JSPlatform) ) .enablePlugins(BuildInfoPlugin) -lazy val testMagnoliaTestsJVM = testMagnoliaTests.jvm -lazy val testMagnoliaTestsJS = testMagnoliaTests.js - lazy val testRefined = crossProject(JVMPlatform, JSPlatform) .in(file("test-refined")) .dependsOn(testMagnolia) @@ -401,12 +442,9 @@ lazy val testRefined = crossProject(JVMPlatform, JSPlatform) ) ) -lazy val testRefinedJVM = testRefined.jvm -lazy val testRefinedJS = testRefined.js - lazy val testScalaCheck = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("test-scalacheck")) - .dependsOn(test) + .dependsOn(tests) .settings(stdSettings("zio-test-scalacheck")) .settings(crossProjectSettings) .settings( @@ -415,11 +453,7 @@ lazy val testScalaCheck = crossProject(JSPlatform, JVMPlatform, NativePlatform) ("org.scalacheck" %%% "scalacheck" % "1.16.0") ) ) - -lazy val testScalaCheckJVM = testScalaCheck.jvm -lazy val testScalaCheckJS = testScalaCheck.js -lazy val testScalaCheckNative = testScalaCheck.native - .settings(nativeSettings) + .nativeSettings(nativeSettings) lazy val stacktracer = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("stacktracer")) @@ -427,14 +461,11 @@ lazy val stacktracer = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(crossProjectSettings) .settings(buildInfoSettings("zio.internal.stacktracer")) .enablePlugins(BuildInfoPlugin) - -lazy val stacktracerJS = stacktracer.js -lazy val stacktracerJVM = stacktracer.jvm - .settings(replSettings) - -lazy val stacktracerNative = stacktracer.native - .settings(nativeSettings) - .settings(scalacOptions -= "-Xfatal-warnings") // Issue 3112 + .jvmSettings(replSettings) + .nativeSettings( + nativeSettings, + scalacOptions -= "-Xfatal-warnings" // Issue 3112 + ) lazy val testRunner = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("test-sbt")) @@ -442,30 +473,27 @@ lazy val testRunner = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(crossProjectSettings) .settings(Test / run / mainClass := Some("zio.test.sbt.TestMain")) .dependsOn(core) - .dependsOn(test) - -lazy val testRunnerJVM = testRunner.jvm - .settings(libraryDependencies ++= Seq("org.scala-sbt" % "test-interface" % "1.0")) -lazy val testRunnerJS = testRunner.js - .settings( + .dependsOn(tests) + .jvmSettings(libraryDependencies ++= Seq("org.scala-sbt" % "test-interface" % "1.0")) + .jsSettings( libraryDependencies ++= Seq( ("org.scala-js" %% "scalajs-test-interface" % scalaJSVersion).cross(CrossVersion.for3Use2_13) ) ) -lazy val testRunnerNative = testRunner.native - .settings(nativeSettings) - .settings(libraryDependencies ++= Seq("org.scala-native" %%% "test-interface" % nativeVersion)) + .nativeSettings( + nativeSettings, + libraryDependencies ++= Seq("org.scala-native" %%% "test-interface" % nativeVersion) + ) -lazy val testJunitRunner = crossProject(JVMPlatform) +lazy val testJunitRunner = crossProject(JVMPlatform) // TODO: make plain project, nothing cross about this .in(file("test-junit")) .settings(stdSettings("zio-test-junit")) .settings(crossProjectSettings) .settings(libraryDependencies ++= Seq("junit" % "junit" % "4.13.2")) - .dependsOn(test) - -lazy val testJunitRunnerJVM = testJunitRunner.jvm + .dependsOn(tests) + .jvm -lazy val testJunitRunnerTests = crossProject(JVMPlatform) +lazy val testJunitRunnerTests = crossProject(JVMPlatform) // TODO: make plain project, nothing cross about this .in(file("test-junit-tests")) .settings(stdSettings("test-junit-tests")) .settings(crossProjectSettings) @@ -494,21 +522,22 @@ lazy val testJunitRunnerTests = crossProject(JVMPlatform) "org.slf4j" % "slf4j-simple" % "1.7.36" % Test ) ) - .dependsOn(test) - .dependsOn(testRunner) - -lazy val testJunitRunnerTestsJVM = testJunitRunnerTests.jvm + .dependsOn( + tests, + testRunner + ) // publish locally so embedded maven runs against locally compiled zio .settings( Test / Keys.test := (Test / Keys.test) - .dependsOn(testJunitRunnerJVM / publishM2) - .dependsOn(testJVM / publishM2) - .dependsOn(coreJVM / publishM2) - .dependsOn(streamsJVM / publishM2) - .dependsOn(stacktracerJVM / publishM2) + .dependsOn(testJunitRunner / publishM2) + .dependsOn(tests.jvm / publishM2) + .dependsOn(core.jvm / publishM2) + .dependsOn(streams.jvm / publishM2) + .dependsOn(stacktracer.jvm / publishM2) .value ) + .jvm lazy val concurrent = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("concurrent")) @@ -519,14 +548,8 @@ lazy val concurrent = crossProject(JSPlatform, JVMPlatform, NativePlatform) .enablePlugins(BuildInfoPlugin) .dependsOn(testRunner % Test) .settings(testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")) - -lazy val concurrentJVM = concurrent.jvm - .settings(mimaSettings(failOnProblem = false)) - -lazy val concurrentJS = concurrent.js - -lazy val concurrentNative = concurrent.native - .settings(nativeSettings) + .jvmSettings(mimaSettings(failOnProblem = false)) + .nativeSettings(nativeSettings) /** * Examples sub-project that is not included in the root project. @@ -541,18 +564,18 @@ lazy val examples = crossProject(JVMPlatform, JSPlatform, NativePlatform) .settings(scalacOptions += "-Xfatal-warnings") .settings(testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")) .settings(publish / skip := true) + .settings(Test / test := (Test / compile).value) .dependsOn(macros, testRunner) - -lazy val examplesJS = examples.js - -lazy val examplesJVM = examples.jvm - .dependsOn(testJunitRunnerJVM) - -lazy val examplesNative = examples.native - .settings(nativeSettings) + .jvmConfigure(_.dependsOn(testJunitRunner)) + .jsSettings( + libraryDependencies ++= List( + ("org.scala-js" %%% "scalajs-java-securerandom" % "1.0.0").cross(CrossVersion.for3Use2_13) + ) + ) + .nativeSettings(nativeSettings) lazy val benchmarks = project.module - .dependsOn(coreJVM, streamsJVM, testJVM) + .dependsOn(core.jvm, streams.jvm, tests.jvm) .enablePlugins(JmhPlugin) .settings(replSettings) .settings( @@ -617,12 +640,12 @@ lazy val docs = project.module scalacOptions ~= { _ filterNot (_ startsWith "-Xlint") }, crossScalaVersions --= List(Scala211, Scala3), ScalaUnidoc / unidoc / unidocProjectFilter := inProjects( - coreJVM, - streamsJVM, - testJVM, - testMagnoliaJVM, - testRefinedJVM, - testScalaCheckJVM + core.jvm, + streams.jvm, + tests.jvm, + testMagnolia.jvm, + testRefined.jvm, + testScalaCheck.jvm ), ScalaUnidoc / unidoc / target := (LocalRootProject / baseDirectory).value / "website" / "static" / "api", cleanFiles += (ScalaUnidoc / unidoc / target).value, @@ -701,5 +724,14 @@ lazy val docs = project.module ) .settings(macroDefinitionSettings) .settings(mdocJS := Some(jsdocs)) - .dependsOn(coreJVM, streamsJVM, concurrentJVM, testJVM, testMagnoliaJVM, testRefinedJVM, testScalaCheckJVM, coreJS) + .dependsOn( + core.jvm, + streams.jvm, + concurrent.jvm, + tests.jvm, + testMagnolia.jvm, + testRefined.jvm, + testScalaCheck.jvm, + core.js + ) .enablePlugins(MdocPlugin, DocusaurusPlugin, ScalaUnidocPlugin) diff --git a/project/build.properties b/project/build.properties index c8fcab543a9c..22af2628c413 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.6.2 +sbt.version=1.7.1 From dd114ff4b9ab8c10d3e5bb6f9ce4d04e18754d8e Mon Sep 17 00:00:00 2001 From: Adam Fraser Date: Thu, 14 Jul 2022 01:01:42 -0700 Subject: [PATCH 6/8] start test clock warning when time is accessed (#7054) --- .../src/main/scala/zio/test/environment/package.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/shared/src/main/scala/zio/test/environment/package.scala b/test/shared/src/main/scala/zio/test/environment/package.scala index 18c5dc571558..814d99208cbb 100644 --- a/test/shared/src/main/scala/zio/test/environment/package.scala +++ b/test/shared/src/main/scala/zio/test/environment/package.scala @@ -268,19 +268,19 @@ package object environment extends PlatformSpecific { * Returns the current clock time as an `OffsetDateTime`. */ def currentDateTime: UIO[OffsetDateTime] = - clockState.get.map(data => toDateTime(data.duration, data.timeZone)) + warningStart *> clockState.get.map(data => toDateTime(data.duration, data.timeZone)) /** * Returns the current clock time in the specified time unit. */ def currentTime(unit: TimeUnit): UIO[Long] = - clockState.get.map(data => unit.convert(data.duration.toMillis, TimeUnit.MILLISECONDS)) + warningStart *> clockState.get.map(data => unit.convert(data.duration.toMillis, TimeUnit.MILLISECONDS)) /** * Returns the current clock time in nanoseconds. */ - val nanoTime: UIO[Long] = - clockState.get.map(_.duration.toNanos) + lazy val nanoTime: UIO[Long] = + warningStart *> clockState.get.map(_.duration.toNanos) /** * Saves the `TestClock`'s current state in an effect which, when run, From 182c9947219e2a5901a80712d6df4fc0854c6bab Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Wed, 20 Jul 2022 04:08:51 +0200 Subject: [PATCH 7/8] Merge 1.x to 2.x fix --- build.sbt | 38 +++++++++++++----------------------- project/plugins.sbt | 2 +- scalafix/project/plugins.sbt | 2 +- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/build.sbt b/build.sbt index f4825344a51a..62bdf9c6a179 100644 --- a/build.sbt +++ b/build.sbt @@ -318,19 +318,15 @@ lazy val managed = crossProject(JSPlatform, JVMPlatform, NativePlatform) Seq("-P:silencer:globalFilters=[zio.stacktracer.TracingImplicits.disableAutoTrace]") } ) + .jvmSettings( + mimaSettings(failOnProblem = false) + ) + .nativeSettings(nativeSettings) -lazy val managedJVM = managed.jvm - .settings(mimaSettings(failOnProblem = false)) - -lazy val managedJS = managed.js - -lazy val managedNative = managed.native - .settings(nativeSettings) - -lazy val managedTests = crossProject(JSPlatform, JVMPlatform) +lazy val managedTests = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("managed-tests")) .dependsOn(managed) - .dependsOn(test) + .dependsOn(tests) .settings(stdSettings("managed-tests")) .settings(crossProjectSettings) .settings(testFrameworks += new TestFramework("zio.test.sbt.ZTestFramework")) @@ -341,13 +337,9 @@ lazy val managedTests = crossProject(JSPlatform, JVMPlatform) Compile / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat ) .enablePlugins(BuildInfoPlugin) - -lazy val managedTestsJVM = managedTests.jvm - .configure(_.enablePlugins(JCStressPlugin)) - .settings(replSettings) - -lazy val managedTestsJS = managedTests.js - .settings( + .jvmConfigure(_.enablePlugins(JCStressPlugin)) + .jvmSettings(replSettings) + .jsSettings( scalacOptions ++= { if (scalaVersion.value == Scala3) { List() @@ -356,6 +348,7 @@ lazy val managedTestsJS = managedTests.js } } ) + .nativeSettings(nativeSettings) lazy val macros = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("macros")) @@ -386,10 +379,7 @@ lazy val internalMacros = crossProject(JSPlatform, JVMPlatform, NativePlatform) .settings(crossProjectSettings) .settings(macroDefinitionSettings) .settings(macroExpansionSettings) - -lazy val internalMacrosJVM = internalMacros.jvm -lazy val internalMacrosJS = internalMacros.js -lazy val internalMacrosNative = internalMacros.native.settings(nativeSettings) + .nativeSettings(nativeSettings) lazy val streams = crossProject(JSPlatform, JVMPlatform, NativePlatform) .in(file("streams")) @@ -757,7 +747,7 @@ lazy val scalafixRules = project.module .settings( scalafixSettings, semanticdbEnabled := true, // enable SemanticDB - libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % "0.9.34" + libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % "0.10.1" ) val zio1Version = "1.0.12" @@ -778,14 +768,14 @@ lazy val scalafixOutput = project scalafixSettings, publish / skip := true ) - .dependsOn(coreJVM, testJVM, streamsJVM, managedJVM) + .dependsOn(core.jvm, tests.jvm, streams.jvm, managed.jvm) lazy val scalafixTests = project .in(file("scalafix/tests")) .settings( scalafixSettings, publish / skip := true, - libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % "0.9.34" % Test cross CrossVersion.full, + libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % "0.10.1" % Test cross CrossVersion.full, Compile / compile := (Compile / compile).dependsOn(scalafixInput / Compile / compile).value, scalafixTestkitOutputSourceDirectories := diff --git a/project/plugins.sbt b/project/plugins.sbt index 20f0fd1605a2..162da1721417 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -15,6 +15,6 @@ addSbtPlugin("org.scalameta" % "sbt-mdoc" addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") addSbtPlugin("pl.project13.scala" % "sbt-jcstress" % "0.2.0") addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.3") -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.34") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.10.1") libraryDependencies += "org.snakeyaml" % "snakeyaml-engine" % "2.3" diff --git a/scalafix/project/plugins.sbt b/scalafix/project/plugins.sbt index cb13b3774461..9d1cd953eb5f 100644 --- a/scalafix/project/plugins.sbt +++ b/scalafix/project/plugins.sbt @@ -1 +1 @@ -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.34") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.10.1") From e5882c3d04e5b2f845ce11a56bc2bd98235f3ff4 Mon Sep 17 00:00:00 2001 From: Ondra Pelech Date: Wed, 20 Jul 2022 05:54:30 +0200 Subject: [PATCH 8/8] Bigger swap for testPlatforms --- .github/workflows/ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 156f00e9bfa0..a9f9d835aa01 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -203,8 +203,12 @@ jobs: uses: coursier/cache-action@v6 - name: Install libuv run: sudo apt-get update && sudo apt-get install -y libuv1-dev + - name: Set Swap Space + uses: pierotofy/set-swap-space@master + with: + swap-size-gb: 7 - name: Test on different Scala target platforms - run: ./sbt root${{ matrix.platform }}/test + run: free --si -tmws 10 & ./sbt root${{ matrix.platform }}/test ci: runs-on: ubuntu-20.04