This is an automated email from the ASF dual-hosted git repository.
slawrence pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-sbt.git
The following commit(s) were added to refs/heads/main by this push:
new a482c69 Use a resource generator to create saved parsers for
daffodilTdmlUsesPackageBin
a482c69 is described below
commit a482c6916b86139eeacf05ec65c67a42e954b505
Author: Steve Lawrence <[email protected]>
AuthorDate: Fri May 17 11:33:07 2024 -0400
Use a resource generator to create saved parsers for
daffodilTdmlUsesPackageBin
A resource generator is probably the "more correct" way to make saved
parsers available to tests, since we are really just generating a
resource to be made available on the classpath. This also allows SBT to
manage the classpath how it expects, instead of us tacking on our file
the dependencyClasspath. However, we don't want this generated saved
parser resource to be included in -test jars, so we also exclude it from
the `Test/packageBin` mapping.
This has the added benefit that IntelliJ knows about generated resources
so this solves the issue of tests run from IntelliJ not being able to
find the parsers. The one drawback is IntelliJ doesn't know how to
actually run the resource generator, so you need to either manually run
it with `sbt Test/compile` or enable "use sbt shell for builds".
Closes #29
---
README.md | 5 +++
.../scala/org/apache/daffodil/DaffodilPlugin.scala | 49 ++++++++++++++++------
.../sbt-daffodil/tdml-saved-parser-01/test.script | 6 +--
3 files changed, 44 insertions(+), 16 deletions(-)
diff --git a/README.md b/README.md
index 985824b..f95559b 100644
--- a/README.md
+++ b/README.md
@@ -128,6 +128,11 @@ Note that only saved parsers for `daffodilVersion` can be
referenced. For this
reason, `daffodilVersion` must also be defined in `daffodilPackageBinVersions`
if `daffodilTdmlUsesPackageBin` is `true`.
+This is implemented using a SBT resource generator which some IDE's, like
+IntelliJ, do not trigger during builds. So you must either run `sbt
Test/compile`
+to manually trigger the resource generator, or let SBT handle builds by
+enabling the "Use SBT shell for builds" option.
+
### Layers and User Defined Functions
If your schema project builds a Daffodil layer or user defined function, then
diff --git a/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
b/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
index 7d072fb..b59e5f9 100644
--- a/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
+++ b/src/main/scala/org/apache/daffodil/DaffodilPlugin.scala
@@ -309,7 +309,14 @@ object DaffodilPlugin extends AutoPlugin {
}
updatedPackagedArtifacts
},
- Test / dependencyClasspath ++= {
+
+ /**
+ * If daffodilTdmlUsesPackageBin is true, we create a resource generator to
build the saved
+ * parsers and add them as a resource for the TDML files to find and use.
Note that we use a
+ * resourceGenerator since other methods make it difficult to convince
IntelliJ to put the
+ * files on the test classpath. See below Test/packageBin/mappings for
related changes.
+ */
+ Test / resourceGenerators += Def.taskIf {
if (daffodilTdmlUsesPackageBin.value) {
if (!daffodilPackageBinVersions.value.contains(daffodilVersion.value))
{
@@ -318,28 +325,44 @@ object DaffodilPlugin extends AutoPlugin {
)
}
- // force creation of saved parsers
+ // force creation of saved parsers, there isn't currently a way to
build them for just
+ // daffodilVersion
val allSavedParsers = packageDaffodilBin.value
- // create a directory that we will put on the classpath, deleting it
and all contents
- // if it already exists
- val parserClasspathDir = target.value / "tdmlparsers"
- IO.delete(parserClasspathDir)
- IO.createDirectory(parserClasspathDir)
-
- // copy the saved parsers for daffodilVersion into our classpath
directory
- daffodilPackageBinInfos.value.foreach { case (_, _, optName) =>
+ // copy the saved parsers for the current daffodilVersion to the root
of the
+ // resourceManaged directory, and consider those our generated
resources
+ val destDir = (Test / resourceManaged).value
+ val tdmlParserFiles = daffodilPackageBinInfos.value.map { case (_, _,
optName) =>
val sourceClassifier = classifierName(optName, daffodilVersion.value)
val source = target.value /
s"${name.value}-${version.value}-${sourceClassifier}.bin"
val destClassifier = optName.map { "-" + _ }.getOrElse("")
- val dest = parserClasspathDir / s"${name.value}${destClassifier}.bin"
+ val dest = destDir / s"${name.value}${destClassifier}.bin"
IO.copyFile(source, dest)
+ dest
}
-
- Seq(parserClasspathDir)
+ tdmlParserFiles
} else {
Seq()
}
+ }.taskValue,
+
+ /**
+ * The above resource generator creates saved parsers as test resources so
that tests can
+ * find them on the classpath. But this means the parsers will also be
packaged in test
+ * jars. Saved parsers are already published as artifacts, so there's no
reason to also
+ * include them in jars--remove them from the mapping that says which
files to put in jars.
+ */
+ Test / packageBin / mappings := {
+ val existingMappings = (Test / packageBin / mappings).value
+ if (daffodilTdmlUsesPackageBin.value) {
+ val tdmlParserNames = daffodilPackageBinInfos.value.map { case (_, _,
optName) =>
+ val destClassifier = optName.map { "-" + _ }.getOrElse("")
+ s"${name.value}${destClassifier}.bin"
+ }
+ existingMappings.filterNot { case (_, name) =>
tdmlParserNames.contains(name) }
+ } else {
+ existingMappings
+ }
},
) ++
inConfig(Compile)(flatLayoutSettings("src")) ++
diff --git a/src/sbt-test/sbt-daffodil/tdml-saved-parser-01/test.script
b/src/sbt-test/sbt-daffodil/tdml-saved-parser-01/test.script
index 4775990..2c8d72e 100644
--- a/src/sbt-test/sbt-daffodil/tdml-saved-parser-01/test.script
+++ b/src/sbt-test/sbt-daffodil/tdml-saved-parser-01/test.script
@@ -22,8 +22,8 @@ $ exists target/test-0.1-daffodil360.bin
$ exists target/test-0.1-two-daffodil350.bin
$ exists target/test-0.1-two-daffodil360.bin
-> Test/dependencyClasspath
-$ must-mirror target/tdmlparsers/test.bin target/test-0.1-daffodil360.bin
-$ must-mirror target/tdmlparsers/test-two.bin
target/test-0.1-two-daffodil360.bin
+> Test/compile
+$ must-mirror target/test-classes/test.bin target/test-0.1-daffodil360.bin
+$ must-mirror target/test-classes/test-two.bin
target/test-0.1-two-daffodil360.bin
> test