Are there any pros to add root module in build.sbt? - sbt

I have multi module sbt project:
├── build.sbt
├── bar
│   ├── build.sbt
│   └── ...
├── foo
│   ├── build.sbt
│   └── ...
└── ...
And 2 versions of build.sbt:
lazy val foo = project in(file("./foo"))
lazy val bar = project in(file("./bar"))
And second version:
lazy val foo = project in(file("./foo"))
lazy val bar = project in(file("./bar"))
lazy val root = Project(id = "root",
base = file(".")) aggregate(foo, bar)
What are the differences between these versions? Are there any pros in second version?

With your second version loaded type projects at the sbt command line and you should see that you have three of them. The one with a star at the front is the default project. It will be your root project. Commands that you type will apply to it. As it is an aggregate project the commands will be applying in turn to both foo and bar.
package is a good example command - typing it should produce a jar file that has both the foo and bar classes in it, if that is what you want.

Related

SBT Dynamic Project Dependency

I recently need to integrate some projects as submodules, and each of them has its own build.sbt.
And there are also dependencies between submodules.
Therefore, I need to dynamically convert the libraryDependencies to dependsOn format.
The project structure looks like this, and root depends on A and B, while A also depends on B.
.
├── build.sbt
├── projA
│   ├── build.sbt
│   └── src
├── projB
│   ├── build.sbt
│   └── src
└── src
   └── main
Since it seems appends .setting/.denpensOn directly to a project that already has build.sbt is ineffective.
// ./build.sbt
lazy val root = (project in file("."))
.settings(commonSettings)
.dependsOn(A, B)
lazy val A = (project in file("projA"))
.settings(commonSettings) <-- not work
.dependsOn(B) <-- not work
lazy val B = (project in file("projB"))
.settings(commonSettings) <-- not work
So, I try this method to dynamically edit libraryDependencies, but this approach is only able to modify settings.
The inter-project dependencies seem to be not controlled by the settings.
Is there any way to dynamically add dependsOn to the project?
Or how to make the depensOn appended on the subproject in the root build.sbt works?
Thanks.

Poetry script: No file/folder found

I am currently building a backend using FastAPI and I am facing some issues to run the backend using poetry scripts. This is my project structure:
├── backend
└── src
└── asgi.py
└── Dockerfile
└── poetry.lock
└── pyproject.toml
pyproject.toml
[tool.poetry]
name = "backend"
version = "0.1.0"
description = ""
authors = ["Pierre-Alexandre35 <46579114+pamousset75#users.noreply.github.com>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.9"
uvicorn = "^0.17.6"
fastapi = "^0.78.0"
psycopg2 = "^2.9.3"
jwt = "^1.3.1"
python-multipart = "^0.0.5"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.poetry.scripts]
foo='asgi:__main__'
If I am running poetry run python asgi.py, it is working perfectly but if I am using poetry foo script, I am getting No file/folder found for package backend. Those are all combinaisons I tried and I have the same error for every poetry run foo:
foo='asgi:main'
foo='backend.asgi:__main__'
foo='backend.asgi:main'
foo='backend.asgi:.'
Your project structure does not seem to be correct. Assuming backend is the package u are trying to create.
Use this structure
└── pyproject.toml
└── poetry.lock
└── README.md
├── backend
└── src
└── asgi.py
└── Dockerfile
└── __init__.py
Also in scripts use. (Assuming you are trying to run main with foo)
[tool.poetry.scripts]
foo='backend.asgi:__main__'

Is it possible to define packages within sbt's project directory

I defined some classes in sbt's project directory using no package (i.e. all my files were directly under project and they did not include any package statement). It worked fine.
Now when I tried to group them into packages and ran sbt reload I got not found: value XXX at the line I imported the package in my build.sbt (XXX is the name of the package).
Can't project deal with packages?
EDIT after comment
It will work if you add your source files in folder project/src/main/scala
Check this structure
tree
.
├── build.sbt
└── project
├── build.properties
└── src
└── main
└── scala
└── foo
└── Bar.scala
5 directories, 3 files
build.sbt
import foo._
version := Bar.ver
and Bar.scala
package foo
object Bar {
val ver = "1.0.0"
}

Can not import Dependencies.scala from top level sbt in multiproject

I have a commons project in sbt which needs some values stored in a Dependencies.scala.
.
├── build.sbt
├── project
│   └── Dependencies.scala
└── src
└── main
└── scala
commons/build.sbt
import Dependencies._
lazy val commons = (project in file("."))
.settings(
name := s"$msg commonsproject",
version := "1.0",
scalaVersion := "2.12.2"
)
commons/project/Dependencies.scala
object Dependencies {
val msg = "Hello world"
}
When I run sbt, I get the correct value for name
[info] Loading project definition from /mydata/workspace/multiproject/commons/project
[info] Set current project to Hello world commonsproject (in build file:/mydata/workspace/multiproject/commons/)
> name
[info] Hello world commonsproject
>
Now, I have integrated it in a top level sbt project.
├── build.sbt(top level)
├── commons
│   ├── build.sbt
│   ├── project
│   │   └── Dependencies.scala
│   └── src
│   └── main
├── project
│   └── build.properties
└── src
├── main
│   └── scala
└── test
└── scala
build.sbt
lazy val commons = (project in file("commons"))
.settings(
name := "subproject",
version := "1.0",
scalaVersion := "2.12.2"
)
lazy val root = (project in file("."))
.settings(
name := "rootproject",
version := "1.0",
scalaVersion := "2.12.2"
).aggregate(commons)
When I run sbt from the top level, it fails with the following error:
/mydata/workspace/multiproject/commons/build.sbt:1: error: not found: object Dependencies
import Dependencies._
^
/mydata/workspace/multiproject/commons/build.sbt:6: error: not found: value msg
name := s"$msg commonsproject",
^
sbt.compiler.EvalException: Type error in expression
[error] sbt.compiler.EvalException: Type error in expression
[error] Use 'last' for the full log.</pre>
Can anyone tell if it's possible to keep the Dependencies.scala in the common project and still be able to run it from a top level sbt ?
The goal would be to be able to run sbt either at the top level or in the subproject while keeping despendencies in each project.
Other design to achieve what I want is also welcome
Thank you
Here is the sample project https://github.com/ccheneson/multiproject
From the SBT 0.13 docs:
You cannot have a project subdirectory or project/*.scala files in the sub-projects. foo/project/Build.scala would be ignored.
In this case your Dependencies.scala file is being ignored because commons is a sub-project - that's why you can't access it.

Why doesn't my sbt project dependency work? (insists on trying to fetch it remotely)

I'm wanting to have a bridge for Scala.js and Snap.svg in an sbt project, but also including demo code for the bridge.
When doing demos/compile sbt starts to say that it cannot resolve the dependency. It looks like it's trying to reach the bridge as if it was a publicized, external project but it's right here, and it compiles.
What am I doing wrong?
Removing the publishing-specific files does not seem to bring a change.
Directory structure:
├── build.sbt
├── project
│   ├── (PublishToBintray.scala)
│   ├── build.properties
│   ├── build.sbt
│   ├── project
│   │   └── ...
│   └── target
│   │   └── ...
├── (publishing.sbt)
├── scalajs_demos
│   ├── main
│   │   └── scala
│   │   └── clock.scala
│   └── target
│      └── ...
├── src
│   └── main
│   └── scala
│   └── org
│   └── scalajs
│   └── snapsvg
│   ├── SnapSvg.scala
│   └── package.scala
└── target
   └── ...
build.sbt:
scalaJSSettings
name := "Scala.js Snap.svg"
normalizedName := "scalajs-snapsvg"
version := "0.01"
organization := "org.scala-lang.modules.scalajs"
scalaVersion := "2.11.1"
crossScalaVersions := Seq("2.10.4", "2.11.1") // note: not tested with 2.10.x
libraryDependencies +=
"org.scala-lang.modules.scalajs" %%% "scalajs-dom" % "0.6" // TBD: probably need it, just like jQuery bridge does
ScalaJSKeys.jsDependencies +=
"org.webjars" % "Snap.svg" % "0.3.0" / "snap.svg.js"
homepage := Some(url("http://snapsvg.io/"))
licenses += ("Apache 2.0", url("https://github.com/adobe-webplatform/Snap.svg/blob/master/LICENSE"))
//---
// bridge (main) project
//
lazy val bridge = project.in( file(".") )
//---
// demos project
//
lazy val demos = project.in( file("scalajs_demos") ).dependsOn(bridge)
What goes wrong in sbt:
> demos/compile
[info] Updating {file:/Users/asko/Hg/scala-js-snapsvg/}demos...
[info] Resolving org.scala-lang.modules.scalajs#scalajs-snapsvg_sjs0.5_2.10;0.01 ...
[warn] module not found: org.scala-lang.modules.scalajs#scalajs-snapsvg_sjs0.5_2.10;0.01
[warn] ==== local: tried
[warn] /Users/asko/.ivy2/local/org.scala-lang.modules.scalajs/scalajs-snapsvg_sjs0.5_2.10/0.01/ivys/ivy.xml
[warn] ==== public: tried
[warn] http://repo1.maven.org/maven2/org/scala-lang/modules/scalajs/scalajs-snapsvg_sjs0.5_2.10/0.01/scalajs-snapsvg_sjs0.5_2.10-0.01.pom
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: org.scala-lang.modules.scalajs#scalajs-snapsvg_sjs0.5_2.10;0.01: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[trace] Stack trace suppressed: run last demos/*:update for the full output.
[error] (demos/*:update) sbt.ResolveException: unresolved dependency: org.scala-lang.modules.scalajs#scalajs-snapsvg_sjs0.5_2.10;0.01: not found
[error] Total time: 0 s, completed 27.7.2014 22:57:22
>
One more thing, the project/plugins.sbt:
addSbtPlugin("org.scala-lang.modules.scalajs" % "scalajs-sbt-plugin" % "0.5.0")
The root cause of your issue is that the bridge project uses scalaVersion := "2.11.1" (as specified by your build.sbt, but your demos project uses the default scalaVersion (which is 2.10.2 in sbt 0.13, IIRC). The dependsOn relation gets confused when it tries to relate projects with different scalaVersions. See this issue: https://github.com/sbt/sbt/issues/1448
You probably thought that scalaVersion := "2.11.1" in the root build.sbt would apply to all subprojects. But that's not true, it only applies to the subproject rooted in . (here, bridge). You have to also specify this setting (and others you want shared) either as arguments of the settings() method of demos, or in the scalajs_demos/build.sbt file.

Resources