4

I'm trying to create a source generator in a SBT plugin that generate code based on the project's sources.

I tried something like this:

sourceGenerators in Compile += (sources in Compile) map { sources => doSomethingWithSources(sources) }

Unfortunately, SBT does not want to load this plugin due to the fact that there exists circular dependency.

Due to this fact I've created another task like this:

lazy val myTask = TaskKey[Unit]("myTask", "Do stuff")

This tasks actually depends on the sources value and generates the files.

Later I override the projectSettings value and add this:

myTask in Compile := {
  val sourcesValue = (sources in Compile).value
  doSomethingWithSources(sourcesValue)
},
sourcesGenerators in Compile += Def.task(Seq(new File("path/to/myGeneratedSource.scala"))).taskValue

I add this task as the dependency to the compile task in the build.sbt of the project that I want my plugin to do stuff like this:

compile in Compile <<= (compile in Compile) dependsOn (myTask in Compile)

While it works (the file is generated), when I launch the sbt command sbt run, it creates the file but does not compile it.

What is more, when I run just sbt compile run, it compiles only the project on the first (compile) task and generates my source and then on run part it compiles the generated source - so, in matter of speaking, it does somehow work, but it needs two compilations.

I'd like to ask if there is a simpler way to do this and, if not, how to make it work in only one compilation.

0 Answers0