Skip to content

Commit

Permalink
Merge pull request #145 from sideeffffect/ZoneMap-for-all-platforms
Browse files Browse the repository at this point in the history
Add support for Scala Native
  • Loading branch information
cquiroz authored Jan 19, 2022
2 parents a07a37f + 5e0f4a0 commit 859cce9
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 45 deletions.
52 changes: 52 additions & 0 deletions sbt-tzdb/src/main/resources/native/TzdbZoneRulesProvider.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package

import org.threeten.bp.DateTimeException

import org.portablescala.reflect.annotation.EnableReflectiveInstantiation

@EnableReflectiveInstantiation
final class TzdbZoneRulesProvider extends ZoneRulesProvider {
import zonedb.threeten.tzdb._

override protected def provideZoneIds: java.util.Set[String] = {
val zones = new java.util.HashSet[String]()
val zonesSet = (stdZones.keySet ++ fixedZones.keySet ++ zoneLinks.keySet)
zonesSet.foreach(zones.add(_))
// I'm not totallly sure the reason why but TTB removes these ZoneIds
// zones.remove("UTC")
// zones.remove("GMT")
zones.remove("GMT0")
zones.remove("GMT+0")
zones.remove("GMT-0")
zones
}

override protected def provideRules(regionId: String,
forCaching: Boolean): ZoneRules = {
val actualRegion = zoneLinks.getOrElse(regionId, regionId)
stdZones
.get(actualRegion)
.orElse(
fixedZones
.get(actualRegion))
.getOrElse(
throw new DateTimeException(s"TimeZone Region $actualRegion unknown"))
}

override protected def provideVersions(
zoneId: String): java.util.NavigableMap[String, ZoneRules] = {
val actualRegion = zoneLinks.getOrElse(zoneId, zoneId)
stdZones
.get(actualRegion)
.orElse(
fixedZones
.get(actualRegion))
.map { z =>
val r = new ZoneMap[String, ZoneRules]
r.put(version, z)
r
}
.getOrElse(
throw new DateTimeException(s"TimeZone Region $actualRegion unknown"))
}
}
38 changes: 20 additions & 18 deletions sbt-tzdb/src/main/scala/io/github/sbt/tzdb/IOTasks.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.gitub.sbt.tzdb
package io.github.sbt.tzdb

import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream
import java.io._
Expand Down Expand Up @@ -49,30 +49,29 @@ object IOTasks {
}

def generateTZDataSources(
base: File,
data: File,
log: Logger,
includeTTBP: Boolean,
jsOptimized: Boolean,
zonesFilter: String => Boolean
base: File,
data: File,
log: Logger,
includeTTBP: Boolean,
tzdbPlatform: TzdbPlugin.Platform,
zonesFilter: String => Boolean
): cats.effect.IO[List[File]] =
for {
paths <- tzDataSources(base, includeTTBP)
_ <- cats.effect.IO(log.info(s"Generating tzdb from db at $data to $base"))
_ <- cats.effect.IO(paths.foreach(t => t._3.getParentFile().mkdirs()))
f <- paths
.map(p =>
if (jsOptimized) {
import kuyfi.TZDBCodeGenerator.OptimizedTreeGenerator._
f <- paths.map { p =>
tzdbPlatform match {
case TzdbPlugin.Platform.Js =>
import kuyfi.TZDBCodeGenerator.OptimizedTreeGenerator.*
TZDBCodeGenerator
.exportAll(data, p._3, p._1, p._2, zonesFilter)
} else {
import kuyfi.TZDBCodeGenerator.PureTreeGenerator._
case _ =>
import kuyfi.TZDBCodeGenerator.PureTreeGenerator.*
TZDBCodeGenerator
.exportAll(data, p._3, p._1, p._2, zonesFilter)
}
)
.sequence
}
}.sequence
} yield f

def providerFile(base: File, name: String, packageDir: String): cats.effect.IO[File] =
Expand Down Expand Up @@ -125,8 +124,11 @@ object IOTasks {

def download(url: String, to: File) =
cats.effect.IO {
import gigahorse._, support.okhttp.Gigahorse
import scala.concurrent._, duration._
import gigahorse.*
import support.okhttp.Gigahorse

import scala.concurrent.*
import duration.*
Gigahorse.withHttp(gigahorse.Config()) { http =>
val r = Gigahorse.url(url)
val f = http.download(r, to)
Expand Down
62 changes: 36 additions & 26 deletions sbt-tzdb/src/main/scala/io/github/sbt/tzdb/SbtTzdb.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.gitub.sbt.tzdb
package io.github.sbt.tzdb

import java.io.{ File => JFile }
import sbt._
Expand All @@ -21,19 +21,27 @@ object TzdbPlugin extends AutoPlugin {
val path: String = s"releases/tzdata$version"
}

sealed abstract class Platform(val name: String) extends Product with Serializable
final object Platform {
final case object Jvm extends Platform("jvm")
final case object Js extends Platform("js")
final case object Native extends Platform("native")
}

object autoImport {

/*
* Settings
*/
val zonesFilter = settingKey[String => Boolean]("Filter for zones")
val dbVersion = settingKey[TZDBVersion]("Version of the tzdb")
val tzdbCodeGen =
val zonesFilter = settingKey[String => Boolean]("Filter for zones")
val dbVersion = settingKey[TZDBVersion]("Version of the tzdb")
val tzdbCodeGen =
taskKey[Seq[JFile]]("Generate scala.js compatible database of tzdb data")
val includeTTBP: SettingKey[Boolean] =
val includeTTBP: SettingKey[Boolean] =
settingKey[Boolean]("Include also a provider for threeten bp")
val jsOptimized: SettingKey[Boolean] =
settingKey[Boolean]("Generates a version with smaller size but only usable on scala.js")
val tzdbPlatform: SettingKey[Platform] = settingKey[Platform](
"The generated code is platform specific. Specify what is the target platform."
)
}

import autoImport._
Expand All @@ -42,7 +50,7 @@ object TzdbPlugin extends AutoPlugin {
zonesFilter := { case _ => true },
dbVersion := LatestVersion,
includeTTBP := false,
jsOptimized := true
tzdbPlatform := Platform.Js
)
override val projectSettings =
Seq(
Expand All @@ -62,7 +70,7 @@ object TzdbPlugin extends AutoPlugin {
zonesFilter = zonesFilter.value,
dbVersion = dbVersion.value,
includeTTBP = includeTTBP.value,
jsOptimized = jsOptimized.value,
tzdbPlatform = tzdbPlatform.value,
log = log
)
}
Expand All @@ -76,34 +84,36 @@ object TzdbPlugin extends AutoPlugin {
zonesFilter: String => Boolean,
dbVersion: TZDBVersion,
includeTTBP: Boolean,
jsOptimized: Boolean,
tzdbPlatform: Platform,
log: Logger
): Set[JFile] = {

import cats._
import cats.syntax.all._

val tzdbData: JFile = resourcesManaged / "tzdb"
val sub = if (jsOptimized) "js" else "jvm"
val ttbp = IOTasks.copyProvider(sourceManaged,
sub,
"TzdbZoneRulesProvider.scala",
"org.threeten.bp.zone",
false
val ttbp = IOTasks.copyProvider(
sourceManaged,
tzdbPlatform.name,
"TzdbZoneRulesProvider.scala",
"org.threeten.bp.zone",
false
)
val jt = IOTasks.copyProvider(
sourceManaged,
tzdbPlatform.name,
"TzdbZoneRulesProvider.scala",
"java.time.zone",
true
)
val jt =
IOTasks.copyProvider(sourceManaged,
sub,
"TzdbZoneRulesProvider.scala",
"java.time.zone",
true
)
val providerCopy = if (includeTTBP) List(ttbp, jt) else List(jt)
(for {
_ <- IOTasks.downloadTZDB(log, resourcesManaged, dbVersion)
// Use it to detect if files have been already generated
p <-
IOTasks.providerFile(sourceManaged / sub, "TzdbZoneRulesProvider.scala", "java.time.zone")
p <- IOTasks.providerFile(sourceManaged / tzdbPlatform.name,
"TzdbZoneRulesProvider.scala",
"java.time.zone"
)
e <- effect.IO(p.exists)
j <- if (e) effect.IO(List(p)) else providerCopy.sequence
f <- if (e) IOTasks.tzDataSources(sourceManaged, includeTTBP).map(_.map(_._3))
Expand All @@ -112,7 +122,7 @@ object TzdbPlugin extends AutoPlugin {
tzdbData,
log,
includeTTBP,
jsOptimized,
tzdbPlatform,
zonesFilter
)
} yield (j ::: f).toSet).unsafeRunSync
Expand Down
2 changes: 1 addition & 1 deletion sbt-tzdb/src/sbt-test/sbt-tzdb/jvm/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ scalaVersion := "2.13.1"

crossScalaVersions := Seq("2.13.1", "2.12.10")

jsOptimized := false
tzdbPlatform := TzdbPlugin.Platform.Jvm

dbVersion := TzdbPlugin.Version("2019c")

Expand Down

0 comments on commit 859cce9

Please sign in to comment.