How to setup SBT dependency for scala code that is located in same directory as Build.scala - scala

Our project features a kind of adhoc "plugin" that reads csv files and stuffs the contents into a database.
This code is defined in /project/DataMigrate.scala
We had our own poorly implemented version of a CSV parser that isn't up to the task anymore so I tried to add this https://github.com/tototoshi/scala-csv to the libraryDependencies in /project/Build.scala but that did not make it importable from DataMigrate.scala. I also tried putting the library dependency in /project/build.sbt as I read something about "Build definition of a build definition", but that did not seem to help either.
Is it at all possible to add dependencies for code that lives in /project?

SBT is recursive, so just as you can define dependencies and settings of the actual project in [something].sbt or project/[something].scala you can define dependencies and settings of the projects project (any ad hoc plugins etc) in project/[something].sbt or project/project/[something].scala

Related

Adding dependencies for use in build.sbt itself

I'm not asking here how to add library dependencies to an SBT project. I'm asking how to add a library that is to be called from within build.sbt itself (or the files under project/* that will be called from build.sbt). For example, the circe-yaml library for parsing and editing YAML files. How does one add a third-party dependencies to that?

How to use SBT's externalPom() command

I have a Maven POM file that the deployment engineers need to deploy the system in the enterprise. I have developers using SBT for a Scala project. They use SBT targets that just aren't supported in Maven. We'd like to use the Maven POM file to define the dependencies, slurp in those dependencies in SBT, and define SBT development targets there.
According to the SBT documentation, the externalPom() command is the way to do that. But even with the simplest POM file (two developers have tried this with two different simple POM files that defined different dependencies), the externalPom() command seems to half work. The SBT targets clearly recognize the dependency defined in the POM, but can't resolve it. This error arises:
Cannot add dependency 'commons-collections#commons-collections;3.2.2'
to configuration 'default' of module
default#maven-sbt$sources_javadoc;0.1-SNAPSHOT because this
configuration doesn't exist!
When the externalPom() command is commented out and the equivalent dependency added directly in the build.sbt file everything goes swimmingly. The dependency comes directly from Maven Central in both cases; one from copying the dependency from the Maven tab and one from copying the dependency from the SBT tab. Once again, two developers are seeing exactly the same thing, from two different dependencies. The thing that's common is that both developers have reduced the build.sbt file down to a single statement. In the "slurp from POM" case, that statement is externalPom(). In the "plain old SBT" case, that statement is the dependency copied from Maven Central. The POM file is a dependency list with a single dependency (as simple as we can make it and still test externalPom()).
We suspect that we need something else in the build.sbt to make the externalPom() command work but we don't know what it is. Any help with that would be greatly appreciated.
I did some experimentation with this, and was able to replicate your error in my experiments.
I'm still a bit of a Scala / SBT newbie, but I created a build.sbt file that looks like so:
val Default = config("default")
lazy val root = (project in file(".")).
configs(Default).
settings(
externalPom()
)
This did compile for me!
One non-obvious catch: I had to make sure to include the scala-library in my POM file as a dependency

Chisel: Compiling Chisel library on Windows

I have been using sbt on windows and a custom build.sbt script in conjunction with an import Chisel._ in the top-level file in order to generate Verilog from my Chisel source successfully.
I'm trying to get an IDE working on Windows to expedite Chisel development. I've gone with the Eclipse based SCALA IDE http://scala-ide.org/download/sdk.html/
I want to compile the Chisel library so that the import Chisel._ can be resolved locally, without having to go off and download the source from the repository each timeand recompile the source. When I download the Chisel-master repo from Git and include the src\main folder in my SCALA project in the SCALA IDE, I get lots of syntax errors in the Chisel SCALA files that prevent me from building the project.
Has anyone done anything like this before on Windows or have any knowledge of working with the SCALA IDE as it may just be a case of undefined symbols in the project configuration?
Not sure exactly what you did with build.sbt respect to recompile (I think it download it only the first time, then it caches it for the future). But I'm using ScalaIDE for Chisel on linux, using the default build.sbt files, maybe you can try to get it working out of the box first to help narrow down the issue.
Here are the steps I took in order to get ScalaIDE work with Chisel:
the latest Scala IDE uses 2.11.8, the current Chisel repository defaults to 2.11.7. So I had to change all the build.sbt reference to scalaVersion from 2.11.7 to 2.11.8
I used sbteclipse
https://github.com/typesafehub/sbteclipse
To create importable the workspace to setup the compilation dependencies.
Except for chiselFrontEnd. For some reason, this package is not added to the dependency. I have to Add chiselFrontEnd as a javabuildpath dependency manually (Properties/JavaBuildPath, under Projects) for my own projects.
To resolve undefined symbols, you can also add a JAR onto the project build path using Project Properties > Java Build Path > Libraries > Add External JARs...
If you are getting your JARs through Maven / SBT, they should be in:
C:\Users\<name>\.ivy2\local\edu.berkeley.cs\chisel3_2.11\jars
If you are using publish-local with chisel3, your JARs should be in
C:\Users\<name>\.ivy2\cache\edu.berkeley.cs\chisel3_2.11\jars
Note that chisel3 is compiled into one JAR, including coreMacros and chiselFrontend sub-projects
Of course, this is a more quick-and-dirty solution compared to something that can parse SBT files.

How to create standalone jar file for elastic4s from sources?

I'm trying to create a standalone jar file from the elastic4s sources on github. I've used sbt compile as detailed on the github page, but I can't find the jar file.
How do I use sbt to create the jar file so I can import it into my projects as a dependency?
The compile task will only compile the project.
> help compile
Compiles sources.
If you want to create a jar file and use it as a dependency in your project, you have two ways of doing that.
Unmanaged dependency (not recommended)
Unmanaged dependency run +package, which will create a jar file for each supported scala version, which you can use in your projects as an unmanaged dependency. Copy the package-generated jar to lib folder in your project.
The jar files will be located in target/scala-2.11 and target/scala-2.10, depending on the Scala version you want to use it with.
Publish to Local Repository (recommended yet imperfect)
If you want to include your custom-built elastic4s, as a managed dependency, you have to run +publishLocal. This will do the same as above, but additionally it will publish the artifact to your local repository. Assuming you've built it with version := "1.2.1.1-SNAPSHOT", you can include it in your project by just adding:
libraryDependencies += "com.sksamuel.elastic4s" %% "elastic4s" % "1.2.1.1-SNAPSHOT"
What makes the approach imperfect is that once you shared the project on GitHub (or any other project sharing platform), people will have to do publishLocal themselves to be able to build your project. The dependency should therefore go to one of the official binary repositories so when a dependency is needed, it's downloaded from Internet. Consult Publishing.
What is the + character in front of the commands
The + in the commands is for cross-building, if you don't use it the command will be executed only using scalaVersion declared in the build.sbt of the project.

How do I use shared configurations across SBT (Play) multi-projects?

I have several SBT 0.13 / Play 2.2 projects (websites). They are all multi-module as they share some common functionality. This makes their project configuration files both complex and almost identical, but not quite.
I would like to be able to share as much as possible of these configuration files across the projects (frequent play updates makes keeping 5+ websites up to date a royal pain, not to mention all the almost-identical-but-evolving dependency lists across the projects).
build.properties and plugins.sbt are identical across projects and can be overwritten by a simple script. Great.
Build.scala is trickier - I would like to introduce a shared base class like so:
abstract class MyBuildBase extends Build { ... }
that in Build.scala do:
object ApplicationBuild extends MyBuildBuild { ... }
In order for this to make any sense at all, MyBuildBase.scala needs to be shared across projects. This can be done with svn:external, which operates on directories. Which means I need to somehow make this shared directory accessible when Build.scala is compiled (otherwise sbt complains loudly).
Reading http://www.scala-sbt.org/0.13.0/docs/Detailed-Topics/Classpaths.html and http://www.scala-sbt.org/0.13.0/docs/Getting-Started/Full-Def.html it seems like this should be possible.
However, it is exceptionally unclear to me what to actually put in the project/project/Build.scala file to actually achieve this - I can't find an example of "an sbt build file that's intended to build an sbt build file and include some extra source files in the build".
Any suggestions?
What you probably want to do is create a plugin, or shared library.
You can make an sbt project with a build like follows:
build.sbt
sbtPlugin := true
organization := "you"
name := "common-build"
version := "1.0"
Then create in src/main/scala your abstract class "MyBuildBase". Release this project as an sbt plugin.
Then in your other projects, you can use this as a library/plugin. In project/plugins.sbt add:
addSbtPlugin("you" % "common-build" % "1.0")
And this will resolve your common build library when building your build.
If you need more information, look up more about sbt plugins and ignore the part about making something that extends a Plugin. Plugins are just libraries versioned with sbt's version number and your own. You should be able to put whatever code you want in there to share between builds.
Note: in 2016, Build.scala is deprecated for Build.sbt.
Here is the new (Dec. 2016) multi-module with App Scala sbt template by Michael Lewis.
Usage
sbt new lewismj/sbt-template.g8
You can then run:
sbt compile
sbt publish-local
sbt assembly
It is based on Scala SBT template (Library)
This giter8 template will write SBT build files for a Scala library.