Home

Awesome

sbt-bazel

Build Status

This plugin is considered experimental. Expect frequent breaking changes.

sbt-bazel is an sbt plugin that converts sbt projects to Bazel workspaces. This readme assumes you have basic knowledge of how a Bazel workspace is organized.

This plugin will generate BUILD files for each project along with a WORKSPACE files that handles importing rules_scala and downloading binary artifacts from Maven repos.

Typical Usage

The readme-example project in the plugin's test directory is a minimal usage example. This section will walk through the settings used.

First you must install the plugin in your project. Do this by adding the following to your project's project/plugins.sbt:

addSbtPlugin("com.stripe" %% "sbt-bazel" % "0.0.1")

In your project's build.sbt file, you must now set the version of rules_scala. This is done by setting bazelScalaRulesVersion to the SHA of the rules_scala commit you'd like to use. For example, to set the version to 0eab80ff0696d419aa54c2ab4b847ce9bdcbb379 add the following to the top of your build file:

ThisBuild / bazelScalaRulesVersion := "0eab80ff0696d419aa54c2ab4b847ce9bdcbb379"

A common sbt pattern is to set up a root project that does not contain any source files itself, but is instead an aggregation all of a repo's sub-projects. This is the pattern the example project follows.

In order to generate one WORKSPACE file, enable workspace file generation with bazelWorkspaceGenerate for the root project. Because the root project is just an empty aggregation, it also makes sense to turn off BUILD file generation with bazelBuildGenerate. Putting all this together, the root target will look as follows:

lazy val root =  project.
  in(file(".")).
  aggregate(core, example).
  settings(
    bazelWorkspaceGenerate := true,
    bazelBuildGenerate := false,
  )

You can now run the bazelGenerate task against the root project. The result will be BUILD files generated for all the aggregated projects. These will appear at the base directory of each of the projects. A WORKSPACE file will also be generated at the root directory of the root project, which will handle downloading binary dependencies and rules_scala.

See the *.expect files for examples of what the generated files will look like.

Overriding Behavior

For more complicated projects, you may need to customize the behavior of the plugin. Several settings are available to you.

Toggling File Generation

Customizing Workspace and Build File Generation

So the default setting is: bazelCustomWorkspace := WorkspacePrelude +: MavenBindings, where the +: operator concatenates sections together.

The BazelString operand allows you add arbitrary text to the WORKSPACE file. The following would completely replace the generated WORKSPACE contents with the string passed to BazelString: bazelCustomWorkspace := BazelString("# Custom workspace file")

The +: operator concatenates sections and BazelString allows you to specify arbitrary strings.

Customizing Dependency Generation

The plugin will add dependencies to targets based on sbt's dependsOn and libraryDependencies setting. If this needs to be overridden for some reason, this can be customized with the bazelRuleDeps setting. The default setting is bazelRuleDeps := Deps(Compile), which means each target will include dependencies on any internal project dependencies and all dependencies in Keys.externalDependencyClasspath.

Each operand of the DSL specifies a set of dependencies, and these sets can be used in an expression with the normal set operators: +, -, , and .

The operands are:

Putting this together, the following would remove the circe-parser 0.9.2 dependency and substitute it for version 0.9.3:

bazelRuleDeps := Deps(Compile) -
  ModuleDep("io.circe" %% "circe-parser" % "0.9.2") +
  ModuleDep("io.circe" %% "circe-parser" % "0.9.3")

Customizing Maven Dependency Resolution in WORKSPACE

You can also customize which dependencies are loaded in the WORKSPACE file with bazelMavenDeps. The default is bazelMavenDeps := AllExternalDeps(Compile)

The operators and operands in the Customizing Dependency Generation section can be used here.

scala_rules Version

Limitations

The plugin has the following limitations:

Contributing

Contributions are welcome. If you have a large contribution in mind, please open an issue to discuss the change first.

To update the test expectations:

Authors