Running as standalone or with `mill`
Hi, I'm moving a project from sbt to mill and did not find a way to use the codegen outside of sbt. Is it possible to run the fs2-grpc codegen as a standalone, e.g. with protoc?
Okay, after searching maven for a while and a lot of trial and error, I seem to have gotten somewhere with
./bin/scalapbc --plugin-artifact=org.typelevel:protoc-gen-fs2-grpc:2.7.14:default,classifier=unix,ext=sh,type=jar -v3.11.1 myprotofile.proto --scala_out=flat_package,java_conversions,single_line_to_proto_string:out --fs2-grpc_out=out
I managed to use this library in mill with the following build setup.
import contrib.scalapblib._ and extends ScalaPBModule.
Add the following libraryDeps
ivy"org.typelevel::fs2-grpc-runtime:${version.fs2Grpc}",
ivy"io.grpc:grpc-netty-shaded:${version.grpcJava}",
and overwrite scalaPBAdditionalArgs as follows:
override def scalaPBAdditionalArgs: T[Seq[String]] = T {
Seq(
s"--plugin-artifact=org.typelevel:protoc-gen-fs2-grpc:${version.fs2Grpc}:default,classifier=unix,ext=sh,type=jar",
s"--fs2-grpc_out=${(T.dest / os.up / "compileScalaPB.dest").toIO.getCanonicalPath}",
)
}
Example:
import mill._, scalalib._
import contrib.scalapblib._
...
object ... extends ScalaPBModule with ... {
def scalaPBVersion = version.scalaPb
def moduleDeps = Seq(...)
def libraryDeps = Agg(
ivy"org.typelevel::fs2-grpc-runtime:${version.fs2Grpc}",
ivy"io.grpc:grpc-netty-shaded:${version.grpcJava}",
)
override def scalaPBIncludePath: T[Seq[PathRef]] = T {
Seq(scalaPBUnpackProto()) ++ T
.sequence(moduleDeps.collect { case m: ScalaPBModule =>
m.scalaPBIncludePath
})()
.flatten
}
override def scalaPBAdditionalArgs: T[Seq[String]] = T {
Seq(
s"--plugin-artifact=org.typelevel:protoc-gen-fs2-grpc:${version.fs2Grpc}:default,classifier=unix,ext=sh,type=jar",
s"--fs2-grpc_out=${(T.dest / os.up / "compileScalaPB.dest").toIO.getCanonicalPath}",
)
}
}
The T.dest / os.up / "compileScalaPB.dest is a hack, but this way the generated files end up in the correct place and are tracked by mill. The version.grpcJava should also ideally be provided by the scalapb plugin. I'm just glad I got something working for now.
@otto-dev Little improvement over your setup. Using scalaPBSearchDeps to include protos from dependencies and dedicated task with destination folder with generated fs2-grpc files to get rid of T.dest / os.up / "compileScalaPB.dest" hack.
import $ivy.`com.lihaoyi::mill-contrib-scalapblib:`
import mill._
import mill.contrib.scalapblib._
import mill.scalalib._
import mill.scalalib.scalafmt._
// define your versions
object Versions {
val scala = "3.3.3"
val scalaPB = "0.11.17"
val fs2grpc = "2.7.16"
}
object ... extends ScalaPBModule {
def scalaVersion = Versions.scala
def scalaPBVersion = Versions.scalaPB
val fs2GrpcCodegen = s"org.typelevel:protoc-gen-fs2-grpc:${Versions.fs2grpc}"
val fs2Grpc = s"org.typelevel::fs2-grpc-runtime:${Versions.fs2grpc}"
override def scalaPBGrpc = true
override def ivyDeps = T {
// add fs2 grpc runtime to dependencies
super.ivyDeps() ++ Agg(ivy"$fs2Grpc")
}
// creates separate destination for generated fs2 files
def fs2GrpcOut: T[PathRef] = T.persistent {
mill.api.Result.Success(PathRef(T.dest))
}
// extend module's generated sources with fs2 generated files
override def generatedSources = T { super.generatedSources() :+ fs2GrpcOut() }
// (optional) if you need to include .protos from dependencies into scalapbc compiler's path
override def scalaPBSearchDeps = true
// setup scalapbc additional arguments
override def scalaPBAdditionalArgs = T {
Seq(
s"--plugin-artifact=$fs2GrpcCodegen:default,classifier=unix,ext=sh,type=jar",
s"--fs2-grpc_out=${fs2GrpcOut().path.toIO.getCanonicalPath}"
)
}
}