Skip to content

Commit

Permalink
WIP: Scala 2.13 support
Browse files Browse the repository at this point in the history
  • Loading branch information
35VLG84 committed Jul 3, 2019
1 parent 3140123 commit c452b38
Show file tree
Hide file tree
Showing 16 changed files with 161 additions and 27 deletions.
2 changes: 1 addition & 1 deletion api/src/main/scala/fi/e257/tackler/api/GeoPoint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class GeoPoint protected (val lat: BigDecimal, val lon: BigDecimal, val alt: Opt

object GeoPoint {
def frmt(v: BigDecimal): String = {
s"%.${v.scale}f".format(v)
f"""%%.${v.scale}%df""".format(v)
}

/**
Expand Down
46 changes: 42 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import Dependencies._

import sbtcrossproject.{crossProject, CrossType}

lazy val scala_12 = "2.12.8"
lazy val scala_13 = "2.13.0"
lazy val supportedScalaVersions = List(scala_12, scala_13)

lazy val noPublishSettings = Seq(
publish := {},
publishLocal := {},
Expand All @@ -28,7 +32,8 @@ lazy val noPublishSettings = Seq(
lazy val commonSettings = Seq(
organization := "fi.e257",
version := "0.32.0-SNAPSHOT",
scalaVersion := "2.12.8",
scalaVersion := scala_13,
crossScalaVersions := supportedScalaVersions,
compileOrder := CompileOrder.JavaThenScala,
scalacOptions ++= Seq(
"-deprecation",
Expand All @@ -37,19 +42,38 @@ lazy val commonSettings = Seq(
"-feature",
"-unchecked",
"-Xcheckinit",
"-Xfatal-warnings",
"-Xlint",
"-Ywarn-dead-code",
"-Ywarn-extra-implicit",
"-Ywarn-numeric-widen",
"-Ywarn-unused:implicits",
"-Ywarn-unused:imports",
"-Ywarn-unused:locals",
"-Ywarn-unused:params",
"-Ywarn-unused:patvars",
"-Ywarn-unused:privates",
"-Ywarn-value-discard"
),
scalacOptions ++= {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 12)) =>
Seq(
//"-Xfatal-warnings",
// These won't work with 2.13
"-Ywarn-inaccessible",
"-Ywarn-infer-any",
"-Ywarn-nullary-override",
"-Ywarn-nullary-unit",
"-Yno-adapted-args",
"-Ypartial-unification",
)
case Some((2, 13)) =>
Seq(
// WIP: Disable fatal-warnings for Scala 2.13 "-Xfatal-warnings",
"-Ywarn-unused:imports",
)
case _ => Nil
}
},
Compile / console / scalacOptions --= Seq(
"-Ywarn-unused:imports",
"-Xfatal-warnings"
Expand All @@ -73,6 +97,8 @@ lazy val tackler = (project in file(".")).
settings(noPublishSettings).
settings(commonSettings: _*).
settings(
// crossScalaVersions must be set to Nil on the aggregating project
crossScalaVersions := Nil,
run / fork := true
)

Expand Down Expand Up @@ -116,8 +142,19 @@ lazy val core = (project in file("core")).
libraryDependencies ++= circe_deps,
libraryDependencies += typesafeConfig,
libraryDependencies += jgit,
libraryDependencies += scalaCollCompat,
libraryDependencies ++= {
CrossVersion.partialVersion(scalaVersion.value) match {
case Some((2, 12)) =>
circe_deps_test
case Some((2, 13)) =>
// workaround until Monocle and Circe-Optics are released for Scala 2.13
// circe_deps_tests
Seq("org.scala-lang.modules" %% "scala-parallel-collections" % "0.2.0")
case _ => Nil
}
},
libraryDependencies += scalatest % "it,test",
libraryDependencies ++= circe_deps_test,
)

val gitCommitId = SettingKey[String]("gitCommit")
Expand Down Expand Up @@ -168,6 +205,7 @@ lazy val cli = (project in file("cli")).
libraryDependencies += scallop,
libraryDependencies += typesafeConfig,
libraryDependencies += logback,
libraryDependencies += scalaCollCompat,
libraryDependencies += scalatest % "it,test",
libraryDependencies += dirsuite % "it,test"
)
Expand Down
8 changes: 4 additions & 4 deletions cli/src/main/scala/fi/e257/tackler/cli/TacklerCli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import fi.e257.tackler.core._
import fi.e257.tackler.model.TxnData
import fi.e257.tackler.parser.{TacklerParseException, TacklerTxns}
import fi.e257.tackler.report.Reports
import io.circe
import io.circe.parser.decode
import org.slf4j.{Logger, LoggerFactory}

Expand Down Expand Up @@ -135,7 +136,7 @@ object TacklerCli {
def runExceptions(args: Array[String]): Unit = {
val tsStart = System.currentTimeMillis()

val cliCfg = new TacklerCliArgs(args)
val cliCfg = new TacklerCliArgs(args.toIndexedSeq)
val settings = Settings(getCfgPath(cliCfg.cfg.toOption), cliCfg.toConfig)

val output: Option[Path] = cliCfg.output.toOption.map(o => settings.getPathWithSettings(o))
Expand Down Expand Up @@ -174,10 +175,9 @@ object TacklerCli {
decode[TxnFilterDefinition](filterStr)
}

if (jsonDecodeResult.isLeft) {
val err = jsonDecodeResult.left.get
jsonDecodeResult.left.foreach[circe.Error](err => {
throw new TxnException("JSON parse error: " + err.getMessage())
}
})

jsonDecodeResult.toOption.map(txnFilterRoot => {
txnDataAll.filter(txnFilterRoot)
Expand Down
15 changes: 9 additions & 6 deletions cli/src/main/scala/fi/e257/tackler/cli/TacklerCliArgs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import com.typesafe.config.{Config, ConfigFactory, ConfigValueFactory}
import org.rogach.scallop.exceptions.{Help, ScallopException, Version}
import org.rogach.scallop.{ScallopConf, ScallopOption}

import scala.collection.JavaConverters
// TODO: Switch to scala.jdk when this is released
// https://github.com/scala/scala-collection-compat/pull/217
// import scala.jdk.CollectionConverters._
import fi.e257.tackler.JDKCollectionConvertersCompat.Converters._

import fi.e257.tackler.core.CfgKeys

Expand Down Expand Up @@ -58,7 +61,7 @@ class TacklerCliArgs(args: Seq[String]) extends ScallopConf(args) {

val optsAsMap: Map[String, String] = opts.flatMap(o => opt2MapItem(o)).toMap

ConfigFactory.parseMap(JavaConverters.mapAsJavaMap(optsAsMap))
ConfigFactory.parseMap(optsAsMap.asJava)
}

version(TacklerCli.version())
Expand Down Expand Up @@ -117,7 +120,7 @@ class TacklerCliArgs(args: Seq[String]) extends ScallopConf(args) {
case Some(reports) =>
stringArgsConf.withValue(
CfgKeys.reporting_reports,
ConfigValueFactory.fromIterable(JavaConverters.asJavaIterable(reports)))
ConfigValueFactory.fromIterable(reports.asJava))
case None =>
stringArgsConf
}
Expand All @@ -126,7 +129,7 @@ class TacklerCliArgs(args: Seq[String]) extends ScallopConf(args) {
case Some(exports) =>
reportsConfig.withValue(
CfgKeys.reporting_exports,
ConfigValueFactory.fromIterable(JavaConverters.asJavaIterable(exports)))
ConfigValueFactory.fromIterable(exports.asJava))
case None =>
reportsConfig
}
Expand All @@ -135,7 +138,7 @@ class TacklerCliArgs(args: Seq[String]) extends ScallopConf(args) {
case Some(accounts) =>
exportsConfig.withValue(
CfgKeys.reporting_accounts,
ConfigValueFactory.fromIterable(JavaConverters.asJavaIterable(accounts)))
ConfigValueFactory.fromIterable(accounts.asJava))
case None =>
exportsConfig
}
Expand All @@ -144,7 +147,7 @@ class TacklerCliArgs(args: Seq[String]) extends ScallopConf(args) {
case Some(formats) =>
reportingAccountsConfig.withValue(
CfgKeys.reporting_formats,
ConfigValueFactory.fromIterable(JavaConverters.asJavaIterable(formats)))
ConfigValueFactory.fromIterable(formats.asJava))
case None =>
reportingAccountsConfig
}
Expand Down
2 changes: 1 addition & 1 deletion cli/src/test/scala/fi/e257/tackler/cli/BuildInfoTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class BuildInfoTest extends FlatSpec {
behavior of "BuildInfo"

it should "scalaVersion" in {
assert(BuildInfo.scalaVersion.startsWith("2.12.8"))
assert(BuildInfo.scalaVersion.startsWith(util.Properties.versionString.substring(8)))
}

it should "name" in {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,18 @@ import fi.e257.tackler.core.Settings
* CLI args and Settings (conf-file).
*/
class TacklerCliSettingsTest extends FlatSpec with Matchers with Inside {
val respath = "core/target/scala-2.12/test-classes/"

val scalaVer = util.Properties.versionString.substring(8,12)
val respath = "core/target/scala-" + scalaVer + "/test-classes/"

it should "respect *ALL* cli args (input.txn)" in {
val absBasepath = File(respath)
val args = Array(
"--basedir", absBasepath.toString, // this must be real path so that --input.fs.dir works correctly with rel-path
"--input.fs.dir", "cli-args-txns/",
"--input.fs.glob", "**/cliargs*.txn"
)
).toIndexedSeq

val cliCfg = new TacklerCliArgs(args)

val settings = Settings(Paths.get("/not/there/cfg.conf"), cliCfg.toConfig)
Expand All @@ -52,7 +55,8 @@ class TacklerCliSettingsTest extends FlatSpec with Matchers with Inside {
"--basedir", absBasepath.toString, // this must be real path so that --input.fs.dir works correctly with rel-path
"--input.file", (absBasepath / "filename.txn").toString,
"--accounts.strict", "false"
)
).toIndexedSeq

val cliCfg = new TacklerCliArgs(args)

val settings = Settings(Paths.get("/not/there/cfg.conf"), cliCfg.toConfig)
Expand All @@ -67,7 +71,8 @@ class TacklerCliSettingsTest extends FlatSpec with Matchers with Inside {
it should "merge configs (cli, ext-conf, embedded conf)" in {
val args = Array(
"--input.fs.glob", "**/cli-args*.txn"
)
).toIndexedSeq

val cliCfg = new TacklerCliArgs(args)

val settings = Settings(Paths.get(respath + "cfg-as-ext-file-rel.conf"), cliCfg.toConfig)
Expand Down
72 changes: 72 additions & 0 deletions core/src/main/scala/fi/e257/tackler/Scala12to13.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2019 E257.FI
*
* Scala12to13 is based on following examples:
* url: https://github.com/scala/scala-parallel-collections/issues/22
* url: https://github.com/scala/scala-collection-compat/issues/208
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package fi.e257.tackler

/**
* author: https://github.com/sjrd
* url: https://github.com/scala/scala-parallel-collections/issues/22#issuecomment-288389306
*/
private[tackler] object Scala12to13 {
val Converters = {
import Compat._

{
import scala.collection.parallel._

CollectionConverters
}
}

object Compat {
object CollectionConverters
}
}

// TODO: Remove when this is released:
// url: https://github.com/scala/scala-collection-compat/pull/217
/**
* author: https://github.com/sjrd
* code: https://github.com/scala/scala-collection-compat/issues/208#issuecomment-497735669
* explanation: https://github.com/scala/scala-collection-compat/issues/208#issuecomment-497785065
*
* Magic to get cross-compiling access to `scala.jdk.CollectionConverters`
* with a fallback on `scala.collection.JavaConverters`, without deprecation
* warning in any Scala version.
*/
object JDKCollectionConvertersCompat {
object Scope1 {
object jdk {
type CollectionConverters = Int
}
}
import Scope1._

object Scope2 {
import scala.collection.{JavaConverters => CollectionConverters}
object Inner {
import scala._
import jdk.CollectionConverters
val Converters = CollectionConverters
}
}

val Converters = Scope2.Inner.Converters
}
1 change: 1 addition & 0 deletions core/src/main/scala/fi/e257/tackler/core/Accumulator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import fi.e257.tackler.math.{TacklerReal, ZERO}
import fi.e257.tackler.model._

import scala.collection.mutable
import fi.e257.tackler.Scala12to13.Converters._

object Accumulator {

Expand Down
6 changes: 5 additions & 1 deletion core/src/main/scala/fi/e257/tackler/core/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@ import better.files._
import com.typesafe.config.{Config, ConfigFactory}
import org.slf4j.{Logger, LoggerFactory}

import scala.collection.JavaConverters._
import fi.e257.tackler.model.AccountTreeNode

// TODO: Switch to scala.jdk when this is released
// https://github.com/scala/scala-collection-compat/pull/217
// import scala.jdk.CollectionConverters._
import fi.e257.tackler.JDKCollectionConvertersCompat.Converters._

/**
* Config keys / paths. All of these keys / paths
* must be available (by embedded default conf).
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/scala/fi/e257/tackler/model/TxnData.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ object TxnData {

if (dup._3 =!= 0) {
val msg =
s"""Found ${dup._3 + 1} duplicate txn uuids with txn set checksum. """ +
f"""Found ${dup._3 + 1}%d duplicate txn uuids with txn set checksum. """ +
s"""At least "${dup._2}" is duplicate, there could be others."""
throw new TxnException(msg)
}
Expand Down
13 changes: 9 additions & 4 deletions core/src/main/scala/fi/e257/tackler/parser/CtxHandler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ import scala.collection.JavaConverters
import scala.util.control.NonFatal
import scala.util.{Failure, Success}

// TODO: Switch to scala.jdk when this is released
// https://github.com/scala/scala-collection-compat/pull/217
// import scala.jdk.CollectionConverters._
import fi.e257.tackler.JDKCollectionConvertersCompat.Converters._

/**
* Handler utilities for ANTLR Parser Contexts.
*
Expand Down Expand Up @@ -91,7 +96,7 @@ abstract class CtxHandler {
"org.wartremover.warts.ListOps"))
protected def handleAccount(accountCtx: AccountContext, commodity: Option[Commodity]): AccountTreeNode = {

val account: String = JavaConverters.asScalaIterator(accountCtx.children.iterator())
val account: String = accountCtx.children.iterator().asScala
.map(_.getText)
.mkString("")

Expand Down Expand Up @@ -316,7 +321,7 @@ abstract class CtxHandler {
// txnCtx.txn_comment is never null, even when there aren't any comments
// (in that case it will be an empty list)
val comments = {
val l = JavaConverters.asScalaIterator(txnCtx.txn_comment().iterator())
val l = txnCtx.txn_comment().iterator().asScala
.map(c => c.comment().text().getText).toList
if (l.isEmpty) {
None
Expand All @@ -326,7 +331,7 @@ abstract class CtxHandler {
}

val posts: Posts =
JavaConverters.asScalaIterator(txnCtx.postings().posting().iterator()).map(p => {
txnCtx.postings().posting().iterator().asScala.map(p => {
handleRawPosting(p)
}).toList

Expand Down Expand Up @@ -358,7 +363,7 @@ abstract class CtxHandler {
* @return sequence of Transactions.
*/
protected def handleTxns(txnsCtx: TxnsContext): Txns = {
JavaConverters.asScalaIterator(txnsCtx.txn().iterator())
txnsCtx.txn().iterator().asScala
.map({ case (txnCtx) =>
try {
handleTxn(txnCtx)
Expand Down
Loading

0 comments on commit c452b38

Please sign in to comment.