An SBT plugin that adds a mixin for doing Thrift code auto-generation during your compile phase
Pull request Compare This branch is 1 commit ahead, 1 commit behind twitter-archive:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Sbt11-scrooge is an sbt 0.11 plugin that adds support for using scrooge to perform thrift code generation.

How it works

The plugin registers itself as a source generator for the compile phase.

It fetches scrooge from the public Twitter maven repository, caches it in your project, and runs it against your thrift folder (usually src/main/thrift). The generated code folder (usually target/src_managed) is then added to your compile path.

Using it

See the sbt page on plugins for information on adding plugins. Usually, you need to add the following to your project/plugins.sbt file:

addSbtPlugin("com.twitter" % "sbt11-scrooge" % "1.0.0")

(But obviously, use the latest version number.)

If you use a build.sbt file, add this incantation:

import com.twitter.sbt._

seq(CompileThriftScrooge.newSettings: _*)

If you use Build.scala, add CompileThriftScrooge.newSettings to your settings list.

Here's a working example project/plugins.sbt:

resolvers += "twitter-repo" at ""

addSbtPlugin("com.twitter" %% "sbt11-scrooge" % "1.0.0")

addSbtPlugin("com.twitter" %% "sbt-package-dist" % "1.0.0")

And project/Build.scala:

import sbt._
import Keys._
import com.twitter.sbt._

object YourProject extends Build {
  val finagleVersion = "3.0.0"

  lazy val root = Project(
    id = "yourproject",
    base = file("."),
    settings = Project.defaultSettings ++
      StandardProject.newSettings ++
    name := "yourproject",
    organization := "com.example",
    version := "1.0.0-SNAPSHOT",
    scalaVersion := "2.9.1",
    libraryDependencies ++= Seq(
      "org.apache.thrift" % "libthrift" % "0.8.0" intransitive,
      "com.twitter" %% "finagle-core" % finagleVersion,
      "com.twitter" %% "finagle-thrift" % finagleVersion,
      "org.jboss.netty" % "netty" % "3.2.6.Final",
      "com.twitter" %% "scrooge-runtime" % "1.1.3"
    CompileThriftScrooge.scroogeVersion := "2.5.4",
    CompileThriftScrooge.scroogeBuildOptions := List("--finagle"),
    PackageDist.packageDistConfigFilesValidationRegex := Some(".*")


A full list of settings is in the (only) source file. Here are the ones you're most likely to want to edit:

  • scroogeVersion: String

    to use a different version of scrooge than the current default

  • scroogeCacheFolder: File

    to unpack the downloaded scrooge release into a different folder

  • scroogeBuildOptions: Seq[String]

    list of command-line arguments to pass to scrooge (default: Seq("--finagle", "--ostrich", "--verbose"))

  • scroogeThriftIncludeFolders: Seq[File]

    list of folders to search when processing "include" directives (default: none)

  • scroogeThriftSourceFolder: File

    where to find thrift files to compile (default: src/main/thrift/)

  • scroogeThriftOutputFolder: File

    where to put the generated scala files (default: target/<scala-ver>/src_managed)

Notes for helping work on sbt11-scrooge


To build the plugin locally and publish it to your local filesystem:

$ sbt publish-local


There is a really crude scripted plugin. You can run it with:

$ sbt scripted

It currently has the version number hard-coded, so you may need to update that manually. (Note: On my mac, this just consumes all memory and dies. Does this work for anyone? -robey)

Notes for people upgrading from very old versions

Upgrading from sbt-thrift

The scala bindings are not 100% compatible with the scala bindings that were generated by sbt-thrift. Here are the notable differences:

  • You need to add "scrooge-runtime" as a dependency:

    val scrooge_runtime = "com.twitter" % "scrooge-runtime" % "1.0.3"

  • The names of the interfaces have changed:

    • (service).ServiceIface is now (service).FutureIface

    • (service).Service is now (service).FinagledService

    • (service).Client is now (service).FinagledClient

    • BinaryThriftSerializer is now BinaryThriftStructSerializer[A], like:

      val serializer = new BinaryThriftStructSerializer[Beer] { def codec = Beer }

Upgrading from java

If you're switching from java generated code, there are a few other (fairly large) differences:

  • All container types are scala-native (Seq, Set, Map).

  • Enums are case objects (but still subclass TEnum).

  • Class, struct, and enum names are all converted to StudyCaps, so for example ERROR becomes Error.

  • Method names are all converted to camelCase, so for example GetName becomes getName and set_name becomes setName.

  • Structs are case classes, so they are immutable and have real, actual constructors (!). Multi-line field-setting struct construction should be converted to a single-line case class constuctor call.

  • Optional fields are implemented as Option[A].