5

Once upon a time, in a far off land, there existed a project with a little project/build.sbt file that looks like this:

resolvers += Resolver.url("scala-js-snapshots",
  url("http://repo.scala-js.org/repo/snapshots/")
)(Resolver.ivyStylePatterns)

addSbtPlugin("org.scala-lang.modules.scalajs" % "scalajs-sbt-plugin" % "0.2-SNAPSHOT")

At project load time, things looked great, and there was peace in the land:

[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] downloading http://repo.scalajs.org/repo/snapshots/org.scalalang.modules.scalajs/scalajs-sbtplugin/scala_2.10/sbt_0.13/0.2-SNAPSHOT/jars/scalajs-sbt-plugin.jar ...
[info]  [SUCCESSFUL ] org.scala-lang.modules.scalajs#scalajs-sbt-plugin;0.2SNAPSHOT!scalajs-sbt-plugin.jar (1936ms)
[info] Done updating.

One day, another project was created. Unlike the first project, this project was big and complicated, and so it has a project/project/Build.scala which looks like this:

import sbt._
import Keys._
object Build extends sbt.Build {
  import sbt._

  override lazy val projects = Seq(root)
  lazy val root =
    Project("plugins", file("."))
      .settings(
        resolvers += Resolver.url("scala-js-snapshots",
          url("http://repo.scala-js.org/repo/snapshots/")
        )(Resolver.ivyStylePatterns),
        addSbtPlugin("org.scala-lang.modules.scalajs" % "scalajs-sbt-plugin" % "0.2-SNAPSHOT")
      )
      .dependsOn(uri("../../scala-js-resource/plugin"))
      .dependsOn(uri("../../scala-js-workbench"))
}

It seemed to me that this should set up the SBT plugin in an identical way to the earlier arrangement. After all, what is a build.sbt but a bunch of settings? The only difference was that it depended on some other local projects and thus couldn't be a plain .sbt file.

But at load time, something terrible happened:

[warn]  module not found: org.scala-lang.modules.scalajs#scalajs-sbt-plugin;0.2-SNAPSHOT
[warn] ==== typesafe-ivy-releases: tried
[warn]   http://repo.typesafe.com/typesafe/ivy-releases/org.scalalang.modules.scalajs/scalajs-sbt-plugin/scala_2.10/sbt_0.13/0.2-SNAPSHOT/ivys/ivy.xml
[warn] ==== sbt-plugin-releases: tried
[warn]   http://repo.scala-sbt.org/scalasbt/sbt-plugin-releases/org.scalalang.modules.scalajs/scalajs-sbt-plugin/scala_2.10/sbt_0.13/0.2-SNAPSHOT/ivys/ivy.xml
[warn] ==== local: tried
[warn]   C:\Users\Haoyi\.ivy2\local\org.scala-lang.modules.scalajs\scalajs-sbt-plugin\scala_2.10\sbt_0.13\0.2-SNAPSHOT\ivys\ivy.xml
[warn] ==== public: tried
[warn]   http://repo1.maven.org/maven2/org/scala-lang/modules/scalajs/scalajs-sbt-plugin_2.10_0.13/0.2-SNAPSHOT/scalajs-sbt-plugin-0.2-SNAPSHOT.pom

Stupid Build.scala, you didn't even try the resolver I gave you! I even told you where to look for the damn module, why did you give up without even trying? Your little brother the build.sbt found it perfectly fine.

Anyone know what gives, and how I can make the Build.scala work like I want it to?

Li Haoyi
  • 15,330
  • 17
  • 80
  • 137

1 Answers1

6

project/build.sbt is not the little brother of project/Build.scala. The former defines sbt plugins, whereas the latter is the actual build file. Its little brother, if you want, would be <root-dir>/build.sbt.

You should leave the plugin definitions in project/build.sbt. There is nothing wrong with having both files.

Your project definition (along with the dependsOn) should either be in project/Build.scala, or you use <root-dir>/build.sbt where in sbt 0.13 you can basically do everything that was formerly restricted to Build.scala, so my advise is to only use .sbt files these days.


So leave project/build.sbt, or better rename it to project/plugins.sbt so there is less confusion, and use this as ./build.sbt:

lazy val root = Project("plugins", file("."))
  .dependsOn(uri("../scala-js-resource/plugin"))
  .dependsOn(uri("../scala-js-workbench"))
0__
  • 66,707
  • 21
  • 171
  • 266
  • It's `project/project/Build.scala` not `project/Build.scala` though. I'm pretty sure those are both meant to handle plugins. Or am I mistaken? – Li Haoyi Dec 26 '13 at 19:25
  • @LiHaoyi - ok, but that still means the OP is trying to mix plugin definitions with project definitions. I am actually surprised that you can _define a project_ in a build file that is in a plugin location. – 0__ Dec 26 '13 at 22:37
  • I don't think that's right; my plugin definitions are in either `project/build.sbt` or `project/project/Build.scala` for the two projects, and my project definitions are in `project/Build.scala`. I'm sorry if the OP wasn't clear on this. Is this not the right way of doing things? – Li Haoyi Dec 26 '13 at 23:23
  • @LiHaoyi exactly. Sorry, I'm just seeing that _you are_ the OP. In the question, you post the contents of `project/project/Build.scala` which is (as you say in your comment as well) a _plugin_ definition file. But there you define a _project_. If you separate your project definition into `./build.sbt` and your plugin definition into `project/plugins.sbt` you should be fine. – 0__ Dec 27 '13 at 10:56