stevedlawrence commented on a change in pull request #681:
URL: https://github.com/apache/daffodil/pull/681#discussion_r755460200
##########
File path: build.sbt
##########
@@ -343,14 +343,38 @@ lazy val unidocSettings = Seq(
lazy val genExamplesSettings = Seq(
Compile / genExamples := {
- val cp = (runtime2 / Runtime / dependencyClasspath).value
- val forkOpts = ForkOptions().withBootJars(cp.files.toVector)
- val mainClass = "org.apache.daffodil.runtime2.CodeGenerator"
- val args = Seq(mainClass)
- val ret = Fork.java(forkOpts, args)
- val stream = streams.value
- if (ret != 0) {
- stream.log.error(s"Failed to generate examples")
+ val cp = (runtime2 / Test / dependencyClasspath).value
+ val inSrc = (runtime2 / Compile / sources).value
+ val inRSrc = (runtime2 / Compile / resources).value
+ val inTSrc = (runtime2 / Test / resources).value
+ val stream = (runtime2 / streams).value
+ val filesToWatch = (inSrc ++ inRSrc ++ inTSrc).toSet
+ val cachedFun = FileFunction.cached(stream.cacheDirectory / "genExamples")
{ _ =>
+ val out = new java.io.ByteArrayOutputStream()
+ val forkOpts = ForkOptions()
+ .withOutputStrategy(Some(CustomOutput(out)))
+ .withBootJars(cp.files.toVector)
+ val mainClass = "org.apache.daffodil.runtime2.CodeGenerator"
+ val args = Seq(mainClass)
+ val ret = Fork.java(forkOpts, args)
+ if (ret != 0) {
+ stream.log.error(s"failed to generate example files")
+ }
+ val bis = new java.io.ByteArrayInputStream(out.toByteArray)
+ val isr = new java.io.InputStreamReader(bis)
+ val br = new java.io.BufferedReader(isr)
+ val iterator = Iterator.continually(br.readLine()).takeWhile(_ !=
null).filterNot(_.startsWith("WARN"))
+ val files = iterator.map { f =>
+ new File(f)
+ }.toSet
+ stream.log.info(s"generated ${files.size} runtime2 example files")
Review comment:
For consistency with Scala logging and potentially easy debugging, can
we include an output directory here? Doesn't have to be the exact directory,
but at least something so a user knows vaguely where the files are being
generated, something like:
```scala
val outDir = (runtime2 / Test / resourceDirectory).value
stream.log.info(s"generated ${files.size} runtime2 example files to
${outDir} ...")
```
Might also be nice if outDir could be passed in as a parameter to the
`CodeGenerator` so the code generator doesn't need to hard code where to write
things to. This is what the prop gen does
##########
File path: .github/workflows/main.yml
##########
@@ -149,6 +149,9 @@ jobs:
- name: Run Integration Tests
run: $SBT coverage IntegrationTest/test
+ - name: Run Modified Example Files Check
+ run: git diff --color --exit-code
Review comment:
Do we want to be more specific about what directory we're checking? I'm
concerned that there might be some cruft leftover from some build process that
might cause this check to fail.
##########
File path:
daffodil-runtime2/src/main/scala/org/apache/daffodil/runtime2/CodeGenerator.scala
##########
@@ -198,3 +200,60 @@ class CodeGenerator(root: Root) extends DFDL.CodeGenerator
{
override def getDiagnostics: Seq[Diagnostic] = diagnostics
override def isError: Boolean = errorStatus
}
+
+/** Runs from "sbt compile" to keep all example generated code files up to
date */
+object CodeGenerator {
+ // Update one set of example generated code files from an example schema
+ private def updateGeneratedCodeExample(schemaFile: os.Path, rootName:
Option[String],
+ exampleCodeHeader: os.Path,
exampleCodeFile: os.Path): Unit = {
+ // Generate code from the example schema file
+ val pf = Compiler().compileFile(schemaFile.toIO, rootName)
+ assert(!pf.isError, pf.getDiagnostics.map(_.getMessage()).mkString("\n"))
+ val cg = pf.forLanguage("c")
+ val rootNS =
QName.refQNameFromExtendedSyntax(rootName.getOrElse("")).toOption
+ val tempDir = os.temp.dir(dir = null, prefix = "daffodil-runtime2-")
+ val codeDir = cg.generateCode(rootNS, tempDir.toString)
+ assert(!cg.isError, cg.getDiagnostics.map(_.getMessage()).mkString("\n"))
+
+ // Replace the example generated files with the newly generated files
+ val generatedCodeHeader = codeDir/"libruntime"/"generated_code.h"
+ val generatedCodeFile = codeDir/"libruntime"/"generated_code.c"
+ os.copy(generatedCodeHeader, exampleCodeHeader, replaceExisting = true,
createFolders = true)
+ os.copy(generatedCodeFile, exampleCodeFile, replaceExisting = true,
createFolders = true)
+
+ // Print the example generated files' names so "sbt 'show genExamples'"
can list them
+ System.out.println(exampleCodeHeader)
+ System.out.println(exampleCodeFile)
+
+ // tempDir should be removed automatically after main exits; this is just
in case
+ os.remove.all(tempDir)
+ }
+
+ // Make sure "sbt compile" calls this main method
+ def main(args: Array[String]): Unit = {
Review comment:
I'm not sure this is a big deal, but if anyone ever runts this jar using
java -jar it's probably going to fail, since it can only be run in the daffodil
root dir. Like, one might expect this to be an alternative to using the CLI,
but it's really a test only thing. Maybe it should go in src/test/scala so it's
not distributed? Or maybe it doesn't really matter.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]