Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SBT: Dependency On Other SBT Project Without Publishing

I have a set of loosely related components where some of these depend on others. For concreteness, lets assume we have components "common", "a" and "b". "common" does not have any dependencies, but all other projects use "common". Furthermore, "a" depends on "b". All components are written in Scala, and I would like to use sbt to build them.

The following properties would be nice to have:

  1. Multiple people work on the different projects, which is why we don't want to have a single repository, but rather one repository per project.
  2. Building a project should be easy, and all dependencies should be build automatically (if necessary). That is, if I modify "common" and then build "b", this should first build "common" and then go on to build "b".
  3. Be able to have all projects in an IDE, such that refactoring and similar IDE-tasks work correctly and all affected projects are changed correctly.

As far as I can see, there are two possibilities to have dependencies of this kind in sbt; either we use sub-projects, or use a managed dependency (that is pushed somewhere, e.g., locally). However, it seems that both of these options don't provide either (1) or (2) above. In particular

  • Using sub-projects forces us to use a single repository, because all sub-project must be in sub-directories of the main project.
  • Publishing the projects locally and using managed dependencies is cumbersome, as changing "common" and then building "b" only picks up the changes in "common" if that project was build and published first. I can see that managed dependencies are useful for many cases, but for our particular use-case they don't seem to work well. We frequently work on several projects and change them at the same time. For this reason, having to publish often seems overly complicated.

Is there really no way to say that an sbt project depends on another sbt project at a certain (relative) location, and having sbt figure out when to build the dependency?

like image 619
stefan Avatar asked Oct 06 '12 23:10

stefan


People also ask

Where are dependencies downloaded in sbt?

All new SBT versions (after 0.7. x ) by default put the downloaded JARS into the . ivy2 directory in your home directory. If you are using Linux, this is usually /home/<username>/.

What is publishLocal?

The publishLocal action is used to publish your project to your Ivy local file repository, which is usually located at $HOME/. ivy2/local/ . You can then use this project from other projects on the same machine.


2 Answers

With SBT you can use source dependencies.

lazy val root = Project("root", file("."), settings = ...) dependsOn(dispatchLiftJson)

lazy val dispatchLiftJson = uri("git://github.com/dispatch/dispatch-lift-json#0.1.0")

It will fetch from git in this example. You may be able to specify a file location on disk, although I can't find examples. Possibly

lazy val dep = file("/path/to") 

or

lazy val dep = uri("file:///path/to")

I'm struggling with this myself - at the moment im using the publish-local method which is working ok.

like image 128
Ivan Meredith Avatar answered Oct 13 '22 20:10

Ivan Meredith


Given directories

  • /build/some_app/
  • /build/some_lib/

File /build/some_app/build.sbt:

lazy val someLib = ProjectRef(file("../some_lib"), "exportedSomeLib")
// = RootProject(file("../some_lib")) also works?

lazy val root = (project in file("."))
                .dependsOn(someLib)

In /build/some-lib/build.sbt:

lazy val exportedSomeLib = (project in file("."))

Caveat: note that items defined in both root scopes of these files will not always lead to errors, but silently change values in the global (?) scope if the keys (=the value names) clash across .sbt files. 😞

like image 39
conny Avatar answered Oct 13 '22 20:10

conny