aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/spray/boilerplate/BoilerplatePlugin.scala
blob: 6049c98c77caec7c4074f2f45e761f4915da642c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/*
 * sbt-boilerplate is distributed under the 2-Clause BSD license. See the LICENSE file in the root
 * of the repository.
 *
 * Copyright (c) 2012 Johannes Rudolph
 */
package spray.boilerplate

import sbt._
import Keys._

object BoilerplatePlugin extends Plugin {
  object Boilerplate {
    val boilerplateGenerate = TaskKey[Seq[File]]("boilerplate-generate", "Generates boilerplate from template files")

    val settings = seq(
      sourceDirectory in boilerplateGenerate <<= (sourceDirectory in Compile) / "boilerplate",

      target in boilerplateGenerate <<= (sourceManaged in Compile),

      boilerplateGenerate <<= (streams, sourceDirectory in boilerplateGenerate, target in boilerplateGenerate) map generateFromTemplates,

      (sourceGenerators in Compile) <+= boilerplateGenerate,
      (managedSourceDirectories in Compile) <+= target in boilerplateGenerate,

      // watch sources support
      includeFilter in boilerplateGenerate := "*.template",
      excludeFilter in boilerplateGenerate <<= excludeFilter in Global,
      watch(sourceDirectory in boilerplateGenerate, includeFilter in boilerplateGenerate, excludeFilter in boilerplateGenerate),

      // add managed sources to the packaged sources
      mappings in (Compile, packageSrc) <++=
        (sourceManaged in Compile, managedSources in Compile) map { (base, srcs) =>
          (srcs x (Path.relativeTo(base) | Path.flat))
        }
    )

    def watch(sourceDirKey: SettingKey[File], filterKey: SettingKey[FileFilter], excludeKey: SettingKey[FileFilter]) =
      watchSources <++= (sourceDirKey, filterKey, excludeKey) map descendents
    def descendents(sourceDir: File, filt: FileFilter, excl: FileFilter) =
      sourceDir.descendentsExcept(filt, excl).get

    def generateFromTemplates(streams: TaskStreams, sourceDir: File, targetDir: File): Seq[File] = {
      val files = sourceDir ** "*.template"

      def changeExtension(f: File): File = {
        val (ext, name) = f.getName.reverse.span(_ != '.')
        new File(f.getParent, name.drop(1).reverse.toString)
      }

      val mapping = (files x rebase(sourceDir, targetDir)).map {
        case (orig, target) => (orig, changeExtension(target))
      }

      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))
          } else
            streams.log.debug("Template '%s' older than target. Ignoring." format templateFile.getName)
      }

      mapping.map(_._2)
    }
  }
}