Execute sbt task without prior compiling (for generating database classes with JOOQ)

170 Views Asked by At

I have a PlayFramework 2.7 application which is build by sbt.

For accessing the database, I am using JOOQ. As you know, JOOQ reads my database schema and generates the Java source classes, which then are used in my application.

The application only compiles, if the database classes are present.

I am generating the classes with this custom sbt task:

// https://mvnrepository.com/artifact/org.jooq/jooq-meta
libraryDependencies += "org.jooq" % "jooq-meta" % "3.12.1"

lazy val generateJOOQ = taskKey[Seq[File]]("Generate JooQ classes")
generateJOOQ := {
  (runner in Compile).value.run("org.jooq.codegen.GenerationTool",
  (fullClasspath in Compile).value.files,    
  Array("conf/db.conf.xml"),
  streams.value.log).failed foreach (sys error _.getMessage)
  ((sourceManaged.value / "main/generated") ** "*.java").get
}

I googled around and found the script above and modified it a little bit according to my needs, but I do not really understand it, since sbt/scala are new to me.

The problem now is, when I start the generateJOOQ, sbt tries to compile the project first, which fails, because the database classes are missing. So what I have to do is, comment all code out which uses the generated classes, execute the task which compiles my project, generates the database classes and then enable the commented out code again. This is a pain!

I guess the problem is the command (runner in Compile) but I did not find any possibility to execute my custom task WITHOUT compiling first.

Please help! Thank you!

1

There are 1 best solutions below

0
cbley On

Usually, when you want to generate sources, you should use a source generator, see https://www.scala-sbt.org/1.x/docs/Howto-Generating-Files.html

sourceGenerators in Compile += generateJOOQ

Doing that automatically causes SBT to execute your task first before trying to compile the Scala/Java sources.

Then, you should not really use the runner task, since that is used to run your project, which depends on the compile task, which needs to execute first of course.

You should add the jooq-meta library as a dependeny of the build, not of your sources. That means you should add the libraryDependencies += "org.jooq" % "jooq-meta" % "3.12.1" line e.g. to project/jooq.sbt.

Then, you can simply call the GenerationTool of jooq just as usually in your task:

// build.sbt

generateJOOQ := {
  org.jooq.codegen.GenerationTool.main(Array("conf/db.conf.xml"))
  ((sourceManaged.value / "main/generated") ** "*.java").get
}