From c6ec43d22011f0dcbb1736b63a835e1f21e92f81 Mon Sep 17 00:00:00 2001 From: Wojciech Mazur <wmazur@virtuslab.com> Date: Fri, 20 Dec 2024 01:07:54 +0100 Subject: [PATCH 1/4] Cross build with Scala Native --- build.sbt | 67 +++++++++++++++++++++++++++++++++++---------- project/plugins.sbt | 2 ++ 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/build.sbt b/build.sbt index 198c956..093fe4e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,8 @@ -ThisBuild / crossScalaVersions := Seq("2.13.15", "3.3.4") +val scalaVersions = Seq("2.13.15", "3.3.4") +ThisBuild / crossScalaVersions := scalaVersions ThisBuild / scalaVersion := (ThisBuild / crossScalaVersions).value.head +Global / concurrentRestrictions += Tags.limit(NativeTags.Link, 1) Global / cancelable := true publish / skip := true // in root @@ -18,43 +20,78 @@ lazy val commonSettings: Seq[Setting[_]] = }), ) -lazy val core = project.in(file("core")) +lazy val testNativeSettings: Seq[Setting[_]] = Seq( + // Required by Scala Native testing infrastructure + Test / fork := false, +) + +lazy val core = projectMatrix.in(file("core")) .settings(commonSettings) .settings( name := "scala-parallel-collections", Compile / doc / autoAPIMappings := true, ) + .jvmPlatform(scalaVersions) + .nativePlatform(scalaVersions, settings = testNativeSettings ++ Seq( + versionPolicyPreviousArtifacts := Nil, // TODO: not yet published , + mimaPreviousArtifacts := Set.empty + )) -lazy val junit = project.in(file("junit")) +lazy val junit = projectMatrix.in(file("junit")) .settings(commonSettings) .settings( - libraryDependencies += "com.github.sbt" % "junit-interface" % "0.13.3" % Test, - libraryDependencies += "junit" % "junit" % "4.13.2" % Test, - // for javax.xml.bind.DatatypeConverter, used in SerializationStabilityTest - libraryDependencies += "javax.xml.bind" % "jaxb-api" % "2.3.1" % Test, testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-v"), - Test / fork := true, publish / skip := true, ).dependsOn(testmacros, core) + .jvmPlatform(scalaVersions, + settings = Seq( + libraryDependencies += "com.github.sbt" % "junit-interface" % "0.13.3" % Test, + libraryDependencies += "junit" % "junit" % "4.13.2" % Test, + // for javax.xml.bind.DatatypeConverter, used in SerializationStabilityTest + libraryDependencies += "javax.xml.bind" % "jaxb-api" % "2.3.1" % Test, + Test / fork := true, + ) + ) + .nativePlatform(scalaVersions = scalaVersions, + axisValues = Nil, + configure = _ + .enablePlugins(ScalaNativeJUnitPlugin) + .settings( + Test/unmanagedSources/excludeFilter ~= { _ || + "SerializationTest.scala" || // requires ObjectOutputStream + "SerializationStability.scala" || // requires jaxb-api + "SerializationStabilityBase.scala" || + "SerializationStabilityTest.scala" + }, + Test / fork := false + ) + ) -lazy val scalacheck = project.in(file("scalacheck")) +lazy val scalacheck = projectMatrix.in(file("scalacheck")) .settings(commonSettings) .settings( - libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.18.1", - Test / fork := true, + libraryDependencies += "org.scalacheck" %%% "scalacheck" % "1.18.1", Test / testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-workers", "1", "-minSize", "0", "-maxSize", "4000", "-minSuccessfulTests", "5"), publish / skip := true ).dependsOn(core) + .jvmPlatform(scalaVersions, + settings = Seq( + Test / fork := true + ) + ) + .nativePlatform(scalaVersions, settings = testNativeSettings) -lazy val testmacros = project.in(file("testmacros")) +lazy val testmacros = projectMatrix.in(file("testmacros")) .settings(commonSettings) .settings( - libraryDependencies += (CrossVersion.partialVersion(scalaVersion.value) match { - case Some((3, _)) => scalaOrganization.value %% "scala3-compiler" % scalaVersion.value - case _ => scalaOrganization.value % "scala-compiler" % scalaVersion.value + libraryDependencies ++= (CrossVersion.partialVersion(scalaVersion.value) match { + case Some((3, _)) => Nil + case _ => List(scalaOrganization.value % "scala-compiler" % scalaVersion.value) }), publish / skip := true, ) + .jvmPlatform(scalaVersions) + .nativePlatform(scalaVersions, settings = testNativeSettings) commands += Command.single("setScalaVersion") { (state, arg) => val command = arg match { diff --git a/project/plugins.sbt b/project/plugins.sbt index a985cc4..9b6525c 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1 +1,3 @@ addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "3.2.0") +addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.10.1") +addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.6") From 350a2bed169f8be3698a5b03bb284e48782a2e57 Mon Sep 17 00:00:00 2001 From: Wojciech Mazur <wmazur@virtuslab.com> Date: Fri, 20 Dec 2024 12:38:07 +0100 Subject: [PATCH 2/4] Don't create Scala binary specific subprojects --- build.sbt | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/build.sbt b/build.sbt index 093fe4e..a96177b 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,11 @@ val scalaVersions = Seq("2.13.15", "3.3.4") +val defaultScalaVersion = scalaVersions.head + +// When defining JVM / Scala Native matrix we don't want duplicated projects for Scala 2/3 +val matrixScalaVersions = Seq(defaultScalaVersion) + ThisBuild / crossScalaVersions := scalaVersions -ThisBuild / scalaVersion := (ThisBuild / crossScalaVersions).value.head +ThisBuild / scalaVersion := defaultScalaVersion Global / concurrentRestrictions += Tags.limit(NativeTags.Link, 1) Global / cancelable := true @@ -10,6 +15,7 @@ lazy val commonSettings: Seq[Setting[_]] = Seq(scalaModuleAutomaticModuleName := Some("scala.collection.parallel")) ++ ScalaModulePlugin.scalaModuleSettings ++ Seq( versionPolicyIntention := Compatibility.BinaryAndSourceCompatible, + crossScalaVersions := scalaVersions, Compile / compile / scalacOptions --= (CrossVersion.partialVersion(scalaVersion.value) match { case Some((3, _)) => Seq("-Xlint") case _ => Seq() @@ -31,9 +37,9 @@ lazy val core = projectMatrix.in(file("core")) name := "scala-parallel-collections", Compile / doc / autoAPIMappings := true, ) - .jvmPlatform(scalaVersions) - .nativePlatform(scalaVersions, settings = testNativeSettings ++ Seq( - versionPolicyPreviousArtifacts := Nil, // TODO: not yet published , + .jvmPlatform(matrixScalaVersions) + .nativePlatform(matrixScalaVersions, settings = testNativeSettings ++ Seq( + versionPolicyPreviousArtifacts := Nil, // TODO: not yet published mimaPreviousArtifacts := Set.empty )) @@ -43,7 +49,7 @@ lazy val junit = projectMatrix.in(file("junit")) testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-v"), publish / skip := true, ).dependsOn(testmacros, core) - .jvmPlatform(scalaVersions, + .jvmPlatform(matrixScalaVersions, settings = Seq( libraryDependencies += "com.github.sbt" % "junit-interface" % "0.13.3" % Test, libraryDependencies += "junit" % "junit" % "4.13.2" % Test, @@ -52,18 +58,18 @@ lazy val junit = projectMatrix.in(file("junit")) Test / fork := true, ) ) - .nativePlatform(scalaVersions = scalaVersions, + .nativePlatform(matrixScalaVersions, axisValues = Nil, configure = _ .enablePlugins(ScalaNativeJUnitPlugin) .settings( - Test/unmanagedSources/excludeFilter ~= { _ || - "SerializationTest.scala" || // requires ObjectOutputStream - "SerializationStability.scala" || // requires jaxb-api - "SerializationStabilityBase.scala" || - "SerializationStabilityTest.scala" - }, - Test / fork := false + Test/unmanagedSources/excludeFilter ~= { _ || + "SerializationTest.scala" || // requires ObjectOutputStream + "SerializationStability.scala" || // requires jaxb-api + "SerializationStabilityBase.scala" || + "SerializationStabilityTest.scala" + }, + Test / fork := false ) ) @@ -73,13 +79,14 @@ lazy val scalacheck = projectMatrix.in(file("scalacheck")) libraryDependencies += "org.scalacheck" %%% "scalacheck" % "1.18.1", Test / testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-workers", "1", "-minSize", "0", "-maxSize", "4000", "-minSuccessfulTests", "5"), publish / skip := true - ).dependsOn(core) - .jvmPlatform(scalaVersions, - settings = Seq( - Test / fork := true - ) + ) + .dependsOn(core) + .jvmPlatform(matrixScalaVersions, + settings = Seq( + Test / fork := true ) - .nativePlatform(scalaVersions, settings = testNativeSettings) + ) + .nativePlatform(matrixScalaVersions, settings = testNativeSettings) lazy val testmacros = projectMatrix.in(file("testmacros")) .settings(commonSettings) @@ -90,8 +97,8 @@ lazy val testmacros = projectMatrix.in(file("testmacros")) }), publish / skip := true, ) - .jvmPlatform(scalaVersions) - .nativePlatform(scalaVersions, settings = testNativeSettings) + .jvmPlatform(matrixScalaVersions) + .nativePlatform(matrixScalaVersions, settings = testNativeSettings) commands += Command.single("setScalaVersion") { (state, arg) => val command = arg match { From 9e9b8c9298d1933b4ef646b3b983bbad7e122cf7 Mon Sep 17 00:00:00 2001 From: Wojciech Mazur <wmazur@virtuslab.com> Date: Fri, 20 Dec 2024 12:54:39 +0100 Subject: [PATCH 3/4] Add command for JVM/Native tests, use them in the CI --- .github/workflows/ci.yml | 8 +++++--- build.sbt | 11 +++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 47e6162..d9ad3c1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,8 +25,10 @@ jobs: distribution: temurin java-version: ${{matrix.java}} - uses: sbt/setup-sbt@v1 - - name: Test - run: sbt "setScalaVersion ${{matrix.scala}}" test core/headerCheck package + - name: Test JVM + run: sbt "setScalaVersion ${{matrix.scala}}" testJVM core/headerCheck package + - name: Test Native + run: sbt "setScalaVersion ${{matrix.scala}}" testNative test-rc: strategy: @@ -52,4 +54,4 @@ jobs: java-version: ${{matrix.java}} - uses: sbt/setup-sbt@v1 - name: Test - run: sbt "setScalaVersion ${{matrix.scala}}" test core/headerCheck package + run: sbt "setScalaVersion ${{matrix.scala}}" testJVM core/headerCheck package diff --git a/build.sbt b/build.sbt index a96177b..db274f0 100644 --- a/build.sbt +++ b/build.sbt @@ -107,3 +107,14 @@ commands += Command.single("setScalaVersion") { (state, arg) => } command :: state } + +def testPlatformCommand(name: String, selector: ProjectMatrix => sbt.internal.ProjectFinder): Command = + Command.command(name) { state => + List(junit, scalacheck, testmacros) + .flatMap(selector(_).get) + .map{ project => s"${project.id}/test"} + .toList ::: state + } + +commands += testPlatformCommand("testNative", _.native) +commands += testPlatformCommand("testJVM", _.jvm) From 8a0501e59873934d898cae628c7c17d6dc637d38 Mon Sep 17 00:00:00 2001 From: Wojciech Mazur <wmazur@virtuslab.com> Date: Fri, 20 Dec 2024 12:58:14 +0100 Subject: [PATCH 4/4] Fix compilation --- build.sbt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index db274f0..6e5ecae 100644 --- a/build.sbt +++ b/build.sbt @@ -108,7 +108,8 @@ commands += Command.single("setScalaVersion") { (state, arg) => command :: state } -def testPlatformCommand(name: String, selector: ProjectMatrix => sbt.internal.ProjectFinder): Command = +import sbt.internal.{ProjectMatrix, ProjectFinder} +def testPlatformCommand(name: String, selector: ProjectMatrix => ProjectFinder): Command = Command.command(name) { state => List(junit, scalacheck, testmacros) .flatMap(selector(_).get)