Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

adding task to sbt 13.x build.sbt

Tags:

scala

sbt

I have added this to build.sbt

libraryDependencies += "com.typesafe.slick" %% "slick-codegen" % "2.1.0"

lazy val slickGenerate = TaskKey[Seq[File]]("slick code generation")

slickGenerate <<= slickGenerateTask 

lazy val slickGenerateTask = {
    (sourceManaged in Compile, dependencyClasspath in Compile, runner in Compile, streams) map { (dir, cp, r, s) =>
      val dbName = "dbname"
      val userName = "user"
      val password = "password"
      val url = s"jdbc:mysql://server:port/$dbName" 
      val jdbcDriver = "com.mysql.jdbc.Driver"
      val slickDriver = "scala.slick.driver.MySQLDriver"
      val targetPackageName = "models"
      val outputDir = (dir / dbName).getPath // place generated files in sbt's managed sources folder
      val fname = outputDir + s"/$targetPackageName/Tables.scala"
      println(s"\nauto-generating slick source for database schema at $url...")
      println(s"output source file file: file://$fname\n")
      r.run("scala.slick.codegen.SourceCodeGenerator", cp.files, Array(slickDriver, jdbcDriver, url, outputDir, targetPackageName, userName, password), s.log)
      Seq(file(fname))
    }
}

The task's code itself isn't very exciting. It just needs to create an auto-generated scala source file. Problem is, sbt starts fine, yet this new task is evidently not recognized by sbt and cannot be run in the sbt prompt. I have also had very little luck with the := syntax for task definition. Existing documentation has been just confounding.

How can this new task be made available in the sbt prompt?

like image 941
matanster Avatar asked Feb 11 '23 22:02

matanster


1 Answers

This works

libraryDependencies += "com.typesafe.slick" %% "slick-codegen" % "2.1.0"

lazy val slickGenerate = taskKey[Seq[File]]("slick code generation")

slickGenerate := {
  val dbName = "dbname"
  val userName = "user"
  val password = "password"
  val url = s"jdbc:mysql://server:port/$dbName"
  val jdbcDriver = "com.mysql.jdbc.Driver"
  val slickDriver = "scala.slick.driver.MySQLDriver"
  val targetPackageName = "models"
  val outputDir = ((sourceManaged in Compile).value / dbName).getPath // place generated files in sbt's managed sources folder
  val fname = outputDir + s"/$targetPackageName/Tables.scala"
  println(s"\nauto-generating slick source for database schema at $url...")
  println(s"output source file file: file://$fname\n")
  (runner in Compile).value.run("scala.slick.codegen.SourceCodeGenerator", (dependencyClasspath in Compile).value.files, Array(slickDriver, jdbcDriver, url, outputDir, targetPackageName, userName, password), streams.value.log)
  Seq(file(fname))
}

In sbt 0.13.x you don't need all those blabla map sameblabla boilerplates. Just access value as is (runner in Compile).value - macro will do everything else for you.

> slickGenerate
[info] Updating {file:/Users/user/slick/}slick...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.

auto-generating slick source for database schema at jdbc:mysql://server:port/dbname...
output source file file: file:///Users/user/slick/target/scala-2.10/src_managed/main/dbname/models/Tables.scala

> help slickGenerate
slick code generation

Talking about <<= - your TaskKey is incorrect, see the definition:

def apply[T](label : scala.Predef.String, description : scala.Predef.String // not description

So, the old definition <<= uses "generate slick code" as label, while the new := uses the code-given name for command (new style), so it uses your "generate slick code" as a doc. Which looks strange and inconsistent, but that's a fact and it's partially reasoned by backward-compatibility.

So, correct old-style version is:

import sbt.Keys._

lazy val slickGenerate = TaskKey[Seq[File]]("slick-generate", "generate slick code")

slickGenerate <<= slickGenerateTask

def slickGenerateTask =
  (sourceManaged in Compile, dependencyClasspath in Compile, runner in Compile, streams) map { (dir, cp, r, s) =>
    ...
  }

It works in the same way as previous. Note, that you have to use "slickGenerate", not "slick-generate", the last one doesn't work for "help" command.

By the way, you're using Bare build definition now - you may want to switch to Multi-project .sbt definition as it's recommended by sbt docs, see also.

like image 165
dk14 Avatar answered Feb 16 '23 02:02

dk14