pull/5745/head
Thibault Duplessis 2019-12-12 23:03:38 -06:00
parent 8f8af7d55a
commit 540e632404
7 changed files with 134 additions and 115 deletions

6
.scalafmt.conf 100644
View File

@ -0,0 +1,6 @@
version = "2.3.2"
align = more
maxColumn = 110
spaces.inImportCurlyBraces = true
rewrite.rules = [SortImports, RedundantParens, SortModifiers]
rewrite.redundantBraces.stringInterpolation = true

View File

@ -1,5 +1,4 @@
import com.typesafe.sbt.packager.Keys.scriptClasspath
import com.typesafe.sbt.SbtScalariform.autoImport.scalariformFormat
import BuildSettings._
import Dependencies._
@ -25,7 +24,10 @@ PlayKeys.playDefaultPort := 9663
PlayKeys.externalizeResources := false
// shorter prod classpath
scriptClasspath := Seq("*")
// offline := true
// don't make an assets jar
resourceDirectory in Assets := (sourceDirectory in Compile).value / "assets"
// format: off
libraryDependencies ++= Seq(
macwire.macros, macwire.util, play.json, jodaForms, ws,
scalaz, chess, compression, scalalib, hasher,
@ -35,12 +37,6 @@ libraryDependencies ++= Seq(
scrimage, scaffeine, lettuce, epoll
) ++ silencer.bundle
resourceDirectory in Assets := (sourceDirectory in Compile).value / "assets"
scalariformPreferences := scalariformPrefs(scalariformPreferences.value)
excludeFilter in scalariformFormat := "*Routes*"
routesGenerator := LilaRoutesGenerator
lazy val modules = Seq(
common, db, rating, user, security, hub, socket,
message, notifyModule, i18n, game, bookmark, search,

View File

@ -1,7 +1,5 @@
import com.typesafe.sbt.SbtScalariform.autoImport.scalariformPreferences
import play.sbt.PlayImport._
import sbt._, Keys._
import scalariform.formatter.preferences._
object BuildSettings {
@ -19,29 +17,31 @@ object BuildSettings {
// disable publishing the main API jar
publishArtifact in (Compile, packageDoc) := false,
// disable publishing the main sources jar
publishArtifact in (Compile, packageSrc) := false,
scalariformPreferences := scalariformPrefs(scalariformPreferences.value)
publishArtifact in (Compile, packageSrc) := false
)
def scalariformPrefs(prefs: IFormattingPreferences) = prefs
.setPreference(DanglingCloseParenthesis, Force)
.setPreference(DoubleIndentConstructorArguments, true)
def defaultLibs: Seq[ModuleID] = Seq(
play.api, scalaz, chess, scalalib, jodaTime, ws,
macwire.macros, macwire.util, autoconfig, specs2
play.api,
scalaz,
chess,
scalalib,
jodaTime,
ws,
macwire.macros,
macwire.util,
autoconfig,
specs2
)
def module(
name: String,
deps: Seq[sbt.ClasspathDep[sbt.ProjectReference]],
libs: Seq[ModuleID]
name: String,
deps: Seq[sbt.ClasspathDep[sbt.ProjectReference]],
libs: Seq[ModuleID]
) =
Project(
name,
file("modules/" + name)
)
.dependsOn(deps: _*)
).dependsOn(deps: _*)
.settings(
libraryDependencies ++= defaultLibs ++ libs ++ silencer.bundle,
buildSettings,
@ -59,8 +59,10 @@ object BuildSettings {
"-Ywarn-macros:after",
"-Ywarn-unused:_",
// "-Xfatal-warnings",
"-Xmaxerrs", "12",
"-Xmaxwarns", "12"
"-Xmaxerrs",
"12",
"-Xmaxwarns",
"12"
)
val srcMain = Seq(

View File

@ -5,41 +5,41 @@ object Dependencies {
object Resolvers {
val sonatype = Resolver.sonatypeRepo("releases")
val sonatype = Resolver.sonatypeRepo("releases")
val lilaMaven = "lila-maven" at "https://raw.githubusercontent.com/ornicar/lila-maven/master"
val commons = Seq(lilaMaven, sonatype)
}
val scalaz = "org.scalaz" %% "scalaz-core" % "7.2.29"
val scalalib = "com.github.ornicar" %% "scalalib" % "6.7"
val hasher = "com.roundeights" %% "hasher" % "1.2.1"
val jodaTime = "joda-time" % "joda-time" % "2.10.5"
val chess = "org.lichess" %% "scalachess" % "9.0.27"
val compression = "org.lichess" %% "compression" % "1.5"
val maxmind = "com.sanoma.cda" %% "maxmind-geoip2-scala" % "1.3.1-THIB"
val prismic = "io.prismic" %% "scala-kit" % "1.2.13-THIB213"
val scrimage = "com.sksamuel.scrimage" %% "scrimage-core" % "2.1.8-SNAPSHOT"
val scaffeine = "com.github.blemale" %% "scaffeine" % "3.1.0" % "compile"
val googleOAuth = "com.google.auth" % "google-auth-library-oauth2-http" % "0.18.0"
val scalaUri = "io.lemonlabs" %% "scala-uri" % "1.5.1"
val scalatags = "com.lihaoyi" %% "scalatags" % "0.7.0"
val lettuce = "io.lettuce" % "lettuce-core" % "5.2.1.RELEASE"
val epoll = "io.netty" % "netty-transport-native-epoll" % "4.1.43.Final" classifier "linux-x86_64"
val markdown = "com.vladsch.flexmark" % "flexmark-all" % "0.50.44"
val autoconfig = "io.methvin.play" %% "autoconfig-macros" % "0.3.2-SNAPSHOT" % "provided"
val scalaz = "org.scalaz" %% "scalaz-core" % "7.2.29"
val scalalib = "com.github.ornicar" %% "scalalib" % "6.7"
val hasher = "com.roundeights" %% "hasher" % "1.2.1"
val jodaTime = "joda-time" % "joda-time" % "2.10.5"
val chess = "org.lichess" %% "scalachess" % "9.0.27"
val compression = "org.lichess" %% "compression" % "1.5"
val maxmind = "com.sanoma.cda" %% "maxmind-geoip2-scala" % "1.3.1-THIB"
val prismic = "io.prismic" %% "scala-kit" % "1.2.13-THIB213"
val scrimage = "com.sksamuel.scrimage" %% "scrimage-core" % "2.1.8-SNAPSHOT"
val scaffeine = "com.github.blemale" %% "scaffeine" % "3.1.0" % "compile"
val googleOAuth = "com.google.auth" % "google-auth-library-oauth2-http" % "0.18.0"
val scalaUri = "io.lemonlabs" %% "scala-uri" % "1.5.1"
val scalatags = "com.lihaoyi" %% "scalatags" % "0.7.0"
val lettuce = "io.lettuce" % "lettuce-core" % "5.2.1.RELEASE"
val epoll = "io.netty" % "netty-transport-native-epoll" % "4.1.43.Final" classifier "linux-x86_64"
val markdown = "com.vladsch.flexmark" % "flexmark-all" % "0.50.44"
val autoconfig = "io.methvin.play" %% "autoconfig-macros" % "0.3.2-SNAPSHOT" % "provided"
object macwire {
val version = "2.3.3"
val macros = "com.softwaremill.macwire" %% "macros" % version % "provided"
val util = "com.softwaremill.macwire" %% "util" % version % "provided"
val macros = "com.softwaremill.macwire" %% "macros" % version % "provided"
val util = "com.softwaremill.macwire" %% "util" % version % "provided"
}
object reactivemongo {
val version = "0.19.3"
val driver = "org.reactivemongo" %% "reactivemongo" % "0.20.0-SNAPSHOT"
val bson = "org.reactivemongo" %% "reactivemongo-bson-api" % "0.20.0-SNAPSHOT"
val stream = "org.reactivemongo" %% "reactivemongo-akkastream" % version
val driver = "org.reactivemongo" %% "reactivemongo" % "0.20.0-SNAPSHOT"
val bson = "org.reactivemongo" %% "reactivemongo-bson-api" % "0.20.0-SNAPSHOT"
val stream = "org.reactivemongo" %% "reactivemongo-akkastream" % version
// val native = "org.reactivemongo" % "reactivemongo-shaded-native" % s"$version-linux-x86-64" classifier "linux-x86_64"
val native = "org.reactivemongo" % "reactivemongo-shaded-native" % s"$version-linux-x86-64"
// #TODO remove compat
@ -49,19 +49,19 @@ object Dependencies {
object play {
val version = "2.8.0"
val api = "com.typesafe.play" %% "play" % version
val json = "com.typesafe.play" %% "play-json" % version
val api = "com.typesafe.play" %% "play" % version
val json = "com.typesafe.play" %% "play-json" % version
}
object kamon {
val core = "io.kamon" %% "kamon-core" % "2.0.2"
val influxdb = "io.kamon" %% "kamon-influxdb" % "2.0.1-LILA"
val metrics = "io.kamon" %% "kamon-system-metrics" % "2.0.0"
val core = "io.kamon" %% "kamon-core" % "2.0.2"
val influxdb = "io.kamon" %% "kamon-influxdb" % "2.0.1-LILA"
val metrics = "io.kamon" %% "kamon-system-metrics" % "2.0.0"
}
object silencer {
val version = "1.4.4"
val plugin = "com.github.ghik" % "silencer-plugin" % version cross CrossVersion.full
val lib = "com.github.ghik" % "silencer-lib" % version % Provided cross CrossVersion.full
val bundle = Seq(compilerPlugin(plugin), lib)
val plugin = "com.github.ghik" % "silencer-plugin" % version cross CrossVersion.full
val lib = "com.github.ghik" % "silencer-lib" % version % Provided cross CrossVersion.full
val bundle = Seq(compilerPlugin(plugin), lib)
}
}

View File

@ -17,24 +17,25 @@ object MessageCompiler {
private def doFile(db: String, sourceFile: File, destDir: File, compileTo: File): Seq[File] = {
destDir.mkdirs()
val registry = ("en-GB" -> sourceFile) :: destDir.list.toList.map { f =>
f.takeWhile('.' !=) -> (destDir / f)
}.sortBy(_._1)
val registry = ("en-GB" -> sourceFile) :: destDir.list.toList
.map { f =>
f.takeWhile('.' !=) -> (destDir / f)
}
.sortBy(_._1)
compileTo.mkdirs()
var translatedLocales = Set.empty[String]
val res = for {
entry <- registry
compilable <- {
val (locale, file) = entry
val compileToFile = compileTo / s"$locale.scala"
val compileToFile = compileTo / s"$locale.scala"
if (!isFileEmpty(file)) {
translatedLocales = translatedLocales + locale
if (file.lastModified > compileToFile.lastModified) {
printToFile(compileToFile)(render(db, locale, file))
}
Some(compileToFile)
}
else None
} else None
}
} yield compilable
writeRegistry(db, compileTo, translatedLocales) :: res
@ -77,25 +78,28 @@ private[i18n] object Registry {
}
private def render(db: String, locale: String, file: File): String = {
val xml = try {
XML.loadFile(file)
}
catch {
case e: Exception => println(file); throw e;
}
val xml =
try {
XML.loadFile(file)
} catch {
case e: Exception => println(file); throw e;
}
def quote(msg: String) = s"""""\"$msg""\""""
val content = xml.child.collect {
case e if e.label == "string" =>
val safe = escape(e.text)
val translation = escapeHtmlOption(safe) match {
case None => s"""new Simple(\"\"\"$safe\"\"\")"""
case None => s"""new Simple(\"\"\"$safe\"\"\")"""
case Some(escaped) => s"""new Escaped(\"\"\"$safe\"\"\",\"\"\"$escaped\"\"\")"""
}
s"""m.put(${toKey(e)},$translation)"""
case e if e.label == "plurals" =>
val items: Map[String, String] = e.child.filter(_.label == "item").map { i =>
ucfirst(i.\("@quantity").toString) -> s"""\"\"\"${escape(i.text)}\"\"\""""
}.toMap
val items: Map[String, String] = e.child
.filter(_.label == "item")
.map { i =>
ucfirst(i.\("@quantity").toString) -> s"""\"\"\"${escape(i.text)}\"\"\""""
}
.toMap
s"""m.put(${toKey(e)},new Plurals(${pluralMap(items)}))"""
}
s"""package lila.i18n
@ -116,15 +120,14 @@ ${content mkString "\n"}
}
private def pluralMap(items: Map[String, String]): String =
if (items.size > 4) s"""Map(${items.map { case (k, v) => s"$k->$v" } mkString ","})"""
if (items.size > 4) s"""Map(${items.map { case (k, v) => s"$k->$v" } mkString ","})"""
else s"""new Map.Map${items.size}(${items.map { case (k, v) => s"$k,$v" } mkString ","})"""
private val badChars = """[<>&"'\r\n]""".r.pattern
private def escapeHtmlOption(s: String): Option[String] =
if (badChars.matcher(s).find) Some {
val sb = new java.lang.StringBuilder(s.size + 10) // wet finger style
var i = 0
var i = 0
while (i < s.length) {
s.charAt(i) match {
case '<' => sb append "&lt;"
@ -143,6 +146,10 @@ ${content mkString "\n"}
private def printToFile(f: File)(content: String): Unit = {
val p = new java.io.PrintWriter(f, "UTF-8")
try { content.foreach(p.print) } finally { p.close() }
try {
content.foreach(p.print)
} finally {
p.close()
}
}
}

View File

@ -6,15 +6,19 @@ import play.routes.compiler.RoutesCompiler.RoutesCompilerTask
object LilaRoutesGenerator extends RoutesGenerator {
val ForwardsRoutesFile = "Routes.scala"
val ReverseRoutesFile = "ReverseRoutes.scala"
val RoutesPrefixFile = "RoutesPrefix.scala"
val JavaWrapperFile = "routes.java"
val ReverseRoutesFile = "ReverseRoutes.scala"
val RoutesPrefixFile = "RoutesPrefix.scala"
val JavaWrapperFile = "routes.java"
val id = "lila"
import InjectedRoutesGenerator.Dependency
def generate(task: RoutesCompilerTask, namespace: Option[String], rules: List[Rule]): Seq[(String, String)] = {
def generate(
task: RoutesCompilerTask,
namespace: Option[String],
rules: List[Rule]
): Seq[(String, String)] = {
val folder = namespace.map(_.replace('.', '/') + "/").getOrElse("") + "/"
val sourceInfo =
@ -25,16 +29,20 @@ object LilaRoutesGenerator extends RoutesGenerator {
val forwardsRoutesFiles = if (task.forwardsRouter) {
Seq(folder + ForwardsRoutesFile -> generateRouter(sourceInfo, namespace, task.additionalImports, rules))
}
else {
} else {
Nil
}
val reverseRoutesFiles = if (task.reverseRouter) {
generateReverseRouters(sourceInfo, namespace, task.additionalImports, routes, task.namespaceReverseRouter) ++
generateReverseRouters(
sourceInfo,
namespace,
task.additionalImports,
routes,
task.namespaceReverseRouter
) ++
generateJavaWrappers(sourceInfo, namespace, rules, task.namespaceReverseRouter)
}
else {
} else {
Nil
}
@ -42,16 +50,16 @@ object LilaRoutesGenerator extends RoutesGenerator {
}
private def generateRouter(
sourceInfo: RoutesSourceInfo,
namespace: Option[String],
additionalImports: Seq[String],
rules: List[Rule]
sourceInfo: RoutesSourceInfo,
namespace: Option[String],
additionalImports: Seq[String],
rules: List[Rule]
) = {
@annotation.tailrec
def prepare(
rules: List[Rule],
includes: Seq[Include],
routes: Seq[Route]
rules: List[Rule],
includes: Seq[Include],
routes: Seq[Route]
): (Seq[Include], Seq[Route]) = rules match {
case (inc: Include) :: rs =>
prepare(rs, inc +: includes, routes)
@ -89,7 +97,7 @@ object LilaRoutesGenerator extends RoutesGenerator {
routes.headOption.map { route =>
val clazz = packageName.map(_ + ".").getOrElse("") + controller
// If it's using the @ syntax, we depend on the provider (ie, look it up each time)
val dep = if (instantiate) s"javax.inject.Provider[$clazz]" else clazz
val dep = if (instantiate) s"javax.inject.Provider[$clazz]" else clazz
val ident = controller + "_" + index
key -> Dependency(ident, dep, route)
@ -135,11 +143,11 @@ object LilaRoutesGenerator extends RoutesGenerator {
.body
private def generateReverseRouters(
sourceInfo: RoutesSourceInfo,
namespace: Option[String],
additionalImports: Seq[String],
routes: List[Route],
namespaceReverseRouter: Boolean
sourceInfo: RoutesSourceInfo,
namespace: Option[String],
additionalImports: Seq[String],
routes: List[Route],
namespaceReverseRouter: Boolean
) = {
routes.groupBy(_.call.packageName).map {
case (pn, routes) =>
@ -149,24 +157,24 @@ object LilaRoutesGenerator extends RoutesGenerator {
.orElse(pn.orElse(namespace))
(packageName.map(_.replace(".", "/") + "/").getOrElse("") + ReverseRoutesFile) ->
static.twirl
.reverseRouter(
sourceInfo,
namespace,
additionalImports,
packageName,
routes,
namespaceReverseRouter,
_ => true
)
.body
.reverseRouter(
sourceInfo,
namespace,
additionalImports,
packageName,
routes,
namespaceReverseRouter,
_ => true
)
.body
}
}
private def generateJavaWrappers(
sourceInfo: RoutesSourceInfo,
namespace: Option[String],
rules: List[Rule],
namespaceReverseRouter: Boolean
sourceInfo: RoutesSourceInfo,
namespace: Option[String],
rules: List[Rule],
namespaceReverseRouter: Boolean
): Iterable[(String, String)] =
rules.collect { case r: Route => r }.groupBy(_.call.packageName).map {
case (pn, routes) =>
@ -177,7 +185,7 @@ object LilaRoutesGenerator extends RoutesGenerator {
val controllers = routes.groupBy(_.call.controller).keys.toSeq
(packageName.map(_.replace(".", "/") + "/").getOrElse("") + JavaWrapperFile) -> {
val pack = packageName getOrElse "controllers"
val ns = namespace getOrElse "routes"
val ns = namespace getOrElse "routes"
s"""package $pack;
import $ns.RoutesPrefix;

View File

@ -1,2 +1,2 @@
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.0")
addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.3")
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.0")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.3.0")