SBT, Run a main class from dependency project - scala

My build.sbt:
libraryDependencies += "org" %% "A" % "0.0.1"
So I run sbt on this file:
> sbt
I know that there is Main class in 'A', let's say "mainRun.scala". But I don't how to run it from my project.
How should I run it from SBT?

By default, sbt does not look into your dependencies for the auto detection of a main class. You can can however force it to use a specific class, either on the command line with
> runMain pack.MainClass
or via the sbt setting
mainClass := Some("pack.MainClass")

Related

why sbt-assembly failed to auto detect main class?

I have a Boot object with below definition
object Boot extends App with xxxService {}
And add below lines in plugins.sbt to enable sbt-assembly
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0")
then run this command to build up the whole project:
sbt clean compile assembly
In the genearted jar META-INF/MAINFEST.MF file, it does not have Main-Class generated, if I specify main class in build.sbt like mainClass in assembly := Some("com.XXX.Boot"), it worked.
My sbt version is 1.3.2, jvm is zulu8, scala is 2.12.13
From enter link description here it says, sbt-assembly will autodetect main class, then how does my example failed?
I update sbt-assembly into below
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0")
it can auto detect the main class without specify in build.sbt...
I guess this is might be related with sbt and scala verion...
my colleague can run the config in the question correctly...

How to execute Main-Class as part of compile in SBT

I wanted to execute a task as part of SBT compile, I tried runMain in compile but it is not executing the main class that I am providing. Below is how task looks like in build.sbt
lazy val scalaGeneratorPlugin = Project("scala-generator", file("scala-generator"))
.settings(
libraryDependencies += "org.freemarker" % "freemarker" % "2.3.23",
runMain in compile := Some("com.my.MyMainClass")
)
I am running following command:
sbt scala-generator/compile
Although it gives me success message, it does not execute my MainClass
I am copying laughedelic's answer in comment here:
I think you should use source generation in sbt for that, i.e. there should be different compilation stages.

How to activate the sbt DockerPlugin in scala?

I have two scala projects, one is already defined to build its docker container through the sbt docker plugin. The other one I want to dockerify as well.
The working one has in its build.sbt the following lines relevant to the docker config:
organization := "com.namespace"
name := "dockerized-app"
version := sys.env.getOrElse("PIPELINE_VERSION", "0.1.0_local")
scalaVersion := "2.12.4"
enablePlugins(JavaAppPackaging)
enablePlugins(DockerPlugin)
packageName in Docker := packageName.value
dockerRepository := Some("our-docker.io:5001")
dockerExposedPorts := Seq(8080)
I thought that I could copy paste the relevant lines to the new project, change the name, and make it work.
Yet when I add the line to the about to be dockerified scala project:
enablePlugins(DockerPlugin)
I get the error:
Cannot resolve symbol DockerPlugin
I've looked through the prexisting projects libraryDependencies, yet it doesn't seem to be configured that way. In the the pre-configured project, IntellJ somehow knows the plugin, I can track that the DockerPlugin comes from com.typesafe.sbt.packager.docker. This made me assume that sbt comes shipped with it by default.
Yet apparently I have to activate it somehow.
Digging deeper I also tried adding this to my plugins.sbt to no avail:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.2")
How to activate DockerPlugin using sbt in scala?
In order to make it working properly you need to add the following line:
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.2")
in your project/plugins.sbt file.
Then refresh your project and it should work.
For further information, please check the Sbt Native Packager documentation.

How do I call a dependent library function from an sbt task?

I have a CLI tool written in Java which can modify some source with the added params. For example, it can rename an enum value across a whole project.
I want to write an sbt task that can run this tool from my project dir with the given params, like sbt 'enums -rename A B'. My tool can be injected to the project through the sbt dependencies.
I skimmed through the book sbt in Action looking for an answer, but those examples are not this specific.
My build.sbt (far from working):
name := """toolTestWithActivator"""
version := "1.0-SNAPSHOT"
resolvers += "Local Repository" at "file://C:/Users/torcsi/.ivy2/local"
lazy val root = (project in file(".")).enablePlugins(PlayJava)
scalaVersion := "2.11.6"
libraryDependencies ++= Seq(
"tool" % "tool_2.11" % "1.0",
javaJdbc,
javaEbean,
cache,
javaWs
)
val mytool = taskKey[String]("mytool")
mytool := {
com.my.tool.Main
}
Can sbt handle this type of task/dependency structure, or do I need to do this another way?
SBT is recursive: it compiles .sbt files and .scala files under the project folder and use those to execute your build (in fact you can see sbt as a library that helps you producing builds).
So, as you need your library to define a task, that one is a dependency of your build.sbt file (and not a dependency of your project).
To declare that the build.sbt file depends on your library, just create a ".sbt" file in the project folder; example:
project/dependencies.sbt
libraryDependencies += "tool" %% "tool" % "1.0"
and in build.sbt add:
val mytool = taskKey[Unit]("mytool")
mytool := {
com.my.tool.main(Array())
}
Some comments:
be careful with the scala version used: as sbt 0.13 is compiled with scala 2.10; your library should also be compiled for scala 2.10 (the package should be tools_2.10 ). And the new sbt 1.0 is compiled with scala 2.12.
I used the %% notation, so that sbt adds by itself the expected scala version.
I supposed your cli tool defines a classic java main method (or the scala equivalent). So, the argument should be an Array of String (here an empty one) and it returns Unit (void in java).
Some reference to understand the solution:
http://www.scala-sbt.org/0.13/docs/Organizing-Build.html

Why does SBT 0.12.2 resolve plugins with Scala 2.9.2 and ignore scalaVersion in build.sbt?

SBT 0.12.2 always attempts to resolve plugins using Scala 2.9.2 when using the %% syntax on plugin imports.
I have tried setting older versions of Scala in build.sbt, newer versions, etc. Even deleting target folder each time... nothing seems to make a difference.
name := "Game"
version := "1.0"
scalaVersion := "2.9.1" // SBT is ignoring the scala version
SBT is recursive, so you need to specify scala version for project, that build your project. Another words, you need to add appropriate scalaVersion to the plugins.sbt file.
For all plugins in your project, you set scalaVersion in project/plugins.sbt file that configures the build project definition for your project and where you define plugins.
$ cat project/plugins.sbt
scalaVersion := "2.9.3"
There's however a way to set up a more specific version of sbt and Scala for a plugin.
Instead of using addSbtPlugin that accepts a single ModuleID (constructed with % and %%), use addSbtPlugin(dependency: ModuleID, sbtVersion: String) or even addSbtPlugin(dependency: ModuleID, sbtVersion: String, scalaVersion: String), e.g.
$ cat project/plugins.sbt
// It doesn't exist and it's only for demo purposes
addSbtPlugin("com.timushev.sbt" % "sbt-updates" % "0.1.0", "0.12.2", "2.5")