How to switch between project and library dependencies in SBT?

It's easy to declare managed library dependencies in SBT, like

libraryDependencies ++= Seq( "org.specs2" %% "specs2" % "1.12.2" % "test" , "junit" % "junit" % "4.7" % "test" ) 

And although it is not easy to declare project dependencies in SBT, I can do this too:

 object RichMath extends Build { lazy val myApp = Project("RichMath", file(".")) dependsOn(richUtil) lazy val richUtil = RootProject(file("../RichUtil")) } 

But in practice, I usually want to change the project mode when the changes are immediately visible in upstream projects and in library mode, where I have to post the changes to see them in dependent projects, as the code matures.

At the beginning of the code life cycle, or whenever I want to make frequent changes to modules, I don’t want the reissue to be just for viewing the changes upstream. But in stable / mature code, I want to specify exactly which version I am dependent on.

It seems that SBT views the two dependencies as completely different. Is there a more direct way to switch between dependencies between projects and libraries than rewriting the definition of my assembly?

+5
source share
2 answers

I have several scripts for my sbt scripts (tests, publications, production). I start sbt from a script (from bash, you may have a different environment), for example with DO=TESTS sbt . These are my dynamic dependencies regarding an environment variable:

 if (sys.env.contains("LOCAL_BUILD")) { Seq[Project.Setting[_]]( unmanagedResourceDirectories in Compile <+= baseDirectory { _ / "src" / "main" / "scala" }, libraryDependencies ++= { Seq( "org.digimead" %% "digi-lib-slf4j" % "0.2.1-SNAPSHOT" % "test", "org.digimead" %% "digi-lib-test" % "0.2.1-SNAPSHOT" % "test", "org.scalatest" %% "scalatest" % "1.9" % "test" ) } ) } else { Seq[Project.Setting[_]]( libraryDependencies ++= { Seq( "org.slf4j" % "slf4j-log4j12" % "1.7.1" ) } ) } 

As you can see, I can have different project settings with a single .sbt definition controlled by a single environment variable. An environment variable affects the entire package of projects / subprojects.

+3
source

It is true that two types of dependencies are handled differently, and it would be nice if they weren't. The main obstacle is that sbt must know about all external projects before loading parameters (for various reasons).

At the moment, the easiest solution is probably an environment variable or a system property, as described in another answer. We go further, in sbt it is very close to the possible, but one more work is still required:

  • Declare dependency as usual

     libraryDependencies += "org.example" % "rich-util" % "0.1" 
  • Add the original dependency from the command line, automatically replacing the usual dependency in the process

     $ sbt > projects add ../RichUtil 

The conventions-based approach described in setting up the sbt environment to crack several libraries at the same time is a special case and will also be included in this work.

+3
source

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


All Articles