Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,13 @@ import protocbridge.Artifact
import protocgen.{ CodeGenApp, CodeGenRequest, CodeGenResponse }

object AkkaserverlessTestGenerator extends CodeGenApp {
val enableDebug = "enableDebug"

override def registerExtensions(registry: ExtensionRegistry): Unit = {
registry.add(com.akkaserverless.Annotations.service)
registry.add(com.akkaserverless.Annotations.file)
}

override def process(request: CodeGenRequest): CodeGenResponse = {
val debugEnabled = request.parameter.contains(enableDebug)
val debugEnabled = request.parameter.contains(AkkaserverlessGenerator.enableDebug)
val model = ModelBuilder.introspectProtobufClasses(request.filesToGenerate)(DebugPrintlnLog(debugEnabled))
try {
CodeGenResponse.succeed(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2021 Lightbend Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.akkaserverless.codegen.scalasdk

import com.google.protobuf.ExtensionRegistry
import com.google.protobuf.compiler.PluginProtos.CodeGeneratorResponse
import com.lightbend.akkasls.codegen.ModelBuilder
import protocbridge.Artifact
import protocgen.{ CodeGenApp, CodeGenRequest, CodeGenResponse }

object AkkaserverlessUnmanagedGenerator extends CodeGenApp {
override def registerExtensions(registry: ExtensionRegistry): Unit = {
registry.add(com.akkaserverless.Annotations.service)
registry.add(com.akkaserverless.Annotations.file)
}

override def process(request: CodeGenRequest): CodeGenResponse = {
val debugEnabled = request.parameter.contains(AkkaserverlessGenerator.enableDebug)
val model = ModelBuilder.introspectProtobufClasses(request.filesToGenerate)(DebugPrintlnLog(debugEnabled))
try {
CodeGenResponse.succeed(
SourceGenerator
.generateUnmanaged(model)
.map(file =>
CodeGeneratorResponse.File
.newBuilder()
.setName(file.name)
.setContent(file.content)
.build()))
} catch {
case t: Throwable =>
t.printStackTrace()
CodeGenResponse.fail(t.getMessage)
}
}

override def suggestedDependencies: Seq[Artifact] = Nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,18 @@ object SourceGenerator {
* Generate the 'managed' code for this model: code that will be regenerated regularly in the 'compile' configuratio
*/
def generateManaged(model: ModelBuilder.Model): Seq[File] =
Seq(File("foo/bar/Baz.scala", "package foo.bar\n\ntrait Baz"))
Seq(File("foo/bar/AbstractBaz.scala", "package foo.bar\n\nabstract class AbstractBaz"))

/**
* Generate the 'managed' code for this model: code that will be regenerated regularly in the 'compile' configuratio
*/
def generateManagedTest(model: ModelBuilder.Model): Seq[File] =
Seq(File("foo/bar/BazSpec.scala", "package foo.bar\n\ntrait BazSpec"))
Seq(File("foo/bar/BazSpec.scala", "package foo.bar\n\nclass BazSpec { new Baz() }"))

/**
* Generate the 'unmanaged' code for this model: code that is generated once on demand and then maintained by the
* user.
*/
def generateUnmanaged(model: ModelBuilder.Model): Seq[File] =
Seq.empty
Seq(File("foo/bar/Baz.scala", "package foo.bar\n\nclass Baz extends AbstractBaz"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2021 Lightbend Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.akkaserverless.codegen.scalasdk

import protocbridge.SandboxedJvmGenerator

object genUnmanaged {
def apply(options: Seq[String] = Seq.empty): (SandboxedJvmGenerator, Seq[String]) =
gen(options, "com.akkaserverless.codegen.scalasdk.AkkaserverlessUnmanagedGenerator$")
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@

package com.akkaserverless.sbt

import com.akkaserverless.codegen.scalasdk.{ gen, genTests, AkkaserverlessGenerator }
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.Files

import com.akkaserverless.codegen.scalasdk.{ gen, genTests, genUnmanaged, AkkaserverlessGenerator, SourceGenerator }
import sbt.{ Compile, _ }
import sbt.Keys._
import sbtprotoc.ProtocPlugin
Expand All @@ -27,14 +31,52 @@ object AkkaserverlessPlugin extends AutoPlugin {
override def trigger = allRequirements
override def requires = ProtocPlugin

trait Keys { _: autoImport.type =>
val generateUnmanaged = taskKey[Unit](
"Generate \"unmanaged\" akkaserverless scaffolding code based on the available .proto definitions.\n" +
"These are the source files that are placed in the source tree, and after initial generation should typically be maintained by the user.\n" +
"Files that already exist they are not re-generated.")
val temporaryUnmanagedDirectory = settingKey[File]("Directory to generate 'unmanaged' sources into")
}
object autoImport extends Keys
import autoImport._

override def projectSettings: Seq[sbt.Setting[_]] = Seq(
libraryDependencies ++= Seq(
"com.akkaserverless" % "akkaserverless-sdk-protocol" % "0.7.0-beta.18" % "protobuf",
"com.google.protobuf" % "protobuf-java" % "3.17.3" % "protobuf"),
Compile / PB.targets +=
gen(Seq(AkkaserverlessGenerator.enableDebug)) -> (Compile / sourceManaged).value / "akkaserverless",
Compile / temporaryUnmanagedDirectory := (Compile / baseDirectory).value / "target" / "akkaserverless-unmanaged",
Compile / PB.targets +=
genUnmanaged(Seq(AkkaserverlessGenerator.enableDebug)) -> (Compile / temporaryUnmanagedDirectory).value,
Test / PB.protoSources ++= (Compile / PB.protoSources).value,
Test / PB.targets +=
genTests(Seq(AkkaserverlessGenerator.enableDebug)) -> (Test / sourceManaged).value / "akkaserverless")
genTests(Seq(AkkaserverlessGenerator.enableDebug)) -> (Test / sourceManaged).value / "akkaserverless",
Compile / generateUnmanaged := {
// Make sure generation has happened
(Compile / PB.generate).value
// Then copy over any new generated unmanaged sources
copyIfNotExist(
java.nio.file.Paths.get((Compile / temporaryUnmanagedDirectory).value.toURI),
Paths.get((Compile / sourceDirectory).value.toURI).resolve("scala"))
},
Compile / managedSources :=
(Compile / managedSources).value.filter(s => !isIn(s, (Compile / temporaryUnmanagedDirectory).value)))

def isIn(file: File, dir: File): Boolean =
Paths.get(file.toURI).startsWith(Paths.get(dir.toURI))

private def copyIfNotExist(from: Path, to: Path): Unit = {
java.nio.file.Files
.walk(from)
.filter(Files.isRegularFile(_))
.forEach(file => {
val target = to.resolve(from.relativize(file))
if (!Files.exists(target)) {
Files.createDirectories(target.getParent)
Files.copy(file, target)
}
})
}
}
9 changes: 9 additions & 0 deletions sbt-plugin/src/sbt-test/sbt-akkaserverless/basic/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import com.akkaserverless.sbt.AkkaserverlessPlugin.autoImport.generateUnmanaged

Compile / compile := {
// Make sure 'generateUnmanaged' is executed on each compile, to generate scaffolding code for
// newly-introduced concepts.
// After initial generation they are to be maintained manually and will not be overwritten.
(Compile / generateUnmanaged).value
(Compile / compile).value
}
3 changes: 2 additions & 1 deletion sbt-plugin/src/sbt-test/sbt-akkaserverless/basic/test
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
> compile
$ exists target/scala-2.12/src_managed/main/akkaserverless/foo/bar/Baz.scala
$ exists src/main/scala/foo/bar/Baz.scala
$ exists target/scala-2.12/src_managed/main/akkaserverless/foo/bar/AbstractBaz.scala
> Test/compile
$ exists target/scala-2.12/src_managed/test/akkaserverless/foo/bar/BazSpec.scala
$ absent target/scala-2.12/src_managed/test/akkaserverless/foo/bar/Baz.scala