scala - Integrate translation generating task into play build process
问题描述
I have an SBT task that generates effective translation files in a play 2.6 project (conf/messages{,de,fr,..}) from a base file (conf/variants/base/messages{en,de,fr,...}) and variant file (conf/variants/[variant]/messages{en,de,fr,...}). It produces the effective file by merging the base with the variant file, maybe overwriting base file translation keys. This system is working correctly and makes working with different variants (builds for different customers) of our translations bearable.
How can I now integrate this task into both the packaging (dist or universal:packageZipTarball) and run tasks? The play run task can be hooked but not using sbt taks, only using regular scala classes. I could also not find the appropriate task to extend for the compile or package task. What would be the best approach here? Additionally, what would be the best way to configure the variant in effect? I currently use settingKey[String] for this.
package sbttranslationvariants
import sbt._
import Keys._
object TranslationVariantsPlugin extends AutoPlugin {
override val requires = plugins.JvmPlugin
override val trigger = allRequirements
// by defining autoImport, the settings are automatically imported into user's `*.sbt`
object autoImport {
val variant = settingKey[String]("The variant of the kussbus-backend build")
val languages = settingKey[Seq[String]]("The languages used")
val variantsFile = settingKey[File]("The directory where variants are stored")
val baseMessagesFiles = settingKey[Map[String, File]]("The files that implement the base messages")
val variantMessagesFiles = settingKey[Map[String, File]]("The file that implement variant message overrides")
val baseMessages = taskKey[Map[String, Map[String, String]]]("The base messages per language")
val variantMessages = taskKey[Map[String, Map[String, String]]]("The variant messages per language")
val targetMessages = taskKey[Map[String, Map[String, String]]]("The messages merged")
val writeTargetMessagesFiles = taskKey[Map[String, File]]("Write the merged messages to disk")
val deleteTargetMessagesFiles = taskKey[Map[String, File]]("Delete the generated messages")
}
import autoImport._
private def mkVariantFile(variantDir: File, variant: String, lang: String): File =
variantDir / variant / Seq("messages", lang).mkString(".")
private def mkTargetFile(baseDir: File, lang: String): File =
baseDir / "conf" / (lang match { case "en" => "messages"
case _ => Seq("messages", lang).mkString(".") })
override def projectSettings = Seq(
variant := "kussbus",
languages := Seq("en", "de"),
variantsFile := baseDirectory.value / "conf" / "variants",
baseMessagesFiles := languages.value.map(l => (l -> mkVariantFile(variantsFile.value, "base", l))).toMap,
variantMessagesFiles := languages.value.map(l => (l -> mkVariantFile(variantsFile.value, variant.value, l))).toMap,
baseMessages := {
baseMessagesFiles.value.map({ case (k, v) => k -> util.loadMessages(v) })
},
variantMessages := {
variantMessagesFiles.value.map({ case (k, v) => k -> util.loadMessages(v) })
},
targetMessages := {
baseMessages.value.map({
case (lang, baseMessagesMap) =>
lang -> util.mergeOverwrite(baseMessagesMap, variantMessages.value.get(lang).get)
})
},
writeTargetMessagesFiles := {
targetMessages.value.map({
case (lang, messages) => {
val tf = mkTargetFile(baseDirectory.value, lang)
val messagesRendered = messages.toSeq.sortBy(_._1).foldLeft("") { case (s, (k, v)) => s + s"$k = $v\n" }
IO.write(tf, messagesRendered)
(lang -> tf)
}
})
},
deleteTargetMessagesFiles := {
targetMessages.value.map({
case (lang, messages) => {
val tf = mkTargetFile(baseDirectory.value, lang)
IO.delete(tf)
(lang -> tf)
}
})
}
)
}
object util {
def merge[A, B](a: Map[A, B], b: Map[A, B])(mergef: (B, Option[B]) => B): Map[A, B] = {
a.foldLeft(b) { case (z, (k, v)) => z + (k -> mergef(v, z.get(k))) }
}
def mergeOverwrite[A, B](a: Map[A, B], b: Map[A, B]) = {
merge(a, b) ((v1, v2) => v1)
}
import play.api.i18n.Messages
def loadMessages(file: File) = {
Messages.parse(Messages.UrlMessageSource(file.toURI.toURL), "messages").right.get
}
}
解决方案
推荐阅读
- arduino - 如何让步进电机回到起始位置?
- python - 在线程函数之外使用线程的输出。(Python)
- amazon-s3 - 使用 minio 列出 S3 存储桶中文件夹内的文件
- pandas - 熊猫滚动应用乘法
- javascript - 以编程方式访问公开可用的图像时出现 403 禁止错误
- heroku - 如何解决与 Heroku 部署相关的此错误 - buildpacks 错误
- r - R nleqslv 困难 - 解决酸碱缓冲液中的 pH 值
- f# - 在 F# 中对类型中的静态字典感到困惑
- sql - 计数与返回的行数不同。如何?
- javascript - 如何在 React 中使用 Typescript 转换