diff options
author | Christopher Vogt <oss.nsp@cvogt.org> | 2017-03-22 10:11:46 -0400 |
---|---|---|
committer | Christopher Vogt <oss.nsp@cvogt.org> | 2017-03-24 11:32:09 -0400 |
commit | 758611576a4f6ceb7020e3cee1f70bbd1cc0b4d8 (patch) | |
tree | 63befde48bed261a1fbed42543206711818858a3 | |
parent | 3d321f42c19d2166204079ba7eece66b36037042 (diff) | |
download | cbt-758611576a4f6ceb7020e3cee1f70bbd1cc0b4d8.tar.gz cbt-758611576a4f6ceb7020e3cee1f70bbd1cc0b4d8.tar.bz2 cbt-758611576a4f6ceb7020e3cee1f70bbd1cc0b4d8.zip |
ScalaPB plugin
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | examples/scalapb-example/build/build.scala | 8 | ||||
-rw-r--r-- | examples/scalapb-example/build/build/build.scala | 5 | ||||
-rw-r--r-- | examples/scalapb-example/protobuf-schemas/address.proto | 6 | ||||
-rw-r--r-- | examples/scalapb-example/protobuf-schemas/person.proto | 12 | ||||
-rw-r--r-- | examples/scalapb-example/src/Main.scala | 14 | ||||
-rw-r--r-- | plugins/scalapb/ScalaPB.scala | 72 | ||||
-rw-r--r-- | plugins/scalapb/build/build.scala | 23 | ||||
-rw-r--r-- | plugins/scalapb/src_generated/BuildInfo.scala | 5 | ||||
-rw-r--r-- | stage2/BuildBuild.scala | 1 | ||||
-rw-r--r-- | stage2/Lib.scala | 1 | ||||
-rw-r--r-- | test/test.scala | 6 |
12 files changed, 154 insertions, 0 deletions
@@ -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 @@ -269,6 +269,12 @@ object Main{ } { + 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) assert(res.err contains s"Expected class ${lib.buildClassName}(val context: Context), but found different constructor", res.err) |