We have a multitude of smaller sbt projects, which we would like to keep separate (no multi-project build). However we would like to share configuration between the builds. In order to do so we currently have yet another project, which all the projects use as a libraryDependency in their project/project/Build.scala files. We were able to centralize build configuration using only built-in sbt features this way.
What we haven't figured out is how to centralize plugin specific build configuration. For example, we use sbt-assembly for several of our services. We are adapting the assembly mergeStrategy and would like to use that in all projects. How can we re-use the configuration?
Also how can we automatically make certain sbt-plugins available to all of our builds, such as the assembly or scalariform plugins, without manually adding it to each build?
Plugins can be installed for all your projects at once by declaring them in $HOME/. sbt/1.0/plugins/ . $HOME/. sbt/1.0/plugins/ is an sbt project whose classpath is exported to all sbt build definition projects.
Typically, if a key has no associated value in a more-specific scope, sbt will try to get a value from a more general scope, such as the ThisBuild scope. This feature allows you to set a value once in a more general scope, allowing multiple more-specific scopes to inherit the value.
SBT is tied to a specific project defined by a build. sbt file in a way that $ sbt console will load up the same REPL environment as $ scala but with the addition of all of the project code and dependencies defined in the build available for import. Also, it will use the version of Scala defined by build.
Create or open your sbt project. In the Project tool window, in the source root directory, locate the build. properties file and open it in the editor. In the editor explicitly specify the version of sbt that you want to use in the project.
This is one of the usage pattern we had in mind for auto plugins. Auto plugins can depend on sbt-assembly or sbt-scalariform and introduce the settings automatically to all projects.
sbt-your-company can include sbt-scalariform as a library dependency as follows in build.sbt
:
lazy val commonSettings = Seq(
organization := "com.example",
version := "0.1.0"
)
lazy val root = (project in file(".")).
settings(
commonSettings ++
addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.3.0")
: _*).
settings(
sbtPlugin := true,
name := "sbt-your-company",
// other settings here
)
Since addSbtPlugin(...)
normally appear only in project/plugins.sbt
this may be a bit odd, but if you look at the implementation of addSbtPlugin
is basically libraryDependencies
with a few extra attributes:
def addSbtPlugin(dependency: ModuleID): Setting[Seq[ModuleID]] =
libraryDependencies <+= (sbtBinaryVersion in update, scalaBinaryVersion in update) { (sbtV, scalaV) => sbtPluginExtra(dependency, sbtV, scalaV) }
One of the feature added by auto plugin is the ability to trigger a plugin based on other plugins. By triggering your plugin based on plugins.JvmPlugin
, you can effectively make a plugin that's enabled by default. Here's an example plugin called FormatPlugin
:
package foo
package houserules
import sbt._
import Keys._
import com.typesafe.sbt.SbtScalariform.{ ScalariformKeys => sr, _ }
object FormatPlugin extends AutoPlugin {
override def requires = plugins.JvmPlugin
override def trigger = allRequirements
override def projectSettings: Seq[Def.Setting[_]] = baseSettings
lazy val baseSettings: Seq[Setting[_]] = scalariformSettings ++ Seq(
sr.preferences := formatPrefs
)
def formatPrefs = {
import scalariform.formatter.preferences._
FormattingPreferences().setPreference(AlignSingleLineCaseStatements, true)
}
}
This plugin introduces sbt-scalariform's scalariformSettings
and custom format preferences.
All you have to do is include sbt-your-company to your builds.
In case one of your projects want to opt-out of the FormatPlugin
you can use disablePlugins(...)
. See Using plugins.
For full example, see also sbt-houserules I just created. (Coincidentally I've been meaning to create this for sbt modularization.)
You can use also auto plugins to configure other things like version of common libraries like Akka version, or excluding all logging libraries etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With