SBT Multi-Project Build with Dynamic External Projects?

Let's say we have a SBT bar project with a dependency on some foo artifact:

 val bar = Project('bar', file('.')).settings( libraryDependencies += "com.foo" % "foo" % "1.0.0" ) 

However, in some cases, I want to check the source foo and load the SBT source from my file system instead of the published artifact; that way, I could make local changes to foo and check them out immediately with bar without posting anything.

 val foo = Project('foo', file('foo')) val bar = Project('bar', file('.')).dependsOn(foo) 

We have a spec.json file in the root folder of bar , which already indicates whether to use foo from the source or as an artifact. Is there a way to configure my assembly to read this file and add dependsOn or libraryDependencies based on the value in spec.json ?

This is easy to do for libraryDependencies :

 val bar = Project('bar', file('.')).settings( libraryDependencies ++= if (containsFoo(baseDirectory.value / "spec.json")) { Seq() } else { Seq("com.foo" % "foo" % "1.0.0") } ) 

However, we cannot find a way to set anything β€œdynamic” in dependsOn , for example, reading baseDirectory SettingKey .

+6
source share
2 answers

We tried several approaches, but the only thing we could get to work, and it did not look like an incomprehensible / unattainable hack, was to add an implicit class that adds a Project method that can add a dependency either locally or as artifact.

Pseudo-code implementation diagram:

 implicit class RichProject(val project: Project) extends AnyVal { def withSpecDependencies(moduleIds: ModuleID*): Project = { // Read the spec.json file that tells us which modules are on the local file system val localModuleIds = loadSpec(project.base / "spec.json") // Partition the passed in moduleIds into those that are local and those to be downloaded as artifacts val (localModules, artifactModules) = moduleIds.partition(localModuleIds.contains) val localClasspathDependencies = toClasspathDependencies(localModules) project .dependsOn(localClasspathDependencies: _*) .settings(libraryDependencies ++= artifactDependencies) } } 

The usage scheme in a real SBT assembly is quite simple:

 val foo = Project("foo", file("foo")).withSpecDependencies( "com.foo" % "bar" % "1.0.0", "org.foo" % "bar" % "2.0.0" ) 
+2
source

The Mecha SBT build automation plugin does this depending on whether other projects exist on the local file system. This is a new project, so there are not enough documents, but you can take a look at its source: https://github.com/storm-enroute/mecha

0
source

Source: https://habr.com/ru/post/959299/


All Articles