aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Rudolph <johannes.rudolph@gmail.com>2016-03-01 15:05:17 +0100
committerJohannes Rudolph <johannes.rudolph@gmail.com>2016-03-01 15:05:47 +0100
commit8e89d97e4775426666727ce7db5ed807d60ff7e3 (patch)
tree210ec18679d4126d195a554b96fc3dcb6e2c66c7
parent11b21a1042dd4bb5007ff3e7eaf18b5e7dbdf8dd (diff)
downloadsbt-boilerplate-8e89d97e4775426666727ce7db5ed807d60ff7e3.tar.gz
sbt-boilerplate-8e89d97e4775426666727ce7db5ed807d60ff7e3.tar.bz2
sbt-boilerplate-8e89d97e4775426666727ce7db5ed807d60ff7e3.zip
add signature to all generated files and remove files not regenerated in current run, fixes #16
-rw-r--r--src/main/scala/spray/boilerplate/BoilerplatePlugin.scala51
1 files changed, 45 insertions, 6 deletions
diff --git a/src/main/scala/spray/boilerplate/BoilerplatePlugin.scala b/src/main/scala/spray/boilerplate/BoilerplatePlugin.scala
index 9394be8..ebd0d7d 100644
--- a/src/main/scala/spray/boilerplate/BoilerplatePlugin.scala
+++ b/src/main/scala/spray/boilerplate/BoilerplatePlugin.scala
@@ -6,34 +6,41 @@
*/
package spray.boilerplate
+import java.io.FileInputStream
+
import sbt._
import Keys._
+import sbt.plugins.JvmPlugin
object BoilerplatePlugin extends AutoPlugin {
override def trigger: PluginTrigger = noTrigger
- override def `requires`: Plugins = empty
+ override def `requires`: Plugins = JvmPlugin
object autoImport {
val boilerplateGenerate = taskKey[Seq[File]]("Generates boilerplate from template files")
val boilerplateSource = settingKey[File]("Default directory containing boilerplate template sources.")
+ val boilerplateSignature = settingKey[String](
+ "Function that creates signature string to prepend to the generated file (given an input file name). " +
+ "Will be used to detect boilerplate-generated files")
}
import autoImport._
override def projectSettings: Seq[Def.Setting[_]] =
- inConfig(Compile)(rawBoilerplateSettings) ++ inConfig(Test)(rawBoilerplateSettings)
+ inConfig(Compile)(rawBoilerplateSettings) ++ inConfig(Test)(rawBoilerplateSettings) ++ Seq(
+ boilerplateSignature := "// auto-generated by sbt-boilerplate\n")
private def rawBoilerplateSettings: Seq[Setting[_]] = {
val inputFilter = "*.template"
Seq(
boilerplateSource := sourceDirectory.value / "boilerplate",
watchSources in Defaults.ConfigGlobal ++= ((boilerplateSource.value ** inputFilter) --- (boilerplateSource.value ** excludeFilter.value ** inputFilter)).get,
- boilerplateGenerate := generateFromTemplates(streams.value, boilerplateSource.value, sourceManaged.value),
+ boilerplateGenerate := generateFromTemplates(streams.value, boilerplateSignature.value, boilerplateSource.value, sourceManaged.value),
mappings in packageSrc ++= managedSources.value pair (Path.relativeTo(sourceManaged.value) | Path.flat),
sourceGenerators <+= boilerplateGenerate)
}
- def generateFromTemplates(streams: TaskStreams, sourceDir: File, targetDir: File): Seq[File] = {
+ def generateFromTemplates(streams: TaskStreams, signature: String, sourceDir: File, targetDir: File): Seq[File] = {
val files = sourceDir ** "*.template"
def changeExtension(f: File): File = {
@@ -49,16 +56,48 @@ object BoilerplatePlugin extends AutoPlugin {
case (orig, target) ⇒ (orig, changeExtension(target))
}
+ val newFiles = mapping.map(_._2)
+ clearTargetDir(streams, targetDir, signature, newFiles)
mapping foreach {
case (templateFile, target) ⇒
if (templateFile.lastModified > target.lastModified) {
streams.log.info("Generating '%s'" format target.getName)
val template = IO.read(templateFile)
- IO.write(target, Generator.generateFromTemplate(template, 22))
+ IO.write(target,
+ signature + Generator.generateFromTemplate(template, 22))
} else
streams.log.debug("Template '%s' older than target. Ignoring." format templateFile.getName)
}
- mapping.map(_._2)
+ newFiles
+ }
+
+ def clearTargetDir(streams: TaskStreams, targetDir: File, signature: String, newFiles: Seq[File]): Seq[File] = {
+ val fileSet = newFiles.toSet
+
+ val buffer = new Array[Byte](signature.getBytes("utf8").size)
+ def containsSignature(file: File): Boolean = {
+ val f = new FileInputStream(file)
+ try {
+ val read = f.read(buffer)
+ (read != buffer.length) || // if we haven't read the full signature assume we had read it
+ new String(buffer, "utf8") == signature
+ } finally f.close()
+ }
+
+ val toRemove =
+ targetDir.***
+ // apply filters with increasing effort
+ .filter(f ⇒ f.exists && f.isFile)
+ .filter(_.length >= signature.length)
+ .filter(!fileSet(_))
+ .filter(containsSignature)
+ .get
+
+ toRemove.foreach { f ⇒
+ streams.log.debug(s"Removing $f that was formerly created by sbt-boilerplate (but won't be created anew).")
+ f.delete
+ }
+ toRemove
}
}