opt-tech / sbt-diff-project

SBT plugin to show which projects are different between in git diff



Make CI for sbt multi-project FASTER.

Show projects and their children which are different in git diff.

Circle CI

Use case

Imagine that your sbt multi-project is defined as below.

lazy val root = project in file(".")

lazy val core = project
lazy val web = project.dependsOn(core)
lazy val batch = project.dependsOn(core)
lazy val secondBatch = project.dependsOn(batch)

Then, suppose that followings.

  • You write unit tests to all projects.
  • You added this multi-project build to Git version control and commit to master branch.
  • master branch passed the tests.

If you modified a file in batch project, you need to test batch and secondBatch project only.

This can be achieved as follows. (suppose that changes are committed to feature/batch branch)

$ cd /path/to/sbt-project
$ sbt --error 'set showSuccess := false' 'git-diff-all master feature/batch' # suppress sbt debug log

Voila, git-diff-all command prints batch(contains modified file) and secondBatch(is dependsOn batch).

Now, you can test batch and secondBatch via pipe or redirection.



Add the plugin in project/plugins.sbt:

addSbtPlugin("jp.ne.opt" % "sbt-diff-project" % "0.2.1")

git-diff-all command

git-diff-all sbt command executes git diff --name-only internally.

You can use this command as follows.

$ sbt git-diff-all
$ sbt 'git-diff-all 752a93 b2f98f'
$ sbt 'git-diff-all master feature/foo'
$ sbt --error 'set showSuccess := false' git-diff-all  # suppress sbt debug log

You can use printGitDiffToFile to configure output. (stdout by default)

$ sbt
> set printGitDiffToFile := Some(file("/path/to/diff.txt"))
> git-diff-all


  • gitDiffSeparator : Specify separator string for printing projects. \n as default.
  • printGitDiffByBaseDirectory : Print base directory instead of project ID. false as default.
  • printGitDiffByAbsolutePath : Print absolute path instead of related path. (only affects when printGitDiffByBaseDirectory is true) false by default.
  • printGitDiffToFile : Print to a file instead of stdout. None (print to stdout) by default.
  • excludeRootProject : This plugin derives project-diff based on project's base directory. Since root project's base directory-path is included to any project's, excluding root project from diff is reasonable. true by default.
  • patternsAffectAllProjects : For some special files, you would want to force testing all projects if the file is modified. (e.g. .travis.yml, circle.yml, build.sbt, ...) Seq(""".+\.sbt$""", """.+project/[^/]+\.scala""") by default.


Published under the MIT License.