In order to run assembly without tests, it's recommended to run:
sbt 'set test in assembly := {}' clean assembly
But when we have a multi-project setup, this doesn't work. I have to do things like
sbt 'set test in assembly in sub1 := {}' 'set test in assembly in sub2 := {}' clean assembly
But what I'm working on is a generic script that creates jenkins jobs. So I have no knowledge of submodules of our future projects.
Is there a way to exclude tests for all the submodules with a single command?
Related
When I had a single-part project, from the command line I could say:
sbt testOnly *.FooSpec
Now that I have a multi-part project, that same command returns nothing--it can't find FooSpec. Imagine FooSpec lives in a subproject called 'part'. How can I specify 'part' in my sbt command? I tried:
sbt testOnly part:*.FooSpec
Didn't work.
(btw, I know I can do 'project part' then 'testOnly *.FooSpec' from inside sbt. I want to do this all from the shell, not inside sbt)
I don't wanna create any deployable without running tests. Is there anyway in sbt-native-packager / sbt where I could run sbt test in inside sbt dist, which would fail when any test fails?
There are multiple ways to achieve this.
Create a command alias
This is my recommended approach as it is very explicit, easy to understand and extend. In your build.sbt add
addCommandAlias("buildDist", "; compile ; test ; dist")
Now you can call sbt buildDist
Depend on test
You can add dependencies between tasks. In your build.sbt
dist := (dist dependsOn test).value
This will add the test task as a dependency
Cheers,
Muki
I am in the process of creating a plugin that will modify both the compile:compile and test:test tasks. My ultimate aim is to be able to do sbt monkjack or sbt monkjack:test (either is fine). In the compile:compile scope I need to add a compiler plugin, and in the test:test scope I need to run some code after the tests have finished.
My first attempts were around trying to create a custom configuration but which to extend, compile or test, was unclear as both are needed (At the moment I have two, and I copy the CustomTest into the CustomCompile and then run monkjack:test). My second attempts were focusing on a custom task that in turn invoked (compile in Compile).value and (test in Test).value after setting various options.
I realize my knowledge of SBT tasks and how they are related/inherited/scoped is not great.
Q1. Is there a chain of tasks like in maven? In maven if you execute test, it will execute the other phases in order. So mvn clean test will automatically run prepare-sources, compile, etc etc. So in SBT if I run sbt test how are the other tasks automatically executed.
Q2. If you execute a task with a custom config, eg sbt millertime:test will that config propagate to the other tasks that run. Eg, is this the same as sbt monkjack:compile monkjack:test or the same as sbt compile monkjack:test or neither :)
Q3. How do tasks know which is their default config? If I do sbt compile how does SBT know that means sbt compile:compile?
Q4. Which is the best way to go here, a custom configuration or a new task.
I have a multi-module build, and would like to run tests for different sub-projects independently.
Is there a way to do this in sbt, e.g. if my multi-project build has a core and commons projects, I'd like to only run test in the commons project.
Run sbt commons/test. See detailed explanation in Scopes.
You may also use the combination of two commands from sbt - changing the current project using project and executing test afterwards.
sbt "project commons" test
You can also use
sbt "; project commons; test"
It you are running sbt in interactive mode:
> project commons
> test
You can switch back to core with:
> project core
Never mind, I came across this:
How to execute package for one submodule only on Jenkins?
sbt "project core" test
Another way to do this.
Get into SBT interactive mode
> sbt
sbt:core> commons / test
No need to switch between projects.
to run sbt test only for ONLY the submodules having added, modified on deleted files, if you use git:
while read -r proj ; do sbt "project $proj" test ; \
done < <(git status --porcelain | cut -c 3- | cut -d/ -f1
There is another way to have sbt open for a particular module.
Go to the location of the module directory and type in the "sbt" command.
sbt will then open in interactive mode for that module only
I'm trying to set up a Scala project, built using SBT, that will consist of a library and several command-line tools to do various things using that library. The library and tools are going to depend on another Scala project which I've installed into my local Ivy cache with sbt publish-local.
I've never used SBT before, so I'm a bit lost as to how to set this up. I would like several Linux executables or shell scripts in my top-level project directory, each of which executes a main() methods defined in a Scala file, and all of which depend on a single library. How do I get that sort of setup with an SBT project?
The way I'm thinking this will have to work is as an SBT configuration with multiple projects, and a bunch of wrapper shell scripts that execute sbt run in the appropriate project. However, when I run sbt run in my current single-project setup, I get, in addition to my program's intended output, a bunch of SBT noise:
Loading /pod/home/anovak/build/sbt/bin/sbt-launch-lib.bash
[info] Loading project definition from /pod/home/anovak/sequence-graphs/project
[info] Set current project to Sequence Graph API (in build file:/pod/home/anovak/sequence-graphs/)
[info] Running SequenceGraphs
Sequence Graphs are great!
[success] Total time: 2 s, completed Jan 6, 2014 6:01:17 PM
I would like my wrapper scripts to be able to run my command-line tools without seeing anything from SBT on screen at all. I think the [info] and [success] messages can be suppressed by messing about with the project's log level settings, but would that eliminate the "Loading..." line as well? If not, is there some other way to run an SBT project "on its own", without much/any interference from SBT?
I think what you need is one root project - sequence-graphs - with two submodules - library and cmd-tools.
project/build.properties would be as follows:
sbt.version=0.13.1
build.sbt for the root project would be as follows:
lazy val root = project in file(".") aggregate (library, `cmd-tools`)
lazy val library = project
lazy val `cmd-tools` = project dependsOn library
With only these two files you can run sbt and do projects to see the projects available.
[root]> projects
[info] In file:/Users/jacek/sandbox/so/sequence-graphs/
[info] cmd-tools
[info] library
[info] * root
At the same time SBT will create necessary subdirectories for the submodules.
With the project layout you start developing your own command-line tools in cmd-tools submodule.
To make things simple, I assume that a simple App-extending applications are enough.
cmd-tools/Hello1.scala
object Hello1 extends App {
println("Hello1")
}
cmd-tools/Hello2.scala
object Hello2 extends App {
println("Hello2")
}
With these two Hellos you can run cmd-tools/run from SBT shell in the root project.
[root]> cmd-tools/run
[info] Compiling 2 Scala sources to /Users/jacek/sandbox/so/sequence-graphs/cmd-tools/target/scala-2.10/classes...
Multiple main classes detected, select one to run:
[1] Hello2
[2] Hello1
Enter number:
The same could be run from the command line as sbt cmd-tools/run:
jacek:~/sandbox/so/sequence-graphs
$ sbt cmd-tools/run
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Loading project definition from /Users/jacek/sandbox/so/sequence-graphs/project
[info] Set current project to root (in build file:/Users/jacek/sandbox/so/sequence-graphs/)
Multiple main classes detected, select one to run:
[1] Hello1
[2] Hello2
Enter number: 1
[info] Running Hello1
Hello1
[success] Total time: 4 s, completed Jan 9, 2014 9:44:39 PM
Let's start it over as well as disable infos and [success]es messages.
jacek:~/sandbox/so/sequence-graphs
$ sbt --error 'set showSuccess := false' cmd-tools/run
Multiple main classes detected, select one to run:
[1] Hello1
[2] Hello2
Enter number: 1
Hello1
There's also the runMain command that Runs the main class selected by the first argument, passing the remaining arguments to the main method.
With that and the other examples you could have a sample command-line script to execute Hello1 as follows:
sbt --error 'set showSuccess := false' 'cmd-tools/runMain Hello1'
It could be even simpler when you use the sbt-onejar plugin that can Package your project using One-JARâ„¢ With the plugin you don't have to use SBT after you distribute your command-line tools.
Quoting the plugin's documentation:
sbt-onejar is a simple-build-tool plugin for building a single executable JAR containing all your code and dependencies as nested JARs.
Please note that the Officially supported packages of SBT add some additional checks and printouts, i.e. tgz comes with bin/sbt script that does the following (amongst the other things):
echo "Loading $(dirname "$(realpath "$0")")/sbt-launch-lib.bash"
It's not an integral part of SBT itself, but the script itself that wants to do as much as possible so an end user is, say, happy. In your case, you are not necessarily happy, so either remove the line from the script or follow the steps as described in Manual Installation.