Skip to content

Commit

Permalink
Add a method to run protoc with parameters given in a file.
Browse files Browse the repository at this point in the history
  • Loading branch information
thesamet committed May 9, 2024
1 parent 497f24e commit 20c99d1
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
28 changes: 28 additions & 0 deletions bridge/src/main/scala/protocbridge/ProtocRunner.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package protocbridge

import java.nio.file.Files
import scala.io.Source
import scala.sys.process.Process
import scala.sys.process.ProcessLogger
Expand Down Expand Up @@ -74,4 +75,31 @@ object ProtocRunner {
extraEnv: _*
).!
}

// Transforms the given protoc runner to a new runner that writes the
// options into a temporary file and passes the file to `protoc` as an `@`
// parameter.
def withParametersAsFile[T](underlying: ProtocRunner[T]): ProtocRunner[T] =
fromFunction { (args, extraEnv) =>
{
val argumentFile = Files.createTempFile("protoc-args-", ".txt")
try {
val writer = Files.newBufferedWriter(argumentFile)

try {
args.foreach { arg =>
writer.write(arg)
writer.write('\n')
}
} finally {
writer.close()
}

val fileArgument = s"@${argumentFile.toString}"
underlying.run(Seq(fileArgument), extraEnv)
} finally {
Files.delete(argumentFile)
}
}
}
}
12 changes: 10 additions & 2 deletions bridge/src/test/scala/protocbridge/ProtocIntegrationSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ object TestUtils {
}

class ProtocIntegrationSpec extends AnyFlatSpec with Matchers {
"ProtocBridge.run" should "invoke JVM and Java plugin properly" in {
def invokeProtocProperly(runner: ProtocRunner[Int]) = {
val protoFile =
new File(getClass.getResource("/test.proto").getFile).getAbsolutePath
val protoDir = new File(getClass.getResource("/").getFile).getAbsolutePath
Expand All @@ -77,7 +77,7 @@ class ProtocIntegrationSpec extends AnyFlatSpec with Matchers {
(0 to 4).map(i => Files.createTempDirectory(s"testout$i").toFile())

ProtocBridge.execute(
RunProtoc,
runner,
Seq(
protocbridge.gens.java("3.8.0") -> javaOutDir,
TestJvmPlugin -> testOutDirs(0),
Expand Down Expand Up @@ -111,6 +111,14 @@ class ProtocIntegrationSpec extends AnyFlatSpec with Matchers {
readLines(new File(testOutDirs(0), "parameters.txt")) must be(Seq("Empty"))
}

"ProtocBridge.run" should "invoke JVM and Java plugin properly" in {
invokeProtocProperly(RunProtoc)
}

"ProtocBridge.run" should "invoke JVM and Java plugin properly with options file" in {
invokeProtocProperly(ProtocRunner.withParametersAsFile(RunProtoc))
}

it should "not deadlock for highly concurrent invocations" in {
val availableProcessors = Runtime.getRuntime.availableProcessors
assert(
Expand Down

0 comments on commit 20c99d1

Please sign in to comment.