tg44
tg44

Reputation: 850

Different project on the same base-directory (or share a single file between projects)

My initial setup had two separate projects (sbt 1.2.6);

The feature request came in; we should show the "valid" values in the command line app. The valid values are in an enum in the web app. So I fired up the sbt documentation and came up with an idea which looked like this;

//main webapp
lazy val core = project
  .in(file("."))
  .withId("core") //I tried this just in case, not helped...
  //... here comes all the plugins and deps

//my hack to get a single-file compile
lazy val `feature-signer-helper` = project
  .in(file("."))
  .withId("feature-signer-helper")
  .settings(
    target := { baseDirectory.value / "target" / "features" },
    sources in Compile := {
      ((scalaSource in Compile).value ** "Features.scala").get
    }
  )

//the command line app
lazy val `feature-signer` = project
  .in(file("feature-signer"))
  .dependsOn(`feature-signer-helper`)
  .settings(
    libraryDependencies ++= signerDeps
  )

The problem is that it seems like, that whatever the last lazy val xxx = project.in(file(y)) that will be the only project for the y dir.

Also, I don't want to move that one file to a separate directory structure... And logically the command line app and the web app are not "depends on" each other, they have different dependencies (and really different build times).

My questions are;

EDIT:

The below code can copy the needed file (if you have the same dir structure). I'm not super happy with it, but it works. Still interested in other methods.

import sbt._
import Keys._

object FeaturesCopyTask {
  val featuresCopyTask = {
    sourceGenerators in Compile += Def.task {
      val outFile = (sourceManaged in Compile).value / "Features.scala"
      val rootDirSrc = (Compile / baseDirectory).value / ".." / "src"
      val inFile: File = (rootDirSrc ** "Features.scala").get().head

      IO.copyFile(inFile, outFile, preserveLastModified = true)

      Seq(outFile)
    }.taskValue
  }
}
lazy val `feature-signer` = project
  .in(file("feature-signer"))
  .settings(
    libraryDependencies ++= signerDeps,
    FeaturesCopyTask.featuresCopyTask
  )

Upvotes: 1

Views: 251

Answers (1)

Levi Ramsey
Levi Ramsey

Reputation: 20561

I would have the tree be something more like

+- core/
+- webapp/
+- cli/
  • core is the small amount (mostly model type things) that webapp and cli have in common
  • webapp depends on core (among many other things)
  • cli depends on core (and not much else)

So the build.sbt would be something like

lazy val core = (project in file("core"))
  // yadda yadda yadda

lazy val webapp = (project in file("webapp"))
  .dependsOn(core)
  // yadda yadda yadda

lazy val cli = (project in file("cli"))
  .dependsOn(core)
  // yadda yadda yadda

lazy val root = (project in file("."))
  .aggregate(
    core,
    webapp,
    cli
  )

Upvotes: 2

Related Questions