2012-09-15 00:08:35 +02:00
=============
Using Plugins
=============
Please read the earlier pages in the Getting Started Guide first, in
particular you need to understand :doc: `build.sbt <Basic-Def>` ,
:doc: `library dependencies <Library-Dependencies>` ,
and :doc: `.scala build definition <Full-Def>` before reading
this page.
What is a plugin?
-----------------
A plugin extends the build definition, most commonly by adding new
settings. The new settings could be new tasks. For example, a plugin
2013-07-29 13:27:17 +02:00
could add a `code-coverage` task which would generate a test coverage
2012-09-15 00:08:35 +02:00
report.
Adding a plugin
---------------
The short answer
~~~~~~~~~~~~~~~~
2013-07-29 13:27:17 +02:00
If your project is in directory `hello` , edit
`hello/project/build.sbt` and add the plugin location as a resolver,
then call `addSbtPlugin` with the plugin's Ivy module ID:
2012-09-15 00:08:35 +02:00
::
resolvers += Classpaths.typesafeResolver
addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.0.0")
If the plugin were located on one of the default repositories, you
wouldn't have to add a resolver, of course.
Global plugins
~~~~~~~~~~~~~~
Plugins can be installed for all your projects at once by dropping them
2013-07-29 13:27:17 +02:00
in `~/.sbt/plugins/` . `~/.sbt/plugins/` is an sbt project whose
2012-09-15 00:08:35 +02:00
classpath is exported to all sbt build definition projects. Roughly
2013-07-29 13:27:17 +02:00
speaking, any `.sbt` files in `~/.sbt/plugins/` behave as if they
were in the `project/` directory for all projects, and any `.scala`
files in `~/.sbt/plugins/project/` behave as if they were in the
`project/project/` directory for all projects.
2012-09-15 00:08:35 +02:00
2013-07-29 13:27:17 +02:00
You can create `~/.sbt/plugins/build.sbt` and put `addSbtPlugin()`
2012-09-15 00:08:35 +02:00
expressions in there to add plugins to all your projects at once.
How it works
~~~~~~~~~~~~
Be sure you understand the :doc: `recursive nature of sbt projects <Full-Def>`
described earlier and how to add a :doc: `managed dependency <Library-Dependencies>` .
Dependencies for the build definition
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Adding a plugin means *adding a library dependency to the build
definition*. To do that, you edit the build definition for the build
definition.
2013-07-29 13:27:17 +02:00
Recall that for a project `hello` , its build definition project lives
in `hello/*.sbt` and `hello/project/*.scala` :
2012-09-15 00:08:35 +02:00
2012-09-19 02:12:32 +02:00
.. code-block :: text
2012-09-15 00:08:35 +02:00
hello/ # your project's base directory
build.sbt # build.sbt is part of the source code for the
# build definition project inside project/
project/ # base directory of the build definition project
Build.scala # a source file in the project/ project,
# that is, a source file in the build definition
2013-07-29 13:27:17 +02:00
If you wanted to add a managed dependency to project `hello` , you
would add to the `libraryDependencies` setting either in
`hello/*.sbt` or `hello/project/*.scala` .
2012-09-15 00:08:35 +02:00
2013-07-29 13:27:17 +02:00
You could add this in `hello/build.sbt` :
2012-09-15 00:08:35 +02:00
::
libraryDependencies += "org.apache.derby" % "derby" % "10.4.1.3" % "test"
If you add that and start up the sbt interactive mode and type
2013-07-29 13:27:17 +02:00
`show dependencyClasspath` , you should see the derby jar on your
2012-09-15 00:08:35 +02:00
classpath.
To add a plugin, do the same thing but recursed one level. We want the
*build definition project* to have a new dependency. That means changing
2013-07-29 13:27:17 +02:00
the `libraryDependencies` setting for the build definition of the
2012-09-15 00:08:35 +02:00
build definition.
The build definition of the build definition, if your project is
2013-07-29 13:27:17 +02:00
`hello` , would be in `hello/project/*.sbt` and
`hello/project/project/*.scala` .
2012-09-15 00:08:35 +02:00
The simplest "plugin" has no special sbt support; it's just a jar file.
2013-07-29 13:27:17 +02:00
For example, edit `hello/project/build.sbt` and add this line:
2012-09-15 00:08:35 +02:00
::
libraryDependencies += "net.liftweb" % "lift-json" % "2.0"
2013-07-29 13:27:17 +02:00
Now, at the sbt interactive prompt, `reload plugins` to enter the
build definition project, and try `show dependencyClasspath` . You
2012-09-15 00:08:35 +02:00
should see the lift-json jar on the classpath. This means: you could use
2013-07-29 13:27:17 +02:00
classes from lift-json in your `Build.scala` or `build.sbt` to
2012-09-15 00:08:35 +02:00
implement a task. You could parse a JSON file and generate other files
2013-07-29 13:27:17 +02:00
based on it, for example. Remember, use `reload return` to leave the
2012-09-15 00:08:35 +02:00
build definition project and go back to the parent project.
2013-07-29 13:27:17 +02:00
(Stupid sbt trick: type `reload plugins` over and over. You'll find
2012-09-15 00:08:35 +02:00
yourself in the project rooted in
2013-07-29 13:27:17 +02:00
`project/project/project/project/project/project/` . Don't worry, it
isn't useful. Also, it creates `target` directories all the way down,
2012-09-15 00:08:35 +02:00
which you'll have to clean up.)
2013-07-29 13:27:17 +02:00
`addSbtPlugin`
2012-09-15 00:08:35 +02:00
^^^^^^^^^^^^^^^^
2013-07-29 13:27:17 +02:00
`addSbtPlugin` is just a convenience method. Here's its definition:
2012-09-15 00:08:35 +02:00
::
def addSbtPlugin(dependency: ModuleID): Setting[Seq[ModuleID]] =
2012-11-19 02:29:01 +01:00
libraryDependencies +=
sbtPluginExtra(dependency, (sbtVersion in update).value, scalaVersion.value)
2013-07-29 13:27:17 +02:00
The appended dependency is based on `sbtVersion in update`
(sbt's version scoped to the `update` task) and `scalaVersion` (the
2012-09-15 00:08:35 +02:00
version of scala used to compile the project, in this case used to
2013-07-29 13:27:17 +02:00
compile the build definition). `sbtPluginExtra` adds the sbt and Scala
2012-09-15 00:08:35 +02:00
version information to the module ID.
2013-07-29 13:27:17 +02:00
`plugins.sbt`
2012-09-15 00:08:35 +02:00
^^^^^^^^^^^^^^^
2013-07-29 13:27:17 +02:00
Some people like to list plugin dependencies (for a project `hello` )
in `hello/project/plugins.sbt` to avoid confusion with
`hello/build.sbt` . sbt does not care what `.sbt` files are called,
so both `build.sbt` and `project/plugins.sbt` are conventions. sbt
*does* of course care where the sbt files are *located* . `hello/*.sbt`
would contain dependencies for `hello` and `hello/project/*.sbt`
would contain dependencies for `hello` 's build definition.
2012-09-15 00:08:35 +02:00
Plugins can add settings and imports automatically
--------------------------------------------------
2013-07-29 13:27:17 +02:00
In one sense a plugin is just a jar added to `libraryDependencies` for
2012-09-15 00:08:35 +02:00
the build definition; you can then use the jar from build definition
code as in the lift-json example above.
However, jars intended for use as sbt plugins can do more.
If you download a plugin jar (`here's one for
sbteclipse <http://repo.typesafe.com/typesafe/ivy-releases/com.typesafe.sbteclipse/sbteclipse/scala_2.9.1/sbt_0.11.0/1.4.0/jars/sbteclipse.jar>`_)
2013-07-29 13:27:17 +02:00
and unpack it with `jar xf` , you'll see that it contains a text file
`sbt/sbt.plugins` . In `sbt/sbt.plugins` there's an object name on
2012-09-15 00:08:35 +02:00
each line like this:
2012-09-19 02:12:32 +02:00
.. code-block :: text
2012-09-15 00:08:35 +02:00
com.typesafe.sbteclipse.SbtEclipsePlugin
2013-07-29 13:27:17 +02:00
`com.typesafe.sbteclipse.SbtEclipsePlugin` is the name of an object
that extends `sbt.Plugin` . The `sbt.Plugin` trait is very simple:
2012-09-15 00:08:35 +02:00
::
trait Plugin {
def settings: Seq[Setting[_]] = Nil
}
2013-07-29 13:27:17 +02:00
sbt looks for objects listed in `sbt/sbt.plugins` . When it finds
`com.typesafe.sbteclipse.SbtEclipsePlugin` , it adds
`com.typesafe.sbteclipse.SbtEclipsePlugin.settings` to the settings
2012-09-15 00:08:35 +02:00
for the project. It also does
2013-07-29 13:27:17 +02:00
`import com.typesafe.sbteclipse.SbtEclipsePlugin._` for any `.sbt`
2012-09-15 00:08:35 +02:00
files, allowing a plugin to provide values, objects, and methods to
2013-07-29 13:27:17 +02:00
`.sbt` files in the build definition.
2012-09-15 00:08:35 +02:00
Adding settings manually from a plugin
--------------------------------------
2013-07-29 13:27:17 +02:00
If a plugin defines settings in the `settings` field of a `Plugin`
2012-09-15 00:08:35 +02:00
object, you don't have to do anything to add them.
However, plugins often avoid this because you could not control which
projects in a :doc: `multi-project build <Multi-Project>` would use the plugin.
2012-09-19 02:12:32 +02:00
A whole batch of settings can be added by directly referencing the sequence of settings in a `build.sbt` file. So, if a plugin has something like this:
2012-09-15 00:08:35 +02:00
::
object MyPlugin extends Plugin {
val myPluginSettings = Seq(settings in here)
}
2013-07-29 13:27:17 +02:00
You could add all those settings in `build.sbt` with this syntax:
2012-09-15 00:08:35 +02:00
::
2012-09-19 02:12:32 +02:00
myPluginSettings
2012-09-15 00:08:35 +02:00
Creating a plugin
-----------------
After reading this far, you pretty much know how to *create* an sbt
2013-07-29 13:27:17 +02:00
plugin as well. There's one trick to know; set `sbtPlugin := true` in
`build.sbt` . If `sbtPlugin` is true, the project will scan its
compiled classes for instances of `Plugin` , and list them in
`sbt/sbt.plugins` when it packages a jar. `sbtPlugin := true` also
2012-09-15 00:08:35 +02:00
adds sbt to the project's classpath, so you can use sbt APIs to
implement your plugin.
Learn more about creating a plugin at :doc: `/Extending/Plugins`
and :doc: `/Extending/Plugins-Best-Practices` .
Available Plugins
-----------------
2012-09-19 02:12:32 +02:00
There's :doc: `a list of available plugins </Community/Community-Plugins>` .
2012-09-15 00:08:35 +02:00
Some especially popular plugins are:
- those for IDEs (to import an sbt project into your IDE)
- those supporting web frameworks, such as
2012-12-01 06:09:39 +01:00
`xsbt-web-plugin <https://github.com/JamesEarlDouglas/xsbt-web-plugin> `_ .
2012-09-15 00:08:35 +02:00
2012-09-19 02:12:32 +02:00
:doc: `Check out the list</Community/Community-Plugins>` .
2012-09-15 00:08:35 +02:00
Next
----
Move on to :doc: `multi-project builds <Multi-Project>` .