SBT: Dependency On Other SBT Project Without Publi

2020-07-02 11:16发布

问题:

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?

回答1:

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.



回答2:

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.