0

I am using sbt 0.13.7.

I guess my question is a bit similar to this one. I have however a multi-project build.

Let's say my project structure looks like this:

- A
   - build.sbt
- B
   - build.sbt
build.sbt

and B.dependsOn(A).

Is there a way to write a custom task in build.sbt in B that uses sources from A?

Community
  • 1
  • 1
reikje
  • 2,850
  • 2
  • 24
  • 44
  • You need `B.aggregate(A)`? http://www.scala-sbt.org/0.12.2/docs/Getting-Started/Multi-Project.html#aggregation – Nikita Apr 17 '15 at 12:28
  • `aggregate` is to let the commands/tasks to be executed in projects specified as aggregated. It sets no classpath dependency. See [Aggregration](http://www.scala-sbt.org/0.13/tutorial/Multi-Project.html#Aggregation) in the official docs. – Jacek Laskowski Apr 18 '15 at 09:16

2 Answers2

3

Assuming that A and B are completely separate builds (it's not just multi-project build as you have several .sbt files), it's possible only if your A build is physically placed inside B.


1) If you need A-sources to be available to B-sources:

- B
   - build.sbt
   - A
     - build.sbt
build.sbt

then you may describe A's sources as some regular B's project , like:

B/build.sbt

lazy val a = project in "./A"   // or deeply if your sources not in A's root

lazy val b = project in "." dependsOn a

B/A/build.sbt (if you really need separate build here)

lazy val a = project in "."

You may want to share some plugin with source-path-independent project definition between A and B then, like:

def a(base: String) = Project(base = base, settings = someAsettings)

You may organize such structure with a symlink (Linux/Mac):

ln -s ../B A

Otherwise you will need to manually publish A (publishLocal) to your local ivy repository and use it as external dependency.

If you use Git - symlinks should be fine as long as participants are using same OS. Another solution is git submodules or subtree.


2) If you need the code from A-sources to be available inside B-build (not B-sources) then you need a structure like this:

- B
   - build.sbt
   - project
     - project
       - A  
     build.sbt

Project inside project actually becomes an sbt-plugin, so its code is available to B.

If you don't want to change the structure then A should became an sbt-plugin and you need to publish it to the local repository.

Community
  • 1
  • 1
dk14
  • 22,206
  • 4
  • 51
  • 88
  • I understand. I like alternative A better but it's still a bit to awkward to nest it like this, will probably take the bullet an use an external dependency instead. This is something I was trying to avoid because then I have to release project `A` every time before changes are reflected in `B`. – reikje Apr 20 '15 at 09:05
0

What about the following in build.sbt in the top-level root project?

lazy val a = project
lazy val b = project

lazy val printSources = taskKey[Unit]("Prints the sources of A")
printSources := {
  println("== sources of A ==")
  (sources in (a, Compile)).value.foreach(println)
}

Execute the task printSources and you should see the following:

[multi-sbt-project]> printSources
== sources of A ==
/Users/jacek/dev/sandbox/multi-sbt-project/a/hello.scala
[success] Total time: 0 s, completed Apr 18, 2015 11:26:54 AM
Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420