aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/spray
diff options
context:
space:
mode:
authorJohannes Rudolph <johannes_rudolph@gmx.de>2012-10-16 14:24:54 +0200
committerJohannes Rudolph <johannes_rudolph@gmx.de>2012-10-16 14:24:54 +0200
commit3dc171e41676e9043fe0c6d935b97a944c143dad (patch)
treed4a9a441eef5502567f79270e136b2bde7e99ea1 /src/main/scala/spray
parentcbbca47a06609e4c523dfbf8498d4f0552f2aa20 (diff)
downloadsbt-boilerplate-3dc171e41676e9043fe0c6d935b97a944c143dad.tar.gz
sbt-boilerplate-3dc171e41676e9043fe0c6d935b97a944c143dad.tar.bz2
sbt-boilerplate-3dc171e41676e9043fe0c6d935b97a944c143dad.zip
move from "cc.spray" to "io.spray"
Diffstat (limited to 'src/main/scala/spray')
-rw-r--r--src/main/scala/spray/boilerplate/BoilerplatePlugin.scala68
-rw-r--r--src/main/scala/spray/boilerplate/Generator.scala32
-rw-r--r--src/main/scala/spray/boilerplate/TemplateParser.scala56
3 files changed, 156 insertions, 0 deletions
diff --git a/src/main/scala/spray/boilerplate/BoilerplatePlugin.scala b/src/main/scala/spray/boilerplate/BoilerplatePlugin.scala
new file mode 100644
index 0000000..6049c98
--- /dev/null
+++ b/src/main/scala/spray/boilerplate/BoilerplatePlugin.scala
@@ -0,0 +1,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)
+ }
+ }
+}
diff --git a/src/main/scala/spray/boilerplate/Generator.scala b/src/main/scala/spray/boilerplate/Generator.scala
new file mode 100644
index 0000000..f124691
--- /dev/null
+++ b/src/main/scala/spray/boilerplate/Generator.scala
@@ -0,0 +1,32 @@
+/*
+ * 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 util.parsing.combinator.RegexParsers
+
+object Generator {
+ def generateFromTemplate(template: String, expandTo: Int): String =
+ generate(TemplateParser.parse(template))(expandTo)
+
+ def formatNum0(num: Int) = num.formatted("%d")
+ def formatNumSpace(num: Int) = num.formatted("%d")
+ def replaceInPattern(pattern: String)(idx: Int): String =
+ // in likely identifiers replace by '04' etc.
+ pattern.replaceAll("(?<=\\w)(?<!\\d)(?<!##)1(?!\\d)", formatNum0(idx))
+ .replaceAll("(?<=\\w)(?<!\\d)(?<!##)0(?!\\d)", formatNum0(idx - 1))
+
+ // in other places replace by ' 4' etc.
+ .replaceAll("(?<!\\w)(?<!\\d)(?<!##)1(?!\\d)", formatNumSpace(idx))
+ .replaceAll("(?<!\\w)(?<!\\d)(?<!##)0(?!\\d)", formatNumSpace(idx - 1))
+
+ def generate(format: TemplateElement)(idx: Int): String = format match {
+ case Sequence(els) => els.map(e => generate(e)(idx)).mkString
+ case Expand(inner, sep) => (1 to idx).map(generate(inner)).mkString(sep)
+ case LiteralString(lit) => replaceInPattern(lit)(idx)
+ case FixedString(lit) => lit
+ }
+}
diff --git a/src/main/scala/spray/boilerplate/TemplateParser.scala b/src/main/scala/spray/boilerplate/TemplateParser.scala
new file mode 100644
index 0000000..ca6b329
--- /dev/null
+++ b/src/main/scala/spray/boilerplate/TemplateParser.scala
@@ -0,0 +1,56 @@
+/*
+ * 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 util.parsing.combinator.RegexParsers
+import java.lang.RuntimeException
+
+sealed trait TemplateElement
+case class Sequence(elements: Seq[TemplateElement]) extends TemplateElement
+case class LiteralString(literal: String) extends TemplateElement
+case class FixedString(literal: String) extends TemplateElement
+case class Expand(inner: TemplateElement, separator: String) extends TemplateElement
+
+object TemplateParser extends RegexParsers {
+ override type Elem = Char
+ type Tokens = TemplateElement
+ override val skipWhitespace = false
+
+ def elements: Parser[TemplateElement] = rep1(element) ^^ {
+ case one :: Nil => one
+ case several => Sequence(several)
+ }
+
+ def element: Parser[TemplateElement] = literal | fixed | expand
+
+ def literalChar: Parser[String] = """(?s:(?!\[#)(?!#[^\]]*\]).)""".r
+ def literalChars: Parser[String] = rep1(literalChar) ^^ { _.reduceLeft(_ + _) }
+
+ def literal: Parser[LiteralString] = literalChars ^^ LiteralString
+
+ def fixed: Parser[FixedString] = "##" ~> ".".r ^^ (new String(_)) ^^ FixedString
+
+ def expand: Parser[Expand] = "[#" ~> elements ~ "#" ~ separatorChars <~ "]" ^^ {
+ case els ~ x ~ sep => Expand(els, sep.getOrElse(", "))
+ }
+
+ def separatorChars: Parser[Option[String]] = rep("""[^\]]""".r) ^^ (_.reduceLeftOption(_ + _))
+
+ def parse(input:String): TemplateElement =
+ phrase(elements)(new scala.util.parsing.input.CharArrayReader(input.toCharArray)) match {
+ case Success(res,_) => res
+ case x:NoSuccess => throw new RuntimeException(x.msg)
+ }
+}
+
+object TestParser extends App {
+ def check(format: String) {
+ println(TemplateParser.parse(format))
+ }
+
+ check("[#abc ##1 # ++ ]")
+} \ No newline at end of file