ProjectDefinitionExamples  

This page lists some examples of project definitions, mostly drawn from the project definitions of sbt and Sling.

Overriding Package Name

This example overrides the name of the produced jar.

import sbt._

class SamplesProject(info: ProjectInfo) extends DefaultProject(info)
{
    override def artifactID = "samplez"
}

Changing Compile Options

This example shows how to specify additional options to pass to the compiler. Common options are provided as case classes or objects.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
    override def compileOptions = ExplainTypes :: CompileOption("-Xexperimental") :: super.compileOptions.toList
}

Include Extra Files in Jar

The default location for resources to be included in the produced jar is src/main/resources. This example shows how to add additional resources to the jar file. In this case, the extra files are license and notice files in the project root directory.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
    def extraResources = "LICENSE" +++ "NOTICE"
    override def mainResources = super.mainResources +++ extraResources
}

Exclude Tests

Running test will skip the sample.TestSpecification test in this example.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
    override def testOptions = ExcludeTests("sample.TestSpecification" :: Nil) :: super.testOptions.toList
}

Add Managed Dependencies not in a Repository

This example shows how to specify managed dependencies that are not in a repository. They will be downloaded when update is run, like normal managed dependencies.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
	val slinky = "slinky" % "slinky" % "2.1" from "http://slinky2.googlecode.com/svn/artifacts/2.1/slinky.jar"
}

Exclude Dependencies

This example shows an inline Ivy XML file to exclude some transitive dependencies. See the Ivy documentation for details.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
  override def ivyXML =
    <dependencies>
      <dependency org="javax.mail" name="mail" rev="1.4.2">
        <exclude module="activation"/>
      </dependency>
    </dependencies>
}

Or, exclude dependencies globally by putting the exclude element directly under dependencies. Again, see the Ivy documentation for details.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
  val jm = "javax.mail" % "mail" % "1.4.2"

  override def ivyXML =
    <dependencies>
      <exclude module="activation"/>
    </dependencies>
}

Specify Dependencies Inline

Declares a dependency on Jetty. Running update will download jetty and its dependencies transitively.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
    val jetty6 = "org.mortbay.jetty" % "jetty-ajp" % "6.1.14"
}

Add Repositories Inline

You can add repositories in your project definition instead of in an ivy-settings.xml file. Note that specifying repositories in your project definition means any ivy-settings.xml file will be ignored.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
    val snapshots = "Databinder Snapshots" at "http://databinder.net/repo/"
    val dispatch = "net.databinder" %% "dispatch" % "0.7.2"
}

Dependency Configurations

See the Hello Lift Example for an example of using configurations to restrict the scope of dependencies (for example: runtime, provided, compile, test).

Insert Task Dependency

Built-in actions are defined in the following pattern:

    lazy val compile = compileAction
    def compileAction = task { ... } dependsOn(...)

You can override the compileAction method to change the behavior of the built-in action, including adding dependencies. This example shows how to specify a new task to run before a built-in action by adding a dependency.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
    lazy val printAction = task { print("Testing...") }
    override def compileAction = super.compileAction dependsOn(printAction)
}

Conditional Task

If you have some work that takes some sources and generates some outputs, you can use fileTask to only run the task when the outputs are out of date with respect to the inputs.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
    def output: Path = "output"
    def input: Path = "input"

    lazy val showdown = fileTask(output from input) {
        generate(input, output)
    }
    def generate(in: Path, out: Path): Option[String] = ...
}

Extending Classpath

You can add directories and libraries to the unmanaged classpath. The context here is compiling Javascript to Java classes using Rhino and then putting those classes on the classpath.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
    def js_classpath = outputPath / "js_classes"
    override def unmanagedClasspath = super.unmanagedClasspath +++ js_classpath
}

Note that if this were a web project, package would automatically include the classes and libraries added in this manner in the war file.

Modifying Specific Classpaths

sbt uses different classpaths for different actions. The run action uses the classpath provided by the runClasspath method, the compile action uses compileClasspath, etc.... You can modify these classpaths as shown in this example.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
    override def runClasspath = super.runClasspath +++ extraRunClasspath
    def extraRunClasspath = ...
}

Additional Run Tasks

This example shows how to create an additional run-like task. It runs sample.Main using testClasspath after ensuring that main and test sources have been compiled.

import sbt._

class SampleProject(info: ProjectInfo) extends DefaultProject(info)
{
    lazy val demo = runTask(Some("sample.Main"), testClasspath).dependsOn(testCompile) describedAs "Runs the demo."
}

Add Task to Multiple Projects

This examples shows a parent project with two subprojects that have a new task tool that is configured with two paths. One path is from the parent project's directory and the other is in the sub project's directory.

import sbt._

class ExampleProject(info: ProjectInfo) extends ParentProject(info)
{
   def toolConfigurationFile = path("config")

   def subProject(path: Path, name: String) =
      project(path, name, new ExampleSubProject(_))

   lazy val subA = subProject("subA", "Sub Project A")
   lazy val subB = subProject("subB", "Sub Project B")

   class ExampleSubProject(info: ProjectInfo) extends DefaultProject(info)
   {
      def toolOutput = outputPath / "tool"
      def absolute(path: Path) = path.asFile.getAbsolutePath
      lazy val tool = task
      {
          log.info("Tool configuration " + absolute(toolConfigurationFile) + " and output " + absolute(toolOutput))
          None
      }
   }
}