Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining sbt task that invokes method from project code?

Tags:

I'm using SBT to build a scala project. I want to define a very simple task, that when I input generate in sbt:

sbt> generate 

It will invoke my my.App.main(..) method to generate something.

There is a App.scala file in myproject/src/main/scala/my, and the simplified code is like this:

object App {    def main(args: Array[String]) {        val source = readContentOfFile("mysource.txt")        val result = convert(source)        writeToFile(result, "mytarget.txt");    }    // ignore some methods here } 

I tried to add following code into myproject/build.sbt:

lazy val generate = taskKey[Unit]("Generate my file")  generate := {   my.App.main(Array()) } 

But which doesn't compile since it can't find my.App.

Then I tried to add it to myproject/project/build.scala:

import sbt._ import my._  object HelloBuild extends Build {    lazy val generate = taskKey[Unit]("Generate my file")    generate := {     App.main(Array())   }  } 

But it still can't be compiled, that it can't find package my.

How to define such a task in SBT?

like image 481
Freewind Avatar asked May 01 '14 14:05

Freewind


People also ask

How do I create a sbt task?

To declare a new task, define a lazy val of type TaskKey : lazy val sampleTask = taskKey[Int]("A sample task.") The name of the val is used when referring to the task in Scala code and at the command line. The string passed to the taskKey method is a description of the task.

What is ThisBuild in sbt?

Typically, if a key has no associated value in a more-specific scope, sbt will try to get a value from a more general scope, such as the ThisBuild scope. This feature allows you to set a value once in a more general scope, allowing multiple more-specific scopes to inherit the value.


1 Answers

In .sbt format, do:

lazy val generate = taskKey[Unit]("Generate my file")  fullRunTask(generate, Compile, "my.App") 

This is documented at http://www.scala-sbt.org/0.13.2/docs/faq.html, “How can I create a custom run task, in addition to run?”

Another approach would be:

lazy val generate = taskKey[Unit]("Generate my file")  generate := (runMain in Compile).toTask(" my.App").value 

which works fine in simple cases but isn't as customizable.

Update: Jacek's advice to use resourceGenerators or sourceGenerators instead is good, if it fits your use case — can't tell from your description whether it does.

like image 154
Seth Tisue Avatar answered Oct 21 '22 11:10

Seth Tisue