Doug
Doug

Reputation: 35186

How do you use `ProjectRef` to reference a local project in sbt 1.x?

There's a lot of vague handwaving in other answers, or things referring to much older versions of sbt (ie. 0.12.x) about this, but no one actually seems to answer the question.

Given I have a folder, and I have run:

sbt new scala/scala-seed.g8
name [Scala Seed Project]: one

sbt new scala/scala-seed.g8
name [Scala Seed Project]: two

I now have a directory structure that looks like this:

8   ./one/build.sbt
8   ./one/...
8   ./two/build.sbt
8   ./two/...
80  .

Right, so I now go and change the example namespace in one and two, so the code looks like this in the respective Hello.scala files:

package example.two

object Hello extends Greeting {
}

trait Greeting {
  lazy val greeting: String = "hello two"
}

and:

package example.one

object Hello extends Greeting with App {
  println(greeting)
  println(example.two.Hello.greeting)
}

trait Greeting {
  lazy val greeting: String = "hello one"
}

Now, how exactly do I make the code in one compile and run?

From the reading I've done, it appears I should do something similar to this in one/project/Dependencies.scala:

import sbt._

object Dependencies {
  lazy val scalaTest = "org.scalatest" %% "scalatest" % "3.0.5"
  lazy val two = ProjectRef(file("../two"), "two") <------------ ADD THIS
}

and this in the one/build.sbt:

import Dependencies._

lazy val root = (project in file("."))
  .dependsOn(two) <--------------------- ADD THIS
  .settings(
    inThisBuild(List(
      organization := "com.example",
      scalaVersion := "2.12.7",
      version      := "0.1.0-SNAPSHOT"
    )),
    name := "one",
    libraryDependencies += scalaTest % Test
  )

...but it doesn't work:

92-168-1-4:one doug$ sbt run
[info] Loading settings for project global-plugins from idea.sbt ...
[info] Loading global plugins from /Users/doug/.sbt/1.0/plugins
[info] Loading project definition from /Users/doug/tmp/one/project
[info] Compiling 1 Scala source to /Users/doug/tmp/one/project/target/scala-2.12/sbt-1.0/classes ...
[info] Done compiling.
[info] Loading settings for project root from build.sbt ...
[info] Loading project definition from /Users/doug/tmp/two/project
[info] Loading settings for project root from build.sbt ...
[error] java.lang.RuntimeException: No project 'two' in 'file:/Users/doug/tmp/two/'.
[error] Valid project IDs: root
[error]     at scala.sys.package$.error(package.scala:26)

What does '[error] Valid project IDs: root' mean?

Am I doing this completely wrong, and should eg. be using sbt publishLocal or something?

I can't find any meaningful documentation on how you're supposed to consume local libraries that are not submodules on the current project; did I miss part of the sbt documentation?

The section on Inter-project dependencies in the 1.x documentation doesn't seem to explain this at all, it just talks about tracking references...

help?

Upvotes: 2

Views: 2373

Answers (1)

Toxaris
Toxaris

Reputation: 7266

The full error message is:

No project 'two' in 'file:/Users/doug/tmp/two/'.
Valid project IDs: root
at scala.sys.package$.error(package.scala:26)

So the problem is that your folder two doesn't contain a project called two, but only a project called root (as created by the g8 template). Note that the name := … doesn't matter here, this only sets the name in the project metadata but not the name that sbt itself uses to refer to the project.

To proceed, you can try:

  • changing lazy val root into lazy val two in the two/build.sbt file
  • changing ProjectRef(…, "two") into ProjectRef(…, "root")

Upvotes: 4

Related Questions