how to set concrete working directory in multi mod

2019-08-17 00:54发布

问题:

I have package structure similar to below;

myapplication/
├── my-library/
│   └── src
│       └──main
│          └── scala
│   
├── my-other-library/
│   └── src/
│       └──main/
│          └── scala/
│── my-executable-project/
│   │── src/
│   │   └──main/
│   │      └── scala/
│   └── resources/
│       └── somefile.txt
└── build.sbt

When I run the tests via sbt or intellij;

  • relative files (e.g. new File("build.sbt")) being relative to myapplication.

When I run the project with reStart via sbt-revolver or from the binary;

  • my-executable-project is being the working directory. So to access same build.sbt file I should be using new File("../build.sbt")

This project structure make sense to me because there may be other executable projects later. I prefer keeping every project under the parent one.

Only my-executable-project is being packaged and run in the production. And when it runs there again my-executable-project is being the working directory.

The only inconvenience right now is when I want to reference to a relative file it is different in tests and regular runs.

I overcome resource loading with the usage of classpath and classloader but couldn't find a way for relative file references. When app runs tests fail, when tests run app fails.


Edit: This is how my one and only build.sbt looks like;

lazy val root = project
  .in(file("."))
  .disablePlugins(RevolverPlugin)
  .aggregate(library1, library2, service, common)
  .settings(
    settings,
    name := "parent",
    version := "0.1"
  )

lazy val common = project
  .in(file("common"))
  .disablePlugins(RevolverPlugin)
  .settings(
    settings,
    name := "common",
    libraryDependencies ++= ... some deps ...
  )

lazy val library1 = project
  .in(file("library1"))
  .disablePlugins(RevolverPlugin)
  .dependsOn(common)
  .settings(
    settings,
    name := "library1",
    libraryDependencies ++= ... some deps ...
  )

lazy val library2 = project
  .in(file("library2"))
  .disablePlugins(RevolverPlugin)
  .dependsOn(common)
  .settings(
    settings,
    name := "library2",
    libraryDependencies ++= ... some deps ...
  )

lazy val service = project
  .in(file("service1"))
  .dependsOn(library1, library2)
  .enablePlugins(JavaServerAppPackaging)
  .settings(
    settings,
    name := "service1",
    mappings in Universal ++= directory("service1/src/main/resources"),
    mainClass in Compile := Some("my.main.class.service.Main"),
    Revolver.enableDebugging(port = 5005, suspend = false),
    libraryDependencies ++= ... some deps ...
  )

回答1:

I solved these issues putting all sbt stuff in the parent project.

See here the docu: https://www.scala-sbt.org/1.x/docs/Multi-Project.html

The main structure of build.sbt looks then:

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

lazy val util = (project in file("util"))

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

Every project can then be configured like:

lazy val core = (project in file("core"))
  .enablePlugins(PlayScala, BuildInfoPlugin)
  .settings(generalConf.noPublishSettings)
  .settings(generalConf.buildInfoSettings)
  .settings(coreConf.settings)

Here you see that we use general configs generalConf and special project config (coreConf). These files are then in the /project folder.