= ScalaPB
:page-aliases: Plugin_ScalaPB.adoc
:mill-api-url: {mill-doc-url}/api/latest
:mill-api-scalapb-url: {mill-api-url}/mill/contrib/scalapblib


This module allows https://scalapb.github.io[ScalaPB] to be used in Mill builds. ScalaPB is a https://developers.google.com/protocol-buffers/[Protocol Buffers] compiler plugin that generates Scala case classes, encoders and decoders for protobuf messages.

To declare a module that uses ScalaPB you can extend the `mill.contrib.scalapblib.ScalaPBModule` trait when defining your module.

This creates a Scala module which compiles `.proto` files in the `protobuf` folder of the module with ScalaPB and adds the resulting `.scala` sources to your module's `generatedSources`.

.`build.mill`
[source,scala]
----
//| mvnDeps: ["com.lihaoyi::mill-contrib-scalapblib:$MILL_VERSION"]
package build

import contrib.scalapblib.*

object example extends ScalaPBModule {
  def scalaVersion = "2.12.6"
  def scalaPBVersion = "0.7.4"
}
----

This defines a project with the following layout:

[source,text]
----
build.mill
example/
    src/
    protobuf/
    resources/
----

== Configuration options

Please inspect the {mill-api-scalapb-url}/ScalaPBModule.html[API docs of `ScalaPBModule`] for all available tasks.

If you'd like to configure the https://scalapb.github.io/docs/scalapbc#passing-generator-parameters[options] that are passed to the ScalaPB compiler directly, you can override the `scalaPBOptions` task, for example:

.`build.mill`
[source,scala]
----
//| mvnDeps: ["com.lihaoyi::mill-contrib-scalapblib:$MILL_VERSION"]
package build

import contrib.scalapblib.*

object example extends ScalaPBModule {
  def scalaVersion = "2.12.6"
  def scalaPBVersion = "0.7.4"
  override def scalaPBOptions = "flat_package,java_conversions"
}
----

If you'd like to pass additional arguments to the ScalaPB compiler directly, you can override the `scalaPBAdditionalArgs` task, for example:

.`build.mill`
[source,scala]
----
//| mvnDeps: ["com.lihaoyi::mill-contrib-scalapblib:$MILL_VERSION"]
package build

import contrib.scalapblib.*

object example extends ScalaPBModule {
  def scalaVersion = "2.12.6"
  def scalaPBVersion = "0.7.4"
  override def scalaPBAdditionalArgs =
    Seq(s"--zio_out=${Task.dest.toIO.getCanonicalPath}")
}
----

If you rely on any `.proto` files from your dependencies that requires case classes to be generated, override the `scalaPBSources` as follows:

.`build.mill`
[source,scala]
----
//| mvnDeps: ["com.lihaoyi::mill-contrib-scalapblib:$MILL_VERSION"]
package build

import contrib.scalapblib.*

object example extends ScalaPBModule {
  def scalaVersion = "2.12.6"
  def scalaPBVersion = "0.7.4"
  override def scalaPBSources = {
    defaultResolver().classpath(
      Seq(ivy"..."),
      sources = true
    ).foreach(jar => os.unzip(jar.path, Task.dest))

    super.scalaPBSources() ++ Seq(PathRef(Task.dest))
  }
}
----
