ssuperczynski ssuperczynski - 1 year ago 113
Scala Question

SBT how to create custom command

Given I have

build.sbt


name := """app"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.11.7"

// <-- some other code -->

import Fixtures._

lazy val fixtures = inputKey[Unit]("Generating Cassandra fixtures")

fixtures := {
Fixtures.generate()
}


and Fixtures.scala in
project
directory

object Fixtures {
def generate (): Unit = {
println("generating fixtures")
}
}


I am able to run command
./activator fixtures
and I am getting "generating fixtures"

But how can I call some service, let say
GenerateUserFixtureService.scala
but from
app/scala/com/MyProject/Service
directory. Import package does not work, because
project
directory belongs to different package. I am not able to import anything to
Fixtures.scala
from Play

|
|___app
| |__scala
| |__com
| |__MyProject
| |__Service
| |--GenerateUserFixtureService.scala
|___project
| |--Fixtures.scala
|___
|--build.sbt


Actually the question is, why I am able to import to
build.sbt
only files from
project
directory. Or how can I call another files from
app
dir?

Or maybe the way I am thinking is completely wrong. I just want to create some command
upload:fixtures
send:emails
etc, and call some scala class. How can I achieve this?

Answer Source

For creating a custom command you must specify a function which corresponds to the logic of your command. Let's consider a few examples: first just print hello message:

 def helloSbt = Command.command("hello") { state =>
        println("Hello, SBT")
        state
    }

commands += helloSbt

just put this code into build.sbt, commands is project key which is present into sbt.Keys as val commands = SettingKey[Seq[Command]]

Of course, you can manage the statement of your command like success or fail:

def failJustForFun = Command.single("fail-condidtion") {
        case (state, "true") => state.fail
        case (state, _) => state
    }

You can change the color in console for specific part of your command or output of this command via leveraging of DefaultParsers:

    lazy val color = token( Space ~> ("blue" ^^^ "4" | "green" ^^^ "2") )
    lazy val select = token( "fg" ^^^ "3" | "bg" ^^^ "4" )
    lazy val setColor = (select ~ color) map { case (g, c) => "\033[" + g + c + "m" }

And like alternative, you can extend xsbti.AppMain and implement - your own logic

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download