Skip to content

Commit

Permalink
Port to Scala 3 (with newly released scalafmt)
Browse files Browse the repository at this point in the history
* Port to Scala 3

* Refactor reference package object

* Convert package objects to toplevel

* Set Scala 3 rewrite rules

* Run scalafmt

* Update copyright

* Set version to 3.12.0-SNAPSHOT

* Update changelog

* Update GH actions

* Workaround for scalafmt issue

See scalameta/scalafmt#3787
  • Loading branch information
mtomko authored Feb 22, 2024
1 parent 5727164 commit f119692
Show file tree
Hide file tree
Showing 142 changed files with 1,466 additions and 1,855 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: jrouly/scalafmt-native-action@v3
with:
version: "3.8.0"
- name: Set up JDK 8
uses: actions/setup-java@v4
with:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ jobs:
- run: git config --global user.email "[email protected]"
- run: git config --global user.name "GPP Informatics"
- uses: jrouly/scalafmt-native-action@v3
with:
version: "3.8.0"
- name: Set up JDK 8
uses: actions/setup-java@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .scalafix.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ OrganizeImports {
expandRelative = true
groups = ["re:javax?\\.", "scala.", "*"]
groupedImports = Merge
removeUnused = true
removeUnused = false
}
14 changes: 12 additions & 2 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# PoolQ3 .scalafmt configuration
version=3.7.17
version=3.8.0
runner.dialect = scala3

# work around https://github.com/scalameta/scalafmt/issues/3787
fileOverride {
"glob:**.sbt" {
runner.dialect = sbt1
}
}
style = IntelliJ

maxColumn = 120
Expand All @@ -14,4 +22,6 @@ rewrite.redundantBraces.generalExpressions = false
rewrite.redundantBraces.includeUnitMethods = false
rewrite.redundantBraces.maxBreaks = 16
rewrite.redundantBraces.stringInterpolation = true
runner.dialect = scala213source3
rewrite.scala3.convertToNewSyntax = true
rewrite.scala3.removeOptionalBraces = oldSyntaxToo
rewrite.scala3.insertEndMarkerMinLines = 8
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 3.12.0
* Update to Scala 3.3.1

## 3.11.0
* Machine-parseable condition barcode summary file

Expand Down
25 changes: 8 additions & 17 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,37 @@ val artifactId = "poolq"

inThisBuild(
List(
scalaVersion := "2.13.11",
scalaVersion := "3.3.1",
semanticdbEnabled := true,
semanticdbVersion := scalafixSemanticdb.revision,
versionScheme := Some("early-semver")
)
)

lazy val versions = new {
val acyclic = "0.2.1"
val betterFiles = "3.9.2"
val betterMonadicFor = "0.3.1"
val catsEffect3 = "3.5.2"
val catsEffect3 = "3.5.3"
val cats = "2.10.0"
val commonsIo = "2.15.1"
val commonsText = "1.11.0"
val commonsMath3 = "3.6.1"
val fastutil = "8.5.12"
val fs2 = "3.9.3"
val fastutil = "8.5.13"
val fs2 = "3.9.4"
val log4s = "1.10.0"
val logback = "1.2.13"
val munit = "0.7.29"
val munitCatsEffect3 = "1.0.7"
val samTools = "3.0.5"
val scalaCheck = "1.17.0"
val scalaCsv = "1.3.10"
val scalaTest = "3.2.17"
val scalaTestPlusScalaCheck = "3.2.2.0"
val scalaTest = "3.2.18"
val scalaTestPlusScalaCheck = "3.2.18.0"
val scopt = "4.1.0"
val slf4j = "1.7.36"
}

lazy val libraries = new {
val acyclic = "com.lihaoyi" %% "acyclic" % versions.acyclic
val betterFiles = "com.github.pathikrit" %% "better-files" % versions.betterFiles
val betterMonadicFor = "com.olegpy" %% "better-monadic-for" % versions.betterMonadicFor
val cats = "org.typelevel" %% "cats-core" % versions.cats
val catsEffect3 = "org.typelevel" %% "cats-effect" % versions.catsEffect3
val commonsIo = "commons-io" % "commons-io" % versions.commonsIo
Expand All @@ -59,12 +55,11 @@ lazy val libraries = new {
val munitCatsEffect3 = "org.typelevel" %% "munit-cats-effect-3" % versions.munitCatsEffect3
val scalaTest = "org.scalatest" %% "scalatest" % versions.scalaTest
val scalaCheck = "org.scalacheck" %% "scalacheck" % versions.scalaCheck
val scalaTestPlusScalaCheck = "org.scalatestplus" %% "scalacheck-1-14" % versions.scalaTestPlusScalaCheck
val scalaTestPlusScalaCheck = "org.scalatestplus" %% "scalacheck-1-17" % versions.scalaTestPlusScalaCheck
}

lazy val dependencies =
List(
libraries.acyclic % "provided",
libraries.cats,
libraries.commonsIo,
libraries.commonsMath3,
Expand All @@ -90,7 +85,7 @@ lazy val dependencies =
)

lazy val headerLicenseText =
"""|Copyright (c) 2022 The Broad Institute, Inc. All rights reserved.
"""|Copyright (c) 2024 The Broad Institute, Inc. All rights reserved.
|
|SPDX-License-Identifier: BSD-3-Clause
|""".stripMargin
Expand Down Expand Up @@ -130,13 +125,9 @@ lazy val poolq = project
name := "poolq3",
organization := "org.broadinstitute.gpp",
libraryDependencies := dependencies,
scalacOptions ++= List("-P:acyclic:force", "-Xsource:3"),
buildInfoKeys := Seq[BuildInfoKey](name, version),
buildInfoPackage := "org.broadinstitute.gpp.poolq3",
addCompilerPlugin(libraries.acyclic),
addCompilerPlugin(libraries.betterMonadicFor),
testFrameworks += new TestFramework("munit.Framework"),
scalacOptions += "-Yrangepos", // ensure munit clues work
// Tests pass in parallel, but SLF4J logging behaves weirdly. Disable this flag to examine test
// log output; leave this enabled for very fast test execution.
Test / parallelExecution := true
Expand Down
46 changes: 23 additions & 23 deletions src/main/scala/org/broadinstitute/gpp/poolq3/PoolQ.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 The Broad Institute, Inc. All rights reserved.
* Copyright (c) 2024 The Broad Institute, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
Expand All @@ -9,7 +9,7 @@ import java.nio.file.{Files, Path}

import scala.util.{Failure, Success, Try, Using}

import cats.syntax.all._
import cats.syntax.all.*
import org.broadinstitute.gpp.poolq3.PoolQConfig.synthesizeArgs
import org.broadinstitute.gpp.poolq3.barcode.{BarcodePolicy, Barcodes, barcodeSource}
import org.broadinstitute.gpp.poolq3.parser.{BarcodeSet, CloseableIterable, ReferenceData}
Expand All @@ -20,7 +20,7 @@ import org.broadinstitute.gpp.poolq3.process.{
ScoringConsumer,
UnexpectedSequenceTracker
}
import org.broadinstitute.gpp.poolq3.reference.{ExactReference, Reference, referenceFor}
import org.broadinstitute.gpp.poolq3.reference.{ExactReference, Reference}
import org.broadinstitute.gpp.poolq3.reports.{
BarcodeCountsWriter,
CorrelationFileWriter,
Expand All @@ -45,7 +45,7 @@ import org.broadinstitute.gpp.poolq3.types.{
}
import org.log4s.{Logger, getLogger}

object PoolQ {
object PoolQ:

private[this] val log: Logger = getLogger

Expand All @@ -60,19 +60,17 @@ object PoolQ {
)

final def main(args: Array[String]): Unit =
PoolQConfig.parse(args) match {
PoolQConfig.parse(args) match
case None => System.exit(-1)
case Some(config) =>
run(config) match {
run(config) match
case Success(_) => // do nothing
case Failure(t) =>
log.error(t)("PoolQ failed")
System.exit(-1)
}
}

/** The main entry point for PoolQ3 as an API */
final def run(config: PoolQConfig): Try[PoolQSummary] = {
final def run(config: PoolQConfig): Try[PoolQSummary] =
log.info(s"PoolQ version: ${BuildInfo.version}")
logCli(config)

Expand Down Expand Up @@ -108,7 +106,7 @@ object PoolQ {

log.info("Building row reference")
val rowReference: Reference =
referenceFor(
Reference(
config.rowMatchFn,
ReferenceData.truncator(rowBarcodeLength),
config.countAmbiguous,
Expand All @@ -118,7 +116,7 @@ object PoolQ {
log.info("Building column reference")
val colBarcodeLength = colBarcodePolicyOpt.map(_.length).getOrElse(colReferenceData.barcodeLength)
val colReference: Reference =
referenceFor(
Reference(
config.colMatchFn,
ReferenceData.truncator(colBarcodeLength),
config.countAmbiguous,
Expand All @@ -136,21 +134,20 @@ object PoolQ {
barcodeSource(config.input, rowBarcodePolicy, revRowBarcodePolicyOpt, colBarcodePolicyOrLength, umiInfo.map(_._2))

lazy val unexpectedSequenceCacheDirOpt: Option[Path] =
if (config.skipUnexpectedSequenceReport) None
else {
if config.skipUnexpectedSequenceReport then None
else
val ret = config.unexpectedSequenceCacheDir.map(Files.createDirectories(_)).orElse {
val ret: Path = Files.createTempDirectory("unexpected-sequence-cache")
Some(ret)
}
ret.foreach(path => log.info(s"Writing unexpected sequence cache files to $path"))
ret
}

lazy val unexpectedSequenceTrackerOpt: Option[UnexpectedSequenceTracker] =
unexpectedSequenceCacheDirOpt.map(new UnexpectedSequenceTracker(_, colReference))

val consumer =
if (config.noopConsumer) new NoOpConsumer
if config.noopConsumer then new NoOpConsumer
else
new ScoringConsumer(
rowReference,
Expand All @@ -162,7 +159,7 @@ object PoolQ {
config.isPairedEnd
)

for {
for
runSummary <- runProcess(barcodes, consumer)
state = runSummary.state
counts = state.known
Expand Down Expand Up @@ -220,17 +217,19 @@ object PoolQ {
config.unexpectedSequenceMaxSampleSize
)
.as(UnexpectedSequencesFileType.some)
if (config.removeUnexpectedSequenceCache) {
if config.removeUnexpectedSequenceCache then
log.info(s"Removing unexpected sequence cache ${config.unexpectedSequenceCacheDir}")
UnexpectedSequenceWriter.removeCache(dir)
}
ret
}
_ = log.info(s"Writing run info ${config.output.unexpectedSequencesFile}")
_ <- RunInfoWriter.write(config.output.runInfoFile, config)
_ = log.info("PoolQ complete")
} yield PoolQSummary(runSummary, AlwaysWrittenFiles ++ Set(cfto, usfto).flatten)
}
yield PoolQSummary(runSummary, AlwaysWrittenFiles ++ Set(cfto, usfto).flatten)

end for

end run

def runProcess(barcodes: CloseableIterable[Barcodes], consumer: Consumer): Try[PoolQRunSummary] =
Using(barcodes.iterator) { iterator =>
Expand All @@ -257,7 +256,7 @@ object PoolQ {
(rowBarcodePolicy, None, rowBarcodePolicy.length)
}

private[this] def logCli(config: PoolQConfig): Unit = {
private[this] def logCli(config: PoolQConfig): Unit =
val logStr =
synthesizeArgs(config)
.map {
Expand All @@ -266,6 +265,7 @@ object PoolQ {
}
.mkString(" \\\n")
log.info(s"PoolQ command-line settings:\n$logStr")
}

}
end logCli

end PoolQ
Loading

0 comments on commit f119692

Please sign in to comment.