build.properties in SBT multi-project build - scala

I have a multi project build , the structure of the project looks like this:
project
build.properties
plugins.sbt
subprojects
subProj1
project/
build.properties
Now can we have 2 different sbt versions in 2 build.properies files ? Like we use sbt 0.13 in root project and 1.3 under subProj1 ? Or do sbt ignores the build.properties file for subprojects like it uses to do with plugins.sbt ?

build.properties is only relevant to the sbt launcher script which downloads appropriate version artefacts. After sbt "mother ship" is launched then sbtVersion should not be modified anymore as per inspect sbtVesion:
> inspect sbtVersion
[info] Setting: java.lang.String = 1.4.7
[info] Description:
[info] Provides the version of sbt. This setting should not be modified.
Considering project structure in OP, after sbt is launched at the root level, then build.properties files other than <root>/project/build.properties will be ignored.

Related

How to change sbt version for project

I have build.properties file in the project with the following line:
sbt.version=1.2.8
build.properties file is in the same folder as build.sbt file.
But when I enter the command "sbt about", it reports 1.0.3. Following is the actual output of the command:
/Users/kale> sbt about
[info] Loading settings from idea.sbt ...
[info] Loading global plugins from /Users/kale/.sbt/1.0/plugins
[info] Loading settings from plugins.sbt ...
[info] Loading project definition from
/Users/kale/workspace/gr8Project/myapp/project
[info] Loading settings from build.sbt ...
[info] Set current project to myapp (in build
file:/Users/kale/workspace/gr8Project/myapp/)
[info] This is sbt 1.0.3
[info] The current project is
{file:/Users/kale/workspace/gr8Project/myapp/}myapp 0.1-SNAPSHOT
[info] The current project is built against Scala 2.12.8
[info] Available Plugins: sbt.plugins.IvyPlugin,
sbt.plugins.JvmPlugin, sbt.plugins.CorePlugin,
sbt.plugins.JUnitXmlReportPlugin,
sbt.plugins.Giter8TemplatePlugin, sbtassembly.AssemblyPlugin,
com.lucidchart.sbt.scalafmt.ScalafmtCorePlugin,
com.lucidchart.sbt.scalafmt.ScalafmtPlugin,
com.lucidchart.sbt.scalafmt.ScalafmtSbtPlugin,
scoverage.ScoverageSbtPlugin,
net.virtualvoid.sbt.graph.DependencyGraphPlugin,
sbtdocker.DockerPlugin, Build, Docker
[info] sbt, sbt plugins, and build definitions are using Scala
2.12.4
How can I change sbt version to 1.2.8?
your project structure should be <root>/project/build.properties, and then you should change the sbt version property (see https://github.com/pedrorijo91/play-slick3-steps/blob/master/project/build.properties as an example)
Use sbt about to know the version in use.

How to use external dependencies in sbt's .scala files?

This is for Scala 2.11.1 and sbt 0.13.5.
Say I have a Scala/sbt project with the following directory structure:
root/
build.sbt
src/ ..
project/
plugins.sbt
build.properties
LolUtils.scala
and I want to use some external library in LolUtils.scala. How is this generally accomplished in sbt?
If I simply add the libs I need into build.sbt via libraryDependencies += .. then it doesn't find them and fails on the import line with not found: object ...
If I add a separate project/build.sbt, for some reason it starts failing to resolve my plugins, plus I need to manually specify the Scala version in the nested project/build.sbt, which is unnecessary duplication.
What's the best way to accomplish this?
sbt is recursive which means that it uses itself to compile a build definition, i.e. *.sbt files and *.scala files under project directory. To add extra dependencies to use them in the build definition you have to declare them in a project/build.sbt.
There is one caveat to that. You can set any scalaVersion to your project, that is in build.sbt, but you should not modify scalaVersion in the project/build.sbt as it might conflict with the version sbt itself uses (that may or may not lead to binary incompatibility for plugins).
Sbt 0.13.5 is using Scala 2.10.4, and the library you're going to use must be compatible with that particular version of Scala.
> about
[info] This is sbt 0.13.5
...
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4

sbt-onejar and multi-project build

When using oneJar to package a multi project sbt build, project dependencies are not bundled into the jar. My setting is the following:
foo/build.sbt (top-level build.sbt)
foo/src/ (sources of the root project)
foo/gui/build.sbt (project 'build' definition)
foo/gui/src (sources of the 'gui' project)
The build definitions are:
// foo/build.sbt
name := "foo"
version := "0.0.1"
scalaVersion := "2.10.4"
lazy val root = project.in( file(".") )
lazy val gui = project.in( file("gui") ).dependsOn( root )
[...]
//foo/gui/build.sbt
name := "foo-gui"
seq(com.github.retronym.SbtOneJar.oneJarSettings: _*)
[...]
When calling oneJar on the gui project everything seems to run fine, but the classes of the root project are not included in the jar (although the library dependencies are). Is there any fix ?
I never tried a light configuration as you but shouldn't you put the oneJar settings in the root sbt file? You want to package the root and include guy right?
I tried something similar for the first time today and started with oneJar but when using a full sbt configuration the compiler complained that settings were a Seq(_) and sbt expected a single setting or something like that. I switched to sbt-assembly and it worked.
sbt-oneJar has not been updated for 2 years while sbt-assembly was recently updated. I'm not sure which one is preferred but I'd rather use an active tool.

How to exclude resources during packaging with SBT but not during testing

I have a bunch of conf files in a project structure like this:
```
src / main / resources / live.conf
src / test / resources / test.conf
```
I want to excluded live.conf from the artifact that is build when I run sbt one-jar (using the one-jar plugin). I added this line which unfortunately also excludes test.conf when running sbt test:compile
excludeFilter in Runtime in unmanagedResources := "*.conf"
How can I exclude live.conf in the artifact jar but not for the tests?
This should help:
mappings in (Compile, packageBin) ~= { _.filter(!_._1.getName.endsWith(".conf")) }
packageBin is a task which produces your jar artifact and mappings denotes files wich are used for compilation and project packaging in Compile scope

Why version of SBT is playing role in name of fully qualified dependency?

Why version of SBT is playing role in name of fully qualified dependency ?
I thought it only depends on version of Scala.
Here is example.
build.sbt has scalaVersion set to 2.10.2
build.properties has sbt.version set to 0.12.1
plugins.sbt has plugin dependency "com.github.siasia" %% "xsbt-web-plugin" % "0.12.0-0.2.11.1"
If I build it I see following in the log:
[info] Resolving com.github.siasia#xsbt-web-plugin_2.9.2;0.12.0-0.2.11.1 ...
But if I change sbt.version set to 0.13.0-RC5 SBT fails to find this plugin and says in the log
[info] Resolving com.github.siasia#xsbt-web-plugin_2.10;0.12.0-0.2.11.1 ...
Why did it change scala version if it remains 2.10.2 in my config ? How to fix it ?
sbt projects are recursive, so each layer has its own settings(including scala version and classpath) (see http://www.scala-sbt.org/0.13.0/docs/Getting-Started/Full-Def.html )
sbt plugins are just regular libraries which depend on sbt, hence the plugins need to be cross-built across sbt versions (and each sbt version may require different scala version)
addSbtPlugin function takes care of that and resolves an appropriate artifact for current sbt and scala
siasia#xsbt-web-plugin is not really maintained anymore and it does not have versions for sbt 0.13, use https://github.com/JamesEarlDouglas/xsbt-web-plugin as a replacement