4

I'm using ScalaPB to synthesize Scala classes for converting my data to and from Protobuf representation. By default, the SBT setup hooks into sbt compile to generate the files under the target folder.

Because I expect my .proto files to change very infrequently, I would rather manually invoke the ScalaPB process when they do, and keep the generated files under version control. This is the same approach I use for Slick's code generation functionality.

I can do something like:

lazy val genProto = TaskKey[Unit]("gen-proto", "Generate Scala classes from a proto file")
genProto := {
  val protoSources = ...
  val outputDirectory = ...

  // ? run the same process 
}

But I'm not sure how to invoke the process from SBT with custom inputs and outputs.

My latest attempt:

ScalaPbPlugin.runProtoc in ScalaPbPlugin.protobufConfig := (args =>
  com.github.os72.protocjar.Protoc.runProtoc("-v261" +: args.toArray))

lazy val genProto = TaskKey[Unit]("gen-proto", "Generate Scala classes from a proto file")

genProto := {
  val protoSourceDirectory = sourceDirectory.value / "main" / "protobuf"
  val outputDirectory = (scalaSource in Compile).value / outputProtoDirectory
  val schemas = (protoSourceDirectory ** "*.proto").get.map(_.getAbsoluteFile)
  val includeOption = Seq(s"-I$protoSourceDirectory")
  val outputOption = Seq(s"--scala_out=${outputDirectory.absolutePath}")
  val options = schemas.map(_.absolutePath) ++ includeOption ++ outputOption
  (ScalaPbPlugin.runProtoc in ScalaPbPlugin.protobufConfig).value(options)
  (outputDirectory ** "*.scala").get.toSet
}

I get the following error:

> genProto
protoc-jar: protoc version: 261, detected platform: mac os x/x86_64
protoc-jar: executing: [/var/folders/lj/_85rbyf5525d3ktt666yjztr0000gn/T/protoc2879794465962204787.exe, /Users/alan/projects/causality/src/main/protobuf/lotEventStoreModel.proto, -I/Users/alan/projects/causality/src/main/protobuf, --scala_out=/Users/alan/projects/causality/src/main/scala/net/artsy/auction/protobuf]
protoc-gen-scala: program not found or is not executable
--scala_out: protoc-gen-scala: Plugin failed with status code 1.
[success] Total time: 0 s, completed Apr 25, 2016 9:39:09 AM
acjay
  • 34,571
  • 6
  • 57
  • 100

1 Answers1

0
import sbt._
import Keys._

lazy val genProto = TaskKey[Unit]("gen-proto", "Generate Scala classes from a proto file")

genProto := {
    Seq("/path/to/scalapbc-0.5.24/bin/scalapbc",
        "src/main/protobuf/test.proto",
        "--scala_out=src/main/scala/") !
}
thesamet
  • 6,382
  • 2
  • 31
  • 42
  • I think my problem is that I don't know what the path to `scalapbc` is – acjay Apr 25 '16 at 13:35
  • That is, the executable as installed by SBT. I'd really like to keep the workflow all within SBT, if possible, so no dependencies need to be manually installed. – acjay Apr 25 '16 at 13:48