scala scalafmt How to specify that to build project A another project B has to be built first?



sbt-release example (3)

You could have two separate projects, and just publish one of them locally, adding it as a normal library dependency to the other.

Suppose one guy in my company has an sbt project called commons that's pretty general-purpose. This project is defined in the traditional sbt way: in the main folder with the build definition in project/Build.scala file.

Now some other guy is developing a project called databinding that depends on commons. We want to define this project in the same way, with project/Build.scala.

We have the following directory layout:

dev/
  commons/
    src/
      *.scala files here...
    project/
      Build.scala
  databinding/
    src/
      *.scala files here...
    project/
      Build.scala

How can I specify that databinding requires commons to be built first and use the output class files?

I read Multi-project builds, and came up with the following for the build definition of databinding:

object MyBuild extends Build {

  lazy val root = Project(id = "databinding", base = file(".")) settings (
    // ... omitted
  ) dependsOn (commons)

  lazy val common = Project(id = "commons",
    base = file("../commons")
  )

}

Except it doesn't work: sbt doesn't like the .. and throws an AssertionError. Apparently, commons should be a folder inside databinding. But these two projects are kept in separate git repositories, which we cannot nest.

How can this dependency be specified properly?


Answer #1

You need to define the multi-project in a root project (or whatever name but this one fits well) that will be define in dev/project/Build.scala.

object RootBuild extends Build {
  lazy val root = Project(id = "root", base = file("."))
    .settings(...)
    .aggregate(commons, databinding)

  lazy val commons = Project(id = "commons", base = file("commons"))
    .settings(...)

  lazy val databinding = Project(id = "databinding", base = file("databinding"))
    .settings(...)
    .dependsOn(commons)
}

one more thing, SBT doesn't support *.scala configuration files in sub-projects. This means that you will have to migrate the configuration you made on commons/project/Build.scala and databinding/project/Build.scala into respectively commons/build.sbt and databinding/build.sbt.

If some of your configuration are not suitable for a .sbt definition file, you will have to add them in the root project/Build.scala. Obviously, settings defined in root Build.scala are available in *.sbt files.


Answer #2

You should use RootProject (in case of referring to root project of another project) or ProjectRef (in case of referring to subproject of another project).

Here is a sample of using RootProject:

       lazy val commons = RootProject(file("../commons"))
       lazy val root = Project(id = "databinding", base = file(".")) settings (...) dependsOn (commons)

And here is the sample for using ProjectRef

       lazy val commons = ProjectRef(file("../commons"), "sub-project")
       lazy val root = Project(id = "databinding", base = file(".")) settings (...) dependsOn (commons)




sbt