sbt/project/Transform.scala

109 lines
4.3 KiB
Scala

import sbt.io.Path._
import sbt._
import Keys._
object Transform {
lazy val transformSources = TaskKey[Seq[File]]("transform-sources")
lazy val inputSourceDirectories = SettingKey[Seq[File]]("input-source-directories")
lazy val inputSourceDirectory = SettingKey[File]("input-source-directory")
lazy val inputSources = TaskKey[Seq[File]]("input-sources")
lazy val sourceProperties = TaskKey[Map[String, String]]("source-properties")
lazy val transformResources = TaskKey[Seq[File]]("transform-resources")
lazy val inputResourceDirectories = SettingKey[Seq[File]]("input-resource-directories")
lazy val inputResourceDirectory = SettingKey[File]("input-resource-directory")
lazy val inputResources = TaskKey[Seq[File]]("input-resources")
lazy val resourceProperties = TaskKey[Map[String, String]]("resource-properties")
lazy val conscriptConfigs = TaskKey[Unit]("conscript-configs")
def conscriptSettings(launch: Reference) = Seq(
conscriptConfigs := {
val res = (managedResources in launch in Compile).value
val src = (sourceDirectory in Compile).value
val source = res.find(_.getName == "sbt.boot.properties") getOrElse sys.error(
"No managed boot.properties file.")
copyConscriptProperties(source, src / "conscript")
()
}
)
def copyConscriptProperties(source: File, conscriptBase: File): Seq[File] = {
IO.delete(conscriptBase)
val pairs = Seq(
"sbt.xMain" -> "xsbt",
"sbt.ScriptMain" -> "scalas",
"sbt.ConsoleMain" -> "screpl"
)
for ((main, dir) <- pairs) yield {
val file = conscriptBase / dir / "launchconfig"
copyPropertiesFile(source, main, file)
file
}
}
def copyPropertiesFile(source: File, newMain: String, target: File): Unit = {
def subMain(line: String): String =
if (line.trim.startsWith("class:")) " class: " + newMain else line
IO.writeLines(target, IO.readLines(source) map subMain)
}
def crossGenSettings = transSourceSettings ++ Seq(
sourceProperties := Map("cross.package0" -> "sbt", "cross.package1" -> "cross")
)
def transSourceSettings = Seq(
inputSourceDirectory := sourceDirectory.value / "input_sources",
inputSourceDirectories := Seq(inputSourceDirectory.value),
inputSources := (inputSourceDirectories.value ** (-DirectoryFilter)).get,
fileMappings in transformSources := transformSourceMappings.value,
transformSources := {
val rs = (fileMappings in transformSources).value
val props = sourceProperties.value
rs map { case (in, out) => transform(in, out, props) }
},
sourceGenerators += transformSources.taskValue
)
def transformSourceMappings = Def task {
val ss = inputSources.value
val sdirs = inputSourceDirectories.value
val sm = sourceManaged.value
((ss --- sdirs) pair (rebase(sdirs, sm) | flat(sm))).toSeq
}
def configSettings = transResourceSettings ++ Seq(
resourceProperties :=
Map("org" -> organization.value,
"sbt.version" -> version.value,
"scala.version" -> scalaVersion.value)
)
def transResourceSettings = Seq(
inputResourceDirectory := sourceDirectory.value / "input_resources",
inputResourceDirectories := Seq(inputResourceDirectory.value),
inputResources := (inputResourceDirectories.value ** (-DirectoryFilter)).get,
fileMappings in transformResources := transformResourceMappings.value,
transformResources := {
val rs = (fileMappings in transformResources).value
val props = resourceProperties.value
rs map { case (in, out) => transform(in, out, props) }
},
resourceGenerators += transformResources.taskValue
)
def transformResourceMappings = Def task {
val rs = inputResources.value
val rdirs = inputResourceDirectories.value
val rm = resourceManaged.value
((rs --- rdirs) pair (rebase(rdirs, rm) | flat(rm))).toSeq
}
def transform(in: File, out: File, map: Map[String, String]): File = {
def get(key: String): String =
map.getOrElse(key, sys.error("No value defined for key '" + key + "'"))
val newString = Property.replaceAllIn(IO.read(in), mtch => get(mtch.group(1)))
if (Some(newString) != read(out))
IO.write(out, newString)
out
}
def read(file: File): Option[String] = try { Some(IO.read(file)) } catch {
case _: java.io.IOException => None
}
lazy val Property = """\$\{\{([\w.-]+)\}\}""".r
}