26

If I want to add a plugin that's in a local directory outside the project tree, what's the right way to do that? Say I clone something simple like https://github.com/steppenwells/sbt-sh.git to /tmp/sbt-sh - what do I put in my build.sbt file to use the plugin from /tmp/sbt-sh that will pick up any changes I make in /tmp/sbt-sh?

2 Answers 2

18

Something like this in project/project/Build.scala should do it:

import sbt._
object PluginDef extends Build {
    lazy val projects = Seq(root)
    lazy val root = Project("plugins", file(".")) dependsOn( shPlugin )
    lazy val shPlugin = uri("file:///tmp/sbt-sh")
}

Note that that the doubly-nested project directories are required. I'm not aware of any way to do this from an .sbt file (there may be a way, but I don't know what it is).

This is documented here (see "1d) Project dependency").

4
  • 2
    Thanks. I saw that but it didn't occur to me that you could just use a file:// url. Seems like there should be a more straightforward way to do this though, something like addLocalSbtPlugin("/tmp/sbtsh") Commented Dec 20, 2011 at 0:51
  • 2
    This might work too (I've not tried it): lazy val shPlugin = file("/tmp/sbt-sh") Commented Dec 20, 2011 at 0:55
  • 2
    Also, the error message you get if you put in the wrong filename is a bit misleading: Invalid build URI (no handler available): file:///tmp/sbt-shX/ (where sbt-shX doesn't exist) Commented Dec 20, 2011 at 1:09
  • 1
    And yes, your file() suggestion works: lazy val webPlugin = file("/tmp/sbt-sh") Commented Dec 20, 2011 at 1:11
13

In 0.13, there's a) a simple way to do this, and b) better documentation. @PaulButcher's answer pointed to section 1d of the sbt documentation for plugins, which now tells you to edit project/plugins.sbt:

Up to 0.13.0:

(@axel22 points out this has changed, so check the current doc before you copy this)

lazy val root = project.in( file(".") ).dependsOn( assemblyPlugin )
lazy val assemblyPlugin = uri("git://github.com/sbt/sbt-assembly#0.9.1")

And of course that uri(... can be replaced with a file("/tmp/sbt-sh").

Update:

After sbt 0.13.0 you'll need to wrap the uri or file with RootProject. I.e.,

lazy val root = project.in( file(".") ).dependsOn( assemblyPlugin )
lazy val assemblyPlugin = RootProject(file("lib/sbt-sh"))
4
  • 3
    RootProject is missing in the second line.
    – axel22
    Commented May 2, 2019 at 19:19
  • 1
    @axel22 That's a later addition; 0.13 didn't use it. Commented May 5, 2019 at 3:14
  • Thanks for clarifying - I had only tried with 1.0+.
    – axel22
    Commented May 5, 2019 at 16:42
  • do you put this in build.sbt? or plugins.sbt? Commented Jun 26, 2023 at 3:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.