Skip to content

Commit

Permalink
add signature to all generated files and remove files not regenerated…
Browse files Browse the repository at this point in the history
… in current run, fixes #16
  • Loading branch information
jrudolph committed Mar 1, 2016
1 parent 11b21a1 commit 8e89d97
Showing 1 changed file with 45 additions and 6 deletions.
51 changes: 45 additions & 6 deletions src/main/scala/spray/boilerplate/BoilerplatePlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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
}
}

0 comments on commit 8e89d97

Please sign in to comment.