From 3c26e4e0119a81c1d03fba070acaa0dfa72c59cc Mon Sep 17 00:00:00 2001 From: pierscin <30854591+pierscin@users.noreply.github.com> Date: Thu, 24 Sep 2026 13:49:10 +0200 Subject: [PATCH 1/5] Migrate to sbt 2.0.9 and sbt-softwaremill 3.0.1 - sbt 2.0.9, sbt-softwaremill 3.0.1, sbt-mima-plugin 1.2.1 - removed sbt-projectmatrix (built into sbt 2) - removed sbt-revolver and sbt-jsdependencies, which aren't available for sbt 2: - the test server is now started as a forked sbt background job (bgRunMain), reused if already listening on the port, and stopped when sbt exits - spark-md5.min.js is vendored in core/src/test/js and loaded before the JS tests via Test / jsEnvInput - common settings are now bare settings in build.sbt (applied to all subprojects in sbt 2) - updateDocs and compileDocs are defined on the root project only - in sbt 2, Scala 3 matrix projects have no suffix, while Scala 2.13 ones get the 2_13 suffix: compileScoped/testScoped filters and CI project names adjusted (examples3 -> examples, examplesCe2 -> examplesCe22_13) - testScoped uses testFull, as `test` is incremental in sbt 2; the test server is also started before testFull - the fs2-ce2 sttp-shared dependency explicitly uses the JVM artifact on all platforms, as before (in sbt 2 `%%` is platform-aware) - removed the no-op native `Test / test` override (the release check never had any effect) - sbt 2 syntax adjustments (%%% -> %%, `: _*` -> `*`, slash syntax, InputTask test, uncached tasks) - put -release 11 explicitly in scalac options for Scala 2 on the JVM (same target as Scala 3's -java-output-version) - terminate the actor systems in akka/pekko streaming tests, otherwise pekko crashes the sbt server once the test classloader is closed - CI: JDK 11 -> 17, setup-sbt v1.5.10, shut down the sbt server before ci-release - scalafmt: scala3 dialect for *.sbt and project/*.scala files Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 26 +-- .scalafmt.conf | 8 +- CLAUDE.md | 4 +- .../akkahttp/AkkaHttpStreamingTest.scala | 8 +- build.sbt | 219 +++++++++--------- core/src/test/js/spark-md5-3.0.2.min.js | 1 + .../pekkohttp/PekkoHttpStreamingTest.scala | 8 +- project/build.properties | 2 +- project/plugins.sbt | 7 +- 9 files changed, 154 insertions(+), 129 deletions(-) create mode 100644 core/src/test/js/spark-md5-3.0.2.min.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cdc3059553..3275da6e8a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: matrix: scala-version: [ "2.12", "2.13", "3" ] target-platform: [ "JVM", "JS", "Native" ] - java: [ "11", "21" ] + java: [ "17", "21" ] steps: - name: Checkout uses: actions/checkout@v2 @@ -32,7 +32,7 @@ jobs: distribution: 'temurin' cache: 'sbt' java-version: ${{ matrix.java }} - - uses: sbt/setup-sbt@3e125ece5c3e5248e18da9ed8d2cce3d335ec8dd # v1, specifically v1.1.14 + - uses: sbt/setup-sbt@ce95da69b39609ea153bad087708da5f37366897 # v1, specifically v1.5.10 - name: Install libidn2-dev libcurl3-dev if: matrix.target-platform == 'Native' run: | @@ -61,18 +61,18 @@ jobs: - name: Compile run: sbt -v "compileScoped ${{ matrix.scala-version }} ${{ matrix.target-platform }}" - name: Compile documentation - if: matrix.target-platform == 'JVM' && matrix.java == '11' + if: matrix.target-platform == 'JVM' && matrix.java == '17' run: sbt -v compileDocs - name: Verify that examples compile using Scala CLI if: matrix.target-platform == 'JVM' && matrix.java == '21' && matrix.scala-version == '3' - run: sbt $SBT_JAVA_OPTS -v "project examples3" verifyExamplesCompileUsingScalaCli + run: sbt -v "project examples" verifyExamplesCompileUsingScalaCli - name: Verify that examples-ce2 compile using Scala CLI - if: matrix.target-platform == 'JVM' && matrix.java == '11' && matrix.scala-version == '2.13' - run: sbt $SBT_JAVA_OPTS -v "project examplesCe2" verifyExamplesCompileUsingScalaCli + if: matrix.target-platform == 'JVM' && matrix.java == '17' && matrix.scala-version == '2.13' + run: sbt -v "project examplesCe22_13" verifyExamplesCompileUsingScalaCli - name: Test run: sbt -v "testScoped ${{ matrix.scala-version }} ${{ matrix.target-platform }}" - name: Prepare release notes - if: matrix.java == '11' + if: matrix.java == '17' uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6, specifically v6.1.0 with: config-name: release-drafter.yml @@ -89,7 +89,7 @@ jobs: runs-on: ubuntu-24.04 strategy: matrix: - java: [ "11", "21" ] + java: [ "17", "21" ] steps: - name: Checkout uses: actions/checkout@v2 @@ -99,7 +99,7 @@ jobs: distribution: 'temurin' java-version: ${{ matrix.java }} cache: 'sbt' - - uses: sbt/setup-sbt@3e125ece5c3e5248e18da9ed8d2cce3d335ec8dd # v1, specifically v1.1.14 + - uses: sbt/setup-sbt@ce95da69b39609ea153bad087708da5f37366897 # v1, specifically v1.5.10 - name: Install libidn2-dev libcurl3-dev run: | sudo apt-get update @@ -112,7 +112,7 @@ jobs: cmake --build build -j $(nproc) sudo cmake --install build - name: Enable Native-specific modules - if: matrix.java == '11' + if: matrix.java == '17' run: echo "STTP_NATIVE=1" >> $GITHUB_ENV - name: Enable ZIO and Loom-specific modules if: matrix.java == '21' @@ -120,7 +120,7 @@ jobs: echo "WITH_ZIO=1" >> $GITHUB_ENV echo "ONLY_LOOM=1" >> $GITHUB_ENV - name: Compile - run: sbt compile + run: sbt "compile ; shutdown" - name: Publish artifacts run: sbt ci-release env: @@ -129,14 +129,14 @@ jobs: SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - name: Extract version from commit message - if: matrix.java == '11' + if: matrix.java == '17' run: | version=${GITHUB_REF/refs\/tags\/v/} echo "VERSION=$version" >> $GITHUB_ENV env: COMMIT_MSG: ${{ github.event.head_commit.message }} - name: Publish release notes - if: matrix.java == '11' + if: matrix.java == '17' uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6, specifically v6.1.0 with: config-name: release-drafter.yml diff --git a/.scalafmt.conf b/.scalafmt.conf index ada12e2cc3..6576656c67 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -11,4 +11,10 @@ fileOverride { "glob:**/effects/ox/**" { runner.dialect = scala3 } -} \ No newline at end of file + "glob:**.sbt" { + runner.dialect = scala3 + } + "glob:**/project/*.scala" { + runner.dialect = scala3 + } +} diff --git a/CLAUDE.md b/CLAUDE.md index 6e841040d3..2574f744a9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3,7 +3,7 @@ ## Build commands - Compile all: `sbt compile` - Compile specific Scala version/platform: `sbt "compileScoped 3 JVM"` (options: 2.12, 2.13, 3 / JVM, JS, Native) -- Test all: `sbt test` +- Test all: `sbt testFull` (in sbt 2, `test` is incremental) - Test specific: `sbt "testScoped 3 JVM"` - Compile docs: `sbt compileDocs` @@ -21,4 +21,4 @@ ## Code style - Follow existing patterns in the codebase -- Use `%%%` for cross-platform dependencies, `%%` for JVM-only +- Use `%%` for Scala dependencies (in sbt 2 it is platform-aware, so there's no need for `%%%`) diff --git a/akka-http-backend/src/test/scala/sttp/client4/akkahttp/AkkaHttpStreamingTest.scala b/akka-http-backend/src/test/scala/sttp/client4/akkahttp/AkkaHttpStreamingTest.scala index b621873772..b1506f48ac 100644 --- a/akka-http-backend/src/test/scala/sttp/client4/akkahttp/AkkaHttpStreamingTest.scala +++ b/akka-http-backend/src/test/scala/sttp/client4/akkahttp/AkkaHttpStreamingTest.scala @@ -9,7 +9,8 @@ import sttp.model.sse.ServerSentEvent import sttp.client4.testing.ConvertToFuture import sttp.client4.testing.streaming.StreamingTest -import scala.concurrent.Future +import scala.concurrent.duration._ +import scala.concurrent.{Await, Future} class AkkaHttpStreamingTest extends StreamingTest[Future, AkkaStreams] { override val streams: AkkaStreams = AkkaStreams @@ -19,6 +20,11 @@ class AkkaHttpStreamingTest extends StreamingTest[Future, AkkaStreams] { override val backend: StreamBackend[Future, AkkaStreams] = AkkaHttpBackend.usingActorSystem(actorSystem) + override protected def afterAll(): Unit = { + super.afterAll() + Await.result(actorSystem.terminate(), 5.seconds) + } + override implicit val convertToFuture: ConvertToFuture[Future] = ConvertToFuture.future diff --git a/build.sbt b/build.sbt index c090c2c4b6..07551a8729 100644 --- a/build.sbt +++ b/build.sbt @@ -3,8 +3,8 @@ import com.softwaremill.SbtSoftwareMillCommon.commonSmlBuildSettings import com.softwaremill.UpdateVersionInDocs import sbt.Keys.publishArtifact import sbt.Reference.display -import sbt.internal.ProjectMatrix import complete.DefaultParsers._ +import org.scalajs.jsenv.Input // run JS tests inside Chrome, due to jsdom not supporting fetch import com.softwaremill.SbtSoftwareMillBrowserTestJS._ @@ -23,12 +23,13 @@ val ideScalaVersion = scala3 lazy val testServerPort = settingKey[Int]("Port to run the http test server on") lazy val startTestServer = taskKey[Unit]("Start a http server used by tests") lazy val verifyExamplesCompileUsingScalaCli = taskKey[Unit]("Verify that each example compiles using Scala CLI") +lazy val compileDocs = taskKey[Unit]("Compiles docs module throwing away its output") // slow down for CI -parallelExecution in Global := false -concurrentRestrictions in Global += Tags.limit(Tags.Test, 1) +Global / parallelExecution := false +Global / concurrentRestrictions += Tags.limit(Tags.Test, 1) -excludeLintKeys in Global ++= Set(ideSkipProject, reStartArgs) +Global / excludeLintKeys ++= Set(ideSkipProject) val scopesDescription = "Scala version can be: 2.12, 2.13, 3; platform: JVM, JS, Native" val compileScoped = inputKey[Unit]( @@ -37,26 +38,28 @@ val compileScoped = val testScoped = inputKey[Unit](s"Run tests in the given scope. Usage: testScoped [scala version] [platform]. $scopesDescription") -val commonSettings = commonSmlBuildSettings ++ ossPublishSettings ++ Seq( - organization := "com.softwaremill.sttp.client4", - ideSkipProject := (scalaVersion.value != ideScalaVersion) - || thisProjectRef.value.project.contains("JS") || thisProjectRef.value.project.contains("Native"), - bspEnabled := !ideSkipProject.value, - mimaPreviousArtifacts := Set.empty // we only use MiMa for `core` for now, using enableMimaSettings -) +commonSmlBuildSettings +ossPublishSettings + +organization := "com.softwaremill.sttp.client4" +ideSkipProject := (scalaVersion.value != ideScalaVersion) || + thisProjectRef.value.project.contains("JS") || + thisProjectRef.value.project.contains("Native") +bspEnabled := !ideSkipProject.value +mimaPreviousArtifacts := Set.empty // we only use MiMa for `core` for now, using enableMimaSettings -val commonJvmSettings = commonSettings ++ Seq( +val commonJvmSettings = Seq( scalacOptions ++= (if (ScalaArtifacts.isScala3(scalaVersion.value)) Seq("-Yfuture-lazy-vals", "-java-output-version", "11") - else Seq.empty), + else Seq("-release", "11")), Test / testOptions += Tests.Argument("-oD") // add test timings; js build specify other options which conflict ) -val commonJsSettings = commonSettings ++ Seq( +val commonJsSettings = Seq( scalaJSLinkerConfig ~= { _.withBatchMode(true).withParallel(false) }, - libraryDependencies += ("org.scala-js" %%% "scalajs-java-securerandom" % "1.0.0").cross(CrossVersion.for3Use2_13), + libraryDependencies += ("org.scala-js" %% "scalajs-java-securerandom" % "1.0.0").cross(CrossVersion.for3Use2_13), Compile / scalacOptions ++= { if (isSnapshot.value) Seq.empty else @@ -73,20 +76,16 @@ val commonJsSettings = commonSettings ++ Seq( } ) -val commonJsBackendSettings = JSDependenciesPlugin.projectSettings ++ List( - jsDependencies ++= Seq( - "org.webjars.npm" % "spark-md5" % "3.0.2" % Test / "spark-md5.js" minified "spark-md5.min.js" +// spark-md5 (MIT) provides the global SparkMD5, used by the JS MD5 digest implementation, and must be loaded before +// running the tests; downloaded from https://cdn.jsdelivr.net/npm/spark-md5@3.0.2/spark-md5.min.js +val commonJsBackendSettings = List( + Test / jsEnvInput := Def.uncached( + Input.Script(((ThisBuild / baseDirectory).value / "core/src/test/js/spark-md5-3.0.2.min.js").toPath) +: + (Test / jsEnvInput).value ) ) -val commonNativeSettings = commonSettings ++ Seq( - Test / test := { - // TODO: re-enable after scala-native release > 0.4.0-M2 - if (sys.env.isDefinedAt("RELEASE_VERSION")) { - println("[info] Release build, skipping sttp native tests") - } else { (Test / test).value } - } -) +val commonNativeSettings: Seq[Def.Setting[?]] = Seq.empty val versioningSchemeSettings = Seq(versionScheme := Some("early-semver")) @@ -111,13 +110,18 @@ val enableMimaSettings = Seq( val testServerSettings = Seq( Test / test := (Test / test) .dependsOn(testServer2_13 / startTestServer) - .value, + .evaluated, + Test / testFull := Def.uncached( + (Test / testFull) + .dependsOn(testServer2_13 / startTestServer) + .value + ), Test / testOnly := (Test / testOnly) .dependsOn(testServer2_13 / startTestServer) .evaluated, Test / testOptions += Tests.Setup { () => val port = (testServer2_13 / testServerPort).value - PollingUtils.waitUntilServerAvailable(url(s"http://localhost:$port")) + PollingUtils.waitUntilServerAvailable(uri(s"http://localhost:$port").toURL) } ) @@ -145,7 +149,7 @@ val pekkoStreamVersion = "1.7.0" val pekkoStreams = "org.apache.pekko" %% "pekko-stream" % pekkoStreamVersion val scalaTest = libraryDependencies ++= Seq("freespec", "funsuite", "flatspec", "wordspec", "shouldmatchers").map(m => - "org.scalatest" %%% s"scalatest-$m" % "3.2.20" % Test + "org.scalatest" %% s"scalatest-$m" % "3.2.20" % Test ) val scalaTestPlusScalaCheck = libraryDependencies += "org.scalatestplus" %% "scalacheck-1-19" % "3.2.20.0" % Test @@ -176,8 +180,8 @@ val slf4jVersion = "1.7.36" val compileAndTest = "compile->compile;test->test" -lazy val loomProjects: Seq[String] = Seq(ox, examples, zioJson).flatMap(_.projectRefs).flatMap(projectId) -lazy val zioProjects: Seq[String] = Seq(zioJson).flatMap(_.projectRefs).flatMap(projectId) +lazy val loomProjects: Seq[String] = Seq[ProjectMatrix](ox, examples, zioJson).flatMap(_.projectRefs).flatMap(projectId) +lazy val zioProjects: Seq[String] = Seq[ProjectMatrix](zioJson).flatMap(_.projectRefs).flatMap(projectId) def projectId(projectRef: ProjectReference): Option[String] = projectRef match { @@ -268,15 +272,16 @@ lazy val rawAllAggregates = testServer.projectRefs def filterProject(p: String => Boolean) = - ScopeFilter(inProjects(allAggregates.filter(pr => p(display(pr.project))): _*)) + ScopeFilter(inProjects(allAggregates.filter(pr => p(display(pr.project)))*)) def filterByVersionAndPlatform(scalaVersionFilter: String, platformFilter: String) = filterProject { projectName => val byPlatform = if (platformFilter == "JVM") !projectName.contains("JS") && !projectName.contains("Native") else projectName.contains(platformFilter) + // in sbt 2, Scala 3 projects have no suffix, while Scala 2 ones are suffixed with 2_12/2_13 val byVersion = scalaVersionFilter match { - case "3" => projectName.contains("3") - case "2.13" => !projectName.contains("2_12") && !projectName.contains("3") + case "3" => !projectName.contains("2_12") && !projectName.contains("2_13") + case "2.13" => projectName.contains("2_13") case "2.12" => projectName.contains("2_12") } @@ -284,7 +289,6 @@ def filterByVersionAndPlatform(scalaVersionFilter: String, platformFilter: Strin } lazy val rootProject = (project in file(".")) - .settings(commonSettings) .settings( publish / skip := true, name := "sttp", @@ -294,11 +298,11 @@ lazy val rootProject = (project in file(".")) }.evaluated, testScoped := Def.inputTaskDyn { val args = spaceDelimited("").parsed - Def.taskDyn((Test / test).all(filterByVersionAndPlatform(args.head, args(1)))) + Def.taskDyn((Test / testFull).all(filterByVersionAndPlatform(args.head, args(1)))) }.evaluated, ideSkipProject := false, scalaVersion := scala2_13, - updateDocs := Def.taskDyn { + updateDocs := Def.uncached(Def.taskDyn { val files1 = UpdateVersionInDocs(sLog.value, organization.value, version.value, List(file("README.md"))) Def.task { (docs.jvm(scala3) / mdoc).toTask("").value @@ -307,9 +311,11 @@ lazy val rootProject = (project in file(".")) GenerateListOfExamples(sLog.value, sourceDirectory.value.getParentFile) files1 ++ Seq(file("generated-docs/out")) } - }.value + }.value), + // TODO this should be invoked by compilation process, see #https://github.com/scalameta/mdoc/issues/355 + compileDocs := (docs.jvm(scala3) / mdoc).toTask(" --out target/sttp-docs").value ) - .aggregate(allAggregates: _*) + .aggregate(allAggregates*) lazy val testServer = (projectMatrix in file("testing/server")) .settings(commonJvmSettings) @@ -321,11 +327,16 @@ lazy val testServer = (projectMatrix in file("testing/server")) akkaStreams ), // the test server needs to be started before running any backend tests - reStart / mainClass := Some("sttp.client4.testing.server.HttpServer"), - reStart / reStartArgs := Seq(s"${(Test / testServerPort).value}"), - reStart / fullClasspath := (Test / fullClasspath).value, testServerPort := 51823, - startTestServer := reStart.toTask("").value + // started as an sbt background job (see `bgList`, `bgStop`), which is stopped when sbt exits; if a server is already + // listening on the port (e.g. started by a previous test run in the same sbt session), it's reused + // bgRunMain uses `run / runner`, so forking is configured on `run` + Compile / run / fork := true, + startTestServer := Def.uncached(Def.taskDyn { + val port = testServerPort.value + if (PollingUtils.urlConnectionAvailable(uri(s"http://localhost:$port").toURL)) Def.task(()) + else (Compile / bgRunMain).toTask(s" sttp.client4.testing.server.HttpServer $port").map(_ => ()) + }.value) ) .jvmPlatform(scalaVersions = scala2) @@ -335,9 +346,9 @@ lazy val core = (projectMatrix in file("core")) .settings( name := "core", libraryDependencies ++= Seq( - "com.softwaremill.sttp.model" %%% "core" % sttpModelVersion, - "com.softwaremill.sttp.shared" %%% "core" % sttpSharedVersion, - "com.softwaremill.sttp.shared" %%% "ws" % sttpSharedVersion + "com.softwaremill.sttp.model" %% "core" % sttpModelVersion, + "com.softwaremill.sttp.shared" %% "core" % sttpSharedVersion, + "com.softwaremill.sttp.shared" %% "ws" % sttpSharedVersion ), scalaTest, scalaTestPlusScalaCheck @@ -383,7 +394,7 @@ lazy val catsCe2 = (projectMatrix in file("effects/cats-ce2")) name := "catsCe2", Test / publishArtifact := true, libraryDependencies ++= Seq( - "org.typelevel" %%% "cats-effect" % catsEffect_2_version + "org.typelevel" %% "cats-effect" % catsEffect_2_version ) ) .dependsOn(core % compileAndTest) @@ -398,9 +409,9 @@ lazy val catsCe2 = (projectMatrix in file("effects/cats-ce2")) lazy val catsEffect = Def.setting { Seq( - "org.typelevel" %%% "cats-effect-kernel" % catsEffect_3_version, - "org.typelevel" %%% "cats-effect-std" % catsEffect_3_version, - "org.typelevel" %%% "cats-effect" % catsEffect_3_version % Test + "org.typelevel" %% "cats-effect-kernel" % catsEffect_3_version, + "org.typelevel" %% "cats-effect-std" % catsEffect_3_version, + "org.typelevel" %% "cats-effect" % catsEffect_3_version % Test ) } @@ -430,9 +441,10 @@ lazy val fs2Ce2 = (projectMatrix in file("effects/fs2-ce2")) name := "fs2Ce2", Test / publishArtifact := true, libraryDependencies ++= Seq( - "co.fs2" %%% "fs2-core" % fs2_2_version + "co.fs2" %% "fs2-core" % fs2_2_version ), - libraryDependencies += "com.softwaremill.sttp.shared" %% "fs2-ce2" % sttpSharedVersion + // the JVM artifact is used on all platforms (as with sbt 1's %%, which wasn't platform-aware) + libraryDependencies += ("com.softwaremill.sttp.shared" %% "fs2-ce2" % sttpSharedVersion).platform(Platform.jvm) ) .settings(testServerSettings) .dependsOn(core % compileAndTest, catsCe2 % compileAndTest) @@ -440,8 +452,8 @@ lazy val fs2Ce2 = (projectMatrix in file("effects/fs2-ce2")) scalaVersions = scala2And3, settings = commonJvmSettings ++ Seq( libraryDependencies ++= Seq( - "co.fs2" %%% "fs2-reactive-streams" % fs2_2_version, - "co.fs2" %%% "fs2-io" % fs2_2_version + "co.fs2" %% "fs2-reactive-streams" % fs2_2_version, + "co.fs2" %% "fs2-io" % fs2_2_version ) ) ) @@ -452,8 +464,8 @@ lazy val fs2 = (projectMatrix in file("effects/fs2")) name := "fs2", Test / publishArtifact := true, libraryDependencies ++= Seq( - "co.fs2" %%% "fs2-core" % fs2_3_version, - "com.softwaremill.sttp.shared" %%% "fs2" % sttpSharedVersion + "co.fs2" %% "fs2-core" % fs2_3_version, + "com.softwaremill.sttp.shared" %% "fs2" % sttpSharedVersion ) ) .settings(testServerSettings) @@ -462,8 +474,8 @@ lazy val fs2 = (projectMatrix in file("effects/fs2")) scalaVersions = scala2And3, settings = commonJvmSettings ++ Seq( libraryDependencies ++= Seq( - "co.fs2" %%% "fs2-reactive-streams" % fs2_3_version, - "co.fs2" %%% "fs2-io" % fs2_3_version + "co.fs2" %% "fs2-reactive-streams" % fs2_3_version, + "co.fs2" %% "fs2-io" % fs2_3_version ), Compile / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "effects" / "fs2" / "src" / "main" / "scalajvmnative" ) @@ -476,7 +488,7 @@ lazy val fs2 = (projectMatrix in file("effects/fs2")) scalaVersions = scala2And3, settings = commonNativeSettings ++ testServerSettings ++ Seq( libraryDependencies ++= Seq( - "co.fs2" %%% "fs2-io" % fs2_3_version + "co.fs2" %% "fs2-io" % fs2_3_version ), Compile / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "effects" / "fs2" / "src" / "main" / "scalajvmnative" ) @@ -487,8 +499,8 @@ lazy val monix = (projectMatrix in file("effects/monix")) name := "monix", Test / publishArtifact := true, libraryDependencies ++= Seq( - "io.monix" %%% "monix" % "3.4.1", - "com.softwaremill.sttp.shared" %%% "monix" % sttpSharedVersion + "io.monix" %% "monix" % "3.4.1", + "com.softwaremill.sttp.shared" %% "monix" % sttpSharedVersion ) ) .settings(testServerSettings) @@ -521,9 +533,9 @@ lazy val zio1 = (projectMatrix in file("effects/zio1")) name := "zio1", Test / publishArtifact := true, libraryDependencies ++= Seq( - "dev.zio" %%% "zio-streams" % zio1Version, - "dev.zio" %%% "zio" % zio1Version, - "com.softwaremill.sttp.shared" %%% "zio1" % sttpSharedVersion + "dev.zio" %% "zio-streams" % zio1Version, + "dev.zio" %% "zio" % zio1Version, + "com.softwaremill.sttp.shared" %% "zio1" % sttpSharedVersion ) ) .settings(testServerSettings) @@ -547,9 +559,9 @@ lazy val zio = (projectMatrix in file("effects/zio")) name := "zio", Test / publishArtifact := true, libraryDependencies ++= Seq( - "dev.zio" %%% "zio-streams" % zio2Version, - "dev.zio" %%% "zio" % zio2Version, - "com.softwaremill.sttp.shared" %%% "zio" % sttpSharedVersion + "dev.zio" %% "zio-streams" % zio2Version, + "dev.zio" %% "zio" % zio2Version, + "com.softwaremill.sttp.shared" %% "zio" % sttpSharedVersion ) ) .settings(testServerSettings) @@ -570,7 +582,7 @@ lazy val zio = (projectMatrix in file("effects/zio")) scalaVersions = List(scala3), settings = commonNativeSettings ++ Seq( libraryDependencies ++= Seq( - "io.github.cquiroz" %%% "scala-java-time" % "2.6.0" + "io.github.cquiroz" %% "scala-java-time" % "2.6.0" ) ) ) @@ -642,7 +654,7 @@ lazy val okhttpBackend = (projectMatrix in file("okhttp-backend")) .dependsOn(core % compileAndTest) def okhttpBackendProject(proj: String) = - ProjectMatrix(s"okhttpBackend${proj.capitalize}", file(s"okhttp-backend/$proj")) + ProjectMatrix(s"okhttpBackend${proj.capitalize}", file(s"okhttp-backend/$proj"), getClass.getClassLoader) .settings(commonJvmSettings) .settings(testServerSettings) .settings(name := s"okhttp-backend-$proj") @@ -672,8 +684,8 @@ lazy val http4sBackend = (projectMatrix in file("http4s-backend")) .settings( name := "http4s-backend", libraryDependencies ++= Seq( - "org.http4s" %%% "http4s-client" % http4s_ce3_version, - "org.http4s" %%% "http4s-ember-client" % http4s_ce3_version % Optional + "org.http4s" %% "http4s-client" % http4s_ce3_version, + "org.http4s" %% "http4s-ember-client" % http4s_ce3_version % Optional ), evictionErrorLevel := Level.Info ) @@ -715,7 +727,7 @@ lazy val armeriaBackend = (projectMatrix in file("armeria-backend")) .dependsOn(core % compileAndTest) def armeriaBackendProject(proj: String, includeScala3: Boolean = true) = - ProjectMatrix(s"armeriaBackend${proj.capitalize}", file(s"armeria-backend/$proj")) + ProjectMatrix(s"armeriaBackend${proj.capitalize}", file(s"armeria-backend/$proj"), getClass.getClassLoader) .settings(commonJvmSettings) .settings(testServerSettings) .settings(name := s"armeria-backend-$proj") @@ -790,9 +802,9 @@ lazy val circe = (projectMatrix in file("json/circe")) .settings( name := "circe", libraryDependencies ++= Seq( - "io.circe" %%% "circe-core" % circeVersion, - "io.circe" %%% "circe-parser" % circeVersion, - "io.circe" %%% "circe-generic" % circeVersion % Test + "io.circe" %% "circe-core" % circeVersion, + "io.circe" %% "circe-parser" % circeVersion, + "io.circe" %% "circe-generic" % circeVersion % Test ), scalaTest ) @@ -808,8 +820,8 @@ lazy val jsoniter = (projectMatrix in file("json/jsoniter")) .settings( name := "jsoniter", libraryDependencies ++= Seq( - "com.github.plokhotnyuk.jsoniter-scala" %%% "jsoniter-scala-core" % jsoniterVersion, - "com.github.plokhotnyuk.jsoniter-scala" %%% "jsoniter-scala-macros" % jsoniterVersion % Test + "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-core" % jsoniterVersion, + "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % jsoniterVersion % Test ), scalaTest ) @@ -825,8 +837,8 @@ lazy val zioJson = (projectMatrix in file("json/zio-json")) .settings( name := "zio-json", libraryDependencies ++= Seq( - "dev.zio" %%% "zio-json" % "1.0.0", - "com.softwaremill.sttp.shared" %%% "zio" % sttpSharedVersion + "dev.zio" %% "zio-json" % "1.0.0", + "com.softwaremill.sttp.shared" %% "zio" % sttpSharedVersion ), scalaTest ) @@ -841,8 +853,8 @@ lazy val zio1Json = (projectMatrix in file("json/zio1-json")) .settings( name := "zio1-json", libraryDependencies ++= Seq( - "dev.zio" %%% "zio-json" % "0.2.0", - "com.softwaremill.sttp.shared" %%% "zio1" % sttpSharedVersion + "dev.zio" %% "zio-json" % "0.2.0", + "com.softwaremill.sttp.shared" %% "zio1" % sttpSharedVersion ), scalaTest ) @@ -873,7 +885,7 @@ lazy val upickle = (projectMatrix in file("json/upickle")) .settings( name := "upickle", libraryDependencies ++= Seq( - "com.lihaoyi" %%% "upickle" % "4.4.3" + "com.lihaoyi" %% "upickle" % "4.4.3" ), scalaTest, // using macroRW causes a "match may not be exhaustive" error @@ -920,7 +932,7 @@ lazy val play29Json = (projectMatrix in file("json/play29-json")) Compile / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "json" / "play-json" / "src" / "main" / "scala", Test / unmanagedSourceDirectories += (ThisBuild / baseDirectory).value / "json" / "play-json" / "src" / "test" / "scala", libraryDependencies ++= Seq( - "com.typesafe.play" %%% "play-json" % play29JsonVersion + "com.typesafe.play" %% "play-json" % play29JsonVersion ), scalaTest ) @@ -935,7 +947,7 @@ lazy val playJson = (projectMatrix in file("json/play-json")) .settings( name := "play-json", libraryDependencies ++= Seq( - "org.playframework" %%% "play-json" % playJsonVersion + "org.playframework" %% "play-json" % playJsonVersion ), scalaTest ) @@ -991,11 +1003,11 @@ lazy val otel4sMetricsBackend = (projectMatrix in file("observability/otel4s-met .settings( name := "opentelemetry-otel4s-metrics-backend", libraryDependencies ++= Seq( - "org.typelevel" %%% "otel4s-core-metrics" % otel4s, - "org.typelevel" %%% "otel4s-semconv" % otel4s, - "org.typelevel" %%% "otel4s-semconv-experimental" % otel4s % Test, - "org.typelevel" %%% "otel4s-semconv-metrics-experimental" % otel4s % Test, - "org.typelevel" %%% "otel4s-sdk-metrics-testkit" % otel4sSdk % Test + "org.typelevel" %% "otel4s-core-metrics" % otel4s, + "org.typelevel" %% "otel4s-semconv" % otel4s, + "org.typelevel" %% "otel4s-semconv-experimental" % otel4s % Test, + "org.typelevel" %% "otel4s-semconv-metrics-experimental" % otel4s % Test, + "org.typelevel" %% "otel4s-sdk-metrics-testkit" % otel4sSdk % Test ) ) .jvmPlatform(scalaVersions = scala2_13And3, settings = commonJvmSettings) @@ -1008,10 +1020,10 @@ lazy val otel4sTracingBackend = (projectMatrix in file("observability/otel4s-tra .settings( name := "opentelemetry-otel4s-tracing-backend", libraryDependencies ++= Seq( - "org.typelevel" %%% "otel4s-core-trace" % otel4s, - "org.typelevel" %%% "otel4s-semconv" % otel4s, - "org.typelevel" %%% "otel4s-sdk-trace-testkit" % otel4sSdk % Test, - "org.typelevel" %%% "cats-effect-testkit" % catsEffect_3_version % Test + "org.typelevel" %% "otel4s-core-trace" % otel4s, + "org.typelevel" %% "otel4s-semconv" % otel4s, + "org.typelevel" %% "otel4s-sdk-trace-testkit" % otel4sSdk % Test, + "org.typelevel" %% "cats-effect-testkit" % catsEffect_3_version % Test ) ) .jvmPlatform(scalaVersions = scala2_13And3, settings = commonJvmSettings) @@ -1024,7 +1036,7 @@ lazy val scribeBackend = (projectMatrix in file("logging/scribe")) .settings( name := "scribe-backend", libraryDependencies ++= Seq( - "com.outr" %%% "scribe" % "3.15.2" + "com.outr" %% "scribe" % "3.15.2" ), scalaTest ) @@ -1051,7 +1063,7 @@ lazy val cachingBackend = (projectMatrix in file("caching")) name := "caching-backend", libraryDependencies ++= Seq( "org.slf4j" % "slf4j-api" % slf4jVersion, - "com.github.plokhotnyuk.jsoniter-scala" %%% "jsoniter-scala-macros" % jsoniterVersion % Compile + "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % jsoniterVersion % Compile ), scalaTest ) @@ -1066,7 +1078,9 @@ lazy val examplesCe2 = (projectMatrix in file("examples-ce2")) libraryDependencies ++= Seq( "io.circe" %% "circe-generic" % circeVersion ), - verifyExamplesCompileUsingScalaCli := VerifyExamplesCompileUsingScalaCli(sLog.value, sourceDirectory.value) + verifyExamplesCompileUsingScalaCli := Def.uncached( + VerifyExamplesCompileUsingScalaCli(sLog.value, sourceDirectory.value) + ) ) .jvmPlatform(scalaVersions = List(scala2_13)) .dependsOn(circe, monix) @@ -1079,7 +1093,7 @@ lazy val examples = (projectMatrix in file("examples")) libraryDependencies ++= Seq( "io.circe" %% "circe-generic" % circeVersion, "io.github.json4s" %% "json4s-native" % json4sVersion, - "com.github.plokhotnyuk.jsoniter-scala" %%% "jsoniter-scala-macros" % jsoniterVersion, + "com.github.plokhotnyuk.jsoniter-scala" %% "jsoniter-scala-macros" % jsoniterVersion, "io.github.resilience4j" % "resilience4j-circuitbreaker" % resilience4jVersion, "io.github.resilience4j" % "resilience4j-ratelimiter" % resilience4jVersion, "com.lihaoyi" %% "os-lib" % osLibVersion, @@ -1089,7 +1103,9 @@ lazy val examples = (projectMatrix in file("examples")) pekkoStreams, logback ), - verifyExamplesCompileUsingScalaCli := VerifyExamplesCompileUsingScalaCli(sLog.value, sourceDirectory.value) + verifyExamplesCompileUsingScalaCli := Def.uncached( + VerifyExamplesCompileUsingScalaCli(sLog.value, sourceDirectory.value) + ) ) .jvmPlatform(scalaVersions = List(examplesScalaVersion)) .dependsOn( @@ -1109,15 +1125,8 @@ lazy val examples = (projectMatrix in file("examples")) openTelemetryBackend ) -//TODO this should be invoked by compilation process, see #https://github.com/scalameta/mdoc/issues/355 -val compileDocs: TaskKey[Unit] = taskKey[Unit]("Compiles docs module throwing away its output") -compileDocs := { - (docs.jvm(scala3) / mdoc).toTask(" --out target/sttp-docs").value -} - lazy val docs: ProjectMatrix = (projectMatrix in file("generated-docs")) // important: it must not be docs/ .enablePlugins(MdocPlugin) - .settings(commonSettings) .settings( mdocIn := file("docs"), moduleName := "sttp-docs", diff --git a/core/src/test/js/spark-md5-3.0.2.min.js b/core/src/test/js/spark-md5-3.0.2.min.js new file mode 100644 index 0000000000..2ef527dd45 --- /dev/null +++ b/core/src/test/js/spark-md5-3.0.2.min.js @@ -0,0 +1 @@ +(function(factory){if(typeof exports==="object"){module.exports=factory()}else if(typeof define==="function"&&define.amd){define(factory)}else{var glob;try{glob=window}catch(e){glob=self}glob.SparkMD5=factory()}})(function(undefined){"use strict";var add32=function(a,b){return a+b&4294967295},hex_chr=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];function cmn(q,a,b,x,s,t){a=add32(add32(a,q),add32(x,t));return add32(a<>>32-s,b)}function md5cycle(x,k){var a=x[0],b=x[1],c=x[2],d=x[3];a+=(b&c|~b&d)+k[0]-680876936|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[1]-389564586|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[2]+606105819|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[3]-1044525330|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[4]-176418897|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[5]+1200080426|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[6]-1473231341|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[7]-45705983|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[8]+1770035416|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[9]-1958414417|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[10]-42063|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[11]-1990404162|0;b=(b<<22|b>>>10)+c|0;a+=(b&c|~b&d)+k[12]+1804603682|0;a=(a<<7|a>>>25)+b|0;d+=(a&b|~a&c)+k[13]-40341101|0;d=(d<<12|d>>>20)+a|0;c+=(d&a|~d&b)+k[14]-1502002290|0;c=(c<<17|c>>>15)+d|0;b+=(c&d|~c&a)+k[15]+1236535329|0;b=(b<<22|b>>>10)+c|0;a+=(b&d|c&~d)+k[1]-165796510|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[6]-1069501632|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[11]+643717713|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[0]-373897302|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[5]-701558691|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[10]+38016083|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[15]-660478335|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[4]-405537848|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[9]+568446438|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[14]-1019803690|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[3]-187363961|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[8]+1163531501|0;b=(b<<20|b>>>12)+c|0;a+=(b&d|c&~d)+k[13]-1444681467|0;a=(a<<5|a>>>27)+b|0;d+=(a&c|b&~c)+k[2]-51403784|0;d=(d<<9|d>>>23)+a|0;c+=(d&b|a&~b)+k[7]+1735328473|0;c=(c<<14|c>>>18)+d|0;b+=(c&a|d&~a)+k[12]-1926607734|0;b=(b<<20|b>>>12)+c|0;a+=(b^c^d)+k[5]-378558|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[8]-2022574463|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[11]+1839030562|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[14]-35309556|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[1]-1530992060|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[4]+1272893353|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[7]-155497632|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[10]-1094730640|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[13]+681279174|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[0]-358537222|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[3]-722521979|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[6]+76029189|0;b=(b<<23|b>>>9)+c|0;a+=(b^c^d)+k[9]-640364487|0;a=(a<<4|a>>>28)+b|0;d+=(a^b^c)+k[12]-421815835|0;d=(d<<11|d>>>21)+a|0;c+=(d^a^b)+k[15]+530742520|0;c=(c<<16|c>>>16)+d|0;b+=(c^d^a)+k[2]-995338651|0;b=(b<<23|b>>>9)+c|0;a+=(c^(b|~d))+k[0]-198630844|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[7]+1126891415|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[14]-1416354905|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[5]-57434055|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[12]+1700485571|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[3]-1894986606|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[10]-1051523|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[1]-2054922799|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[8]+1873313359|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[15]-30611744|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[6]-1560198380|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[13]+1309151649|0;b=(b<<21|b>>>11)+c|0;a+=(c^(b|~d))+k[4]-145523070|0;a=(a<<6|a>>>26)+b|0;d+=(b^(a|~c))+k[11]-1120210379|0;d=(d<<10|d>>>22)+a|0;c+=(a^(d|~b))+k[2]+718787259|0;c=(c<<15|c>>>17)+d|0;b+=(d^(c|~a))+k[9]-343485551|0;b=(b<<21|b>>>11)+c|0;x[0]=a+x[0]|0;x[1]=b+x[1]|0;x[2]=c+x[2]|0;x[3]=d+x[3]|0}function md5blk(s){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=s.charCodeAt(i)+(s.charCodeAt(i+1)<<8)+(s.charCodeAt(i+2)<<16)+(s.charCodeAt(i+3)<<24)}return md5blks}function md5blk_array(a){var md5blks=[],i;for(i=0;i<64;i+=4){md5blks[i>>2]=a[i]+(a[i+1]<<8)+(a[i+2]<<16)+(a[i+3]<<24)}return md5blks}function md51(s){var n=s.length,state=[1732584193,-271733879,-1732584194,271733878],i,length,tail,tmp,lo,hi;for(i=64;i<=n;i+=64){md5cycle(state,md5blk(s.substring(i-64,i)))}s=s.substring(i-64);length=s.length;tail=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(i=0;i>2]|=s.charCodeAt(i)<<(i%4<<3)}tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=n*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(state,tail);return state}function md51_array(a){var n=a.length,state=[1732584193,-271733879,-1732584194,271733878],i,length,tail,tmp,lo,hi;for(i=64;i<=n;i+=64){md5cycle(state,md5blk_array(a.subarray(i-64,i)))}a=i-64>2]|=a[i]<<(i%4<<3)}tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(state,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=n*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(state,tail);return state}function rhex(n){var s="",j;for(j=0;j<4;j+=1){s+=hex_chr[n>>j*8+4&15]+hex_chr[n>>j*8&15]}return s}function hex(x){var i;for(i=0;i>16)+(y>>16)+(lsw>>16);return msw<<16|lsw&65535}}if(typeof ArrayBuffer!=="undefined"&&!ArrayBuffer.prototype.slice){(function(){function clamp(val,length){val=val|0||0;if(val<0){return Math.max(val+length,0)}return Math.min(val,length)}ArrayBuffer.prototype.slice=function(from,to){var length=this.byteLength,begin=clamp(from,length),end=length,num,target,targetArray,sourceArray;if(to!==undefined){end=clamp(to,length)}if(begin>end){return new ArrayBuffer(0)}num=end-begin;target=new ArrayBuffer(num);targetArray=new Uint8Array(target);sourceArray=new Uint8Array(this,begin,num);targetArray.set(sourceArray);return target}})()}function toUtf8(str){if(/[\u0080-\uFFFF]/.test(str)){str=unescape(encodeURIComponent(str))}return str}function utf8Str2ArrayBuffer(str,returnUInt8Array){var length=str.length,buff=new ArrayBuffer(length),arr=new Uint8Array(buff),i;for(i=0;i>2]|=buff.charCodeAt(i)<<(i%4<<3)}this._finish(tail,length);ret=hex(this._hash);if(raw){ret=hexToBinaryString(ret)}this.reset();return ret};SparkMD5.prototype.reset=function(){this._buff="";this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};SparkMD5.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash.slice()}};SparkMD5.prototype.setState=function(state){this._buff=state.buff;this._length=state.length;this._hash=state.hash;return this};SparkMD5.prototype.destroy=function(){delete this._hash;delete this._buff;delete this._length};SparkMD5.prototype._finish=function(tail,length){var i=length,tmp,lo,hi;tail[i>>2]|=128<<(i%4<<3);if(i>55){md5cycle(this._hash,tail);for(i=0;i<16;i+=1){tail[i]=0}}tmp=this._length*8;tmp=tmp.toString(16).match(/(.*?)(.{0,8})$/);lo=parseInt(tmp[2],16);hi=parseInt(tmp[1],16)||0;tail[14]=lo;tail[15]=hi;md5cycle(this._hash,tail)};SparkMD5.hash=function(str,raw){return SparkMD5.hashBinary(toUtf8(str),raw)};SparkMD5.hashBinary=function(content,raw){var hash=md51(content),ret=hex(hash);return raw?hexToBinaryString(ret):ret};SparkMD5.ArrayBuffer=function(){this.reset()};SparkMD5.ArrayBuffer.prototype.append=function(arr){var buff=concatenateArrayBuffers(this._buff.buffer,arr,true),length=buff.length,i;this._length+=arr.byteLength;for(i=64;i<=length;i+=64){md5cycle(this._hash,md5blk_array(buff.subarray(i-64,i)))}this._buff=i-64>2]|=buff[i]<<(i%4<<3)}this._finish(tail,length);ret=hex(this._hash);if(raw){ret=hexToBinaryString(ret)}this.reset();return ret};SparkMD5.ArrayBuffer.prototype.reset=function(){this._buff=new Uint8Array(0);this._length=0;this._hash=[1732584193,-271733879,-1732584194,271733878];return this};SparkMD5.ArrayBuffer.prototype.getState=function(){var state=SparkMD5.prototype.getState.call(this);state.buff=arrayBuffer2Utf8Str(state.buff);return state};SparkMD5.ArrayBuffer.prototype.setState=function(state){state.buff=utf8Str2ArrayBuffer(state.buff,true);return SparkMD5.prototype.setState.call(this,state)};SparkMD5.ArrayBuffer.prototype.destroy=SparkMD5.prototype.destroy;SparkMD5.ArrayBuffer.prototype._finish=SparkMD5.prototype._finish;SparkMD5.ArrayBuffer.hash=function(arr,raw){var hash=md51_array(new Uint8Array(arr)),ret=hex(hash);return raw?hexToBinaryString(ret):ret};return SparkMD5}); diff --git a/pekko-http-backend/src/test/scala/sttp/client4/pekkohttp/PekkoHttpStreamingTest.scala b/pekko-http-backend/src/test/scala/sttp/client4/pekkohttp/PekkoHttpStreamingTest.scala index 7b977fe844..4299a11407 100644 --- a/pekko-http-backend/src/test/scala/sttp/client4/pekkohttp/PekkoHttpStreamingTest.scala +++ b/pekko-http-backend/src/test/scala/sttp/client4/pekkohttp/PekkoHttpStreamingTest.scala @@ -10,7 +10,8 @@ import sttp.model.sse.ServerSentEvent import sttp.client4.testing.ConvertToFuture import sttp.client4.testing.streaming.StreamingTest -import scala.concurrent.Future +import scala.concurrent.duration._ +import scala.concurrent.{Await, Future} class PekkoHttpStreamingTest extends StreamingTest[Future, PekkoStreams] { override val streams: PekkoStreams = PekkoStreams @@ -20,6 +21,11 @@ class PekkoHttpStreamingTest extends StreamingTest[Future, PekkoStreams] { override val backend: StreamBackend[Future, PekkoStreams] = PekkoHttpBackend.usingActorSystem(actorSystem) + override protected def afterAll(): Unit = { + super.afterAll() + Await.result(actorSystem.terminate(), 5.seconds) + } + override implicit val convertToFuture: ConvertToFuture[Future] = ConvertToFuture.future diff --git a/project/build.properties b/project/build.properties index e0a1aa0234..ddca111e14 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.13.0 +sbt.version=2.0.9 diff --git a/project/plugins.sbt b/project/plugins.sbt index 05987a530a..f85f14b3d4 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,10 +1,7 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.22.0") -addSbtPlugin("org.scala-js" % "sbt-jsdependencies" % "1.0.2") addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.12") -addSbtPlugin("io.spray" % "sbt-revolver" % "0.10.0") -addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.11.0") -val sbtSoftwareMillVersion = "2.1.2" +val sbtSoftwareMillVersion = "3.0.1" addSbtPlugin("com.softwaremill.sbt-softwaremill" % "sbt-softwaremill-common" % sbtSoftwareMillVersion) addSbtPlugin("com.softwaremill.sbt-softwaremill" % "sbt-softwaremill-publish" % sbtSoftwareMillVersion) addSbtPlugin("com.softwaremill.sbt-softwaremill" % "sbt-softwaremill-browser-test-js" % sbtSoftwareMillVersion) @@ -12,4 +9,4 @@ addSbtPlugin("com.softwaremill.sbt-softwaremill" % "sbt-softwaremill-browser-tes addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.9.2") addSbtPlugin("org.jetbrains.scala" % "sbt-ide-settings" % "1.1.4") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.5") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.2.1") From f19af0e0a27b915d6a18530685f9bd6485b19034 Mon Sep 17 00:00:00 2001 From: pierscin <30854591+pierscin@users.noreply.github.com> Date: Thu, 1 Oct 2026 11:24:09 +0200 Subject: [PATCH 2/5] Request options format --- .github/pull_request_template.md | 2 +- core/src/main/scala/sttp/client4/RequestOptions.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a4b62eaed7..f479647f62 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,5 @@ Before submitting pull request: - [ ] Check if the project compiles by running `sbt compile` - [ ] Verify docs compilation by running `sbt compileDocs` -- [ ] Check if tests pass by running `sbt test` +- [ ] Check if tests pass by running `sbt testFull` - [ ] Format code by running `sbt scalafmt` diff --git a/core/src/main/scala/sttp/client4/RequestOptions.scala b/core/src/main/scala/sttp/client4/RequestOptions.scala index 5b146d7524..cbada33092 100644 --- a/core/src/main/scala/sttp/client4/RequestOptions.scala +++ b/core/src/main/scala/sttp/client4/RequestOptions.scala @@ -14,8 +14,8 @@ import sttp.model.ResponseMetadata * https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections for details. * @param readTimeout * The maximum duration to wait for a response. If no data is received within this period, the request will fail with - * a timeout exception (or a failed effect). When set to `Duration.Inf` (the default), no timeout is applied. Supported - * by all backends except http4s, where the timeout should be configured on the http4s client directly. + * a timeout exception (or a failed effect). When set to `Duration.Inf` (the default), no timeout is applied. + * Supported by all backends except http4s, where the timeout should be configured on the http4s client directly. * @param decompressResponseBody * Should the response body be decompressed, if a `Content-Encoding` header is present. By default, backends support * [[sttp.model.Encodings.Gzip]] and [[sttp.model.Encodings.Deflate]] encodings, but others might available as well; From 29d6e30a2cc8c7c28b066ed9a5e8b8b45f44945c Mon Sep 17 00:00:00 2001 From: pierscin <30854591+pierscin@users.noreply.github.com> Date: Thu, 1 Oct 2026 14:02:30 +0200 Subject: [PATCH 3/5] using rootProject macro --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 5ea550140a..56e54e398c 100644 --- a/build.sbt +++ b/build.sbt @@ -288,7 +288,7 @@ def filterByVersionAndPlatform(scalaVersionFilter: String, platformFilter: Strin byPlatform && byVersion } -lazy val rootProject = (project in file(".")) +lazy val root = rootProject .settings( publish / skip := true, name := "sttp", From 15a7fcc74f95e261ebdc507e1e4be0b049eca878 Mon Sep 17 00:00:00 2001 From: pierscin <30854591+pierscin@users.noreply.github.com> Date: Thu, 1 Oct 2026 14:03:35 +0200 Subject: [PATCH 4/5] Use scoped task calls for Scala CLI example checks in CI sbtn joins all arguments into a single command, so `sbt "project examples" verifyExamplesCompileUsingScalaCli` fails with "Expected project ID". Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3275da6e8a..f7a3225b6a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,10 +65,10 @@ jobs: run: sbt -v compileDocs - name: Verify that examples compile using Scala CLI if: matrix.target-platform == 'JVM' && matrix.java == '21' && matrix.scala-version == '3' - run: sbt -v "project examples" verifyExamplesCompileUsingScalaCli + run: sbt -v examples/verifyExamplesCompileUsingScalaCli - name: Verify that examples-ce2 compile using Scala CLI if: matrix.target-platform == 'JVM' && matrix.java == '17' && matrix.scala-version == '2.13' - run: sbt -v "project examplesCe22_13" verifyExamplesCompileUsingScalaCli + run: sbt -v examplesCe22_13/verifyExamplesCompileUsingScalaCli - name: Test run: sbt -v "testScoped ${{ matrix.scala-version }} ${{ matrix.target-platform }}" - name: Prepare release notes From 4c14b3e640da85f2634fc32578b2be311a71771c Mon Sep 17 00:00:00 2001 From: pierscin <30854591+pierscin@users.noreply.github.com> Date: Fri, 2 Oct 2026 08:16:39 +0200 Subject: [PATCH 5/5] Comments adjustments --- build.sbt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 56e54e398c..42f306798d 100644 --- a/build.sbt +++ b/build.sbt @@ -328,9 +328,8 @@ lazy val testServer = (projectMatrix in file("testing/server")) ), // the test server needs to be started before running any backend tests testServerPort := 51823, - // started as an sbt background job (see `bgList`, `bgStop`), which is stopped when sbt exits; if a server is already - // listening on the port (e.g. started by a previous test run in the same sbt session), it's reused - // bgRunMain uses `run / runner`, so forking is configured on `run` + // started as an sbt background job, stopped when sbt exits; if a server is already + // listening on the port, it's reused Compile / run / fork := true, startTestServer := Def.uncached(Def.taskDyn { val port = testServerPort.value