How to create an SBT project directory structure with a shell script

This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 18.1, “How to create an SBT project directory structure.”

Problem

The Scala Build Tool (SBT) doesn’t include a command to create a new Scala project, and you’d like to quickly and easily create the directory structure for a new project.

Solution

Use either a shell script or a tool like Giter8 to create your project’s directory structure. Both approaches are shown here.

Use a shell script

SBT uses the same directory structure as Maven, and for simple needs, you can generate a compatible structure using a shell script. For example, the following Unix shell script creates the initial set of files and directories you’ll want for most projects:

#!/bin/sh
mkdir -p src/{main,test}/{java,resources,scala}
mkdir lib project target

# create an initial build.sbt file
echo 'name := "MyProject"
version := "1.0"
scalaVersion := "2.10.0"' > build.sbt

Just save that code as a shell script on Unix systems (or Cygwin on Windows), make it executable, and run it inside a new project directory to create all the subdirectories SBT needs, as well as an initial build.sbt file.

Assuming this script is named mkdirs4sbt, and it’s on your path, the process looks like this:

/Users/Al/Projects> mkdir MyNewProject
/Users/Al/Projects> cd MyNewProject
/Users/Al/Projects/MyNewProject> mkdirs4sbt

If you have the tree command on your system and run it from the current directory, you’ll see that the basic directory structure looks like this:

.
|-- build.sbt
|-- lib
|-- project
|-- src
|   |-- main
|   |   |-- java
|   |   |-- resources
|   |   |-- scala
|   |-- test
|       |-- java
|       |-- resources
|       |-- scala
|-- target

This is just a simple starter script, but it helps to show how easy it is to create a basic SBT directory structure.

The build.sbt file is SBT’s basic configuration file. You define most settings that SBT needs in this file, including specifying library dependencies, repositories, and any other basic settings your project requires. I’ll demonstrate many examples of it in the recipes in this chapter.

Use Giter8

Although that script shows how simple building a basic directory structure is, Giter8 is an excellent tool for creating SBT directory structures with specific project needs. It’s based on a template system, and the templates usually contain everything you need to create a skeleton SBT project that’s preconfigured to use one or more Scala tools, such as ScalaTest, Scalatra, and many others.

The Giter8 templates that you can use are listed on GitHub. As a demonstration of how this works, the following example shows how to use the scalatra/scalatra-sbt template.

To create a project named “NewApp,” Giter8 prompts you with a series of questions, and then creates a newapp folder for your project. To demonstrate this, move to a directory where you normally create your projects, then start Giter8 with the g8 command, giving it the name of the template you want to use:

/Users/Al/Projects> g8 scalatra/scalatra-sbt
organization [com.example]: com.alvinalexander
package [com.example.app]: com.alvinalexander.newapp
name [My Scalatra Web App]: NewApp
scalatra_version [2.2.0]:

servlet_name [MyScalatraServlet]: NewAppServlet
scala_version [2.10.0]:

version [0.1.0-SNAPSHOT]:

Template applied in ./newapp

Because I answered the name prompt with NewApp, Giter8 creates a subdirectory under the current directory named newapp. It contains the following files and directories:

newapp/.gitignore
newapp/project/build.properties
newapp/project/build.scala
newapp/project/plugins.sbt
newapp/README.md
newapp/sbt
newapp/src/main/resources/logback.xml
newapp/src/main/scala/com/alvinalexander/newapp/NewAppServlet.scala
newapp/src/main/scala/com/alvinalexander/newapp/NewappStack.scala
newapp/src/main/scala/ScalatraBootstrap.scala
newapp/src/main/webapp/WEB-INF/templates/layouts/default.jade
newapp/src/main/webapp/WEB-INF/templates/views/hello-scalate.jade
newapp/src/main/webapp/WEB-INF/web.xml
newapp/src/test/scala/com/alvinalexander/newapp/NewAppServletSpec.scala

In this example, Giter8 creates all the configuration files and Scalatra stub files you need to have a skeleton Scalatra project up and running in just a minute or two.

Giter8 notes

At the time of this writing, I had a problem with the current Scalatra template, and had to add this line to the build.sbt file in my root project directory to get the template to work:

scalaVersion := "2.10.0"

To run a Scalatra project, enter the SBT shell from your operating system command line, and then run the container:start command:

/Users/Al/Projects/newapp> sbt
> container:start

This command starts the Jetty server running on port 8080 on your computer, so you can easily test your installation by accessing the http://localhost:8080/ URL from a browser.

In the case of using a new template like this, SBT may have a lot of files to download. Fear not — once they’re downloaded, your new Scalatra project should be up and running, and all of these downloads are required only during the first SBT run.

Discussion

As shown in the Solution, because the SBT directory structure is standard and based on the Maven directory structure, you can create your own tool, or use other tools that are built for this purpose.

For simple SBT projects, I’ve created an improved version of the shell script shown in the Solution. I named it sbtmkdirs, and you can download it from the URL shown in the See Also section. Like Giter8, this script prompts you with several questions, and optionally creates .gitignore and README.md files, along with a full build.sbt file. I use this script whenever I want to create a Scala project where I don’t need a template.

As demonstrated, Giter8 works by downloading project templates from GitHub. Giter8 requires SBT and another tool named Conscript, so to install and use Giter8, you’ll need to follow these steps:

  1. Install SBT
  2. Install Conscript
  3. Install Giter8

Fortunately those projects are well documented, and it takes just a few minutes to install all three tools.

There have been a couple of times when I’ve used Giter8 and it failed to download a project template. I don’t remember the exact error messages, but this was the most recent one:

$ g8 scalatra/scalatra-sbt
Unable to find github repository: scalatra/scalatra-sbt.g8 (master)

Each time this has happened, I’ve upgraded Conscript and Giter8 to their latest versions, and the problem has gone away.

Conscript is an interesting tool that works with GitHub projects for the purpose of “installing and updating Scala programs.” Its purpose and installation process are well documented at its website.

Giter8 currently uses a Java installer. Installing it on a Mac OS X system failed when I double-clicked the JAR file, but when I ran it from the command line (using the java -jar approach), it installed successfully.

See Also