Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate sources in an sbt plugin?

Tags:

scala

sbt

I'm trying to generate some sources as described in Generating files.

When I put the following in my build.sbt, everything works:

sourceGenerators in Compile += Def.task {
  val file = (sourceManaged in Compile).value / "demo" / "Test.scala"
  IO.write(file, """object Test extends App { println("Hi") }""")
  Seq(file)
}.taskValue

But when I attempt to do the same thing in a plugin, the task never runs:

object MyPlugin extends AutoPlugin {
  override lazy val projectSettings = Seq(
    sourceGenerators in Compile += Def.task {
      val file = (sourceManaged in Compile).value / "demo" / "Test.scala"
      IO.write(file, """object Test extends App { println("Hi") }""")
      Seq(file)
    }.taskValue
  )
}

Everything else I put in my plugin seems to work fine, but the source file is never generated.

Am I missing something important?

like image 334
codefinger Avatar asked Jul 13 '14 15:07

codefinger


People also ask

How to add SBT plugin to a project?

So go to the sbt console in the project which use your SBT plugin and type show Compile/libraryDependencies. Then, you should see the new ModuleID, that you added.

What version of SBT is my Consumer Project using?

My consumer project is using SBT 1.2.6 and Scala 2.11.12 . When you build a plugin, the requirements are: SBT version of the plugin needs to be the same as the SBT version of your project. SBT version of the plugin needs to match the Scala version of the plugin.

What is the use of @sbtplugin@true?

sbtPlugin := true is telling SBT that this is an SBT plugin. Important. organization , name and version is for when you are going to load this SBT plugin inside your consumer project: This file is everything related to how to deploy your SBT plugin:

What is plugincrossbuild / sbtversion and why does it matter?

Because sbt does NOT keep forward compatibility, that would typically require all of your plugin users to upgrade to the latest too. pluginCrossBuild / sbtVersion is an optional setting to compile your plugin against an older version of sbt, which allows the plugin users to choose from a range of sbt versions.


1 Answers

You have to load your plugin after the JvmPlugin, which resets sourceGenerators in projectSettings (see sbt.Defaults.sourceConfigPaths).

You can do that by adding it as a requirements to your plugin, e.g.

override def requires = JvmPlugin

Your complete example should look as follows:

import sbt._
import Keys._
import plugins._

object MyPlugin extends AutoPlugin {
  override def requires = JvmPlugin
  override lazy val projectSettings = Seq(
    sourceGenerators in Compile += Def.task {
      val file = (sourceManaged in Compile).value / "demo" / "Test.scala"
      IO.write(file, """object Test extends App { println("Hi") }""")
      Seq(file)
    }.taskValue
  )
}
like image 174
lpiepiora Avatar answered Oct 26 '22 15:10

lpiepiora