How do I add the resourceDirectory in Java Classpath while SBT runs tests?
For now I only have sbt jar.
My need is due to a dependency (spark-cassandra-connector EmbeddedCassandra) loading a resource via ClassLoader.getSystemResourceAsStream rather than getClass().getClassLoader().getResource ...
If you want to add a new file/folder to your Java Classpth you can add the following line in your build.sbt:
(fullClasspath in Test) := (fullClasspath in Test).value ++ Seq(Attributed.blank((resourceDirectory in Test).value))
This will add the folder given by the test:resourceDirectory setting to the Classpath under the Test configuration.
Note:
The fullClasspath task provides a classpath including both the dependencies and the products of a project. For the test classpath, this includes the main and test resources and compiled classes for the project as well as all dependencies for testing.
...
fullClasspath is the concatenation of dependencyClasspath and exportedProducts
More details can be found here.
I have a multi-project build and I'm trying to add the jar with assets generated by sbt-web to the classpath of the launch script
The project I'm interested in is called website.
typing show website/web-assets:packageBin in sbt creates and shows the jar with the assets. I tried putting in (managedClasspath in website) += website/web-assets:packageBin, but that doesn't compile:
path/to/build.sbt:58: error: value / is not a member of sbt.Project
managedClasspath in website += website/web-assets:packageBin
How can I create the jar with assets when I run the stage task, and place it on the classpath of the launch script
You are mixing sbt-console commands with build.sbt commands.
The sbt-web docs give a clear example how you do it for a single project:
(managedClasspath in Runtime) += (packageBin in Assets).value
So now we do the same thing for a multi-module build. Assuming you have a build.sbt that looks like this
val root = (project in ".")
.aggregate(common, website)
val common = (project in "commons")
.settings(
libraryDependencies ++= Seq(...),
...
)
val website = (project in "commons")
.enablePlugins(JavaServerAppPackaging, SbtWeb)
.settings(
// ------ You configure it like a single module project
(managedClasspath in Runtime) += (packageBin in Assets).value
// ----------------------------------------------------
)
.dependsOn(common)
I have not directly tested this as I don't know your exact configuration. However this should give you the right direction.
I'm using latest version of sbt 0.13.7, and I'd like to set Class-Path header of my MANIFEST.MF file with all the project dependencies, and I don't really know how. I did read Configure packaging.
I do know how to set other headers like Main-Class:
mainClass in (Compile, packageBin) := Some("mypackage.MyClass")
I know it can be done with the sbt-assembly plugin, but I don't want to create one big jar, just a small jar, that includes all the dependencies.
I found I could set Class-Path with *.jar, as shown in this snippet:
packageOptions in (Compile, packageBin) +=
Package.ManifestAttributes(java.util.jar.Attributes.Name.CLASS_PATH -> "*.jar")
It appears a kind of workaround not a final solution. Any guidance very welcome.
There are two full build definition files in sbt project: Build.scala and Helpers.scala. They are located in project folder.
I'd like to put Helpers module into separate sub-folder project/utils. When I do import utils.Helpers in Build.scala it says:
not found: object utils
Is it possible to define directory structure that follows the packages in sbt full build definitions?
you should use project/src/main/scala/utils instead of project/utils
Sbt builds are recursive, which means that sbt build definition is built by sbt, applying the same rules as per normal project.
Unlike Java, Scala has no strict relation between the package and folder structure. Meaning you can place your sources wherever you like and it doesn't have to match package declaration. Scala will not complain.
Sbt knows where to search for folders by checking sourceDirectories setting key.
You can check it easily by executing show sourceDirectories. However this will show the sourceDirectories for your actual project. How you can check it for the build? Quite easily, execute reload plugins, this will take you to your build. Execute show sourceDirectories, and it should show you that it looks for sources in /project/src/main/scala, project/src/main/java and one more, which is managed sources (doesn't matter for our case). Now you can execute reload return to go back to your main project.
Given that you should be able to create an object let's say, named Helpers in project/src/main/scala/utils/Helpers.scala:
package utils
object Helpers {
def printFancy(name: String) = println(s">>$name<<")
}
And use it in your Build.scala:
import sbt._
import Keys._
import utils.Helpers._
object MyBuild extends Build {
val printProjectName = taskKey[Unit]("Prints fancy project name")
lazy val root = project.in(file(".")).settings(
printProjectName := printFancy(name.value)
)
}
You can test it by executing printProjectName.
> printProjectName
>>root<<
[success] Total time: 1 s, completed May 29, 2014 1:24:16 AM
I've stated earlier that sbt is recursive. This means, that if you want, you can use the same technique to configure the sbt build, as you use for configuring building of your own project.
If you don't want to keep your files under /project/src/main/scala, but just under /project/utils, you can do so by creating build.sbt in your project folder, with following content:
unmanagedSourceDirectories in Compile += baseDirectory.value / "utils"
Just as it is described in the documentation
Now even if you place your utils in project/utils sbt should be able to find it.
I have tried to install SBT on my macbook. When I run it, it doesn't ask me for any project definitions (e.g. title) and simply says
[info] Set current project to default (in build file:/Users/qui/Documents/Programming/test2/)
It then goes to what looks like the sbt interpreter.
When I look inside "test2", there is a project and target directory but I dont see a src directory to work with
Clearly I have gone wrong somewhere in my installation but I'm unsure where. Any ideas?
Update
So I just installed 0.10 on a fresh fedora install. And I am getting the exact same problem, same "info" message and it has only created a project and target directory
I must be doing something idiotic right? What am I doing wrong? :p
I work with SBT 0.13 so...your mileage may vary.
sbt's default behaviour
What you experience is the default behaviour of sbt. The tool expects that the project files are already in place or when there is no project files it doesn't bother to create them - the default values are just applied to the current directory that effectively becomes the project directory for a project called by the name of the directory it's in. SBT then opens sbt shell.
jacek:~/sandbox/stackoverflow/testaaa
$ tree
.
0 directories, 0 files
jacek:~/sandbox/stackoverflow/testaaa
$ sbt
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Updating {file:/Users/jacek/.sbt/0.13/plugins/}global-plugins...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Set current project to testaaa (in build file:/Users/jacek/sandbox/stackoverflow/testaaa/)
[testaaa]>
Quoting Running from the official documentation of SBT.
Running sbt with no command line arguments starts it in interactive
mode. Interactive mode has a command prompt (with tab completion and
history!).
Example
In your case, when you started sbt in /Users/qui/Documents/Programming/test2/ it silently assumed it's the project directory and applied the default settings.
The following sbt session is in test2 directory, too. I use help to display the help of a setting key and then use the key to display its value.
jacek:~/sandbox/stackoverflow/test2
$ tree
.
0 directories, 0 files
jacek:~/sandbox/stackoverflow/test2
$ sbt
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Set current project to test2 (in build file:/Users/jacek/sandbox/stackoverflow/test2/)
[test2]> help name
Project name.
[test2]> name
[info] test2
[test2]> help organization
Organization/group ID.
[test2]> organization
[info] default
[test2]> help version
The version/revision of the current module.
[test2]> version
[info] 0.1-SNAPSHOT
[test2]> help scalaVersion
The version of Scala used for building.
[test2]> scalaVersion
[info] 2.10.2
(I've changed the prompt so the name of the project, i.e. the name of the directory sbt has been started in, is displayed before the >).
You can change the value of a key with the set command that Evaluates a Setting and applies it to the current project.
[test2]> help set
set [every] <setting-expression>
Applies the given setting to the current project:
1) Constructs the expression provided as an argument by compiling and loading it.
2) Appends the new setting to the current project's settings.
3) Re-evaluates the build's settings.
This command does not rebuild the build definitions, plugins, or configurations.
It does not automatically persist the setting(s) either.
To persist the setting(s), run 'session save' or 'session save-all'.
If 'every' is specified, the setting is evaluated in the current context
and the resulting value is used in every scope. This overrides the value
bound to the key everywhere.
[test2]> set scalaVersion := "2.10.3"
[info] Defining *:scalaVersion
[info] The new value will be used by *:allDependencies, *:dependencyUpdatesData and 11 others.
[info] Run `last` for details.
[info] Reapplying settings...
[info] Set current project to test2 (in build file:/Users/jacek/sandbox/stackoverflow/test2/)
[test2]> scalaVersion
[info] 2.10.3
In the other question on StackOverflow #regis-jean-gilles has showed how to set the other settings using the set command.
[test2]> set name := "My test2 sbt project"
[info] Defining *:name
[info] The new value will be used by *:description, *:normalizedName and 8 others.
[info] Run `last` for details.
[info] Reapplying settings...
[info] Set current project to My test2 sbt project (in build file:/Users/jacek/sandbox/stackoverflow/test2/)
[test2]> set version := "1.0"
[info] Defining *:version
[info] The new value will be used by *:isSnapshot, *:projectId and 5 others.
[info] Run `last` for details.
[info] Reapplying settings...
[info] Set current project to My test2 sbt project (in build file:/Users/jacek/sandbox/stackoverflow/test2/)
[test2]> set scalaVersion := "2.10.3"
[info] Defining *:scalaVersion
[info] The new value will be used by *:allDependencies, *:dependencyUpdatesData and 11 others.
[info] Run `last` for details.
[info] Reapplying settings...
[info] Set current project to My test2 sbt project (in build file:/Users/jacek/sandbox/stackoverflow/test2/)
[test2]> session save
[info] Reapplying settings...
[info] Set current project to My test2 sbt project (in build file:/Users/jacek/sandbox/stackoverflow/test2/)
[test2]> exit
The build.sbt file will then contain all the settings as if there'd been set there in the first place.
$ cat build.sbt
name := "My test2 sbt project"
version := "1.0"
scalaVersion := "2.10.3"
By default, sbt creates various files in target directory. When you look inside the target directory, there are no files - just an empty directory. The same applies to project that also may or may not hold target directory. They're assumed to be available and if there's not, they're created by default.
When you change a setting in sbt's interactive shell (with set), you can save the session with session save.
[test2]> help session
session <command>
Manipulates session settings, which are temporary settings that do not persist past the current sbt execution (that is, the current session).
Valid commands are:
clear, clear-all
Removes temporary settings added using 'set' and re-evaluates all settings.
For 'clear', only the settings defined for the current project are cleared.
For 'clear-all', all settings in all projects are cleared.
list, list-all
Prints a numbered list of session settings defined.
The numbers may be used to remove individual settings or ranges of settings using 'remove'.
For 'list', only the settings for the current project are printed.
For 'list-all', all settings in all projets are printed.
remove <range-spec>
<range-spec> is a comma-separated list of individual numbers or ranges of numbers.
For example, 'remove 1,3,5-7'.
The temporary settings at the given indices for the current project are removed and all settings are re-evaluated.
Use the 'list' command to see a numbered list of settings for the current project.
save, save-all
Makes the session settings permanent by writing them to a '.sbt' configuration file.
For 'save', only the current project's settings are saved (the settings for other projects are left alone).
For 'save-all', the session settings are saved for all projects.
The session settings defined for a project are appended to the first '.sbt' configuration file in that project.
If no '.sbt' configuration file exists, the settings are written to 'build.sbt' in the project's base directory.
[test2]> session save
[info] Reapplying settings...
[info] Set current project to test2 (in build file:/Users/jacek/sandbox/stackoverflow/test2/)
Once you do that, a build.sbt with your own setting(s) is saved. That might be a good starting point for further configuration of a project.
jacek:~/sandbox/stackoverflow/test2
$ cat build.sbt
scalaVersion := "2.10.3"
Typesafe Activator
According to the home page of Typesafe Activator:
Typesafe Activator is a browser-based or command-line tool that helps
developers get started with the Typesafe Reactive Platform.
Under the covers, Activator is a UI built atop of sbt as demo'ed by Josh Suereth in the screencast Introducing sbt 0.13.2.
It appears that that's the only blessed solution for setting up sbt projects out of the many templates available in Activator.
giter8 - sbt project (layout) templates
If you however need some help to lay out the directory structure and have a ready-to-use project setup, you may want to use giter8 that's a command line tool to apply templates defined on github
Say, you want to create a project with scalaz dependency. You may want to use adinapoli/scalaz-revolver (see the list of available templates).
jacek:~/sandbox/stackoverflow
$ g8 adinapoli/scalaz-revolver
Simple scala project with sbt-revolver
organization [org.example]: pl.japila
name [Scala sbt-revolver project]:
scala_version [2.9.2]: 2.10.3
version [0.1-SNAPSHOT]:
Template applied in ./scala-sbt-revolver-project
jacek:~/sandbox/stackoverflow
$ cd scala-sbt-revolver-project/
jacek:~/sandbox/stackoverflow/scala-sbt-revolver-project
$ tree
.
├── README
├── build.sbt
├── project
│ ├── Build.scala
│ ├── build.properties
│ └── plugins.sbt
└── src
└── main
└── scala
└── pl
└── japila
└── ScalaSbtrevolverProject.scala
6 directories, 6 files
See Create a project directory with source code to find out more.
np - new sbt project generation made simple(r)
As pointed out in the comments by #0__ below, there's another project that aims at simplifying how new projects in sbt are created - np. That seems exactly what you needed.
In https://github.com/softprops/np#for-sbt-013 there's a complete description of what's needed to set it up and create new sbt projects using the utility that boils down to:
Registering the sbt plugin. Add the following to ~/.sbt/0.13/plugins/np.sbt.
addSbtPlugin("me.lessis" % "np" % "0.2.0")
Define a custom global overrides in ~/.sbt/0.13/np.sbt. Add the following to the file.
seq(npSettings:_*)
(NpKeys.defaults in (Compile, NpKeys.np)) ~= {
_.copy(org="me.lessis", version="0.1.0-SNAPSHOT")
}
Use the np plugin's command - np. Create an empty directory for the sbt project and run sbt np.
jacek:~/sandbox/stackoverflow
$ mkdir np-sandbox/
jacek:~/sandbox/stackoverflow
$ cd np-sandbox/
jacek:~/sandbox/stackoverflow/np-sandbox
$ sbt np
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Set current project to np-sandbox (in build file:/Users/jacek/sandbox/stackoverflow/np-sandbox/)
[info] Generated build file
[info] Generated source directories
[success] Total time: 0 s, completed Dec 7, 2013 12:51:42 PM
jacek:~/sandbox/stackoverflow/np-sandbox
$ tree
.
├── build.sbt
├── src
│ ├── main
│ │ ├── resources
│ │ └── scala
│ └── test
│ ├── resources
│ └── scala
└── target
└── streams
└── compile
└── np
└── $global
└── out
12 directories, 2 files
jacek:~/sandbox/stackoverflow/np-sandbox
$ cat build.sbt
organization := "me.lessis"
name := "default"
version := "0.1.0-SNAPSHOT"
No you're not doing something wrong, previous versions of sbt (0.7.x) did ask you if you wanted to create your project.
sbt version 0.10.x is a complete rewrite and does not act the same way (i.e. ask you to create a project on startup).
The old project was on googlecode but has since moved to github, you can find the documentation for 0.10.x at https://github.com/harrah/xsbt/wiki, in particular https://github.com/harrah/xsbt/wiki/Settings if you come from a 0.7.x background.
It's a bit hard to wrap your head around the new settings system at first, but trust me when I say you'll love it :)
As described in the np plugin readme, the required steps would be :
mkdir -p src/{main,test}/scala
touch build.sbt && vi build.sbt # fill in the basics (name, organization, version)
touch README.md && vi README.md
sbt
... start coding
One-liner to create the directory-structure and files (all empty):
mkdir -p ./src/{main,test}/{scala,java,resources}; mkdir project; touch build.sbt; touch project/build.properties
I found and updated a script by Alvin Alexander (author of the amazing book Scala Cookbook) that does just what you want.
Once again, I provide a bash script because the task of creating the directories and the files is pedantic, but simple. Making a full fledged plugin for SBT for this is an overkill.
This script creates an SBT project directory beneath the current directory.
Directory/Project Name (MyFirstProject): ProjectX
Create .gitignore File? (Y/n):
Create README.md File? (Y/n):
-----------------------------------------------
Directory/Project Name: ProjectX
Create .gitignore File?: y
Create README.md File?: y
-----------------------------------------------
Create Project? (Y/n):
Project created. See the following URL for build.sbt examples:
http://alvinalexander.com/scala/sbt-syntax-examples
$ cat build.sbt
name := "ProjectX"
version := "1.0"
scalaVersion := "2.11.7"
$
And finally, I believe SBT launched without any arguments should behave exactly like this script.