Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Running as standalone or with mill #714

Open
otto-dev opened this issue Mar 9, 2024 · 3 comments
Open

Running as standalone or with mill #714

otto-dev opened this issue Mar 9, 2024 · 3 comments

Comments

@otto-dev
Copy link

otto-dev commented Mar 9, 2024

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?

@otto-dev
Copy link
Author

otto-dev commented Mar 9, 2024

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

@otto-dev
Copy link
Author

otto-dev commented Mar 9, 2024

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.

@mkrajc
Copy link

mkrajc commented Jul 12, 2024

@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}"
    )
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants