Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to share sbt plugin configuration between multiple projects?

Tags:

plugins

scala

sbt

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?

like image 264
cvogt Avatar asked Feb 14 '15 22:02

cvogt


People also ask

Where are sbt plugins stored?

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.

What is ThisBuild in sbt?

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.

What is the difference between sbt and Scala?

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.

How do I specify sbt?

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.


1 Answers

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.

build.sbt

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) }

src/main/scala/foo/houserules/FormatPlugin.scala

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.

usage

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.)

other usages for in-house plugin

You can use also auto plugins to configure other things like version of common libraries like Akka version, or excluding all logging libraries etc.

like image 150
Eugene Yokota Avatar answered Oct 24 '22 07:10

Eugene Yokota