Scala source external to SBT project folder - scala

When creating an SBT scala project in ItelliJ, it wants me to put all source code in the src/main/scala folder of the project folder. However, I want to put the source code somewhere else independent or particular projects, build-tools, IDEs, etc.
How do I tell it to get the source from arbitrary locations?

You can use the following settings to change the location where SBT looks for your Scala sources:
// Change Scala source directory. Default is:
// scalaSource in Compile := baseDirectory.value / "src" / "main" / "scala"
scalaSource in Compile := file("<Path to your sources...>")
// Change Scala test source directory. Default is:
// scalaSource in Test := baseDirectory.value / "src" / "test" / "scala"
scalaSource in Test := file("<Path to your test sources...>")
For further information (including how to specify other source, library and resource directories), refer to the official SBT documentation for customizing paths.

Related

custom folder structure in sbt for scala

The default folder Structure of SBT is like this:
src
- main
- scala
- test
- scala
But I want to have a custom folder structure, something like this:
src
- main
- test
So my question is:
How can I customize my build.sbt file, to have a custom folder structure and have Intellij Idea recognize the new structure?
According to https://www.scala-sbt.org/1.x/docs/Howto-Customizing-Paths.html, you would need to apply the following in your build.sbt:
Compile / scalaSource := baseDirectory.value / "src/main"
Test / scalaSource := baseDirectory.value / "src/test"
I have not tried this, so not sure if this works as expected nor how far Intellij Idea supports this (though I'd expect it to fully support this).

sbt plugin: add an unmanaged jar file

I'm trying to create a relatively simple sbt plugin to wrap grpc-swagger artifact.
Therefore, I've created a project with the following structure:
projectDir/
build.sbt
lib/grpc-swagger.jar <- the artifact I've downloaded
src/...
where build.sbt looks like the following:
ThisBuild / version := "0.0.1-SNAPSHOT"
ThisBuild / organization := "org.testPlugin"
ThisBuild / organizationName := "testPlugin"
lazy val root = (project in file("."))
.enable(SbtPlugin)
.settings(name := "grpc-swagger-test-plugin")
According to sbt docs, that's all I have to do in order to include an unmanaged dependecy, that is:
create a lib folder;
store the artifact in there;
However, when I do execute sbt compile publishLocal, the plugin published lacks of that external artifact.
So far I've tried to:
set exportJars := true flag
add Compile / unmanagedJars += file(lib/grpc-swagger.jar") (with also variations of the path)
manual fiddling to libraryDependecies using from file("lib/grpc-swagger.jar") specifier
but none so far seemed to work.
So how am I supposed to add an external artifact to a sbt plugin?
The proper solution to this problem is to publish the grpc-swagger library. If for whatever reason this can't be done from that library's build system, you can do it with sbt. Just add a simple subproject whose only job it is to publish that jar. It should work like so:
...
lazy val `grpc-swagger` = (project in file("."))
.settings(
name := "grpc-swagger",
Compile / packageBin := baseDirectory.value / "lib" / "grpc-swagger.jar",
// maybe other settings, such as grpc-swagger's libraryDependencies
)
lazy val root = (project in file("."))
.enable(SbtPlugin)
.settings(name := "grpc-swagger-test-plugin")
.dependsOn(`grpc-swagger`)
...
The pom file generated for the root project should now specify a dependency on grpc-swagger, and running the publish task in the grpc-swagger project will publish that jar along with a pom file.
That should be enough to make things work, but honestly, it's still a hack. The proper solution is to fix grpc-swagger's build system so you can publish an artifact from there and then just use it via libraryDependencies.

variations of sbt directory structure

The standard sbt directory structure is like this:
src
main
java
scala
test
java
scala
I have only one java file, and I would like to simplify this structure by eliinating the intermediate java and scala directories so that the .scala files appear directly under main and test. I tried that and had problems with objects not found and such. Is there a way to configure sbt to make this work? Thanks.
Change the default Scala source directory
https://www.scala-sbt.org/1.x/docs/Howto-Customizing-Paths.html#Change+the+default+Scala+source+directory
scalaSource in Compile := baseDirectory.value / "src" / "main"
scalaSource in Test := baseDirectory.value / "src" / "test"
javaSource in Compile := baseDirectory.value / "src" / "main"
javaSource in Test := baseDirectory.value / "src" / "test"
The Scala source directory can be the same as the Java source directory.

How do I add additional file to class path which is not java or scala file using SBT configuration?

How do I add additional file to classpath which is not java or scala file using SBT configuration ?
My source folder is defined like this
javaSource in Compile := baseDirectory.value / "src"
I have jawr.properties in the root of my /src folder. I'd like this file to be copied to WEB-INF/classes of my packaged app. I tried changing filter to
includeFilter in (Compile, unmanagedSources) := "*.java" || "*.scala" || "jawr.properties",
But it fails on sbt compile because it tries to compile it as java file.
I'm on SBT 0.13.6
The philosophy of SBT is to work by convention (and not by configuration) as much as possible. So the most straightforward solution, in many cases, isn't to look for the correct setting to tell SBT where your files are... But rather to figure out where SBT already expects to find them. You can check this page of the "getting started with SBT" guide for the basics.
For resource files that needs to be packaged together with compiled classes, the default directory is src/main/resources (a convention borrowed from Maven, like most of SBT's default directory structure). Similarly, files in src/test/resources are added to the classpath but only during tests.
If, for some reason, you want to use non-standard directories, you will want to have a look at this page of the documentation. For resources, the key to modify is resourceDirectory:
// resources in `resources` instead of `src/main/resources` :
resourceDirectory in Compile := baseDirectory.value / "resources"
// test resources in `test-resources` instead of `src/test/resources` :
resourceDirectory in Test := baseDirectory.value / "test-resources"
You want it be an unmanaged resource (not source)
unmanagedResourceDirectories in Compile := Seq(baseDirectory.value / "src")
includeFilter in unmanagedResources := "jawr.properties"

Changing Scala sources directory in SBT

I'm having quite a few troubles pointing at a custom directory for Scala source-files in SBT.
I would like sbt to compile scala-files from a given directory instead of the regular src/main/scala directory.
I have tried both defining a .sbt and .scala project files, setting baseDirectory, scalaSource (and scalaSource s in the .scala file). I've also toyed around with everything from system-absolute to relative paths but nothing seems to work. It cannot locate any .scala file under the specified directory.
What are the proper ways to handle this?
Try this in build.sbt:
scalaSource in Compile <<= (sourceDirectory in Compile)(_ / "foo")
This will result in a directory src/main/foo for Scala sources. If you want to use some arbitrary directory, go for this:
scalaSource in Compile := file("/Users/heiko/tmp")
Update answer for SBT 0.13.13 ->
sourceDirectory in Compile := (baseDirectory( _ / "foo" )).value
And to add a source directory (instead of just replacing it) also for SBT 0.13.13 ->
unmanagedSourceDirectories in Compile += (baseDirectory( _ / "foo" )).value