Search code examples
scalasbttwirl

Generate Scala Source from Twirl Template


I know play-twirl is used to generate Scala sources that contain template functions which can be called at runtime.

Is there a way to generate arbitrary Scala source files with play-twirl?

For example
I'd like to automate the creation of some tedious method signatures by creating a template like

src/main/twirl/Foos.scala.scala

object Foos {
  @for(i <- 2 to 22){
  def foo@i[@(...)](chain: @(...)) = @(...)
  }
}

And have a source file generated by SBT like

src_managed/main/scala/Foos.scala

object Foos {
  def foo2[A1, A2](chain: A1 ~ A2) = chain match { case a1 ~ a2 => (a1, a2) }
  def foo3[A1, A2, A3](chain: A1 ~ A2 ~ A3) = ...
  ....
  def foo22[A1, ..., A22] ....
}

Based on some of the Playframework library sources, it looks like they are using their own templating framework to do something similar, though it does not appear to be automated.

So to reiterate the question, is this type of setup possible with Twirl? Is there an alternative sbt plugin that would make this kind of thing easier?


Solution

  • Short of writing my own SBT logic, Twirl doesn't seem to be able to do what I was looking for.

    I did find a useful alternative in sbt-boilerplate. Using that plugin, I can accomplish exactly what I was looking for.

    src/main/boilerplate/Foos.scala.template

    object Foos {
      [2..22#def foo1[[#A1#]](chain: [#A1# ~ ]) = chain match { case [#a1# ~ ] => ([#a1#]) }
      #]
    }
    

    Expands out to

    target/scala-2.xx/src_managed/main/Foos.scala

    object Foos {
      def foo2[A1, A2](chain: A1 ~ A2) = chain match { case a1 ~ a2 => (a1, a2) }
      def foo3[A1, A2, A3] ...
      ...
      def foo22[A1, ..., A22] ...
    }