Can multi-projects from GIT be used as SBT dependencies? - scala

I would like to use banana-rdf in my project, ideally by defining it as a dependency in a build.scala using dependsOn:
lazy val root = Project("root", file(".")) dependsOn RootProject(uri("git://github.com/w3c/banana-rdf"))
However, banana-rdf is a multi-project so needs to be composed differently. From what I can see, these multi-project definitions only allow you to specify project locations as file paths, and won't allow URIs.
Question: Am I right in saying that I have to clone these multi-project GIT dependencies into my project and reference them as folders?
I rather like the idea of leaving all the GIT cloning up to SBT, and having these cloned in some tmp SBT folder rather than cluttering up my project...

I depend on Banana RDF subprojects all the time with ProjectRef, like this:
lazy val core: Project = Project(
...
).dependsOn(
ProjectRef(uri("git://github.com/w3c/banana-rdf.git"), "banana-jena")
)
One especially nice part is that you can just tack a commit or branch name as a fragment identifier on the URI and everything works exactly as you'd expect.

Related

Mutli-projects build with gradle like sbt

I'm basically a scala developer and i have project in scala - sbt recently i've started using kotlin and trying to some parts of my code in to kotlin. I need help in understanding gradle build system.
db-service
queue-service
business-logic
processor-code depends on projects on db-service, queue-service and business logic
another project "X" depends on queue-service and some other service.
Usually in sbt this is something very straight forward you can use ProjectRef to include these projects as dependencies.
How do i achieve the same with gradle? Thanks in advance
//Update
sample build.sbt
lazy val buildSettings = Seq(
scalaVersion := "2.12",
fork in Test := true,
fork in IntegrationTest := true,
...
)
lazy val root = Project("processor-code", file("."))
.settings(buildSettings: _*)
.settings(
libraryDependencies ++= //Deps
)
.dependsOn(db-service, queue-service, utilities)
.aggregate(db-service, queue-service, utilities)
lazy val db-service = ...
lazy val queue-service = Project("queue-service", file(".")).settings()...
lazy val utilities = ProjectRef(file("../utilities"), "utilities")
i have tried including the project in settings.gradle
include 'project'
project(":project").projectDir = "../myProject"
and added
implementation(project(":project"))
however, it doesn't seem working show error plugin already on classpath, then i've also tried creating a submodule and it seemed like it was working but when i was trying to run it throws a initialization exception
i've understood that we can configure a project in the following scenario
Root project: (contains common build.gradle)
| - subproject A
| - subproject B
| - myapp
now myapp easily can depend on subprojects
My scenario (no common build.gradle, each project will have its own build.gradle)
| Independent project A
| Independent project B
| my app
While it's true that you can only depend on other sub-projects, technically, that's still possible with Gradle.
Since project A is a Gradle project, you could pack it with gradle jar command. Then you could move the produced JAR to wherever you want, but probably to your my app project.
Now it's possible to launch an arbitrary command from Gradle using project.exec {}
What's more, you can even write your own Kotlin/Groovy function inside Gradle to do that for you.
That's what SBT is doing for you, actually.

Scala sbt file dependency from github repository

Is it possible to include a dependency from github?
The repository does not have a jar file, just a build.sbt file and a source folder.
You can create a new project which points to the source in your build.sbt and then use dependsOn:
lazy val projectIDependOn = RootProject(uri("git://github.com/user/Project.git"))
lazy val myProject = project in file("my-project").dependsOn(projectIDependOn)
An alternative approach would be to clone to github repository and then use sbt-assembly to create an uber JAR you can use, but that requires a bit more work.

How to add one SBT project as a dependency of another?

I have the following project setup:
Base/
build.sbt
src/
Main/
build.sbt
src/
Where Base and Main are two projects. I would like Main to have the classes of Base on the classpath of Main. If possible, I would like to keep the builds separate. How can I do this?
Thanks!
You can try Multi-Project build, maybe it will be best in you case: http://www.scala-sbt.org/0.13.5/docs/Getting-Started/Multi-Project.html
However if this two projects are completely separate sbt supports source dependencies, it definitely works with github and I think should work with file dependencies as well
lazy val Main = Project("Main", file("."), settings = ...) dependsOn(baseDep)
lazy val baseDep = uri("file:///path/to/base/project")

What is the issue with this sbt file?

When I import a SBT project into intelliJ, the build.sbt file is showing lot of errors as shown in the following screenshot. Wondering what might be the issue
IDEA Version 13.1.4
I also see the following
The following source roots are outside of the corresponding base directories:
C:\Users\p0c\Downloads\recfun\src\main\resources
C:\Users\p0c\Downloads\recfun\src\test\java
C:\Users\p0c\Downloads\recfun\src\test\scala
C:\Users\p0c\Downloads\recfun\src\test\resources
These source roots cannot be included in the IDEA project model. Please consider using shared SBT projects instead of shared source roots.
I think the question perhaps does not provide all the required information to answer conclusively, but I'll give it a spin anyways -
Since sbt runs correctly when invoked from the shell, we know the sbt file is fine. I use Idea for my Scala and sbt projects and I am sure the Idea sbt support works very well, but! Idea is far more restrictive than sbt when it comes to project structure. It is really easy to create a valid sbt project structure that Idea can't support very well.
Given that the source roots error indicates that the recfun/src folder is not in the project folder, it seems clear that this error is not emitted during the processing of recfun/build.sbt. The screenshot shows you have at least three different sbt files, progfun-recfun, submission and scala-recfun. Since Idea will also create projects like submission-build, and you have an assignment-build project there, something is probably broken in the project structure, not from the sbt viewpoint - there you're fine, you can build - but from the Idea viewpoint, which is more restrictive.
My suggestion to resolve this would be to change your project structure as follows. First, have a top level project with a build.sbt. Then create a sub-project for each src folder you want. Do not put a src folder in your top level project. Each sub-project needs a build.sbt as well.
Second, make sure the sub-projects build correctly with sbt when run from the shell. Arrange the sub-project build.sbt files with the proper dependencies, using this syntax:
lazy val a = ProjectRef(file("../a"), "a")
lazy val b = ProjectRef(file("../b"), "b")
lazy val root = Project(id = "c", base = file(".")) dependsOn (a, b)
(This example has three sister projects a, b and c, where c depends on a and b. The three projects are placed in directories with the same name, within the root directory. The code snippet is from the build file for c.)
Third, arrange your top level build.sbt to aggregate the sub-projects, using this syntax in the top level build.sbt:
lazy val a = ProjectRef(file("a"), "a")
lazy val b = ProjectRef(file("b"), "b")
lazy val c = ProjectRef(file("c"), "c")
lazy val root = (project in file(".")).
aggregate(a, b, c)
Building this top level project will build each of the sub-projects a, b and c, and the dependencies established in the sub-project build files will ensure they are built in the right order.
Fourth, import the top level project into Idea, and all should be well.
You can get fancy with the file structure if you want, because the project references use relative paths, but it's usually nice to at least start simple.
I had a lot of frustration with sbt and Idea at the start, I hope this helps :)

Idiomatic way to write multi-project builds with .sbt files in sbt 0.13

I hear .sbt files have been improved in various ways in 0.13, and that now I can specify multi-project builds in them.
http://www.scala-sbt.org/0.13.0/docs/Community/ChangeSummary_0.13.0.html#sbt-format-enhancements mentions that we can now define subprojects in a .sbt file. I also know that multiple .sbt files in the root will be aggregated into a single conceptual file.
What I'd really like, though, is to not pollute my root with a dozen subproject .sbt files. Is there a way I can throw the subproject build.sbt files into their respective subdirectories, keep some common code between them somewhere shared, and then have a root build.sbt for the entire project that aggregates the subprojects? I have a similar setup in .scala files right now but would prefer to use .sbt files if possible.
If that isn't possible, what is the "correct" way to construct large multi-project builds with .sbt files?
It should already be the case in 0.12 that you can put .sbt files in the base directory of a subproject and the settings there will be included in that project's scope.
Code is reused between .sbt files by creating a normal .scala file in project/. The code in project/ will be available for use in the .sbt files. The definitions in one .sbt are not visible to other .sbt files, at least in 0.13. This is mainly an implementation restriction and it is undetermined whether this will be lifted in future versions.
The default root project will aggregate all subprojects, including those coming from projects defined in subProject/build.sbt.
The current difficulty is making it explicit.
For example, the following build.sbt in the root directory would define a subproject in sub/.
This is a full definition, defining the ID, base directory, etc... for the project.
<root>/build.sbt
lazy val sub = project
However, it cannot reference anything defined in <sub>/build.sbt. (The existence of sub/build.sbt is not known until after <root>/build.sbt is compiled and evaluated.)
So, to explicitly define what sub aggregates, you'd need something like:
sub/build.sbt
lazy val sub = project.in(file(".")).aggregates(subSub)
//or: lazy val sub = project in file(".") aggregate subSub
lazy val subSub = project
However, this duplicates the definition of sub.
A possible solution going forward is to make the root definition just a reference, like:
<root>/build.sbt
lazy val sub = LocalProject("sub")