From 758611576a4f6ceb7020e3cee1f70bbd1cc0b4d8 Mon Sep 17 00:00:00 2001 From: Christopher Vogt Date: Wed, 22 Mar 2017 10:11:46 -0400 Subject: ScalaPB plugin --- .gitignore | 1 + examples/scalapb-example/build/build.scala | 8 +++ examples/scalapb-example/build/build/build.scala | 5 ++ .../scalapb-example/protobuf-schemas/address.proto | 6 ++ .../scalapb-example/protobuf-schemas/person.proto | 12 ++++ examples/scalapb-example/src/Main.scala | 14 +++++ plugins/scalapb/ScalaPB.scala | 72 ++++++++++++++++++++++ plugins/scalapb/build/build.scala | 23 +++++++ plugins/scalapb/src_generated/BuildInfo.scala | 5 ++ stage2/BuildBuild.scala | 1 + stage2/Lib.scala | 1 + test/test.scala | 6 ++ 12 files changed, 154 insertions(+) create mode 100644 examples/scalapb-example/build/build.scala create mode 100644 examples/scalapb-example/build/build/build.scala create mode 100644 examples/scalapb-example/protobuf-schemas/address.proto create mode 100644 examples/scalapb-example/protobuf-schemas/person.proto create mode 100644 examples/scalapb-example/src/Main.scala create mode 100644 plugins/scalapb/ScalaPB.scala create mode 100644 plugins/scalapb/build/build.scala create mode 100644 plugins/scalapb/src_generated/BuildInfo.scala diff --git a/.gitignore b/.gitignore index b6ecdc7..979f6df 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ examples/scalajs-plain-example/server/public/generated examples/scalajs-react-example/server/public/generated .cbt-loop.tmp test/simple/src_generated +examples/scalapb-example/src_generated diff --git a/examples/scalapb-example/build/build.scala b/examples/scalapb-example/build/build.scala new file mode 100644 index 0000000..31597d4 --- /dev/null +++ b/examples/scalapb-example/build/build.scala @@ -0,0 +1,8 @@ +import cbt._ + +class Build(val context: Context) extends BaseBuild with Scalapb { + override def compile = taskCache[Build]("compile").memoize{ + scalapb.apply + super.compile + } +} diff --git a/examples/scalapb-example/build/build/build.scala b/examples/scalapb-example/build/build/build.scala new file mode 100644 index 0000000..c461c61 --- /dev/null +++ b/examples/scalapb-example/build/build/build.scala @@ -0,0 +1,5 @@ +import cbt._ + +class Build(val context: Context) extends BuildBuild { + override def dependencies = super.dependencies :+ plugins.scalapb +} diff --git a/examples/scalapb-example/protobuf-schemas/address.proto b/examples/scalapb-example/protobuf-schemas/address.proto new file mode 100644 index 0000000..c588512 --- /dev/null +++ b/examples/scalapb-example/protobuf-schemas/address.proto @@ -0,0 +1,6 @@ +syntax = "proto2"; + +package foo; +message Address { + optional string street = 1; +} diff --git a/examples/scalapb-example/protobuf-schemas/person.proto b/examples/scalapb-example/protobuf-schemas/person.proto new file mode 100644 index 0000000..d829767 --- /dev/null +++ b/examples/scalapb-example/protobuf-schemas/person.proto @@ -0,0 +1,12 @@ +syntax = "proto2"; + +import "address.proto"; + +package foo; +message Person { + optional string name = 1; + optional int32 age = 2; + + // Address is a message defined somewhere else. + repeated Address addresses = 3; +} diff --git a/examples/scalapb-example/src/Main.scala b/examples/scalapb-example/src/Main.scala new file mode 100644 index 0000000..83de69d --- /dev/null +++ b/examples/scalapb-example/src/Main.scala @@ -0,0 +1,14 @@ +import foo._ +object Main extends App { + println( + person.Person( + Some("name"), + Some(123), + Seq( + address.Address( + Some("High Street") + ) + ) + ) + ) +} diff --git a/plugins/scalapb/ScalaPB.scala b/plugins/scalapb/ScalaPB.scala new file mode 100644 index 0000000..e514476 --- /dev/null +++ b/plugins/scalapb/ScalaPB.scala @@ -0,0 +1,72 @@ +package cbt + +import com.trueaccord.scalapb._ +import _root_.protocbridge.ProtocBridge +import _root_.scalapb.ScalaPbCodeGenerator +import java.io.File + +trait Scalapb extends BaseBuild{ + override def dependencies = super.dependencies ++ Resolver( mavenCentral ).bind( + ScalaDependency( + "com.trueaccord.scalapb", "scalapb-runtime", cbt.scalapb.BuildInfo.scalaPBVersion + ) + ) + + def scalapb = Scalapb.apply(lib).config( + input = projectDirectory / "protobuf-schemas", + output = projectDirectory / "src_generated" + ) +} + +sealed trait ProtocVersion +object ProtocVersion{ + case object v310 extends ProtocVersion + case object v300 extends ProtocVersion + case object v261 extends ProtocVersion + case object v250 extends ProtocVersion + case object v241 extends ProtocVersion +} + +object Scalapb{ + case class apply(lib: Lib){ + case class config( + input: File, + output: File, + version: ProtocVersion = ProtocVersion.v310, + flatPackage: Boolean = false, + javaConversions: Boolean = false, + grpc: Boolean = true, + singleLineToString: Boolean = false + ){ + def apply = { + output.mkdirs + val protoFiles = input.listRecursive.filter(_.isFile).map(_.string).toArray + Seq( + javaConversions.option("javaConversions"), + grpc.option("grpc"), + singleLineToString.option("singleLineToString"), + flatPackage.option("flatPackage") + ).flatten.mkString(",") + import _root_.protocbridge.frontend.PluginFrontend + val pluginFrontend: PluginFrontend = PluginFrontend.newInstance() + val (scriptPath, state) = pluginFrontend.prepare( ScalaPbCodeGenerator ) + try { + lib.redirectOutToErr( + ExitCode( + com.github.os72.protocjar.Protoc.runProtoc( + Array( + "-" ++ version.getClass.getSimpleName.stripSuffix("$"), + "-I=" ++ input.string, + "--scala_out=" ++ output.string, + s"--plugin=protoc-gen-scala=${scriptPath}" + ) ++ protoFiles + ) + ) + ) + } finally { + pluginFrontend.cleanup(state) + } + } + } + } +} diff --git a/plugins/scalapb/build/build.scala b/plugins/scalapb/build/build.scala new file mode 100644 index 0000000..cadee1b --- /dev/null +++ b/plugins/scalapb/build/build.scala @@ -0,0 +1,23 @@ +import cbt._ + +class Build(val context: Context) extends Plugin { + private val scalaPBVersion = "0.5.47" + + override def dependencies = + super.dependencies ++ + Resolver( mavenCentral ).bind( + ScalaDependency( "com.trueaccord.scalapb", "scalapbc", scalaPBVersion ) + ) + + override def compile = { buildInfo; super.compile } + + def buildInfo = lib.writeIfChanged( + projectDirectory / "src_generated/BuildInfo.scala", + s"""// generated file +package cbt.scalapb +object BuildInfo{ + def scalaPBVersion = "$scalaPBVersion" +} +""" + ) +} diff --git a/plugins/scalapb/src_generated/BuildInfo.scala b/plugins/scalapb/src_generated/BuildInfo.scala new file mode 100644 index 0000000..8498d10 --- /dev/null +++ b/plugins/scalapb/src_generated/BuildInfo.scala @@ -0,0 +1,5 @@ +// generated file +package cbt.scalapb +object BuildInfo{ + def scalaPBVersion = "0.5.47" +} diff --git a/stage2/BuildBuild.scala b/stage2/BuildBuild.scala index 71a229c..17ccb36 100644 --- a/stage2/BuildBuild.scala +++ b/stage2/BuildBuild.scala @@ -11,6 +11,7 @@ class plugins(implicit context: Context){ final lazy val sbtLayout = plugin( "sbt_layout" ) final lazy val scalafmt = plugin( "scalafmt" ) final lazy val scalaJs = plugin( "scalajs" ) + final lazy val scalapb = plugin( "scalapb" ) final lazy val scalariform = plugin( "scalariform" ) final lazy val scalaTest = plugin( "scalatest" ) final lazy val sonatypeRelease = plugin( "sonatype-release" ) diff --git a/stage2/Lib.scala b/stage2/Lib.scala index 4fdcf2d..fd3346e 100644 --- a/stage2/Lib.scala +++ b/stage2/Lib.scala @@ -131,6 +131,7 @@ final class Lib(val logger: Logger) extends Stage1Lib(logger){ //case e: ExitCode => System.err.println(e.integer); System.exit(e.integer); ??? case s: Seq[_] => s.map(render).mkString("\n") case s: Set[_] => s.map(render).toSeq.sorted.mkString("\n") + case null => "null" case _ => obj.toString } } diff --git a/test/test.scala b/test/test.scala index 6004311..61e98df 100644 --- a/test/test.scala +++ b/test/test.scala @@ -268,6 +268,12 @@ object Main{ assert(res.out contains "version: 0.1", res.out) } + { + val res = runCbt("../examples/scalapb-example", Seq("run")) + assert(res.exit0) + assert(res.out contains "age: 123", res.out ++ "\n--\n" ++ res.err) + } + { val res = runCbt("broken-build/build-class-with-wrong-arguments", Seq("run")) assert(!res.exit0) -- cgit v1.2.3 From 01855e0ed4eae2b1ab11b854176da940347f6131 Mon Sep 17 00:00:00 2001 From: Christopher Vogt Date: Mon, 20 Mar 2017 22:59:11 -0400 Subject: clean scalafix test before running, so it sure runs --- test/test.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test.scala b/test/test.scala index 61e98df..7447a5c 100644 --- a/test/test.scala +++ b/test/test.scala @@ -393,6 +393,7 @@ object Main{ { val sourceFile = cbtHome / "examples" / "scalafix-example" / "Main.scala" val sourceBefore = sourceFile.readAsString + runCbt("../examples/scalafix-example", Seq("clean","force")) val res = runCbt("../examples/scalafix-example", Seq("compile")) assert(res.exit0) val sourceAfter = sourceFile.readAsString -- cgit v1.2.3