diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..120c689
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,6 @@
+version: 2
+updates:
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
\ No newline at end of file
diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml
new file mode 100644
index 0000000..6d9c0a2
--- /dev/null
+++ b/.github/release-drafter.yml
@@ -0,0 +1,59 @@
+name-template: '$RESOLVED_VERSION'
+tag-template: '$RESOLVED_VERSION'
+
+version-resolver:
+ major:
+ labels:
+ - 'major'
+ minor:
+ labels:
+ - 'minor'
+ patch:
+ labels:
+ - 'patch'
+ default: minor
+
+categories:
+ - title: 'Features'
+ label: 'enhancement'
+ - title: 'Bug Fixes'
+ label: 'bug'
+
+exclude-labels:
+ - 'skip'
+
+autolabeler:
+ - label: 'bug'
+ title:
+ - '/.*\[fix\].*/'
+ - label: 'patch'
+ title:
+ - '/.*\[fix\].*/'
+ - label: 'enhancement'
+ title:
+ - '/.*\[feat\].*/'
+ - label: 'minor'
+ title:
+ - '/.*\[feat\].*/'
+ - label: 'skip'
+ title:
+ - '/.*\[skip\].*/'
+ - label: 'major'
+ title:
+ - '/.*\[breaking\].*/'
+
+replacers:
+ - search: '/\[feat\]/g'
+ replace: ''
+ - search: '/\[fix\]/g'
+ replace: ''
+ - search: '/\[skip\]/g'
+ replace: ''
+ - search: '/\[breaking\]/g'
+ replace: ''
+
+template: |
+ # What's Changed
+
+ $CHANGES
+
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
new file mode 100644
index 0000000..435f579
--- /dev/null
+++ b/.github/workflows/ci.yaml
@@ -0,0 +1,46 @@
+name: CI
+
+on:
+ push:
+ branches: [master, main]
+ pull_request:
+ branches: [master, main]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ java: [ '17', '21', '25' ]
+ steps:
+ - run: env
+ shell: bash
+ - uses: actions/checkout@v6
+ - uses: sbt/setup-sbt@v1
+ - uses: coursier/cache-action@v8
+ - uses: actions/setup-java@v5
+ with:
+ distribution: temurin
+ java-version: ${{ matrix.java }}
+ check-latest: true
+ - name: tests
+ run: |
+ sbt clean test
+
+ formatting:
+ runs-on: ubuntu-latest
+ steps:
+ - run: env
+ shell: bash
+ - uses: actions/checkout@v6
+ - uses: sbt/setup-sbt@v1
+ - uses: coursier/cache-action@v8
+ - uses: actions/setup-java@v5
+ with:
+ distribution: temurin
+ java-version: 17
+ check-latest: true
+ - name: Formatting
+ run: |
+ sbt scalafmtSbtCheck scalafmtCheck test:scalafmtCheck
\ No newline at end of file
diff --git a/.github/workflows/draft.yml b/.github/workflows/draft.yml
new file mode 100644
index 0000000..1adb557
--- /dev/null
+++ b/.github/workflows/draft.yml
@@ -0,0 +1,26 @@
+name: Release Drafter
+
+on:
+ push:
+ branches:
+ - main
+
+ pull_request:
+ types: [opened, reopened, synchronize]
+
+permissions:
+ contents: read
+
+jobs:
+ update_release_draft:
+ runs-on: ubuntu-latest
+ permissions:
+ # write permission is required to create a github release
+ contents: write
+ # write permission is required for autolabeler
+ # otherwise, read permission is required at least
+ pull-requests: write
+ steps:
+ - uses: release-drafter/release-drafter@v7.1.1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..5c06996
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,32 @@
+name: Release
+
+on:
+ push:
+ branches: [master, main]
+ release:
+ types: [ published ]
+
+env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+jobs:
+ publish:
+ runs-on: ubuntu-latest
+ steps:
+ - run: env
+ shell: bash
+ - uses: actions/checkout@v6
+ - uses: sbt/setup-sbt@v1
+ - uses: coursier/cache-action@v8
+ - uses: olafurpg/setup-gpg@v3
+ - uses: actions/setup-java@v5
+ with:
+ distribution: temurin
+ java-version: 17
+ check-latest: true
+ - run: sbt ci-release
+ env:
+ PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
+ PGP_SECRET: ${{ secrets.PGP_SECRET }}
+ SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
+ SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
diff --git a/.github/workflows/scala-steward.yml b/.github/workflows/scala-steward.yml
new file mode 100644
index 0000000..21f649c
--- /dev/null
+++ b/.github/workflows/scala-steward.yml
@@ -0,0 +1,20 @@
+name: Scala Steward
+
+# This workflow will launch everyday at 00:00
+on:
+ schedule:
+ - cron: '0 0 * * *'
+ workflow_dispatch: {}
+
+jobs:
+ scala-steward:
+ timeout-minutes: 45
+ runs-on: ubuntu-latest
+ name: Scala Steward
+ steps:
+ - uses: sbt/setup-sbt@v1
+ - name: Scala Steward
+ uses: scala-steward-org/scala-steward-action@v2.86.0
+ with:
+ github-repository: ${{ github.repository }}
+ github-token: ${{ secrets.SCALA_STEWARD }}
\ No newline at end of file
diff --git a/.jvmopts b/.jvmopts
new file mode 100644
index 0000000..e0c699f
--- /dev/null
+++ b/.jvmopts
@@ -0,0 +1,11 @@
+# This is a comment
+-Dfile.encoding=UTF8
+-Xms128M
+-Xmx4G
+-Xss16M
+-XX:+UseG1GC
+--add-opens=java.base/java.util=ALL-UNNAMED
+--add-opens=java.base/java.lang=ALL-UNNAMED
+--add-exports=java.base/sun.nio.ch=ALL-UNNAMED
+--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED
+--enable-native-access=ALL-UNNAMED # Removes some warnings when starting sbt on JDK25+
\ No newline at end of file
diff --git a/.scalafix.conf b/.scalafix.conf
new file mode 100644
index 0000000..e4a9e39
--- /dev/null
+++ b/.scalafix.conf
@@ -0,0 +1,22 @@
+rules = [
+ DisableSyntax
+ // ExplicitResultTypes // Waiting for: https://github.com/scalacenter/scalafix/issues/1583
+ LeakingImplicitClassVal
+ NoAutoTupling
+ NoValInForComprehension
+ OrganizeImports
+ RemoveUnused
+ RedundantSyntax
+]
+
+DisableSyntax.regex = []
+DisableSyntax.noReturns = true
+DisableSyntax.noXml = true
+DisableSyntax.noFinalize = true
+
+// Preset rules compatible with Intellij IDEA
+// See: https://scalacenter.github.io/scalafix/docs/rules/OrganizeImports.html#intellij_2020_3
+OrganizeImports {
+ preset = INTELLIJ_2020_3
+ targetDialect = Scala3
+}
diff --git a/.scalafmt.conf b/.scalafmt.conf
index 4068f5d..0ff23f6 100644
--- a/.scalafmt.conf
+++ b/.scalafmt.conf
@@ -1,2 +1,31 @@
-style = defaultWithAlign
-maxColumn = 120
+version = "3.10.7"
+runner.dialect = scala3 # https://scalameta.org/scalafmt/docs/configuration.html#scala-3
+runner.dialectOverride.allowSignificantIndentation = false # See https://x.com/ghostdogpr/status/1706589471469425074
+maxColumn = 140
+align.preset = most
+continuationIndent.defnSite = 2
+assumeStandardLibraryStripMargin = true
+docstrings.style = Asterisk
+lineEndings = preserve
+includeCurlyBraceInSelectChains = true
+danglingParentheses.preset = true
+optIn.annotationNewlines = true
+newlines.alwaysBeforeMultilineDef = false
+newlines.implicitParamListModifierPrefer = before
+trailingCommas = keep
+docstrings.wrap = no
+
+rewrite.rules = [RedundantBraces, SortModifiers]
+
+rewrite.sortModifiers.order = [
+ "implicit", "override", "private", "protected", "final", "sealed", "abstract", "lazy"
+]
+rewrite.redundantBraces.generalExpressions = false
+rewrite.redundantBraces.stringInterpolation = true
+rewriteTokens = {
+ "⇒": "=>"
+ "→": "->"
+ "←": "<-"
+}
+
+project.excludePaths = []
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b4f13d9..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-sudo: false
-language: scala
-scala:
- - 2.12.8
-script:
- - sbt ++$TRAVIS_SCALA_VERSION clean coverage test coverageReport
-jdk:
- - openjdk8
- - openjdk11
-
-after_success:
- - bash <(curl -s https://codecov.io/bash)
\ No newline at end of file
diff --git a/README.md b/README.md
index a982127..0819190 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,5 @@
# JRubyConcurrentConstantMemoryExcel
-[](https://travis-ci.org/Colisweb/JRubyConcurrentConstantMemoryExcel)
-[](https://codecov.io/gh/Colisweb/JRubyConcurrentConstantMemoryExcel)
-
Goal
----
diff --git a/build.sbt b/build.sbt
index f3ca217..ba9da14 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,91 +1,68 @@
-ThisBuild / organization := "com.colisweb"
-ThisBuild / scalaVersion := "2.12.8"
-ThisBuild / scalafmtOnCompile := true
-ThisBuild / scalafmtCheck := true
-ThisBuild / scalafmtSbtCheck := true
+import BuildHelper.*
-lazy val projectName = "JRubyConcurrentConstantMemoryExcel"
+ThisBuild / organization := "com.guizmaii"
+ThisBuild / scalaVersion := "2.13.18"
+
+ThisBuild / scalafmtCheck := true
+ThisBuild / scalafmtSbtCheck := true
+ThisBuild / scalafmtOnCompile := !insideCI.value
+ThisBuild / semanticdbEnabled := true
+ThisBuild / semanticdbVersion := scalafixSemanticdb.revision // use Scalafix compatible version
+
+ThisBuild / licenses := Seq("MIT" -> url("https://opensource.org/licenses/MIT"))
+ThisBuild / homepage := Some(url("https://github.com/guizmaii-opensource/JRubyConcurrentConstantMemoryExcel"))
+
+Global / onChangedBuildSource := ReloadOnSourceChanges
+
+// ### Aliases ###
+
+addCommandAlias("fmt", "scalafmt;scalafixAll")
+addCommandAlias("tc", "Test/compile")
+addCommandAlias("ctc", "clean; tc")
+addCommandAlias("rctc", "reload; ctc")
+
+// ### Dependencies ###
lazy val testKitLibs = Seq(
- "org.scalacheck" %% "scalacheck" % "1.14.0",
- "org.scalactic" %% "scalactic" % "3.0.7",
- "org.scalatest" %% "scalatest" % "3.0.7",
+ "org.scalacheck" %% "scalacheck" % "1.19.0",
+ "org.scalactic" %% "scalactic" % "3.2.20",
+ "org.scalatest" %% "scalatest" % "3.2.20",
).map(_ % Test)
lazy val poi =
- ((version: String) =>
- Seq(
- "org.apache.poi" % "poi" % version,
- "org.apache.poi" % "poi-ooxml" % version
- ))("4.1.0")
+ (
+ (version: String) =>
+ Seq(
+ "org.apache.poi" % "poi" % version,
+ "org.apache.poi" % "poi-ooxml" % version
+ )
+ )("4.1.0")
lazy val monix =
- ((version: String) =>
- Seq(
- "io.monix" %% "monix-execution" % version,
- "io.monix" %% "monix-eval" % version,
- ))("3.0.0-RC2")
+ (
+ (version: String) =>
+ Seq(
+ "io.monix" %% "monix-execution" % version,
+ "io.monix" %% "monix-eval" % version,
+ )
+ )("3.4.1")
+
+// ### Modules ###
lazy val root =
- Project(id = projectName, base = file("."))
- .settings(moduleName := "root")
- .settings(noPublishSettings: _*)
+ Project(id = "JRubyConcurrentConstantMemoryExcel", base = file("."))
+ .settings(noDoc *)
+ .settings(publish / skip := true)
+ .settings(crossScalaVersions := Nil) // https://www.scala-sbt.org/1.x/docs/Cross-Build.html#Cross+building+a+project+statefully,
.aggregate(core)
- .dependsOn(core)
lazy val core =
project
- .settings(moduleName := projectName)
+ .settings(name := "JRubyConcurrentConstantMemoryExcel")
+ .settings(stdSettings *)
.settings(
libraryDependencies ++= Seq(
- "com.nrinaudo" %% "kantan.csv" % "0.5.0",
- "com.github.pathikrit" %% "better-files" % "3.7.1",
- ) ++ monix ++ poi ++ testKitLibs)
-
-/**
- * Copied from Cats
- */
-lazy val noPublishSettings = Seq(
- publish := {},
- publishLocal := {},
- publishArtifact := false
-)
-
-inThisBuild(
- List(
- credentials += Credentials(Path.userHome / ".bintray" / ".credentials"),
- licenses := Seq("MIT" -> url("http://opensource.org/licenses/MIT")),
- homepage := Some(url("https://github.com/colisweb/JRubyConcurrentConstantMemoryExcel")),
- bintrayOrganization := Some("colisweb"),
- bintrayReleaseOnPublish := true,
- publishMavenStyle := true,
- pomExtra := (
-
- git@github.com:colisweb/JRubyConcurrentConstantMemoryExcel.git
- scm:git:git@github.com:colisweb/JRubyConcurrentConstantMemoryExcel.git
-
-
-
- guizmaii
- Jules Ivanic
-
-
+ "io.github.kantan-scala" %% "kantan.csv" % "0.11.0",
+ "com.github.pathikrit" %% "better-files" % "3.9.2",
+ ) ++ monix ++ poi ++ testKitLibs
)
- )
-)
-
-//// Aliases
-
-/**
- * Copied from kantan.csv
- */
-addCommandAlias("runBenchs", "benchmarks/jmh:run -i 10 -wi 10 -f 2 -t 1")
-
-/**
- * Example of JMH tasks that generate flamegraphs.
- *
- * http://malaw.ski/2017/12/10/automatic-flamegraph-generation-from-jmh-benchmarks-using-sbt-jmh-extras-plain-java-too/
- */
-addCommandAlias(
- "flame93",
- "benchmarks/jmh:run -f1 -wi 10 -i 20 PackerBenchmarkWithRealData -prof jmh.extras.Async:flameGraphOpts=--minwidth,2;verbose=true")
diff --git a/core/src/main/scala/com/colisweb/jruby/concurrent/constant/memory/excel/ConcurrentConstantMemoryExcel.scala b/core/src/main/scala/com/colisweb/jruby/concurrent/constant/memory/excel/ConcurrentConstantMemoryExcel.scala
index b58295e..a5114d9 100644
--- a/core/src/main/scala/com/colisweb/jruby/concurrent/constant/memory/excel/ConcurrentConstantMemoryExcel.scala
+++ b/core/src/main/scala/com/colisweb/jruby/concurrent/constant/memory/excel/ConcurrentConstantMemoryExcel.scala
@@ -1,27 +1,26 @@
package com.colisweb.jruby.concurrent.constant.memory.excel
-import java.io.{File, FileOutputStream}
-import java.nio.file.{Files, Path}
-import java.util.UUID
-
import cats.effect.Resource
import com.colisweb.jruby.concurrent.constant.memory.excel.utils.KantanExtension
import kantan.csv.{CellDecoder, CellEncoder}
import monix.eval.Task
import monix.execution.Scheduler
import monix.execution.atomic.Atomic
-import org.apache.poi.ss.usermodel._
+import org.apache.poi.ss.usermodel.*
import org.apache.poi.ss.util.WorkbookUtil
import org.apache.poi.xssf.streaming.SXSSFWorkbook
-import scala.annotation.switch
+import java.io.{File, FileOutputStream}
+import java.nio.file.{Files, Path}
+import java.util.UUID
+import scala.annotation.{nowarn, switch}
import scala.collection.immutable.SortedSet
import scala.collection.mutable.ListBuffer
import scala.io.Codec
sealed abstract class Cell extends Product with Serializable
object Cell {
- private[excel] final case object BlankCell extends Cell
+ private[excel] case object BlankCell extends Cell
private[excel] final case class StringCell(value: String) extends Cell
private[excel] final case class NumericCell(value: Double) extends Cell
@@ -29,13 +28,13 @@ object Cell {
private[excel] final val STRING_CELL = 's'
private[excel] final val NUMERIC_CELL = 'n'
- private[excel] implicit final val encoder: CellEncoder[Cell] = {
+ implicit private[excel] final val encoder: CellEncoder[Cell] = {
case BlankCell => s"$BLANK_CELL:"
case StringCell(value) => s"$STRING_CELL:$value"
case NumericCell(value) => s"$NUMERIC_CELL:$value"
}
- private[excel] implicit final val decoder: CellDecoder[Cell] =
+ implicit private[excel] final val decoder: CellDecoder[Cell] =
CellDecoder.fromUnsafe { s =>
val Array(cellType, data) = s.split(":", 2)
(cellType(0): @switch) match {
@@ -46,17 +45,19 @@ object Cell {
}
}
+@nowarn // TODO: Remove this nowarm when upgrading to Scala3
final case class Page private[excel] (index: Int, path: Path)
private[excel] object Page {
implicit final val ordering: Ordering[Page] = Ordering.by(_.index)
}
+@nowarn // TODO: Remove this nowarm when upgrading to Scala3
final case class ConcurrentConstantMemoryState private[excel] (
- sheetName: String,
- headerData: Array[String],
- tmpDirectory: File,
- tasks: List[Task[Unit]],
- pages: SortedSet[Page]
+ sheetName: String,
+ headerData: Array[String],
+ tmpDirectory: File,
+ tasks: List[Task[Unit]],
+ pages: SortedSet[Page]
)
object ConcurrentConstantMemoryExcel {
@@ -68,8 +69,8 @@ object ConcurrentConstantMemoryExcel {
private[excel] type Row = Array[Cell]
- private[this] implicit final val codec: Codec = Codec.UTF8
- private[this] implicit final val scheduler: Scheduler =
+ implicit private[this] final val codec: Codec = Codec.UTF8
+ implicit private[this] final val scheduler: Scheduler =
Scheduler.computation(name = "ConcurrentConstantMemoryExcel-computation")
final val blankCell: Cell = Cell.BlankCell
@@ -90,9 +91,9 @@ object ConcurrentConstantMemoryExcel {
)
final def addRows(
- atomicCms: Atomic[ConcurrentConstantMemoryState],
- computeRows: => Array[Row],
- pageIndex: Int
+ atomicCms: Atomic[ConcurrentConstantMemoryState],
+ computeRows: => Array[Row],
+ pageIndex: Int
): Unit = {
import KantanExtension.arrayEncoder
@@ -127,24 +128,23 @@ object ConcurrentConstantMemoryExcel {
}
var rowIndex = 1 // `1` is because the row 0 is already written (header)
- cms.pages.foreach {
- case Page(_, path) =>
- path
- .unsafeReadCsv[ListBuffer, ListBuffer[Cell]](rfc)
- .foreach { rowData =>
- val row = sheet.createRow(rowIndex)
- rowIndex += 1
-
- for ((cellData, cellIndex) <- rowData.zipWithIndex) {
- cellData match {
- case Cell.BlankCell => row.createCell(cellIndex, CellType.BLANK)
- case Cell.NumericCell(value) => row.createCell(cellIndex, CellType.NUMERIC).setCellValue(value)
- case Cell.StringCell(value) => row.createCell(cellIndex, CellType.STRING).setCellValue(value)
- }
+ cms.pages.foreach { case Page(_, path) =>
+ path
+ .unsafeReadCsv[ListBuffer, ListBuffer[Cell]](rfc)
+ .foreach { rowData =>
+ val row = sheet.createRow(rowIndex)
+ rowIndex += 1
+
+ for ((cellData, cellIndex) <- rowData.zipWithIndex) {
+ cellData match {
+ case Cell.BlankCell => row.createCell(cellIndex, CellType.BLANK)
+ case Cell.NumericCell(value) => row.createCell(cellIndex, CellType.NUMERIC).setCellValue(value)
+ case Cell.StringCell(value) => row.createCell(cellIndex, CellType.STRING).setCellValue(value)
}
}
+ }
- sheet.flushRows()
+ sheet.flushRows()
}
}
@@ -157,18 +157,18 @@ object ConcurrentConstantMemoryExcel {
// Used as a Resource to ease the clean of the temporary CSVs created during the tasks calcultation.
val computeIntermediateTmpCsvFiles: Resource[Task, Unit] =
- Resource.make(Task.gatherUnordered(cms.tasks).flatMap(_ => Task.unit))(_ => clean())
+ Resource.make(Task.parSequenceUnordered(cms.tasks).flatMap(_ => Task.unit))(_ => clean())
val workbookResource: Resource[Task, SXSSFWorkbook] =
Resource.make {
// We'll manually manage the `flush` to the hard drive.
Task(new SXSSFWorkbook(-1))
- } { wb: SXSSFWorkbook =>
+ }((wb: SXSSFWorkbook) =>
Task {
wb.dispose() // dispose of temporary files backing this workbook on disk. Necessary because not done in the `close()`. See: https://stackoverflow.com/a/50363245
wb.close()
}
- }
+ )
val fileOutputStreamResource: Resource[Task, FileOutputStream] =
Resource.make(Task(new FileOutputStream(fileName)))(out => Task(out.close()))
diff --git a/core/src/main/scala/com/colisweb/jruby/concurrent/constant/memory/excel/utils/KantanExtension.scala b/core/src/main/scala/com/colisweb/jruby/concurrent/constant/memory/excel/utils/KantanExtension.scala
index 90fa940..f42ba81 100644
--- a/core/src/main/scala/com/colisweb/jruby/concurrent/constant/memory/excel/utils/KantanExtension.scala
+++ b/core/src/main/scala/com/colisweb/jruby/concurrent/constant/memory/excel/utils/KantanExtension.scala
@@ -2,9 +2,11 @@ package com.colisweb.jruby.concurrent.constant.memory.excel.utils
import kantan.csv.{CellEncoder, RowEncoder}
+import scala.collection.immutable.ArraySeq
+
private[excel] object KantanExtension {
implicit final def arrayEncoder[A](implicit CellEncoder: CellEncoder[A]): RowEncoder[Array[A]] =
- (array: Array[A]) => array.map(CellEncoder.encode)
+ (array: Array[A]) => ArraySeq.unsafeWrapArray(array).map(CellEncoder.encode)
}
diff --git a/core/src/test/scala/com/colisweb/jruby/concurrent/constant/memory/excel/ConcurrentConstantMemoryExcelSpec.scala b/core/src/test/scala/com/colisweb/jruby/concurrent/constant/memory/excel/ConcurrentConstantMemoryExcelSpec.scala
index f0a5998..98900ee 100644
--- a/core/src/test/scala/com/colisweb/jruby/concurrent/constant/memory/excel/ConcurrentConstantMemoryExcelSpec.scala
+++ b/core/src/test/scala/com/colisweb/jruby/concurrent/constant/memory/excel/ConcurrentConstantMemoryExcelSpec.scala
@@ -1,13 +1,16 @@
package com.colisweb.jruby.concurrent.constant.memory.excel
+import monix.execution.atomic.Atomic
+import org.scalatest.flatspec.AnyFlatSpec
+import org.scalatest.matchers.should.Matchers
+
import java.io.File
import java.nio.file.Files
import java.util.Date
+import scala.annotation.nowarn
-import monix.execution.atomic.Atomic
-import org.scalatest.{FlatSpec, Matchers}
-
-class ConcurrentConstantMemoryExcelSpec extends FlatSpec with Matchers {
+@nowarn("msg=unused value")
+class ConcurrentConstantMemoryExcelSpec extends AnyFlatSpec with Matchers {
"true" should "be true" in {
true shouldBe true
diff --git a/project/BuildHelper.scala b/project/BuildHelper.scala
new file mode 100644
index 0000000..a123da2
--- /dev/null
+++ b/project/BuildHelper.scala
@@ -0,0 +1,34 @@
+import _root_.org.typelevel.sbt.tpolecat.TpolecatPlugin.autoImport.*
+import org.typelevel.scalacoptions.ScalacOptions
+import sbt.*
+import sbt.Keys.*
+
+object BuildHelper {
+
+ private val javaTarget = "17"
+
+ def env(v: String): Option[String] = sys.env.get(v)
+ def unsafeEnv(v: String): String = sys.env(v)
+
+ lazy val stdSettings =
+ Seq(
+ javacOptions ++= Seq("-source", javaTarget, "-target", javaTarget),
+ scalacOptions ++= Seq("-Xsource:3"), // TODO: Remove when upgrading to Scala3
+ // TODO: Re-enable when upgrading to Scala3
+ // scalacOptions ++= Seq("-no-indent"), // See https://x.com/ghostdogpr/status/1706589471469425074
+ // TODO: Re-enable when upgrading to Scala3
+ // scalacOptions ++= Seq("-language:noAutoTupling"), // See https://github.com/scala/scala3/discussions/19255
+ scalacOptions ++= Seq(s"-release:$javaTarget"),
+ scalacOptions --= (if (insideCI.value) Nil else Seq("-Xfatal-warnings")),
+ // format: off
+ tpolecatScalacOptions ++= Set(
+ ScalacOptions.privateBackendParallelism(), // See https://github.com/typelevel/sbt-tpolecat/blob/main/plugin/src/main/scala/io/github/davidgregory084/ScalacOptions.scala#L409-L424
+ ),
+ // format: on
+ )
+
+ lazy val noDoc = Seq(
+ (Compile / doc / sources) := Seq.empty,
+ (Compile / packageDoc / publishArtifact) := false
+ )
+}
diff --git a/project/build.properties b/project/build.properties
index c03cdb8..15e8f67 100644
--- a/project/build.properties
+++ b/project/build.properties
@@ -1 +1 @@
-sbt.version = 1.2.7
\ No newline at end of file
+sbt.version = 1.12.7
diff --git a/project/plugins.sbt b/project/plugins.sbt
index 114adce..43b730d 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -1,10 +1,6 @@
-resolvers += Resolver.bintrayRepo("colisweb", "sbt-plugins")
-
-addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.3")
-addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.3.4")
-addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.6.0-RC1")
-addSbtPlugin("io.github.davidgregory084" % "sbt-tpolecat" % "0.1.4")
-addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.3.4")
-addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1")
-addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.10")
-addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.4")
+addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.6.4")
+addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.6")
+addSbtPlugin("org.scoverage" % "sbt-scoverage" % "2.4.4")
+addSbtPlugin("org.typelevel" % "sbt-tpolecat" % "0.5.3")
+addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.11.2")
+addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.14.6")
diff --git a/version.sbt b/version.sbt
deleted file mode 100644
index 47af175..0000000
--- a/version.sbt
+++ /dev/null
@@ -1 +0,0 @@
-version in ThisBuild := "1.0.5-SNAPSHOT"