When starting a new Scala project there are a few things that you want do get setup correctly before starting your development work. These are some of the things that I do for each new project.

Spoiler - I have created a GitHub repo basic-scala-template that contains everything that is mentioned here.

Note - Based on feedback, I have listed updates to the template at the bottom of this post.

A Note on Activator

The wonderful people at Typesafe have a project called Activator which is a nice little tool that, among other things, allows you to get started quickly by selecting a base template. While this is useful and there are some good templates, I still prefer to manage my own template. This allows me to make some additions that are missing from the Activator templates and setup my projects in a way that work best for me.

SBT

I setup all my projects as a standard SBT project (because why wouldn’t you) so hopefully you can find this useful. The first thing I do is download the version of SBT that I want and add the launcher and the shell script local to my git repo. This way I always have sbt available on whatever machine that I am working on and I am able to make per-project changes to the launcher. If you do this as well you will have to get used to typing ./sbt vs sbt, but that is an easy change to make.

As of right now, my project structure looks like the following:

1
2
3
4
.
├── bin
│   └── sbt-launch.jar
└── sbt

I will note that for the actual sbt script I usually just use one of my own rather than the super-complex ones that ship with the SBT download. My current sbt launch script looks like:

1
2
3
4
5
6
7
#!/bin/bash
 
JAVA=java
JAVA_OPTS="-Xmx512m -XX:MaxPermSize=256M"
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 
$JAVA $JAVA_OPTS -jar "${DIR}/bin/sbt-launch.jar"

Basic SBT Additions

Now that I have SBT setup for a project, I can start doing some basic configurations that I figure I will need on all my projects. First I’m going to add is the sbt-revolver. This is a very useful plugin that can run your project in a forked JVM and reload it on a change. We can add this to the project by adding the following to our project/plugin.sbt:

1
addSbtPlugin("io.spray" % "sbt-revolver" % "0.7.2")

While I’m at it, I’m going to add one more plugin, sbt-idea, that can generate IDE-specific files for IntelliJ IDE with a simple command gen-idea:

1
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0")

Template Build File

When using SBT I opt for the full Build.scala vs the DSL-like build.sbt file. I find it easier and more straight-forward to work with. I like to break my build file into several logical sections: resolvers, dependencies, build settings, and the application build. My typical build-file looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import sbt._
import Keys._
import spray.revolver.RevolverPlugin._
 
object Resolvers {
}
 
object Dependencies {
   val appDependencies = Seq(
   )
}
 
object BuildSettings {
 
   val buildOrganization = "johnmurray.io"
   val appName = "CHANGE_ME"
   val buildVersion = "0.0.1-SNAPSHOT"
   val buildScalaVersion = "2.10.4"
   val buildScalaOptions = Seq("-unchecked", "-deprecation", "-encoding", "utf8")
 
   import Resolvers._
   import Dependencies._
 
   val buildSettings = Defaults.defaultSettings ++ Seq(
      organization        := buildOrganization,
      version             := buildVersion,
      scalaVersion        := buildScalaVersion,
      libraryDependencies := appDependencies,
      scalacOptions       := buildScalaOptions
   ) ++ Revolver.settings
}
 
object ApplicationBuild extends Build {
 
   import BuildSettings._
 
   lazy val main = Project(
      appName,
      file("."),
      settings = buildSettings)
}

Even though this build file is pretty bare (at the moment) there are some key things that I like to include as part of every build configuration.

Scala
Aside from specifying the version that I will be using for this project, I also specify some basic compiler options to output more verbose warnings and do some extra checks for me.
Versioning
I like to start each project as a snapshot version (0.0.1). I can then extend the build-file later with some publishing configurations to push snapshot versions to a repo (like Sonatype) on each successful build/commit/test-run/etc.
Revolver
Even though we added the sbt-revolver plugin to our plugins.sbt file earlier we still need to add the settings to our build to fully install it.

Style Checking

For me, this is a new addition but I generally like consistency in my projects (open source and closed) when it comes to style. I’ve been playing around with various style checkers, but I’ve settled on Scalastyle for now. I don’t have much beyond the standard, but I’m sure it’ll evolve over time. I added the following to my plugins.sbt file

1
2
3
addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.4.0")
 
resolvers += "sonatype-releases" at "https://oss.sonatype.org/content/repositories/releases/"

I’ve also updated our buildSettings in project/Build.scala by appending the Scalastyle settings

1
2
3
4
5
6
7
 val buildSettings = Defaults.defaultSettings ++ Seq(
  organization        := buildOrganization,
  version             := buildVersion,
  scalaVersion        := buildScalaVersion,
  libraryDependencies := appDependencies,
  scalacOptions       := buildScalaOptions
) ++ Revolver.settings ++ ScalastylePlugin.Settings

As far as the build configuration goes, my configuration isn’t far off the default you get by running sbt scalastyle-generate-config so I won’t list it here.

Testing

For testing I typically start with Specs2 and add from there. For this we add to the build file simply:

1
2
3
4
5
object Dependencies {
   val appDependencies = Seq(
      "org.specs2" %% "specs2" % "2.3.10" % "test"
   )
}

I can easily add others in the same fashion. For example, if I were doing an Akka project I would add the akka-testkit for the spray-teskit for Spray projects.

If the project I am building is open source, I have to think about CI what build system I’m going to use. I personally prefer to use Travis-CI just because it’s so darn simple. Since this is usually the case I add the .travis.yml file:

1
2
3
4
5
6
7
8
9
10
11
language: scala
scala:
  - 2.10.3
script:
  - sbt compile test:compile
  - sbt scalastyle
  - sbt test
jdk:
  - oraclejdk7
  - openjdk7
  - oraclejdk8:w

Miscellaneous

As a final note, I like to add some basic files that I put in most projects:

.gitignore
The baiscs for scala projects as well as IntelliJ project-files and general files (like .swp files and what not)
readme.md
I like to include a readme with all of my projects (open source or not) just as a welcome and a guide for navigating and working with the project.

Done!

Now that I’m done putting together all the pieces to get started, my final directory structure is laid out in the following manner:

1
2
3
4
5
6
7
8
9
10
11
.
├── .gitignore
├── .travis.yml
├── bin
│   └── sbt-launch.jar
├── project
│   ├── Build.scala
│   └── plugins.sbt
├── readme.md
├── sbt
└── scalastyle-config.xml

As I mentioned in the spoiler up top, I have put this into a git repository for my own (and possibly your) convenience here. You can start any new project using this template simply via:

1
git clone https://github.com/JohnMurray/basic-scala-template.git YOUR_PROJECT_NAME

Or, you can clone the repository and add the scala-new script to your path which is located in the root of the project. With this you can simply do

1
2
3
scala-new my-new-project
cd my-new-project
# start working! 

This script will take care of updating the repo, creating a directory, and copying over all the necessary files. Easy peasy.

If you find this useful (and I hope you do) then please fork my repo and customize it to suite your needs. Feel free to send pull requests if you think I am missing something awesome that you feel every Scala project should include.

Enjoy!



Update #1

Thanks to a comment by predef on reddit, I have removed the sbt-launcher jar from my project along with my custom sbt script in favor of using the sbt-extra script and creating a project/build.properties file. You now must simply use the sbt script ./sbt and the correct version of SBT will be downloaded for you.

The second suggestion was to remove the sbt-idea plugin from the project and move it into my global plugins (that’s a thing?!) which is a fantastic idea. So I have now created the file ~/.sbt/0.13/plugins/intellij.sbt that contains the addPlugin... that we used earlier in the plugins.sbt file for the sbt-idea plugin. Now the project can be more agnostic to what editor is used. Do note that if you still want to use the IntelliJ SBT plugin that you’ll need to add that to your global plugins as the script/template will not handle that for you.