Skip to content

Commit d306fe8

Browse files
authored
Merge pull request #2975 from armanbilge/feature/native
Scala Native
2 parents 3a291db + 54782c9 commit d306fe8

File tree

70 files changed

+2123
-94
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+2123
-94
lines changed

.github/workflows/ci.yml

+41-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
os: [ubuntu-latest]
3131
scala: [3.1.3, 2.12.16, 2.13.8]
3232
java: [temurin@17]
33-
project: [rootJS, rootJVM]
33+
project: [rootJS, rootJVM, rootNative]
3434
runs-on: ${{ matrix.os }}
3535
steps:
3636
- name: Checkout current branch (full)
@@ -66,6 +66,10 @@ jobs:
6666
~/Library/Caches/Coursier/v1
6767
key: ${{ runner.os }}-sbt-cache-v2-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }}
6868

69+
- name: Install s2n
70+
if: startsWith(matrix.project, 'rootNative')
71+
run: brew install s2n
72+
6973
- name: Check that workflows are up to date
7074
run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' 'project /' githubWorkflowCheck
7175

@@ -77,6 +81,10 @@ jobs:
7781
if: matrix.project == 'rootJS'
7882
run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' Test/scalaJSLinkerResult
7983

84+
- name: nativeLink
85+
if: matrix.project == 'rootNative'
86+
run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' Test/nativeLink
87+
8088
- name: Test
8189
run: sbt 'project ${{ matrix.project }}' '++${{ matrix.scala }}' test
8290

@@ -96,11 +104,11 @@ jobs:
96104
97105
- name: Make target directories
98106
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/series/2.5.x')
99-
run: mkdir -p target protocols/js/target unidocs/target .js/target core/js/target mdoc/target core/jvm/target .jvm/target .native/target scodec/jvm/target scodec/js/target io/js/target reactive-streams/target io/jvm/target protocols/jvm/target benchmark/target project/target
107+
run: mkdir -p target protocols/js/target io/native/target unidocs/target .js/target core/native/target core/js/target protocols/native/target mdoc/target core/jvm/target .jvm/target .native/target scodec/jvm/target scodec/js/target io/js/target reactive-streams/target io/jvm/target protocols/jvm/target scodec/native/target benchmark/target project/target
100108

101109
- name: Compress target directories
102110
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/series/2.5.x')
103-
run: tar cf targets.tar target protocols/js/target unidocs/target .js/target core/js/target mdoc/target core/jvm/target .jvm/target .native/target scodec/jvm/target scodec/js/target io/js/target reactive-streams/target io/jvm/target protocols/jvm/target benchmark/target project/target
111+
run: tar cf targets.tar target protocols/js/target io/native/target unidocs/target .js/target core/native/target core/js/target protocols/native/target mdoc/target core/jvm/target .jvm/target .native/target scodec/jvm/target scodec/js/target io/js/target reactive-streams/target io/jvm/target protocols/jvm/target scodec/native/target benchmark/target project/target
104112

105113
- name: Upload target directories
106114
if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/series/2.5.x')
@@ -173,6 +181,16 @@ jobs:
173181
tar xf targets.tar
174182
rm targets.tar
175183
184+
- name: Download target directories (3.1.3, rootNative)
185+
uses: actions/download-artifact@v2
186+
with:
187+
name: target-${{ matrix.os }}-${{ matrix.java }}-3.1.3-rootNative
188+
189+
- name: Inflate target directories (3.1.3, rootNative)
190+
run: |
191+
tar xf targets.tar
192+
rm targets.tar
193+
176194
- name: Download target directories (2.12.16, rootJS)
177195
uses: actions/download-artifact@v2
178196
with:
@@ -193,6 +211,16 @@ jobs:
193211
tar xf targets.tar
194212
rm targets.tar
195213
214+
- name: Download target directories (2.12.16, rootNative)
215+
uses: actions/download-artifact@v2
216+
with:
217+
name: target-${{ matrix.os }}-${{ matrix.java }}-2.12.16-rootNative
218+
219+
- name: Inflate target directories (2.12.16, rootNative)
220+
run: |
221+
tar xf targets.tar
222+
rm targets.tar
223+
196224
- name: Download target directories (2.13.8, rootJS)
197225
uses: actions/download-artifact@v2
198226
with:
@@ -213,6 +241,16 @@ jobs:
213241
tar xf targets.tar
214242
rm targets.tar
215243
244+
- name: Download target directories (2.13.8, rootNative)
245+
uses: actions/download-artifact@v2
246+
with:
247+
name: target-${{ matrix.os }}-${{ matrix.java }}-2.13.8-rootNative
248+
249+
- name: Inflate target directories (2.13.8, rootNative)
250+
run: |
251+
tar xf targets.tar
252+
rm targets.tar
253+
216254
- name: Import signing key
217255
if: env.PGP_SECRET != '' && env.PGP_PASSPHRASE == ''
218256
run: echo $PGP_SECRET | base64 -di | gpg --import

build.sbt

+59-13
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import com.typesafe.tools.mima.core._
22

33
Global / onChangedBuildSource := ReloadOnSourceChanges
44

5-
ThisBuild / tlBaseVersion := "3.2"
5+
ThisBuild / tlBaseVersion := "3.3"
66

77
ThisBuild / organization := "co.fs2"
88
ThisBuild / organizationName := "Functional Streams for Scala"
@@ -14,6 +14,16 @@ ThisBuild / crossScalaVersions := Seq("3.1.3", "2.12.16", NewScala)
1414
ThisBuild / tlVersionIntroduced := Map("3" -> "3.0.3")
1515

1616
ThisBuild / githubWorkflowJavaVersions := Seq(JavaSpec.temurin("17"))
17+
ThisBuild / githubWorkflowBuildPreamble +=
18+
WorkflowStep.Run(
19+
List("brew install s2n"),
20+
name = Some("Install s2n"),
21+
cond = Some("startsWith(matrix.project, 'rootNative')")
22+
)
23+
val isLinux = {
24+
val osName = Option(System.getProperty("os.name"))
25+
osName.exists(_.toLowerCase().contains("linux"))
26+
}
1727

1828
ThisBuild / tlCiReleaseBranches := List("main", "series/2.5.x")
1929

@@ -160,7 +170,12 @@ ThisBuild / mimaBinaryIssueFilters ++= Seq(
160170
ProblemFilters.exclude[DirectMissingMethodProblem]("fs2.ChunkCompanionPlatform.makeArrayBuilder"),
161171
ProblemFilters.exclude[ReversedMissingMethodProblem]("fs2.concurrent.Channel.trySend"),
162172
ProblemFilters.exclude[ReversedMissingMethodProblem]("fs2.compression.Compression.gunzip"),
163-
ProblemFilters.exclude[ReversedMissingMethodProblem]("fs2.io.net.tls.TLSContext#Builder.insecure")
173+
ProblemFilters.exclude[ReversedMissingMethodProblem](
174+
"fs2.io.net.tls.TLSContext#Builder.systemResource"
175+
),
176+
ProblemFilters.exclude[ReversedMissingMethodProblem](
177+
"fs2.io.net.tls.TLSContext#Builder.insecureResource"
178+
)
164179
)
165180

166181
lazy val root = tlCrossRootProject
@@ -176,7 +191,11 @@ lazy val root = tlCrossRootProject
176191

177192
lazy val IntegrationTest = config("it").extend(Test)
178193

179-
lazy val core = crossProject(JVMPlatform, JSPlatform)
194+
lazy val commonNativeSettings = Seq(
195+
tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "3.2.15").toMap
196+
)
197+
198+
lazy val core = crossProject(JVMPlatform, JSPlatform, NativePlatform)
180199
.in(file("core"))
181200
.configs(IntegrationTest)
182201
.settings(Defaults.itSettings: _*)
@@ -194,9 +213,9 @@ lazy val core = crossProject(JVMPlatform, JSPlatform)
194213
"org.typelevel" %%% "cats-effect-laws" % "3.3.14" % Test,
195214
"org.typelevel" %%% "cats-effect-testkit" % "3.3.14" % Test,
196215
"org.scodec" %%% "scodec-bits" % "1.1.34",
197-
"org.typelevel" %%% "scalacheck-effect-munit" % "1.0.4" % Test,
198-
"org.typelevel" %%% "munit-cats-effect-3" % "1.0.7" % Test,
199-
"org.typelevel" %%% "discipline-munit" % "1.0.9" % Test
216+
"org.typelevel" %%% "scalacheck-effect-munit" % "2.0.0-M2" % Test,
217+
"org.typelevel" %%% "munit-cats-effect" % "2.0.0-M3" % Test,
218+
"org.typelevel" %%% "discipline-munit" % "2.0.0-M3" % Test
200219
),
201220
tlJdkRelease := Some(8),
202221
Compile / doc / scalacOptions ++= (if (scalaVersion.value.startsWith("2.")) Seq("-nowarn")
@@ -217,12 +236,16 @@ lazy val coreJS = core.js
217236
scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.CommonJSModule))
218237
)
219238

220-
lazy val io = crossProject(JVMPlatform, JSPlatform)
239+
lazy val coreNative = core.native
240+
.disablePlugins(DoctestPlugin)
241+
.settings(commonNativeSettings)
242+
243+
lazy val io = crossProject(JVMPlatform, JSPlatform, NativePlatform)
221244
.in(file("io"))
222245
.settings(
223246
name := "fs2-io",
224-
libraryDependencies += "com.comcast" %%% "ip4s-core" % "3.1.3",
225-
tlVersionIntroduced ~= { _.updated("3", "3.1.0") }
247+
tlVersionIntroduced ~= { _.updated("3", "3.1.0") },
248+
libraryDependencies += "com.comcast" %%% "ip4s-core" % "3.2.0"
226249
)
227250
.jvmSettings(
228251
Test / fork := true,
@@ -235,6 +258,24 @@ lazy val io = crossProject(JVMPlatform, JSPlatform)
235258
tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "3.1.0").toMap,
236259
scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.CommonJSModule))
237260
)
261+
.nativeSettings(commonNativeSettings)
262+
.nativeSettings(
263+
libraryDependencies ++= Seq(
264+
"com.armanbilge" %%% "epollcat" % "0.1.0" % Test
265+
),
266+
nativeConfig ~= { c =>
267+
if (isLinux) { // brew-installed s2n
268+
c.withLinkingOptions(c.linkingOptions :+ "-L/home/linuxbrew/.linuxbrew/lib")
269+
} else c
270+
},
271+
Test / envVars ++= {
272+
val ldLibPath =
273+
if (isLinux)
274+
Map("LD_LIBRARY_PATH" -> "/home/linuxbrew/.linuxbrew/lib")
275+
else Map.empty
276+
Map("S2N_DONT_MLOCK" -> "1") ++ ldLibPath
277+
}
278+
)
238279
.dependsOn(core % "compile->compile;test->test")
239280
.jsSettings(
240281
mimaBinaryIssueFilters ++= Seq(
@@ -283,25 +324,29 @@ lazy val io = crossProject(JVMPlatform, JSPlatform)
283324
ProblemFilters.exclude[DirectMissingMethodProblem]("fs2.io.net.tls.TLSSocket.forAsync")
284325
)
285326
)
327+
.nativeSettings(
328+
nativeConfig ~= { _.withEmbedResources(true) }
329+
)
286330

287-
lazy val scodec = crossProject(JVMPlatform, JSPlatform)
331+
lazy val scodec = crossProject(JVMPlatform, JSPlatform, NativePlatform)
288332
.in(file("scodec"))
289333
.settings(
290334
name := "fs2-scodec",
291335
libraryDependencies += "org.scodec" %%% "scodec-core" % (if (
292336
scalaVersion.value.startsWith("2.")
293337
)
294-
"1.11.9"
295-
else "2.1.0"),
338+
"1.11.10"
339+
else "2.2.0"),
296340
tlVersionIntroduced := List("2.12", "2.13", "3").map(_ -> "3.2.0").toMap,
297341
tlJdkRelease := Some(8)
298342
)
299343
.jsSettings(
300344
scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.CommonJSModule))
301345
)
346+
.nativeSettings(commonNativeSettings)
302347
.dependsOn(core % "compile->compile;test->test", io % "test")
303348

304-
lazy val protocols = crossProject(JVMPlatform, JSPlatform)
349+
lazy val protocols = crossProject(JVMPlatform, JSPlatform, NativePlatform)
305350
.in(file("protocols"))
306351
.settings(
307352
name := "fs2-protocols",
@@ -311,6 +356,7 @@ lazy val protocols = crossProject(JVMPlatform, JSPlatform)
311356
.jsSettings(
312357
scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.CommonJSModule))
313358
)
359+
.nativeSettings(commonNativeSettings)
314360
.dependsOn(core % "compile->compile;test->test", scodec, io)
315361

316362
lazy val reactiveStreams = project

core/js/src/test/scala/fs2/TestPlatform.scala

+1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ package fs2
2323

2424
trait TestPlatform {
2525
def isJVM: Boolean = false
26+
def isNative: Boolean = false
2627
}

core/jvm/src/test/scala/fs2/TestPlatform.scala

+1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ package fs2
2323

2424
trait TestPlatform {
2525
def isJVM: Boolean = true
26+
def isNative: Boolean = false
2627
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2013 Functional Streams for Scala
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
package fs2
23+
24+
private[fs2] trait ChunkRuntimePlatform[+O]
25+
26+
private[fs2] trait ChunkCompanionRuntimePlatform
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2013 Functional Streams for Scala
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
package fs2
23+
24+
trait TestPlatform {
25+
def isJVM: Boolean = false
26+
def isNative: Boolean = true
27+
}

core/shared/src/test/scala/fs2/StreamCombinatorsSuite.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ class StreamCombinatorsSuite extends Fs2Suite {
268268
.map { result =>
269269
assertEquals(result.size, 1)
270270
val head = result.head
271-
assert(head.toMillis >= (delay.toMillis - 5))
271+
assert(clue(head.toMillis) >= clue(delay.toMillis - 5))
272272
}
273273
}
274274

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright (c) 2013 Functional Streams for Scala
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
package fs2
23+
package io
24+
25+
abstract class Fs2IoSuite extends Fs2Suite

io/js/src/main/scala/fs2/io/net/tls/TLSContextPlatform.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ private[tls] trait TLSContextCompanionPlatform { self: TLSContext.type =>
3838

3939
private[tls] trait BuilderPlatform[F[_]] {
4040
def fromSecureContext(context: SecureContext): TLSContext[F]
41+
def system: F[TLSContext[F]]
42+
def insecure: F[TLSContext[F]]
4143
}
4244

4345
private[tls] trait BuilderCompanionPlatform {
44-
private[tls] final class AsyncBuilder[F[_]](implicit F: Async[F]) extends Builder[F] {
46+
private[tls] final class AsyncBuilder[F[_]](implicit F: Async[F]) extends UnsealedBuilder[F] {
4547

4648
def fromSecureContext(
4749
context: SecureContext,
@@ -143,8 +145,14 @@ private[tls] trait TLSContextCompanionPlatform { self: TLSContext.type =>
143145
def system: F[TLSContext[F]] =
144146
Async[F].delay(fromSecureContext(SecureContext.default))
145147

148+
def systemResource: Resource[F, TLSContext[F]] =
149+
Resource.eval(system)
150+
146151
def insecure: F[TLSContext[F]] =
147152
Async[F].delay(fromSecureContext(SecureContext.default, insecure = true))
153+
154+
def insecureResource: Resource[F, TLSContext[F]] =
155+
Resource.eval(insecure)
148156
}
149157
}
150158
}

0 commit comments

Comments
 (0)