How to add custom directory to Scala SBT project? - scala

We have conf directory in our project which is fine, but one of the new components requires its own config to be placed into config directory and we can't change that requirement. In my build.scala I added the line:
unmanagedResourceDirectories in Compile += baseDirectory.value / "config",
In SBT when I run $ inspect tree package-src I can see the config directory under compile:unmanagedResourceDirectories section which is under compile:packageSrc::mappings section.
Then I try to check the deployment package locally by running $ publishLocal. The target config directory is missing in the result .zip package.
What did I miss / do wrong?

This is what I added to my Build.scala to finally solve the issue:
mappings in Universal ++= (baseDirectory.value / "config" * "*" get) map
(x => x -> ("config/" + x.getName)),

Related

sbt - add unmanaged resources to console

In sbt, I want to add a config directory to the runtime class-path (but not export it as part of package). So I have this:
unmanagedClasspath in Runtime += baseDirectory.value / "config"
This works fine for sbt run, but apparently is not on the class-path if I use sbt console.
How can I add this directory to the class-path for the console task without it showing up in the exported jar?
Edit: I also tried the following, but I still cannot get the resources:
unmanagedClasspath in (Compile, console) += baseDirectory.value / "config"
Actually adding the following does work:
unmanagedClasspath in Compile += baseDirectory.value / "config"
I had found the contents in "config" only because the package was created previously and using sbt clean package shows that now the contents of "config" will not be packaged any longer but do appear on the console class-path.

webappResources in package := Seq(baseDirectory.value ....) throws Error parsing expression

I try to configure sbt (version 0.9.0) to use webapp/dist as the webappResource directory when running package task in sbt, and webapp/app as the webappResource directory when running the container:start command, following this description:
How to have different webapp resources for container:start and package tasks in SBT
But it throws the following error:
error: eof expected but 'package' found.
webappResources in package := Seq(baseDirectory.value / "webapp" / "dist")
^
[error] Error parsing expression.
I guess that package is a reserved word also in sbt conf file, any other way to override setting in package task?
The reason for doing this is that I use gulp to manage webclient. Gulp runs the project from app folder, and compiles (minification etc.) the webclient project into dist folder. When I develop, I use the webapp/app folder as declared below:
webappResources in Compile := Seq(baseDirectory.value / "webapp" / "app")
When I create a release, I first build (minification etc.) the webapp client into webapp/dist using gulp. Then I want to package webapp/dist content into the final war.
But I am not able to override the setting above to use webapp/dist, when using the package task.
I have also tried to create my own configuration like this:
webappResources in Compile := Seq(baseDirectory.value / "src" / "main" / "webapp" / "app")
lazy val ReleaseWarConfig = config("release-war") extend (Compile)
val root = (project in file(".")).
configs(ReleaseWarConfig).
settings(inConfig(ReleaseWarConfig)(webSettings): _*).
settings(
webappResources in Compile := Seq(baseDirectory.value/"src"/"main"/"webapp"/"dist")
)
// I have also tried webappResources in ReleaseConfig instead of Compile ..
But it still uses the webapp/app directory instead of webapp/dist directory.
Any help would be very much appreciated !!!!
What is the directory layout of your project? It sounds like you have your Web application resources directory at [myproject]/webapp/dist/, meaning you have WEB-INF/ and WEB-INF/web.xml (and various other optional resources) under [myproject]/webapp/dist/ as well. Is this correct?
To set the location of your Web application resources directory to [myproject]/webapp/dist/, add the following setting to your sbt configuration:
build.sbt:
webappSrc in webapp <<= (baseDirectory in Compile) map { _ / "webapp" / "dist" }
You can read more about this setting in the readme.

Setup logging/config for production with deb file and SBT

I'm search for the best way way to set up my logging/config in production within my deb file using the sbt-native-packager.
a.) I want to copy my reference.conf and logback.xml from my code repository to /etc/my-app/reference.conf or /etc/my-app/logback.xml. I guess its somehow possible with linuxPackageMappings but i could'nt find a example yet and I'm still struggling to get how SBT and the plugings work together.
b.) I need to tell my jvm that i should use this config and this logback config when started via the created upstart - how do I pass parameters from the build.scala to the jvm-runscript
this is my current project val:
lazy val root = Project(id = appName, base = file("."), settings = JavaServerAppPackaging.settings ++ packageSettings ++ allSettings ++ Project.defaultSettings)
lazy val allSettings = Seq(
resolvers += "Typesafe Releases" at "http://repo.typesafe.com/typesafe/releases",
resolvers += "Sonatype OSS Snapshots" at "http://oss.sonatype.org/content/repositories/snapshots/",
libraryDependencies ++= dependencies)
lazy val packageSettings = packageArchetype.java_server ++ Seq(
bashScriptExtraDefines := Seq("aha"),
version := appVersion,
packageSummary := appName,
packageDescription := appName,
maintainer := appAuthor,
debianPackageDependencies in Debian ++= Seq("openjdk-7-jre-headless"))
thanks
a) For logging output see this question. Configuration input can be done easily with
mappings in Universal <+= (packageBin in Compile, baseDirectory ) map { (_, base) =>
val conf = base / "conf" / "reference.conf"
conf -> "conf/application.conf"
}
By convention the Universal packaging defines config files in the conf folder. For debian this automatically mapped to /etc/your-app/filename
b) Passing parameters to the script is also done via a config file. Use 0.7.0-M3 and follow the instructions here and take a look at the etc-default template
Lots of questions mixed in hear...
a) So to you can install your conf and xml files by including them in your debian package. Building debian packages is not built in to sbt out of the box. You could try https://github.com/sbt/sbt-native-packager but you may be better of dropping out of sbt and just using one of the many normal ways to create debian packages.
Note that you should not be logging to /etc on a linux box. Logs should go under /var
b) you can install an init script that has -D peramiters to tell play where to find its conf and logback.xml files.
$JAVA_HOME/bin/java -Dconfig.file=/etc/foo.comf -Dlogger.file=/etc/logger.xml
c) you should be logging to some directory under /var
You can create directories in the postinst script that is part of the debian package. puppet (or something similar) can be a better way to manage config files on deployed boxes though.

sbteclipse additional source folders

How do I configure an extra folder for sbteclipse to include? I have a default sbt directory layout with an additional it/scala folder. I want that folder to be included in the generated .project and .classpath files, but I don't know how to do that....
You can achieve this for example by adding something like the following to your build.sbt:
unmanagedSourceDirectories in Compile <++= baseDirectory { base =>
Seq(
base / "some/subdir/src"
)
}
For details of the relation between unmanaged-sources, unmanaged-source-directories and scala-source you might want to check the documentation. After exporting the eclipse project from sbt, you should find a corresponding entry in your .classpath file, like:
<classpathentry output="target/scala-2.9.1/classes" path="some/subdir/src" kind="src"></classpathentry>
there can be case in which you may just want to add a folder say conf to the eclipse classpath which contains configurations required at runtime. Below is the trick -
unmanagedJars in Compile ++= {
val confBase = (baseDirectory.value ** "conf")
confBase.classpath
}
if you want to add, e.g., the folder src/folderXYZ, then add to build.sbt:
Compile / unmanagedSourceDirectories += baseDirectory.value / "src/folderXYZ"

How to configure sbt to load resources when running application?

My code (Java) reads an image from jar:
Main.class.getResourceAsStream("/res/logo.png")
Everything runs fine (if I start the app after packaging it into a jar). But when I run it using sbt's run task, it returns me null instead of needed stream.
Running this from sbt console also gives null:
getClass.getResourceAsStream("/res/logo.png")
Is there a way to tell sbt to put my resources on classpath?
EDIT:
I set the resources dir to be same as source dir:
build.sbt:
resourceDirectory <<= baseDirectory { _ / "src" }
When I loaded sbt's `console' and ran the following:
classOf[Main].getProtectionDomain().getCodeSource()
I got the location of my classes, but it does not contain neither res folder nor any of my resource files.
Seems that sbt copies resources only to the resulting jar, and does not copy them to classes dir. Should I modify compile task to move these resources files to classes dir?
EDIT2:
Yes, when I manually copy the resource file to classes dir, I can easily access it from console. So, how should I automate this process?
EDIT3:
It seems that sbt is just unable to see my resource folder - it does not add files to resulting jar file, actually!
Solution:
resourceDirectory in Compile <<= baseDirectory { _ / "src" }
I can't give you a full solution right now, but there is a setting called resourceDirectories to which you could add the res folder.
[EDIT]
For me it didn't work also if the resource was in the standard resource folder. Please try it that way:
Main.class.getClassLoader().getResourceAsStream("icon.png")
[EDIT2] This is the full build script (build.scala) which works if your resource is in src/main/java:
import sbt._
import Keys._
object TestBuild extends Build {
lazy val buildSettings = Seq(
organization := "com.test",
version := "1.0-SNAPSHOT",
scalaVersion := "2.9.1"
)
lazy val test = Project(
id = "test",
base = file("test"),
settings = Defaults.defaultSettings ++ Seq(resourceDirectory in Compile <<= javaSource in Compile)
)
}