This is an automated email from the ASF dual-hosted git repository.
shanedell pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil-vscode.git
The following commit(s) were added to refs/heads/main by this push:
new 4d4ac7f Add support for multiple versions of the debugger
4d4ac7f is described below
commit 4d4ac7f39ed3fba02c040c0ee2f8a7054531db4b
Author: Shane Dell <[email protected]>
AuthorDate: Mon Oct 6 13:05:10 2025 -0400
Add support for multiple versions of the debugger
- Support 3 versions of the debugger.
- Scala 2.12 + Daffodil <=3.10.0.
- Scala 2.13 + Daffodil =3.11.0.
- Scala 3 + Daffodil >=4.0.0.
- When running locally, if JDK >= 17 all the debuggers are built but if JDK
< 17 only the Scala 2 debuggers are built.
- Fixed .vscode/launch.json so that the debugging of the tests can be done
now.
- Update CI jobs that defaulted to Java 8 only to default to Java 17 only.
- Add Java 21 to CI some CI jobs for testing multiple versions of Java.
- Update vite config to be able to extract all 3 versions of the debugger.
- Add launch config for daffodilVersion and debugger timeout.
- Values for daffodilVersion should be a proper Daffodil release version
- Timeout is any number but needs to end with s(seconds), m(minutes) or
h(hours).
- If no s, m, h set then s is appended to the end.
- Add more tests for testing that all 3 debuggers can output an XML and
JSON infoset file.
- Cleaned up yarn test output so it looks much cleaner.
- Update daffodil-debugger scripts to not be built to target a single
Daffodil version.
- The extension will download and extract the proper Daffodil release
based on the version set in the launch.json.
- Added a required flag `--daffodilPath` for the daffodil-debugger scripts.
- The extension will build the daffodil based on the version being used
and pass it the script using this flag
- If the user wants to run the debugger on their own, they will need to
provide this flag. This will allow users to test unreleased version of Daffodil.
Closes #1352
---
.github/workflows/CI.yml | 4 +-
.github/workflows/licenses.yml | 2 +-
.github/workflows/nightly.yml | 2 +-
.github/workflows/release-candidate.yml | 2 +-
.vscode/launch.json | 2 +-
.vscode/tasks.json | 2 +-
build.sbt | 169 ++++++++-----
.../org.apache.daffodil.debugger.dap/Convert.scala | 12 +-
.../org.apache.daffodil.debugger.dap/Convert.scala | 12 +-
.../org.apache.daffodil.debugger.dap/DAP.scala | 15 +-
.../org.apache.daffodil.debugger.dap/Support.scala | 71 ++++++
.../org.apache.daffodil.debugger.dap/Convert.scala | 12 +-
.../org.apache.daffodil.debugger.dap/DAP.scala | 15 +-
.../org.apache.daffodil.debugger.dap/Support.scala | 63 +++++
.../Compiler.scala | 14 +-
.../org.apache.daffodil.debugger.dap/DAPodil.scala | 19 +-
.../org.apache.daffodil.debugger.dap/Parse.scala | 49 ++--
.../org.apache.daffodil.debugger.dap/Utils.scala | 2 +-
.../main/scala/org.apache.daffodil.tdml/TDML.scala | 18 +-
debugger/src/templates/bash-template | 17 +-
debugger/src/templates/bat-template | 22 +-
.../org.apache.daffodil.debugger/ParseSuite.scala | 8 +-
package.json | 27 ++-
project/plugins.sbt | 1 +
src/adapter/activateDaffodilDebug.ts | 21 +-
src/adapter/daffodilDebugErrors.ts | 3 +-
src/adapter/daffodilEvent.ts | 4 +-
src/classes/dfdlDebugger.ts | 2 +
src/daffodilDebugger/daffodil.ts | 6 -
src/daffodilDebugger/daffodilJars.ts | 65 +++++
src/daffodilDebugger/debugger.ts | 8 +-
src/daffodilDebugger/utils.ts | 126 +++++++---
src/launchWizard/launchWizard.ts | 8 +-
src/launchWizard/script.js | 16 ++
src/tests/suite/daffodil.test.ts | 143 +++++------
src/tests/suite/daffodilDebugger.test.ts | 264 ++++++++++++++-------
src/tests/suite/utils.test.ts | 2 +
src/utils.ts | 134 ++++++++++-
vite/dev.vite.config.mjs | 53 +++--
vite/package.vite.config.mjs | 86 ++++---
40 files changed, 1058 insertions(+), 443 deletions(-)
diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index adaeecb..77b12cc 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -61,7 +61,7 @@ jobs:
strategy:
matrix:
java_distribution: [temurin]
- java_version: [8]
+ java_version: [17]
os: [ubuntu-22.04]
node: ["20"]
runs-on: ${{ matrix.os }}
@@ -169,7 +169,7 @@ jobs:
strategy:
matrix:
java_distribution: [temurin]
- java_version: [8, 11, 17]
+ java_version: [8, 11, 17, 21]
os: [macos-13, ubuntu-22.04, windows-2022]
node: ["20.19.4", "22.14.0"]
vscode: ["1.90.0", "stable"] # v1.90.0 is the first version of VSCode
to use Node 20
diff --git a/.github/workflows/licenses.yml b/.github/workflows/licenses.yml
index 3a18c46..3af3751 100644
--- a/.github/workflows/licenses.yml
+++ b/.github/workflows/licenses.yml
@@ -29,7 +29,7 @@ jobs:
strategy:
matrix:
java_distribution: [temurin]
- java_version: [8]
+ java_version: [17]
os: [ubuntu-22.04]
runs-on: ${{ matrix.os }}
defaults:
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 29a5c76..86b5999 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -38,7 +38,7 @@ jobs:
node: ["20.18.3", "22.14.0"]
vscode: ["1.90.0", "stable", "insiders"] # v1.90.0 is the first
version of VSCode to use Node 18
java_distribution: [temurin]
- java_version: [8, 11, 17]
+ java_version: [8, 11, 17, 21]
exclude:
# java 8 not available on latest macos
- os: macos-latest
diff --git a/.github/workflows/release-candidate.yml
b/.github/workflows/release-candidate.yml
index 8293c9a..2fbc1c9 100644
--- a/.github/workflows/release-candidate.yml
+++ b/.github/workflows/release-candidate.yml
@@ -56,7 +56,7 @@ jobs:
uses: actions/setup-java@a7ab372554b6eb1a8eb25e7d9aec1cc9f3ea1a76 #
v4.6.0
with:
distribution: temurin
- java-version: 8
+ java-version: 17
- name: Install Node.js
uses: actions/setup-node@5e2628c959b9ade56971c0afcebbe5332d44b398 #
v4.4.0
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 99b6d5a..ad0927c 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -38,7 +38,7 @@
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
-
"--extensionTestsPath=${workspaceFolder}/out/tests/suite"
+
"--extensionTestsPath=${workspaceFolder}/out/tests/suite/index"
],
"outFiles": [
"${workspaceFolder}/out/tests/**/*.js",
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index fcbdcee..029b701 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -32,7 +32,7 @@
"type": "npm",
"script": "watch",
"group": "build",
- "isBackground": true,
+ "isBackground": true
}
]
}
diff --git a/build.sbt b/build.sbt
index 06dc63e..67d4420 100644
--- a/build.sbt
+++ b/build.sbt
@@ -27,23 +27,10 @@ import javax.xml.transform.stream.StreamSource
//Fixes build issues on java11+
run / fork := true
Global / lintUnusedKeysOnLoad := false
-val packageJsonStr = scala.io.Source.fromFile("package.json").mkString
-
-val daffodilVer = {
- val daffodilVerRegex = raw""""daffodilVersion": "(.*)",""".r
- daffodilVerRegex.findFirstMatchIn(packageJsonStr) match {
- case Some(m) => m.toString.split(":")(1).trim.replaceAll("\"",
"").replaceAll(",", "")
- case None => sys.error("Missing daffodilVersion specifier in
package.json")
- }
-}
lazy val commonSettings =
Seq(
version := IO.read((ThisBuild / baseDirectory).value / "VERSION").trim,
- libraryDependencies ++= Seq(
- "org.apache.daffodil" %% "daffodil-sapi" % daffodilVer,
- "org.apache.daffodil" %% "daffodil-runtime1" % daffodilVer
- ),
dependencyOverrides ++= Seq(
"org.apache.commons" % "commons-lang3" % "3.18.0"
),
@@ -51,9 +38,6 @@ lazy val commonSettings =
licenses += ("Apache-2.0", new
URL("https://www.apache.org/licenses/LICENSE-2.0.txt")),
maintainer := "Apache Daffodil <[email protected]>",
organization := "org.apache.daffodil",
- // scala-steward:off
- scalaVersion := "2.13.16",
- // scala-steward:on
// remove the -Xcheckinit option added by the sbt tpoletcat plugin. This
// option leads to non-reproducible builds
scalacOptions --= Seq("-Xcheckinit"),
@@ -74,40 +58,6 @@ lazy val ratSettings = Seq(
ratFailBinaries := true
)
-lazy val `daffodil-debugger` = project
- .in(file("."))
- .settings(commonSettings, ratSettings)
- .settings(publish / skip := true)
- .dependsOn(debugger)
- .aggregate(debugger)
-
-lazy val debugger = project
- .in(file("debugger"))
- .enablePlugins(BuildInfoPlugin, JavaAppPackaging, UniversalPlugin,
ClasspathJarPlugin, SbtXjcPlugin)
- .settings(commonSettings)
- .settings(xjcSettings)
- .settings(
- name := "daffodil-debugger",
- libraryDependencies ++= Seq(
- /* NOTE: To support Java 8:
- * logback-classic can not go above version 1.2.11.
- * com.microsoft.java.debug.core can not go above version 0.34.0.
- */
- // scala-steward:off
- "ch.qos.logback" % "logback-classic" % "1.2.11",
- "com.microsoft.java" % "com.microsoft.java.debug.core" % "0.34.0",
- // scala-steward:on
- "co.fs2" %% "fs2-io" % "3.12.0",
- "com.monovore" %% "decline-effect" % "2.5.0",
- "org.typelevel" %% "log4cats-slf4j" % "2.7.1",
- "org.scalameta" %% "munit" % "1.1.1" % Test,
- "org.fusesource.jansi" % "jansi" % "1.18"
- ),
- buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion,
sbtVersion, "daffodilVersion" -> daffodilVer),
- buildInfoPackage := "org.apache.daffodil.debugger.dap",
- packageName := s"${name.value}-$daffodilVer"
- )
-
/* Workaround: certain reflection (used by JAXB) isn't allowed by default in
JDK 17:
*
https://docs.oracle.com/en/java/javase/17/migrate/migrating-jdk-8-later-jdk-releases.html#GUID-7BB28E4D-99B3-4078-BDC4-FC24180CE82B
*
@@ -128,7 +78,6 @@ lazy val xjcSettings =
libraryDependencies ++= Seq(
"com.sun.xml.bind" % "jaxb-impl" % "2.3.9",
"javax.activation" % "activation" % "1.1.1",
- "org.apache.daffodil" %% "daffodil-lib" % daffodilVer % Test,
"org.glassfish.jaxb" % "jaxb-xjc" % "2.3.9"
),
Test / javaOptions ++= extraJvmOptions, // tests use JAXB at runtime
@@ -150,11 +99,11 @@ lazy val xjcSettings =
// classes
lazy val xjcSourceDir = crossTarget.value / "xjc"
- // Get the daffodil-lib jar from the dependencies, this is the only jar
we need to extract
+ // Get the daffodil-lib or daffodil-core jar from the dependencies, this
is the only jar we need to extract
// files from
- val daffodilLibJar = managedJars(Test, Set[String]("jar"), update.value)
+ val daffodilJarWithTdmlXsd = managedJars(Test, Set[String]("jar"),
update.value)
.map(_.data)
- .find(_.getName.contains("daffodil-lib"))
+ .find(_.getName.contains(getDaffodilJarName(scalaBinaryVersion.value)))
.get
// cache the results of jar extraction so we don't keep extracting files
(which would
@@ -162,7 +111,7 @@ lazy val xjcSettings =
val cachedFun = FileFunction.cached(stream.cacheDirectory /
"xjcSources") { _ =>
// Extract the DFDL TDML schema file used for JAXB generation.
IO.unzip(
- daffodilLibJar,
+ daffodilJarWithTdmlXsd,
xjcSourceDir,
NameFilter.fnToNameFilter(f => f ==
"org/apache/daffodil/xsd/tdml.xsd")
)
@@ -218,6 +167,114 @@ lazy val xjcSettings =
// only invalidate the cache if the daffodil lib jar changed and so
there could be a
// chance the tdml.xsd file has been updated
- cachedFun(Set(daffodilLibJar)).toSeq
+ cachedFun(Set(daffodilJarWithTdmlXsd)).toSeq
}
)
+
+lazy val `daffodil-debugger` = project
+ .in(file("."))
+ .settings(commonSettings, ratSettings)
+ .settings(publish / skip := true)
+ .aggregate(debugger.projectRefs: _*)
+
+/** Since using projectMatrix, there will be a debugger, debugger2_12 and
debugger3 target. The debugger target is for
+ * Daffodil 3.11.0 and Scala 2.13. The debugger2_12 target is for Daffodil
3.10.0 abd older and Scala 2.12. The
+ * debugger3 target is for Daffodil 4.0.0 and newer and Scala 3. (only
availabe when using JDK 17+)
+ *
+ * When running something like "sbt test" that will run all targets. To use a
single target do one of: sbt
+ * debugger/test OR sbt debugger2_12/test OR sbt debugger3/test. Based on
which version of the debugger you are
+ * targeting.
+ */
+lazy val debugger =
+ (projectMatrix in (file("debugger")))
+ .enablePlugins(BuildInfoPlugin, JavaAppPackaging, UniversalPlugin,
ClasspathJarPlugin, SbtXjcPlugin)
+ .settings(commonSettings)
+ .settings(xjcSettings)
+ .settings(
+ name := "daffodil-debugger",
+ scalacOptions ++= buildScalacOptions(scalaBinaryVersion.value),
+ javacOptions ++= buildJavacOptions(scalaBinaryVersion.value),
+ libraryDependencies ++= Seq(
+ /* NOTE: To support Java 8:
+ * logback-classic can not go above version 1.2.11.
+ * com.microsoft.java.debug.core can not go above version 0.34.0.
+ * jansi can not go above version 1.18.
+ */
+ // scala-steward:off
+ "ch.qos.logback" % "logback-classic" % "1.2.11",
+ "com.microsoft.java" % "com.microsoft.java.debug.core" % "0.34.0",
+ "org.fusesource.jansi" % "jansi" % "1.18",
+ // scala-steward:on
+ "co.fs2" %% "fs2-io" % "3.12.0",
+ "com.monovore" %% "decline-effect" % "2.5.0",
+ "org.typelevel" %% "log4cats-slf4j" % "2.7.1",
+ "org.scalameta" %% "munit" % "1.1.1" % Test
+ ),
+ libraryDependencies ++=
getPlatformSpecificLibraries(scalaBinaryVersion.value),
+ buildInfoPackage := "org.apache.daffodil.debugger.dap",
+ buildInfoKeys := Seq[BuildInfoKey](
+ name,
+ version,
+ scalaVersion,
+ sbtVersion
+ ),
+ packageName := s"${name.value}-${scalaBinaryVersion.value}"
+ )
+ .jvmPlatform(
+ scalaVersions =
+ Seq("2.12.20", "2.13.16") ++ (if
(scala.util.Properties.isJavaAtLeast("17")) Seq("3.3.6") else Seq())
+ )
+
+def getPlatformSpecificLibraries(scalaBinaryVersion: String) =
+ scalaBinaryVersion match {
+ case "2.12" =>
+ Seq(
+ // scala-steward:off
+ "org.apache.daffodil" %% "daffodil-sapi" % "3.10.0" % "provided,test",
+ "org.apache.daffodil" %% "daffodil-runtime1" % "3.10.0" %
"provided,test",
+ "org.apache.daffodil" %% "daffodil-lib" % "3.10.0" % Test,
+ // scala-steward:on
+ "org.scala-lang.modules" %% "scala-collection-compat" % "2.14.0"
+ )
+ case "2.13" =>
+ Seq(
+ // scala-steward:off
+ "org.apache.daffodil" %% "daffodil-sapi" % "3.11.0" % "provided,test",
+ "org.apache.daffodil" %% "daffodil-runtime1" % "3.11.0" %
"provided,test",
+ "org.apache.daffodil" %% "daffodil-lib" % "3.11.0" % Test
+ // scala-steward:on
+ )
+ case "3" =>
+ Seq(
+ "org.apache.daffodil" %% "daffodil-core" % "4.0.0" % "provided,test"
+ )
+ }
+
+def getMinSupportedJavaVersion(scalaBinaryVersion: String): String =
+ if (scalaBinaryVersion == "3") "17"
+ else if (scala.util.Properties.isJavaAtLeast("21")) "11"
+ else "8"
+
+def buildJavacOptions(scalaBinaryVersion: String) = {
+ val jdkCompat = getMinSupportedJavaVersion(scalaBinaryVersion)
+
+ if (jdkCompat == "8")
+ Seq("-source", jdkCompat, "-target", jdkCompat)
+ else
+ Seq("--release", jdkCompat)
+}
+
+def buildScalacOptions(scalaBinaryVersion: String) = {
+ val jdkCompat = getMinSupportedJavaVersion(scalaBinaryVersion)
+
+ val commonSettings = Seq(if (scalaBinaryVersion == "2.12")
"-Ypartial-unification" else "")
+
+ if (scalaBinaryVersion == "2.12" && jdkCompat == "8")
+ commonSettings ++ Seq(s"--target:jvm-${jdkCompat}")
+ else
+ commonSettings ++ Seq("--release", jdkCompat)
+}
+
+def getDaffodilJarName(scalaBinaryVersion: String) =
+ if (scalaBinaryVersion == "3") "daffodil-core"
+ else "daffodil-lib"
diff --git a/src/classes/dfdlDebugger.ts
b/debugger/src/main/scala-2.12/org.apache.daffodil.debugger.dap/Convert.scala
similarity index 61%
copy from src/classes/dfdlDebugger.ts
copy to
debugger/src/main/scala-2.12/org.apache.daffodil.debugger.dap/Convert.scala
index a666ff9..3468694 100644
--- a/src/classes/dfdlDebugger.ts
+++
b/debugger/src/main/scala-2.12/org.apache.daffodil.debugger.dap/Convert.scala
@@ -15,8 +15,14 @@
* limitations under the License.
*/
-import { LoggingConfig } from '../classes/loggingConfig'
+/** This file contains support code for making a majority of Scala shareable
between different versions of Scala and
+ * Daffodil. The main difference comes in package names, converting certain
variables, etc. This file has all the
+ * helper code for that for Scala 2.13.
+ */
-export interface DFDLDebugger {
- logging: LoggingConfig
+package org.apache.daffodil.debugger.dap
+
+object Convert {
+ /* Daffodil Maybe wrapper methods */
+ def daffodilMaybeToOption[T <: AnyRef](maybe:
org.apache.daffodil.lib.util.Maybe[T]): Option[T] = maybe.toScalaOption
}
diff --git a/src/classes/dfdlDebugger.ts
b/debugger/src/main/scala-2.13/org.apache.daffodil.debugger.dap/Convert.scala
similarity index 62%
copy from src/classes/dfdlDebugger.ts
copy to
debugger/src/main/scala-2.13/org.apache.daffodil.debugger.dap/Convert.scala
index a666ff9..21decee 100644
--- a/src/classes/dfdlDebugger.ts
+++
b/debugger/src/main/scala-2.13/org.apache.daffodil.debugger.dap/Convert.scala
@@ -15,8 +15,14 @@
* limitations under the License.
*/
-import { LoggingConfig } from '../classes/loggingConfig'
+/** This file contains support code for making a majority of Scala shareable
between different versions of Scala and
+ * Daffodil. The main difference comes in package names, converting certain
variables, etc. This file has all the
+ * helper code for that for Scala 2.13.
+ */
-export interface DFDLDebugger {
- logging: LoggingConfig
+package org.apache.daffodil.debugger.dap
+
+object Convert {
+ /* Daffodil Maybe wrapper methods */
+ def daffodilMaybeToOption[T <: AnyRef](maybe:
org.apache.daffodil.lib.util.Maybe[T]): Option[T] = maybe.toOption
}
diff --git a/src/classes/dfdlDebugger.ts
b/debugger/src/main/scala-2/org.apache.daffodil.debugger.dap/DAP.scala
similarity index 54%
copy from src/classes/dfdlDebugger.ts
copy to debugger/src/main/scala-2/org.apache.daffodil.debugger.dap/DAP.scala
index a666ff9..424de53 100644
--- a/src/classes/dfdlDebugger.ts
+++ b/debugger/src/main/scala-2/org.apache.daffodil.debugger.dap/DAP.scala
@@ -15,8 +15,17 @@
* limitations under the License.
*/
-import { LoggingConfig } from '../classes/loggingConfig'
+package org.apache.daffodil.debugger
-export interface DFDLDebugger {
- logging: LoggingConfig
+/** The dap package object allows other files inside of the package to be able
to use specific classes and types without
+ * directly importing them. This help us with the different versions of
Daffodil where the classes have the same name
+ * but have moved to different import paths.
+ */
+
+package object dap {
+ type Debugger = org.apache.daffodil.runtime1.debugger.Debugger
+ type Diagnostic = org.apache.daffodil.lib.api.Diagnostic
+ type SDiagnostic = org.apache.daffodil.sapi.Diagnostic
+ type InfosetOutputter = org.apache.daffodil.sapi.infoset.InfosetOutputter
+ type DataProcessor = org.apache.daffodil.sapi.DataProcessor
}
diff --git
a/debugger/src/main/scala-2/org.apache.daffodil.debugger.dap/Support.scala
b/debugger/src/main/scala-2/org.apache.daffodil.debugger.dap/Support.scala
new file mode 100644
index 0000000..76394f1
--- /dev/null
+++ b/debugger/src/main/scala-2/org.apache.daffodil.debugger.dap/Support.scala
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/** This file contains support code for making a majority of Scala shareable
between different versions of Scala and
+ * Daffodil. The main difference comes in package names, converting certain
variables, etc. This file has all the
+ * helper code for that for Scala 2.13.
+ */
+
+package org.apache.daffodil.debugger.dap
+
+import java.io._
+import java.nio.file.Path
+import org.apache.daffodil.sapi._
+import org.apache.daffodil.sapi.io.InputSourceDataInputStream
+import org.apache.daffodil.sapi.infoset.{JsonInfosetOutputter,
XMLTextInfosetOutputter}
+
+object Support {
+ /* Daffodil DataProcessor wrapper methods */
+ def dataProcessorWithDebugger(
+ p: DataProcessor,
+ debugger: org.apache.daffodil.runtime1.debugger.Debugger,
+ variables: Map[String, String]
+ ): DataProcessor =
+ p.withDebugger(debugger)
+ .withDebugging(true)
+ .withExternalVariables(variables)
+ .withValidationMode(ValidationMode.Limited)
+
+ /* Daffodil infoset wrapper methods */
+ def getInputSourceDataInputStream(data: InputStream):
InputSourceDataInputStream = new InputSourceDataInputStream(
+ data
+ )
+ def getInfosetOutputter(infosetFormat: String, stream: OutputStream):
InfosetOutputter =
+ infosetFormat match {
+ case "xml" => new XMLTextInfosetOutputter(stream, true)
+ case "json" => new JsonInfosetOutputter(stream, true)
+ }
+
+ /* Daffodil ProcessorFactory wrapper methods */
+ def getProcessorFactory(
+ schema: Path,
+ rootName: Option[String],
+ rootNamespace: Option[String],
+ tunables: Map[String, String]
+ ): ProcessorFactory =
+ Daffodil
+ .compiler()
+ .withTunables(tunables)
+ .compileFile(
+ schema.toFile(),
+ rootName,
+ rootNamespace
+ )
+
+ /* Method to parse diagnostic list, this only necessary in scala 3 but to
make everything match this is needed. */
+ def parseDiagnosticList(dl: Seq[org.apache.daffodil.sapi.Diagnostic]):
Seq[org.apache.daffodil.sapi.Diagnostic] = dl
+}
diff --git a/src/classes/dfdlDebugger.ts
b/debugger/src/main/scala-3/org.apache.daffodil.debugger.dap/Convert.scala
similarity index 62%
copy from src/classes/dfdlDebugger.ts
copy to debugger/src/main/scala-3/org.apache.daffodil.debugger.dap/Convert.scala
index a666ff9..b44e158 100644
--- a/src/classes/dfdlDebugger.ts
+++ b/debugger/src/main/scala-3/org.apache.daffodil.debugger.dap/Convert.scala
@@ -15,8 +15,14 @@
* limitations under the License.
*/
-import { LoggingConfig } from '../classes/loggingConfig'
+/** This file contains support code for making a majority of Scala shareable
between different versions of Scala and
+ * Daffodil. The main difference comes in package names, converting certain
variables, etc. This file has all the
+ * helper code for that for Scala 3.
+ */
-export interface DFDLDebugger {
- logging: LoggingConfig
+package org.apache.daffodil.debugger.dap
+
+object Convert {
+ /* Daffodil Maybe wrapper methods */
+ def daffodilMaybeToOption[T <: AnyRef](maybe:
org.apache.daffodil.lib.util.Maybe[T]): Option[T] = maybe.toOption
}
diff --git a/src/classes/dfdlDebugger.ts
b/debugger/src/main/scala-3/org.apache.daffodil.debugger.dap/DAP.scala
similarity index 55%
copy from src/classes/dfdlDebugger.ts
copy to debugger/src/main/scala-3/org.apache.daffodil.debugger.dap/DAP.scala
index a666ff9..6f3325c 100644
--- a/src/classes/dfdlDebugger.ts
+++ b/debugger/src/main/scala-3/org.apache.daffodil.debugger.dap/DAP.scala
@@ -15,8 +15,17 @@
* limitations under the License.
*/
-import { LoggingConfig } from '../classes/loggingConfig'
+package org.apache.daffodil.debugger
-export interface DFDLDebugger {
- logging: LoggingConfig
+/** The dap package object allows other files inside of the package to be able
to use specific classes and types without
+ * directly importing them. This help us with the different versions of
Daffodil where the classes have the same name
+ * but have moved to different import paths.
+ */
+
+package object dap {
+ type Debugger = org.apache.daffodil.api.debugger.Debugger
+ type Diagnostic = org.apache.daffodil.api.Diagnostic
+ type SDiagnostic = org.apache.daffodil.api.Diagnostic
+ type InfosetOutputter = org.apache.daffodil.api.infoset.InfosetOutputter
+ type DataProcessor = org.apache.daffodil.api.DataProcessor
}
diff --git
a/debugger/src/main/scala-3/org.apache.daffodil.debugger.dap/Support.scala
b/debugger/src/main/scala-3/org.apache.daffodil.debugger.dap/Support.scala
new file mode 100644
index 0000000..5012e9b
--- /dev/null
+++ b/debugger/src/main/scala-3/org.apache.daffodil.debugger.dap/Support.scala
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/** This file contains support code for making a majority of Scala shareable
between different versions of Scala and
+ * Daffodil. The main difference comes in package names, converting certain
variables, etc. This file has all the
+ * helper code for that for Scala 3.
+ */
+
+package org.apache.daffodil.debugger.dap
+
+import java.io._
+import java.nio.file.Path
+import org.apache.daffodil.api._
+import scala.jdk.CollectionConverters._
+
+object Support {
+ /* Daffodil DataProcessor wrapper methods */
+ def dataProcessorWithDebugger(p: DataProcessor, debugger: Debugger,
variables: Map[String, String]): DataProcessor =
+ p.withDebugger(debugger)
+ .withExternalVariables(variables.asJava)
+ .withValidation("daffodil")
+
+ /* Daffodil infoset wrapper methods */
+ def getInputSourceDataInputStream(data: InputStream):
InputSourceDataInputStream =
+ Daffodil.newInputSourceDataInputStream(data)
+ def getInfosetOutputter(infosetFormat: String, stream: OutputStream):
InfosetOutputter =
+ infosetFormat match {
+ case "xml" => Daffodil.newXMLTextInfosetOutputter(stream, true)
+ case "json" => Daffodil.newJsonInfosetOutputter(stream, true)
+ }
+
+ /* Daffodil ProcessorFactory wrapper methods */
+ def getProcessorFactory(
+ schema: Path,
+ rootName: Option[String],
+ rootNamespace: Option[String],
+ tunables: Map[String, String]
+ ): ProcessorFactory =
+ Daffodil
+ .compiler()
+ .withTunables(tunables.asJava)
+ .compileFile(schema.toFile(), rootName.orNull, rootNamespace.orNull)
+
+ /* Method to convert java list of diagnostics to a sequence of diagnostics */
+ def parseDiagnosticList(
+ dl: java.util.List[org.apache.daffodil.api.Diagnostic]
+ ): Seq[org.apache.daffodil.api.Diagnostic] =
+ dl.asScala.toSeq
+}
diff --git
a/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Compiler.scala
b/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Compiler.scala
index b597001..592bbf2 100644
--- a/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Compiler.scala
+++ b/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Compiler.scala
@@ -20,7 +20,6 @@ package org.apache.daffodil.debugger.dap
import cats.effect.IO
import cats.syntax.all._
import java.nio.file.Path
-import org.apache.daffodil.sapi._
trait DAPCompiler {
def compile(
@@ -41,17 +40,10 @@ object DAPCompiler {
tunables: Map[String, String]
): IO[DataProcessor] =
IO.blocking(
- Daffodil
- .compiler()
- .withTunables(tunables)
- .compileFile(
- schema.toFile(),
- rootName,
- rootNamespace
- )
- ).ensureOr(pf => CompilationFailed(pf.getDiagnostics))(!_.isError())
+ Support.getProcessorFactory(schema, rootName, rootNamespace,
tunables)
+ ).ensureOr(pf =>
CompilationFailed(Support.parseDiagnosticList(pf.getDiagnostics)))(!_.isError())
.map(_.onPath("/"))
}
- case class CompilationFailed(seq: Seq[Diagnostic]) extends
Exception(seq.map(_.toString).mkString(", "))
+ case class CompilationFailed(seq: Seq[SDiagnostic]) extends
Exception(seq.map(_.toString).mkString(", "))
}
diff --git
a/debugger/src/main/scala/org.apache.daffodil.debugger.dap/DAPodil.scala
b/debugger/src/main/scala/org.apache.daffodil.debugger.dap/DAPodil.scala
index c5a2d91..d2458ac 100644
--- a/debugger/src/main/scala/org.apache.daffodil.debugger.dap/DAPodil.scala
+++ b/debugger/src/main/scala/org.apache.daffodil.debugger.dap/DAPodil.scala
@@ -35,12 +35,12 @@ import java.io._
import java.net._
import java.nio.file.Path
import java.nio.file.Paths
+import org.apache.daffodil.lib.util.Misc
import org.typelevel.log4cats.Logger
import org.typelevel.log4cats.slf4j.Slf4jLogger
-import scala.jdk.CollectionConverters._
import scala.concurrent.duration._
-
+import scala.jdk.CollectionConverters._
import logging._
/** Communication interface to a DAP server while in a connected session. */
@@ -379,7 +379,8 @@ class DAPodil(
)
) { frame =>
session.sendResponse(
- request.respondSuccess(new
Responses.ScopesResponseBody(frame.scopes.map(_.toDAP()).asJava))
+ request
+ .respondSuccess(new
Responses.ScopesResponseBody(frame.scopes.map(_.toDAP()).asJava))
)
}
} yield ()
@@ -403,7 +404,9 @@ class DAPodil(
)
)
)(variables =>
- session.sendResponse(request.respondSuccess(new
Responses.VariablesResponseBody(variables.asJava)))
+ session.sendResponse(
+ request.respondSuccess(new
Responses.VariablesResponseBody(variables.asJava))
+ )
)
} yield ()
case s => DAPodil.InvalidState.raise(request, "Launched", s)
@@ -435,7 +438,7 @@ object DAPodil extends IOApp {
Opts
.option[Duration]("listenTimeout", "duration to wait for a DAP client
connection (default: 10s)")
.withDefault(10.seconds)
- ).mapN(Options)
+ ).mapN(Options.apply)
implicit val logger: Logger[IO] = Slf4jLogger.getLogger
@@ -446,11 +449,11 @@ object DAPodil extends IOApp {
|
|Build info:
| version: ${BuildInfo.version}
- | daffodilVersion: ${BuildInfo.daffodilVersion}
| scalaVersion: ${BuildInfo.scalaVersion}
| sbtVersion: ${BuildInfo.sbtVersion}
|Runtime info:
| JVM version: ${System.getProperty("java.version")}
(${System.getProperty("java.home")})
+ | Daffodil Version: ${Misc.getDaffodilVersion}
|******************************************************""".stripMargin
def run(args: List[String]): IO[ExitCode] =
@@ -468,7 +471,9 @@ object DAPodil extends IOApp {
_ <- Logger[IO].info(header)
_ <- options match {
case Options(listenPort, listenTimeout) =>
- Logger[IO].info(s"launched with options listenPort: $listenPort,
listenTimeout: $listenTimeout")
+ Logger[IO].info(
+ s"launched with options listenPort: $listenPort, listenTimeout:
$listenTimeout"
+ )
}
_ <- Ref[IO].of[State](State.Uninitialized) // state for the DAPodil
instance
diff --git
a/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Parse.scala
b/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Parse.scala
index 6846390..810dc7a 100644
--- a/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Parse.scala
+++ b/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Parse.scala
@@ -33,16 +33,12 @@ import java.net.URI
import java.nio.file._
import org.apache.commons.io.FileUtils
import org.apache.daffodil.debugger.dap.{BuildInfo => DAPBuildInfo}
-import org.apache.daffodil.runtime1.debugger.Debugger
import org.apache.daffodil.runtime1.infoset.{DIDocument, DIElement,
InfosetWalker}
import org.apache.daffodil.runtime1.processors._
import org.apache.daffodil.runtime1.processors.dfa.DFADelimiter
import org.apache.daffodil.runtime1.processors.parsers._
import org.apache.daffodil.lib.exceptions.SchemaFileLocation
import org.apache.daffodil.lib.util.Misc
-import org.apache.daffodil.sapi.{Diagnostic => SDiagnostic, ValidationMode}
-import org.apache.daffodil.sapi.infoset._
-import org.apache.daffodil.sapi.io.InputSourceDataInputStream
import org.apache.daffodil.tdml.TDML
import org.typelevel.log4cats.Logger
import org.typelevel.log4cats.slf4j.Slf4jLogger
@@ -86,12 +82,7 @@ object Parse {
for {
dp <- DAPCompiler()
.compile(schema, rootName, rootNamespace, tunables)
- .map(p =>
- p.withDebugger(debugger)
- .withDebugging(true)
- .withExternalVariables(variables)
- .withValidationMode(ValidationMode.Limited)
- )
+ .map(p => Support.dataProcessorWithDebugger(p, debugger, variables))
done <- Ref[IO].of(false)
pleaseStop <- Deferred[IO, Unit]
} yield new Parse {
@@ -104,18 +95,13 @@ object Parse {
val stopper =
pleaseStop.get *> IO.canceled // will cancel the concurrent
parse effect
- val infosetOutputter = infosetFormat match {
- case "xml" => new XMLTextInfosetOutputter(os, true)
- case "json" => new JsonInfosetOutputter(os, true)
- }
-
val dataSize = data.available()
val parse =
IO.interruptibleMany(
dp.parse(
- new InputSourceDataInputStream(data),
- infosetOutputter
+ Support.getInputSourceDataInputStream(data),
+ Support.getInfosetOutputter(infosetFormat, os)
)
// WARNING: parse doesn't close the OutputStream, so closed
below
).flatTap { res =>
@@ -123,7 +109,9 @@ object Parse {
dapEvents
.send(
Parse.Event.Error(
- res.getDiagnostics.toList
+ Support
+ .parseDiagnosticList(res.getDiagnostics)
+ .toList
.map(d => d.toString)
.mkString("\n")
)
@@ -131,7 +119,7 @@ object Parse {
.void
} else IO.unit
}.ensureOr { res =>
- new Parse.Exception(res.getDiagnostics.toList)
+ new
Parse.Exception(Support.parseDiagnosticList(res.getDiagnostics).toList)
}(res => !res.isError())
.flatMap { parseResult =>
val loc = parseResult.location()
@@ -167,9 +155,9 @@ object Parse {
class Debugee(
schema: DAPodil.Source,
- data: DAPodil.Source,
+ dataIn: DAPodil.Source,
outputData: Signal[IO, DAPodil.Data],
- events: Stream[IO, Events.DebugEvent],
+ eventsIn: Stream[IO, Events.DebugEvent],
breakpoints: Breakpoints,
control: Control,
parseEvents: Channel[IO, Parse.Event]
@@ -178,13 +166,13 @@ object Parse {
outputData
def events(): Stream[IO, Events.DebugEvent] =
- events
+ eventsIn
/** We return only the "static" sources of the schema and data file, and
notify the debugger of additional sources,
* if any, via source change events, which only subsequently fetch the
content directly via `sourceContent`.
*/
def sources(): IO[List[DAPodil.Source]] =
- IO.pure(List(schema, data))
+ IO.pure(List(schema, dataIn))
def sourceContent(ref: DAPodil.Source.Ref):
IO[Option[DAPodil.Source.Content]] =
IO.pure(None) // no additional source content available; infoset and
data position info sent as custom events
@@ -1054,14 +1042,14 @@ object Parse {
schemaLocation: SchemaFileLocation,
pointsOfUncertainty: List[PointOfUncertainty],
delimiterStack: List[Delimiter],
- diagnostics: List[org.apache.daffodil.lib.api.Diagnostic],
+ diagnostics: List[Diagnostic],
infoset: Option[InfosetEvent]
) extends Event {
// PState is mutable, so we copy all the information we might need
downstream.
def this(pstate: PState, infoset: Option[InfosetEvent]) =
this(
pstate.copyStateForDebugger,
- pstate.currentNode.toOption.map(element =>
ElementName(element.name)),
+ Convert.daffodilMaybeToOption(pstate.currentNode).map(node =>
ElementName(node.asElement.name)),
pstate.schemaFileLocation,
pstate.pointsOfUncertainty.iterator.toList.map(mark =>
PointOfUncertainty(
@@ -1074,7 +1062,7 @@ object Parse {
pstate.mpstate.delimiters.toList.zipWithIndex.map { case (delimiter,
i) =>
Delimiter(if (i < pstate.mpstate.delimitersLocalIndexStack.top)
"remote" else "local", delimiter)
},
- pstate.diagnostics,
+ pstate.diagnostics.toList,
infoset
)
}
@@ -1168,7 +1156,7 @@ object Parse {
}
}
- case class BuildInfo(version: String, daffodilVersion: String,
scalaVersion: String)
+ case class BuildInfo(version: String, scalaVersion: String)
def apply(launchArgs: Debugee.LaunchArgs): ConfigEvent =
ConfigEvent(
@@ -1201,7 +1189,6 @@ object Parse {
},
BuildInfo(
DAPBuildInfo.version,
- DAPBuildInfo.daffodilVersion,
DAPBuildInfo.scalaVersion
)
)
@@ -1222,14 +1209,10 @@ object Parse {
private def infosetToString(format: String, ie: DIElement): String = {
val bos = new java.io.ByteArrayOutputStream()
- val infosetOutputter = format match {
- case "xml" => new XMLTextInfosetOutputter(bos, true)
- case "json" => new JsonInfosetOutputter(bos, true)
- }
val iw = InfosetWalker(
ie.asInstanceOf[DIElement],
- infosetOutputter,
+ Support.getInfosetOutputter(format, bos),
walkHidden = false,
ignoreBlocks = true,
releaseUnneededInfoset = false
diff --git
a/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Utils.scala
b/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Utils.scala
index 3dced22..8d27225 100644
--- a/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Utils.scala
+++ b/debugger/src/main/scala/org.apache.daffodil.debugger.dap/Utils.scala
@@ -17,7 +17,7 @@
package org.apache.daffodil.debugger.dap
-import java.io.RandomAccessFile
+import java.io._
import java.nio.ByteBuffer
import java.nio.file.Path
import org.apache.daffodil.io.DataDumper
diff --git a/debugger/src/main/scala/org.apache.daffodil.tdml/TDML.scala
b/debugger/src/main/scala/org.apache.daffodil.tdml/TDML.scala
index e450b39..66366cd 100644
--- a/debugger/src/main/scala/org.apache.daffodil.tdml/TDML.scala
+++ b/debugger/src/main/scala/org.apache.daffodil.tdml/TDML.scala
@@ -23,8 +23,8 @@ import javax.xml.bind.JAXBContext
import javax.xml.bind.JAXBElement
import javax.xml.bind.Marshaller
import javax.xml.namespace.QName
-import scala.jdk.CollectionConverters._
import org.apache.daffodil.lib.xml.XMLUtils
+import scala.jdk.CollectionConverters._
object TDML {
def getDefaultTDMLTestCaseDescription(): String =
@@ -189,14 +189,14 @@ object TDML {
def execute(tdmlName: String, tdmlPath: String): Option[(Path, Path)] = {
val basePath = Paths.get(tdmlPath).toAbsolutePath().getParent().toString()
- val testCaseList = JAXBContext
- .newInstance(classOf[TestSuite])
- .createUnmarshaller()
- .unmarshal(new File(tdmlPath))
- .asInstanceOf[TestSuite]
- .getTutorialOrParserTestCaseOrDefineSchema()
- .asScala
- .toList
+ val testCaseList =
+ JAXBContext
+ .newInstance(classOf[TestSuite])
+ .createUnmarshaller()
+ .unmarshal(new File(tdmlPath))
+ .asInstanceOf[TestSuite]
+ .getTutorialOrParserTestCaseOrDefineSchema()
+ .asScala
testCaseList.collectFirst {
case (ptc: ParserTestCaseType) if ptc.getName() == tdmlName =>
diff --git a/debugger/src/templates/bash-template
b/debugger/src/templates/bash-template
index dbf7ba1..fb7d01b 100644
--- a/debugger/src/templates/bash-template
+++ b/debugger/src/templates/bash-template
@@ -212,6 +212,8 @@ process_args () {
-java-home) require_arg path "$1" "$2" && jre=`eval echo $2` &&
java_cmd="$jre/bin/java" && shift 2 ;;
+ --daffodilPath) daffodil_path="$2" && shift 2 ;;
+
-D*|-agentlib*|-XX*) addJava "$1" && shift ;;
-J*) addJava "${1:2}" && shift ;;
*) addResidual "$1" && shift ;;
@@ -263,10 +265,18 @@ run() {
java_opts="${JAVA_OPTS}"
fi
+ # add daffodil jars to classpath
+ if [[ -z $daffodil_path ]]; then
+ echo "No Daffodil path provided using the --daffodilPath flag. Exiting as
debugger can't run without the Daffodil path"
+ exit 1
+ fi
+
+ daffodil_lib_dir=$(echo $daffodil_path/lib | sed 's/ /\ /g')
+ daffodil_jars="$daffodil_lib_dir/"'*'
+ new_classpath="$app_classpath:$daffodil_jars"
+
if [[ "$DAFFODIL_DEBUG_CLASSPATH" != "" ]]; then
- new_classpath="$app_classpath:$DAFFODIL_DEBUG_CLASSPATH"
- else
- new_classpath="$app_classpath"
+ new_classpath="$new_classpath:$DAFFODIL_DEBUG_CLASSPATH"
fi
# run sbt
@@ -376,4 +386,3 @@ declare java_cmd=$(get_java_cmd)
[[ -f "$script_conf_file" ]] && set -- $(loadConfigFile "$script_conf_file")
"$@"
run "$@"
-stupid thing
diff --git a/debugger/src/templates/bat-template
b/debugger/src/templates/bat-template
index 1c21cf7..403f2f2 100644
--- a/debugger/src/templates/bat-template
+++ b/debugger/src/templates/bat-template
@@ -114,12 +114,19 @@ if defined CUSTOM_MAIN_CLASS (
set MAIN_CLASS=!APP_MAIN_CLASS!
)
-if defined DAFFODIL_DEBUG_CLASSPATH (
- set NEW_CLASSPATH="%APP_CLASSPATH%;%DAFFODIL_DEBUG_CLASSPATH%"
-) else (
- set NEW_CLASSPATH="%APP_CLASSPATH%"
+set NEW_CLASSPATH=%APP_CLASSPATH%
+
+rem ensure daffodil path provided
+if not defined DAFFODIL_PATH (
+ echo "No Daffodil path provided using the --daffodilPath flag. Exiting as
debugger can't run without the Daffodil path"
+ exit 1
)
+set NEW_CLASSPATH=%NEW_CLASSPATH%;!DAFFODIL_PATH!\lib\*
+
+if defined DAFFODIL_DEBUG_CLASSPATH (
+ set NEW_CLASSPATH="%NEW_CLASSPATH%;%DAFFODIL_DEBUG_CLASSPATH%"
+)
rem Call the application and pass all arguments unchanged.
"%_JAVACMD%" !_JAVA_OPTS! !DAFFODIL_DEBUGGER_OPTS! -cp "%NEW_CLASSPATH%"
%MAIN_CLASS% !_APP_ARGS!
@@ -194,7 +201,12 @@ rem Processes incoming arguments and places them in
appropriate global variables
call set CUSTOM_MAIN_CLASS=%%2
shift
) else (
- set _APP_ARGS=!_APP_ARGS! !_PARAM1!
+ if "!_TEST_PARAM!"=="--daffodilPath" (
+ call set DAFFODIL_PATH=%%2
+ shift
+ ) else (
+ set _APP_ARGS=!_APP_ARGS! !_PARAM1!
+ )
)
)
shift
diff --git
a/debugger/src/test/scala/org.apache.daffodil.debugger/ParseSuite.scala
b/debugger/src/test/scala/org.apache.daffodil.debugger/ParseSuite.scala
index 1caabb0..843f3d4 100644
--- a/debugger/src/test/scala/org.apache.daffodil.debugger/ParseSuite.scala
+++ b/debugger/src/test/scala/org.apache.daffodil.debugger/ParseSuite.scala
@@ -25,8 +25,8 @@ class ParseSuite extends FunSuite {
val request = "launch"
val launchType = "dfdl"
val schema = new JsonObject()
- var schemaPath =
Paths.get("./src/test/data/emptySchema.dfdl.xsd").toAbsolutePath().toString()
- var data =
Paths.get("./src/test/data/emptyData.xml").toAbsolutePath().toString()
+ var schemaPath =
Paths.get("../../../debugger/src/test/data/emptySchema.dfdl.xsd").toAbsolutePath().toString()
+ var data =
Paths.get("../../../debugger/src/test/data/emptyData.xml").toAbsolutePath().toString()
val debugServer = 4711
val infosetFormat = "xml"
var infosetOutputType = "none"
@@ -46,8 +46,8 @@ class ParseSuite extends FunSuite {
var testTDMLObject = new JsonObject()
override def beforeEach(context: BeforeEach): Unit = {
- schemaPath =
Paths.get("./src/test/data/emptySchema.dfdl.xsd").toAbsolutePath().toString()
- data =
Paths.get("./src/test/data/emptyData.xml").toAbsolutePath().toString()
+ schemaPath =
Paths.get("../../../debugger/src/test/data/emptySchema.dfdl.xsd").toAbsolutePath().toString()
+ data =
Paths.get("../../../debugger/src/test/data/emptyData.xml").toAbsolutePath().toString()
infosetOutputType = "none"
infosetOutputPath = "testPath/infoset.xml"
tdmlAction = ""
diff --git a/package.json b/package.json
index 443010e..2dc2b17 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,6 @@
"displayName": "Apache Daffodil™ Extension for Visual Studio Code",
"description": "Apache Daffodil™ Extension for Visual Studio Code providing
DFDL syntax highlighting, DFDL code completion, DFDL schema debugging, and data
editor",
"version": "1.4.2-SNAPSHOT",
- "daffodilVersion": "3.11.0",
"publisher": "asf",
"author": "Apache Daffodil",
"license": "Apache-2.0",
@@ -30,7 +29,7 @@
"check-license-compatibility": "run-func build/yarn-scripts.ts
checkLicenseCompatibility",
"clean": "yarn nodeclean && yarn scalaclean",
"precompile": "yarn nodeclean && yarn gen-version-ts && yarn svelte:build
&& yarn compile:tdmlEditorJS",
- "compile": "tsc -p ./ && yarn sbt",
+ "compile": "tsc -p ./ && yarn sbt && yarn vite:dev",
"lint": "yarn prettier src -c",
"lint:fix": "yarn prettier src -w",
"prewatch": "yarn gen-version-ts && yarn sbt",
@@ -44,7 +43,7 @@
"pretest": "yarn compile && yarn vite:dev",
"test": "sbt test && yarn test:svelte && node ./out/tests/runTest.js",
"test:svelte": "mocha -r ts-node/register ./src/svelte/tests/**/*.test.ts",
- "sbt": "sbt debugger/Universal/packageBin",
+ "sbt": "sbt Universal/packageBin",
"svelte:check": "svelte-check --tsconfig ./src/svelte/tsconfig.json",
"svelte:build": "cd src/svelte && vite build --config ./vite.config.mjs
--mode production --emptyOutDir",
"update-version": "run-func build/yarn-scripts.ts updateVersion",
@@ -685,8 +684,18 @@
},
"dfdlDebugger": {
"type": "object",
- "description": "Configuration for debugger. Settings are
logging (level and file)",
+ "description": "Configuration for debugger. Settings are
daffodilVersion, timeout and logging (level and file)",
"properties": {
+ "daffodilVersion": {
+ "type": "string",
+ "default": "3.11.0",
+ "description": "Daffodil version to use."
+ },
+ "timeout": {
+ "type": "string",
+ "default": "10s",
+ "description": "Debugger connection timeout in seconds(s),
minutes(m) or hours(h)"
+ },
"logging": {
"type": "object",
"description": "DFDL Debugger Logging Configuration",
@@ -716,6 +725,8 @@
}
},
"default": {
+ "daffodilVersion": "3.11.0",
+ "timeout": "10s",
"logging": {
"level": "INFO",
"file": "${workspaceFolder}/daffodil-debugger.log"
@@ -760,6 +771,8 @@
}
},
"dfdlDebugger": {
+ "daffodilVersion": "3.11.0",
+ "timeout": "10s",
"logging": {
"level": "INFO",
"file": "${workspaceFolder}/daffodil-debugger.log"
@@ -806,6 +819,8 @@
}
},
"dfdlDebugger": {
+ "daffodilVersion": "3.11.0",
+ "timeout": "10s",
"logging": {
"level": "INFO",
"file": "^\"\\${workspaceFolder}/daffodil-debugger.log\""
@@ -926,8 +941,10 @@
},
"dfdlDebugger": {
"type": "object",
- "description": "Configuration for debugger. Settings are logging
(level and file)",
+ "description": "Configuration for debugger. Settings are
daffodilVersion, timeout and logging (level and file)",
"default": {
+ "daffodilVersion": "3.11.0",
+ "timeout": "10s",
"logging": {
"level": "INFO",
"file": "${workspaceFolder}/daffodil-debugger.log"
diff --git a/project/plugins.sbt b/project/plugins.sbt
index bd53581..d43fc8c 100644
--- a/project/plugins.sbt
+++ b/project/plugins.sbt
@@ -21,3 +21,4 @@ addSbtPlugin("org.typelevel" % "sbt-tpolecat" % "0.5.2")
addSbtPlugin("org.musigma" % "sbt-rat" % "0.7.0")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.5")
addSbtPlugin("org.scala-sbt.plugins" % "sbt-xjc" % "0.10")
+addSbtPlugin("com.eed3si9n" % "sbt-projectmatrix" % "0.11.0")
diff --git a/src/adapter/activateDaffodilDebug.ts
b/src/adapter/activateDaffodilDebug.ts
index a655f4b..02ef6cf 100644
--- a/src/adapter/activateDaffodilDebug.ts
+++ b/src/adapter/activateDaffodilDebug.ts
@@ -8,13 +8,13 @@
import * as fs from 'fs'
import * as path from 'path'
import * as vscode from 'vscode'
-import * as infoset from 'infoset'
-import * as launchWizard from 'launchWizard'
-import * as dfdlLang from 'language/dfdl'
-import * as dfdlExt from 'language/semantics/dfdlExt'
-import * as dataEditClient from 'dataEditor'
-import * as tdmlEditor from 'tdmlEditor'
-import * as rootCompletion from 'rootCompletion'
+import * as infoset from '../infoset'
+import * as launchWizard from '../launchWizard/launchWizard'
+import * as dfdlLang from '../language/dfdl'
+import * as dfdlExt from '../language/semantics/dfdlExt'
+import * as dataEditClient from '../dataEditor'
+import * as tdmlEditor from '../tdmlEditor'
+import * as rootCompletion from '../rootCompletion'
import { tmpdir } from 'os'
import {
@@ -34,11 +34,11 @@ import {
getTmpTDMLFilePath,
copyTestCase,
TMP_TDML_FILENAME,
-} from 'tdmlEditor/utilities/tdmlXmlUtils'
+} from '../tdmlEditor/utilities/tdmlXmlUtils'
import xmlFormat from 'xml-formatter'
import { CommandsProvider } from '../views/commands'
import * as daffodilDebugErrors from './daffodilDebugErrors'
-import { TDMLProvider } from 'tdmlEditor/TDMLProvider'
+import { TDMLProvider } from '../tdmlEditor/TDMLProvider'
export const outputChannel: vscode.OutputChannel =
vscode.window.createOutputChannel('Daffodil')
@@ -217,6 +217,9 @@ export function activateDaffodilDebug(
) {
setupViews(context)
+ context.subscriptions.push(
+ vscode.commands.registerCommand('getContext', () => context)
+ )
context.subscriptions.push(
vscode.commands.registerCommand(
'extension.dfdl-debug.runEditorContents',
diff --git a/src/adapter/daffodilDebugErrors.ts
b/src/adapter/daffodilDebugErrors.ts
index 66c160d..fe5d9c5 100644
--- a/src/adapter/daffodilDebugErrors.ts
+++ b/src/adapter/daffodilDebugErrors.ts
@@ -24,6 +24,7 @@ import {
extractDaffodilEvent,
parseErrorEvent,
} from '../daffodilDebugger/daffodil'
+import { displayModalError } from '../utils'
export const activate = () =>
vscode.debug.onDidReceiveDebugSessionCustomEvent(async (e) => {
@@ -51,6 +52,6 @@ export const activate = () =>
if (message !== '') {
// Make the message have two line breaks between each line to make the
message look better.
message = message.replaceAll('\n', '\n\n')
- vscode.window.showErrorMessage(message, { modal: true })
+ displayModalError(message)
}
})
diff --git a/src/adapter/daffodilEvent.ts b/src/adapter/daffodilEvent.ts
index 6990f7e..97a7aaa 100644
--- a/src/adapter/daffodilEvent.ts
+++ b/src/adapter/daffodilEvent.ts
@@ -19,7 +19,7 @@ import * as vscode from 'vscode'
import * as fs from 'fs'
import * as daf from '../daffodilDebugger'
-import { ensureFile, tmpFile } from '../utils'
+import { displayModalError, ensureFile, tmpFile } from '../utils'
import { outputChannel } from './activateDaffodilDebug'
export function handleDebugEvent(e: vscode.DebugSessionCustomEvent) {
@@ -33,7 +33,7 @@ export function handleDebugEvent(e:
vscode.DebugSessionCustomEvent) {
// this allows for any error event to be caught in this case
case e.event.startsWith('daffodil.error') ? e.event : '':
if (!e.body.message.startsWith('Schema Definition Error:')) {
- vscode.window.showErrorMessage(e.body.message, { modal: true })
+ displayModalError(e.body.message)
}
outputChannel.appendLine(e.body.message)
outputChannel.show(true)
diff --git a/src/classes/dfdlDebugger.ts b/src/classes/dfdlDebugger.ts
index a666ff9..5327d70 100644
--- a/src/classes/dfdlDebugger.ts
+++ b/src/classes/dfdlDebugger.ts
@@ -18,5 +18,7 @@
import { LoggingConfig } from '../classes/loggingConfig'
export interface DFDLDebugger {
+ daffodilVersion: string
+ timeout: string
logging: LoggingConfig
}
diff --git a/src/daffodilDebugger/daffodil.ts b/src/daffodilDebugger/daffodil.ts
index 132094d..3baa498 100644
--- a/src/daffodilDebugger/daffodil.ts
+++ b/src/daffodilDebugger/daffodil.ts
@@ -15,8 +15,6 @@
* limitations under the License.
*/
-import * as fs from 'fs'
-import { parse as jsoncParse } from 'jsonc-parser'
import { DebugSession, DebugSessionCustomEvent, debug } from 'vscode'
import { SchemaData } from '../classes/schemaData'
@@ -71,10 +69,6 @@ export interface BuildInfo {
scalaVersion: string
}
-export function getDaffodilVersion(filePath: fs.PathLike) {
- return jsoncParse(fs.readFileSync(filePath).toString())['daffodilVersion']
-}
-
export interface IDaffodilEvent {
readonly type: DaffodilEventType
readonly body: DaffodilDataType
diff --git a/src/daffodilDebugger/daffodilJars.ts
b/src/daffodilDebugger/daffodilJars.ts
new file mode 100644
index 0000000..f6c8d8c
--- /dev/null
+++ b/src/daffodilDebugger/daffodilJars.ts
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+import * as path from 'path'
+import * as fs from 'fs'
+import * as vscode from 'vscode'
+import { outputChannel } from '../adapter/activateDaffodilDebug'
+import { downloadAndExtract } from '../utils'
+
+/**
+ * The daffodil debugger doesn't bundle any of daffodil jars because we want
to support
+ * many versions of daffodil and do not want to bundle them all. The CLI zip
is an official
+ * daffodil release that contains all the daffodil jars (and their transitive
dependencies)
+ * that the debugger needs for a particular Daffodil version. The debugger
doesn't need all
+ * the jars that it bundles (e.g. daffodil-cli.jar) but those will just be
ignored.
+ */
+export async function checkIfDaffodilJarsNeeded(
+ daffodilVersion: string
+): Promise<string> {
+ const context = (await vscode.commands.executeCommand(
+ 'getContext'
+ )) as vscode.ExtensionContext
+
+ /**
+ * Global storage paths:
+ * Mac: /Users/<username>/Library/Application
Support/Code/User/globalStorage/asf.apache-daffodil-vscode
+ * Windows: %APPDATA%\Code\User\globalStorage\asf.apache-daffodil-vscode
+ * Linux:
/home/<username>/.config/Code/User/globalStorage/asf.apache-daffodil-vscode
+ */
+
+ const destFolder = path.join(context.globalStorageUri.fsPath, 'daffodil')
+ const binFolder = path.join(
+ destFolder,
+ `apache-daffodil-${daffodilVersion}-bin`
+ )
+
+ if (!fs.existsSync(binFolder)) {
+ const url =
`https://www.apache.org/dyn/closer.lua/download/daffodil/${daffodilVersion}/bin/apache-daffodil-${daffodilVersion}-bin.zip`
+ try {
+ await downloadAndExtract('Daffodil CLI JARs', url, destFolder)
+ } catch (err) {
+ console.error(err)
+ }
+ } else {
+ outputChannel.appendLine(
+ `[INFO] Daffodil CLI JARs already exists. Skipping download.`
+ )
+ }
+
+ return binFolder
+}
diff --git a/src/daffodilDebugger/debugger.ts b/src/daffodilDebugger/debugger.ts
index 02bcddd..ca95f8d 100644
--- a/src/daffodilDebugger/debugger.ts
+++ b/src/daffodilDebugger/debugger.ts
@@ -210,13 +210,19 @@ export async function getDebugger(
setCurrentConfig(config)
if (!config.useExistingServer) {
- await runDebugger(
+ let newDebugger = await runDebugger(
context.asAbsolutePath('./'),
daffodilDebugClasspath,
context.asAbsolutePath('./package.json'),
config.debugServer,
config.dfdlDebugger
)
+
+ // This ensures the extension doesn't try to connect to the debugger if
the debugger
+ // wasn't created
+ if (!newDebugger) {
+ return await stopDebugging().then((_) => undefined)
+ }
}
}
}
diff --git a/src/daffodilDebugger/utils.ts b/src/daffodilDebugger/utils.ts
index 68aad43..b65620c 100644
--- a/src/daffodilDebugger/utils.ts
+++ b/src/daffodilDebugger/utils.ts
@@ -23,14 +23,11 @@ import { IJavaHomeInfo } from
'@viperproject/locate-java-home/js/es5/lib/interfa
import * as semver from 'semver'
import { LIB_VERSION } from '../version'
import { deactivate } from '../adapter/extension'
-import { getDaffodilVersion } from './daffodil'
import { Artifact } from '../classes/artifact'
import { DFDLDebugger } from '../classes/dfdlDebugger'
-import { osCheck, runScript, terminalName } from '../utils'
-
-export const daffodilVersion = (filePath: string): string => {
- return getDaffodilVersion(filePath)
-}
+import { displayModalError, osCheck, runScript, terminalName } from '../utils'
+import { outputChannel } from '../adapter/activateDaffodilDebug'
+import { checkIfDaffodilJarsNeeded } from './daffodilJars'
export const daffodilArtifact = (version: string): Artifact => {
return new Artifact('daffodil-debugger', version, 'daffodil-debugger')
@@ -39,7 +36,12 @@ export const daffodilArtifact = (version: string): Artifact
=> {
export const stopDebugger = async (id: number | undefined = undefined) =>
child_process.exec(osCheck(`taskkill /F /PID ${id}`, `kill -9 ${id}`))
-export const shellArgs = (port: number, isAtLeastJdk17: boolean) => {
+export const shellArgs = (
+ port: number,
+ timeout: string,
+ daffodilPath: string,
+ isAtLeastJdk17: boolean
+) => {
// Workaround: certain reflection (used by JAXB) isn't allowed by default in
JDK 17:
//
https://docs.oracle.com/en/java/javase/17/migrate/migrating-jdk-8-later-jdk-releases.html#GUID-7BB28E4D-99B3-4078-BDC4-FC24180CE82B
const extraArgs = isAtLeastJdk17
@@ -48,7 +50,22 @@ export const shellArgs = (port: number, isAtLeastJdk17:
boolean) => {
['-J--add-opens', '-Jjava.base/java.lang=ALL-UNNAMED']
)
: []
- return ['--listenPort', `${port}`].concat(extraArgs)
+ return [
+ '--listenPort',
+ `${port}`,
+ '--listenTimeout',
+ `${timeout}`,
+ '--daffodilPath',
+ `"${daffodilPath}"`,
+ ].concat(extraArgs)
+}
+
+export async function getScalaVersion(
+ daffodilVersion: string
+): Promise<string> {
+ if (semver.satisfies(daffodilVersion, '>=4.0.0')) return '3'
+ else if (semver.satisfies(daffodilVersion, '>=3.11.0')) return '2.13'
+ else return '2.12'
}
export async function runDebugger(
@@ -58,34 +75,59 @@ export async function runDebugger(
serverPort: number,
dfdlDebugger: DFDLDebugger,
createTerminal: boolean = false
-): Promise<vscode.Terminal> {
- const dfdlVersion = daffodilVersion(filePath)
+): Promise<vscode.Terminal | undefined> {
+ if (
+ !dfdlDebugger.timeout.endsWith('s') &&
+ !dfdlDebugger.timeout.endsWith('m') &&
+ !dfdlDebugger.timeout.endsWith('s')
+ ) {
+ vscode.window.showErrorMessage(
+ `DFDL Debugger Timeout ${dfdlDebugger.timeout} does not end in either s
for seconds, m for minutes or h for hours.
+ Appending s to end of timeout string.`
+ )
+ dfdlDebugger.timeout = `${dfdlDebugger.timeout}s`
+ }
+
+ // Locates the $JAVA_HOME, or if not defined, the highest version available.
+ const javaHome: IJavaHomeInfo | undefined = await getJavaHome()
+
+ const isAtLeastJdk17: boolean = parseFloat(javaHome?.version ?? '0') >= 17
+ outputChannel.appendLine(
+ `[DEBUG] Choosing java home at ${javaHome?.path}, version
${javaHome?.version}, is at least JDK 17: ${isAtLeastJdk17}`
+ )
+
+ let dfdlVersion = dfdlDebugger.daffodilVersion
+ let scalaVersion = await getScalaVersion(dfdlDebugger.daffodilVersion)
+
+ if (scalaVersion == '') {
+ displayModalError(
+ `Daffodil Version ${dfdlDebugger.daffodilVersion} does not satisfy any
version requirements`
+ )
+ return undefined
+ }
+
+ outputChannel.appendLine(
+ `[INFO] Using Scala ${scalaVersion} + Daffodil ${dfdlVersion} debugger`
+ )
+
+ /**
+ * The Scala 3 with Daffodil >= 4.0.0 debugger can only be ran on JDK 17 or
greater. So if the java version
+ * being used is less than 17, fallback to the Scala 2.13 and Daffodil
3.11.0 debugger and notify the user.
+ */
+ if (semver.satisfies(dfdlVersion, '>=4.0.0') && !isAtLeastJdk17) {
+ displayModalError(`Daffodil Versions 4.0.0+ requires JDK >= 17`)
+ return undefined
+ }
+
+ // Download the daffodil CLI jars if needed
+ const daffodilPath = await checkIfDaffodilJarsNeeded(dfdlVersion)
+
const artifact = daffodilArtifact(dfdlVersion)
const scriptPath = path.join(
rootPath,
- `daffodil-debugger-${dfdlVersion}-${LIB_VERSION}`
- )
- // Locates the $JAVA_HOME, or if not defined, the highest version available.
- const javaHome: IJavaHomeInfo | undefined = await new Promise(
- (resolve, reject) => {
- _locateJavaHome({ version: '>=1.8' }, (error, javaHomes) => {
- console.log(`detected java homes: ${JSON.stringify(javaHomes)}`)
- javaHomes
- ? resolve(
- process.env.JAVA_HOME
- ? javaHomes.find(
- (home, idx, obj) => home.path == process.env.JAVA_HOME
- )
- : latestJdk(javaHomes)
- )
- : undefined
- })
- }
- )
- const isAtLeastJdk17: boolean = parseFloat(javaHome?.version ?? '0') >= 17
- console.log(
- `choosing java home at ${javaHome?.path}, version ${javaHome?.version}, is
at least JDK 17: ${isAtLeastJdk17}`
+ `daffodil-debugger-${scalaVersion}-${LIB_VERSION}`
)
+
// The backend's launch script honors $JAVA_HOME, but if not set it assumes
java is available on the path.
const env = javaHome
? {
@@ -108,12 +150,30 @@ export async function runDebugger(
scriptPath,
artifact.scriptName,
createTerminal,
- shellArgs(serverPort, isAtLeastJdk17),
+ shellArgs(serverPort, dfdlDebugger.timeout, daffodilPath, isAtLeastJdk17),
env,
'daffodil'
)
}
+export const getJavaHome = async (): Promise<IJavaHomeInfo | undefined> =>
+ await new Promise((resolve, reject) => {
+ _locateJavaHome({ version: '>=1.8' }, (error, javaHomes) => {
+ outputChannel.appendLine(
+ `[DEBUG] Detected java homes: ${JSON.stringify(javaHomes)}`
+ )
+ javaHomes
+ ? resolve(
+ process.env.JAVA_HOME
+ ? javaHomes.find(
+ (home, idx, obj) => home.path == process.env.JAVA_HOME
+ )
+ : latestJdk(javaHomes)
+ )
+ : undefined
+ })
+ })
+
function latestJdk(jdkHomes: IJavaHomeInfo[]): IJavaHomeInfo | undefined {
if (jdkHomes.length > 0) {
return jdkHomes.sort((a, b) => {
diff --git a/src/launchWizard/launchWizard.ts b/src/launchWizard/launchWizard.ts
index aa87ede..4ca6753 100644
--- a/src/launchWizard/launchWizard.ts
+++ b/src/launchWizard/launchWizard.ts
@@ -535,10 +535,10 @@ class LaunchWizard {
})
let dfdlDebugger: DFDLDebugger = defaultValues.dfdlDebugger
+
let debuggerLogLevelSelect = ''
let debuggerLogLevelTypes = getAllowedLogLevels()
let debuggerLogLevel = dfdlDebugger.logging.level
-
debuggerLogLevelTypes.forEach((type) => {
if (type === debuggerLogLevel) {
debuggerLogLevelSelect += `<option selected
value="${type}">${type}</option>`
@@ -646,6 +646,12 @@ class LaunchWizard {
<p class="setting-description">Port debug server running on.</p>
<input class="file-input" value="${defaultValues.debugServer}"
id="debugServer"/>
+ <p id="dfdlDaffodilVersionLabel" style="margin-top: 10px;"
class="setting-description">Version (Daffodil Version):</p>
+ <input class="file-input" value="${dfdlDebugger.daffodilVersion}"
id="dfdlDaffodilVersion">
+
+ <p id="dfdlDebuggerTimeoutLabel" style="margin-top: 10px;"
class="setting-description">Timeout (should end with s, m or h):</p>
+ <input class="file-input" value="${dfdlDebugger.timeout}"
id="dfdlDebuggerTimeout">
+
<p id="dfdlDebuggerLogFileLabel" style="margin-top: 10px;"
class="setting-description">Log File:</p>
<input class="file-input" value="${dfdlDebugger.logging.file}"
id="dfdlDebuggerLogFile">
diff --git a/src/launchWizard/script.js b/src/launchWizard/script.js
index 2704fde..c7356db 100644
--- a/src/launchWizard/script.js
+++ b/src/launchWizard/script.js
@@ -72,6 +72,12 @@ function getConfigValues() {
)
const dataEditorLogFile = document.getElementById('dataEditorLogFile').value
const dataEditorLogLevel =
document.getElementById('dataEditorLogLevel').value
+ const dfdlDaffodilVersion = document.getElementById(
+ 'dfdlDaffodilVersion'
+ ).value
+ const dfdlDebuggerTimeout = document.getElementById(
+ 'dfdlDebuggerTimeout'
+ ).value
const dfdlDebuggerLogFile = document.getElementById(
'dfdlDebuggerLogFile'
).value
@@ -109,6 +115,8 @@ function getConfigValues() {
dataEditorPort,
dataEditorLogFile,
dataEditorLogLevel,
+ dfdlDaffodilVersion,
+ dfdlDebuggerTimeout,
dfdlDebuggerLogFile,
dfdlDebuggerLogLevel,
daffodilDebugClasspath,
@@ -306,6 +314,8 @@ function save() {
},
},
dfdlDebugger: {
+ daffodilVersion: configValues.dfdlDaffodilVersion,
+ timeout: configValues.dfdlDebuggerTimeout,
logging: {
file: configValues.dfdlDebuggerLogFile,
level: configValues.dfdlDebuggerLogLevel,
@@ -380,6 +390,8 @@ function copyConfig() {
},
},
dfdlDebugger: {
+ daffodilVersion: configValues.dfdlDaffodilVersion,
+ timeout: configValues.dfdlDebuggerTimeout,
logging: {
file: configValues.dfdlDebuggerLogFile,
level: configValues.dfdlDebuggerLogLevel,
@@ -444,6 +456,10 @@ async function updateConfigValues(config) {
document.getElementById('dataEditorLogLevel').value =
config.dataEditor.logging.level
+ document.getElementById('dfdlDaffodilVersion').value =
+ config.dfdlDebugger.daffodilVersion
+ document.getElementById('dfdlDebuggerTimeout').value =
+ config.dfdlDebugger.timeout
document.getElementById('dfdlDebuggerLogFile').value =
config.dfdlDebugger.logging.file
document.getElementById('dfdlDebuggerLogLevel').value =
diff --git a/src/tests/suite/daffodil.test.ts b/src/tests/suite/daffodil.test.ts
index 09019cc..f485192 100644
--- a/src/tests/suite/daffodil.test.ts
+++ b/src/tests/suite/daffodil.test.ts
@@ -18,27 +18,13 @@
import * as vscode from 'vscode'
import * as assert from 'assert'
import * as daffodil from '../../daffodilDebugger'
-import * as fs from 'fs'
import * as path from 'path'
import { Artifact } from '../../classes/artifact'
import { LIB_VERSION } from '../../version'
-import { before, after } from 'mocha'
-import { PROJECT_ROOT, TDML_PATH, TEST_SCHEMA } from './common'
+import { TDML_PATH, TEST_SCHEMA } from './common'
import { osCheck } from '../../utils'
suite('Daffodfil', () => {
- const packageFile = path.join(PROJECT_ROOT, 'package-test.json')
-
- // Create test package.json before anything else happens
- before(() => {
- fs.writeFileSync(packageFile, JSON.stringify({ daffodilVersion: '0.0.0' }))
- })
-
- // Delete test package.json after all tests are done
- after(() => {
- fs.unlinkSync(packageFile)
- })
-
// suite to test all functions work properly
suite('interfaces', () => {
test('DaffodilData functions properly', () => {
@@ -166,72 +152,67 @@ suite('Daffodfil', () => {
})
})
- suite('getDaffodilVersion', () => {
- test('getDaffodilVersion returns same version as file', () => {
- var daffodilVersion = daffodil.getDaffodilVersion(packageFile)
- assert.strictEqual(daffodilVersion, '0.0.0')
- })
- })
-
- suite('non-debug specific commands', () => {
- const nonDebugSpecificCmds = [
- 'extension.dfdl-debug.debugEditorContents',
- 'extension.dfdl-debug.runEditorContents',
- 'extension.dfdl-debug.debugLastEditorContents',
- 'extension.dfdl-debug.executeTDML',
- ]
-
- // This breaks when the omega-edit tests run for some reason
- // test('Available by default', () => {
- // nonDebugSpecificCmds.forEach(async (cmd) => {
- // assert.strictEqual(
- // (await vscode.commands.getCommands()).includes(cmd),
- // true
- // )
- // })
- // })
-
- test('Not available when inDebugMode', () => {
- vscode.commands.executeCommand('setContext', 'inDebugMode', true)
-
- nonDebugSpecificCmds.forEach(async (cmd) => {
- assert.strictEqual(
- (await vscode.commands.getCommands()).includes(cmd),
- false
- )
- })
- })
- })
-
- suite('debug specific commands', () => {
- const debugSpecificCmds = [
- 'extension.dfdl-debug.toggleFormatting',
- 'infoset.display',
- 'infoset.diff',
- 'infoset.save',
- ]
-
- test('Not available by default', () => {
- debugSpecificCmds.forEach(async (cmd) => {
- assert.strictEqual(
- (await vscode.commands.getCommands()).includes(cmd),
- false
- )
- })
- })
-
- // This breaks when the omega-edit tests run for some reason
- // test('Available when inDebugMode', () => {
- // vscode.commands.executeCommand('setContext', 'inDebugMode', true)
-
- // debugSpecificCmds.forEach(async (cmd) => {
- // assert.strictEqual(
- // (await vscode.commands.getCommands()).includes(cmd),
- // true
- // )
- // })
- // })
- })
+ // This breaks when the omega-edit tests run for some reason
+ // suite('non-debug specific commands', () => {
+ // const nonDebugSpecificCmds = [
+ // 'extension.dfdl-debug.debugEditorContents',
+ // 'extension.dfdl-debug.runEditorContents',
+ // 'extension.dfdl-debug.debugLastEditorContents',
+ // 'extension.dfdl-debug.executeTDML',
+ // ]
+
+ // test('Available by default', () => {
+ // nonDebugSpecificCmds.forEach(async (cmd) => {
+ // assert.strictEqual(
+ // (await vscode.commands.getCommands()).includes(cmd),
+ // true
+ // )
+ // })
+ // })
+
+ // test('Not available when inDebugMode', () => {
+ // vscode.commands.executeCommand('setContext', 'inDebugMode', true)
+
+ // nonDebugSpecificCmds.forEach(async (cmd) => {
+ // assert.strictEqual(
+ // (await vscode.commands.getCommands()).includes(cmd),
+ // false
+ // )
+ // })
+ // })
+ // })
+
+ // This breaks when the omega-edit tests run for some reason
+ // suite('debug specific commands', () => {
+ // const debugSpecificCmds = [
+ // 'extension.dfdl-debug.toggleFormatting',
+ // 'infoset.display',
+ // 'infoset.diff',
+ // 'infoset.save',
+ // ]
+
+ // // This breaks when the omega-edit tests run for some reason
+ // test('Not available by default', () => {
+ // debugSpecificCmds.forEach(async (cmd) => {
+ // assert.strictEqual(
+ // (await vscode.commands.getCommands()).includes(cmd),
+ // false
+ // )
+ // })
+ // })
+
+ // // This breaks when the omega-edit tests run for some reason
+ // test('Available when inDebugMode', () => {
+ // vscode.commands.executeCommand('setContext', 'inDebugMode', true)
+
+ // debugSpecificCmds.forEach(async (cmd) => {
+ // assert.strictEqual(
+ // (await vscode.commands.getCommands()).includes(cmd),
+ // true
+ // )
+ // })
+ // })
+ // })
suite('getCommands', () => {
test('getSchemaName file exists', async () => {
diff --git a/src/tests/suite/daffodilDebugger.test.ts
b/src/tests/suite/daffodilDebugger.test.ts
index 26f6c5f..4969811 100644
--- a/src/tests/suite/daffodilDebugger.test.ts
+++ b/src/tests/suite/daffodilDebugger.test.ts
@@ -23,17 +23,27 @@ import * as os from 'os'
import { PROJECT_ROOT, PACKAGE_PATH, TEST_SCHEMA } from './common'
import { getConfig, killProcess } from '../../utils'
import { runDebugger, stopDebugging } from '../../daffodilDebugger'
-import { before, after } from 'mocha'
+import { before, after, Suite, Test } from 'mocha'
import { DFDLDebugger } from '../../classes/dfdlDebugger'
import { DataEditorConfig } from '../../classes/dataEditor'
+import { getJavaHome } from '../../daffodilDebugger'
+import { delay } from '../../utils'
+import { TDMLConfig } from 'classes/tdmlConfig'
-// Not using the debug adapter like adapter.test.ts as it will not fully
connect the debugger
-suite('Daffodil Debugger', () => {
+interface TestDebuggerConfig {
+ debugger: DFDLDebugger
+ port: number
+ infosetFormat: string
+}
+
+const debuggers: vscode.Terminal[] = []
+const dfdlDebuggerConfigs: Array<TestDebuggerConfig> = []
+
+suite('Daffodil Debugger', function (this: Suite) {
// debugger options
const DATA = path.join(PROJECT_ROOT, 'src/tests/data/test.txt')
const XML_INFOSET_PATH = path.join(PROJECT_ROOT, 'testinfoset.xml')
const JSON_INFOSET_PATH = path.join(PROJECT_ROOT, 'testinfoset.json')
- const debuggers: vscode.Terminal[] = []
const tdmlConf = {
action: 'none',
@@ -47,41 +57,44 @@ suite('Daffodil Debugger', () => {
},
}
- const dfdlDebuggers: Array<DFDLDebugger> = [
- {
- logging: {
- level: 'INFO',
- file: path.join(os.tmpdir(), 'yarn-test-daffodil-debugger-4711.log'),
- },
- },
- {
- logging: {
- level: 'INFO',
- file: path.join(os.tmpdir(), 'yarn-test-daffodil-debugger-4712.log'),
- },
- },
- ]
-
before(async () => {
- debuggers.push(
- await runDebugger(
+ await getDebuggerConfigs()
+
+ /**
+ * When testing locally running all debuggers before running the tests
caused the tests to complete
+ * 1 second faster and the whole "yarn test" process completed 1 second
faster than when running a
+ * single debugger instance right before the debugging was started. So
currently sticking with this
+ * but if wanting to shift to running the instance right before starting
the debug process it is not
+ * too dramatic of performance decrease and time increase.
+ */
+ for (var i = 0; i < dfdlDebuggerConfigs.length; i++) {
+ let newDebugger = await runDebugger(
PROJECT_ROOT,
[],
PACKAGE_PATH,
- 4711,
- dfdlDebuggers[0],
+ dfdlDebuggerConfigs[i].port,
+ dfdlDebuggerConfigs[i].debugger,
true
)
+
+ newDebugger ? debuggers.push(newDebugger) : true
+ }
+
+ await addDebuggerRunningTests(
+ this,
+ dfdlDebuggerConfigs,
+ XML_INFOSET_PATH,
+ JSON_INFOSET_PATH,
+ DATA,
+ tdmlConf,
+ dataEditor
)
- debuggers.push(
- await runDebugger(
- PROJECT_ROOT,
- [],
- PACKAGE_PATH,
- 4712,
- dfdlDebuggers[1],
- true
- )
+ })
+
+ test('debugger config size is correct', async () => {
+ assert.strictEqual(
+ (await getDaffodilVersionsToTest()).length * 2,
+ dfdlDebuggerConfigs.length
)
})
@@ -91,66 +104,141 @@ suite('Daffodil Debugger', () => {
const pid = await d.processId
await killProcess(pid)
}
+
// No need to deleted the debugging server because upon re-run, webpack
cleans and re-extracts it.
- if (fs.existsSync(XML_INFOSET_PATH)) fs.rmSync(XML_INFOSET_PATH)
- if (fs.existsSync(JSON_INFOSET_PATH)) fs.rmSync(JSON_INFOSET_PATH)
+ ;(await getDaffodilVersionsToTest()).forEach((version) => {
+ const xmlPath = XML_INFOSET_PATH.replace('.xml', `${version}.xml`)
+ const jsonPath = JSON_INFOSET_PATH.replace('.json', `${version}.json`)
+ if (fs.existsSync(xmlPath)) fs.rmSync(xmlPath)
+ if (fs.existsSync(jsonPath)) fs.rmSync(jsonPath)
+ })
})
+})
- test('should output xml infoset', async () => {
- await vscode.debug.startDebugging(
- undefined,
- getConfig({
- name: 'Run',
- request: 'launch',
- type: 'dfdl',
- schema: {
- path: TEST_SCHEMA,
- },
- data: DATA,
- debugServer: 4711,
- infosetFormat: 'xml',
- infosetOutput: {
- type: 'file',
- path: XML_INFOSET_PATH,
- },
- tdmlConfig: tdmlConf,
- dataEditor: dataEditor,
- dfdlDebugger: dfdlDebuggers[0],
- }),
- {
- noDebug: true,
- }
- )
+// Gets all debugger version to test based on if JDK is >= 17
+async function getDaffodilVersionsToTest(): Promise<Array<string>> {
+ const javaHome = await getJavaHome()
+ const isAtLeastJdk17: boolean = parseFloat(javaHome?.version ?? '0') >= 17
- assert.strictEqual(fs.existsSync(XML_INFOSET_PATH), true)
- })
+ const dfdlVersions = ['3.10.0', '3.11.0']
+ if (isAtLeastJdk17) dfdlVersions.push('4.0.0')
+ return dfdlVersions
+}
+
+/**
+ * Populates the array of debugger configs with all debugger configs. If JDK
>= 17 there
+ * should be 6 and if JDK < 17 there should be 4. Each version of the debugger
has two
+ * configs, one for XML and one for JSON.
+ */
+async function getDebuggerConfigs() {
+ const debuggerVersionsToTest = await getDaffodilVersionsToTest()
+ let versionIndex = 0
- test('should output json infoset', async () => {
- await vscode.debug.startDebugging(
- undefined,
- getConfig({
- name: 'Run',
- request: 'launch',
- type: 'dfdl',
- schema: {
- path: TEST_SCHEMA,
- },
- data: DATA,
- debugServer: 4712,
- infosetFormat: 'json',
- infosetOutput: {
- type: 'file',
- path: JSON_INFOSET_PATH,
- },
- tdmlConfig: tdmlConf,
- dataEditor: dataEditor,
- dfdlDebugger: dfdlDebuggers[1],
- }),
- {
- noDebug: true,
- }
+ for (var i = 0; i < debuggerVersionsToTest.length * 2; i++) {
+ if (i > 0 && i % 2 == 0) versionIndex++
+
+ const port = 4711 + i
+ const infosetFormat = i % 2 == 0 ? 'xml' : 'json'
+ const dfdlDebugger: DFDLDebugger = {
+ daffodilVersion: debuggerVersionsToTest[versionIndex],
+ timeout: '4m',
+ logging: {
+ level: 'INFO',
+ file: path.join(os.tmpdir(),
`yarn-test-daffodil-debugger-${port}.log`),
+ },
+ }
+
+ dfdlDebuggerConfigs.push({
+ debugger: dfdlDebugger,
+ port: port,
+ infosetFormat: infosetFormat,
+ })
+ }
+}
+
+// This method is for starting the debug and making sure the infoset file was
created
+async function checkDebug(
+ data: string,
+ port: number,
+ infosetFormat: string,
+ infosetPath: string,
+ tdmlConfig: TDMLConfig,
+ dataEditor: DataEditorConfig,
+ dfdlDebugger: DFDLDebugger
+) {
+ await vscode.debug.startDebugging(
+ undefined,
+ getConfig({
+ name: 'Run',
+ request: 'launch',
+ type: 'dfdl',
+ schema: {
+ path: TEST_SCHEMA,
+ },
+ data: data,
+ debugServer: port,
+ infosetFormat: infosetFormat,
+ infosetOutput: {
+ type: 'file',
+ path: infosetPath,
+ },
+ tdmlConfig: tdmlConfig,
+ dataEditor: dataEditor,
+ dfdlDebugger: dfdlDebugger,
+ stopOnEntry: false,
+ }),
+ {
+ noDebug: true,
+ }
+ )
+
+ await delay(1000)
+
+ assert.strictEqual(fs.existsSync(infosetPath), true)
+}
+
+/**
+ * This function adds a number of tests to the suite for connecting to the
debuggers.
+ * Since we have 3 different versions of the debugger, each needs to be
connected to
+ * twice. Once for outputting XML and one for outputting JSON. Not sure if
this is
+ * a common way to add tests to a test suite but it seemed better and more
efficient
+ * than making a single separate test for each combination of the debugger
plus infoset
+ * format. Especially since two of the combinations can only be ran if the JDK
version
+ * being used is >= 17.
+ */
+async function addDebuggerRunningTests(
+ suite: Suite,
+ dfdlDebuggerConfigs: Array<TestDebuggerConfig>,
+ xmlInfosetPath: string,
+ jsonInfosetPath: string,
+ data: string,
+ tdmlConfig: TDMLConfig,
+ dataEditor: DataEditorConfig
+) {
+ for (var i = 0; i < dfdlDebuggerConfigs.length; i++) {
+ const debuggerConfig = dfdlDebuggerConfigs[i]
+ const baseInfosetPath =
+ debuggerConfig.infosetFormat == 'xml' ? xmlInfosetPath : jsonInfosetPath
+ const infosetPath = baseInfosetPath.replace(
+ `.${debuggerConfig.infosetFormat}`,
+
`${debuggerConfig.debugger.daffodilVersion}.${debuggerConfig.infosetFormat}`
)
- assert.strictEqual(fs.existsSync(JSON_INFOSET_PATH), true)
- })
-})
+ suite.addTest(
+ new Test(
+ `should output ${debuggerConfig.infosetFormat} infoset - debugger
version ${debuggerConfig.debugger.daffodilVersion}`,
+ async function () {
+ await checkDebug(
+ data,
+ debuggerConfig.port,
+ debuggerConfig.infosetFormat,
+ infosetPath,
+ tdmlConfig,
+ dataEditor,
+ debuggerConfig.debugger
+ )
+ }
+ )
+ )
+ }
+}
diff --git a/src/tests/suite/utils.test.ts b/src/tests/suite/utils.test.ts
index 291d3c6..9649161 100644
--- a/src/tests/suite/utils.test.ts
+++ b/src/tests/suite/utils.test.ts
@@ -60,6 +60,8 @@ suite('Utils Test Suite', () => {
},
},
dfdlDebugger: {
+ daffodilVersion: '3.11.0',
+ timeout: '10s',
logging: {
level: 'INFO',
file: '${workspaceFolder}/daffodil-debugger.log',
diff --git a/src/utils.ts b/src/utils.ts
index 735d58a..9a3aee8 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -23,7 +23,9 @@ import path from 'path'
import { VSCodeLaunchConfigArgs } from './classes/vscode-launch'
import { InfosetOutput } from './daffodilDebugger'
import { XMLParser } from 'fast-xml-parser'
-
+import * as unzip from 'unzip-stream'
+import { pipeline } from 'stream/promises'
+import { Transform } from 'stream'
let currentConfig: vscode.DebugConfiguration
export const terminalName = 'daffodil-debugger'
@@ -114,6 +116,37 @@ function checkInfosetFileExtension(
}
}
+function checkSettingValue<T>(target: unknown, defaults: T): T {
+ if (
+ typeof defaults !== 'object' ||
+ defaults === null ||
+ Array.isArray(defaults)
+ ) {
+ return target === undefined ? defaults : (target as T)
+ }
+
+ if (typeof target !== 'object' || target === null) {
+ return defaults
+ }
+
+ const result: Record<string, any> = {}
+
+ for (const key of Object.keys(defaults)) {
+ result[key] = checkSettingValue(
+ (target as any)[key],
+ (defaults as any)[key]
+ )
+ }
+
+ for (const key of Object.keys(target as any)) {
+ if (!(key in result)) {
+ result[key] = (target as any)[key]
+ }
+ }
+
+ return result as T
+}
+
export function getConfig(jsonArgs: object): vscode.DebugConfiguration {
const launchConfigArgs: VSCodeLaunchConfigArgs = JSON.parse(
JSON.stringify(jsonArgs)
@@ -157,6 +190,8 @@ export function getConfig(jsonArgs: object):
vscode.DebugConfiguration {
},
}),
dfdlDebugger: defaultConf.get('dfdlDebugger', {
+ daffodilVersion: '3.11.0',
+ timeout: '10s',
logging: {
level: 'INFO',
file: '${workspaceFolder}/daffodil-debugger.log',
@@ -164,13 +199,9 @@ export function getConfig(jsonArgs: object):
vscode.DebugConfiguration {
}),
}
- Object.entries(defaultValues).map(
- ([key, defaultValue]) =>
- (launchConfigArgs[key] =
- launchConfigArgs[key] !== undefined
- ? launchConfigArgs[key]
- : defaultValue)
- )
+ for (const [key, defaults] of Object.entries(defaultValues)) {
+ launchConfigArgs[key] = checkSettingValue(launchConfigArgs[key], defaults)
+ }
if (launchConfigArgs.infosetOutput?.type == 'file') {
checkInfosetFileExtension(
@@ -277,7 +308,7 @@ export async function runScript(
type: string = '',
hideTerminal: boolean = false,
port: number | undefined = undefined
-) {
+): Promise<vscode.Terminal> {
// Get the full path to the script
const scriptFullPath = path.join(scriptPath, 'bin', scriptName)
@@ -316,6 +347,7 @@ export async function runScript(
const wait_port = require('wait-port')
await wait_port({ host: '127.0.0.1', port: port, output: 'silent' })
}
+
return terminal
}
@@ -444,3 +476,87 @@ export function getTDMLTestCaseItems(path: string):
string[] {
: []
return testCaseArr.map((item) => item['@_name'])
}
+
+/**
+ * Displays a VSCode error message as modal. In some cases such as when
running tests, using modal
+ * can cause an error because the dialog service is not available. If this
happens when trying
+ * to display the message, this error is grabbed and then message is displayed
with modal disabled.
+ *
+ * @param message - The message to display
+ * @param items — A set of items that will be rendered as actions in the
message.
+ * @returns — A thenable that resolves to the selected item or undefined when
being dismissed.
+ */
+export const displayModalError = async (
+ message: string,
+ ...items: string[]
+): Promise<Thenable<string | undefined>> =>
+ vscode.window
+ .showErrorMessage(message, { modal: true }, ...items)
+ .then(undefined, () =>
+ vscode.window.showErrorMessage(message, { modal: false })
+ )
+
+/**
+ * Download and extract a files with a progress bar
+ *
+ * @param title A title to use for printing to the user what is being
downloaded
+ * @param url The url to donwload the binary from
+ * @param targetDir The directory to target for extraction
+ */
+export async function downloadAndExtract(
+ title: string,
+ url: string,
+ targetDir: string
+): Promise<void> {
+ await vscode.window.withProgress(
+ {
+ location: vscode.ProgressLocation.Notification,
+ title: `Downloading ${title}...`,
+ cancellable: false,
+ },
+ async (progress) => {
+ progress.report({ increment: 0, message: 'Starting download...' })
+
+ const res = await fetch(url)
+ if (!res.ok || !res.body) {
+ throw new Error(
+ `Failed to download ${url}: ${res.status} ${res.statusText}`
+ )
+ }
+
+ const totalBytes = Number(res.headers.get('content-length')) || 0
+ let downloaded = 0
+ let lastPercent = 0
+
+ // Transform stream to track download progress
+ const progressStream = new Transform({
+ transform(chunk: Buffer, _encoding, callback) {
+ downloaded += chunk.length
+ if (totalBytes > 0) {
+ const percent = (downloaded / totalBytes) * 100
+ const increment = percent - lastPercent
+ lastPercent = percent
+ progress.report({
+ increment,
+ message: `${percent.toFixed(1)}%`,
+ })
+ }
+ callback(null, chunk)
+ },
+ })
+
+ await fs.promises.mkdir(targetDir, { recursive: true })
+
+ await pipeline(
+ res.body as any,
+ progressStream,
+ unzip.Extract({ path: targetDir })
+ )
+
+ progress.report({
+ increment: 100 - lastPercent,
+ message: 'Extracting complete!',
+ })
+ }
+ )
+}
diff --git a/vite/dev.vite.config.mjs b/vite/dev.vite.config.mjs
index 944c156..0ca10ef 100644
--- a/vite/dev.vite.config.mjs
+++ b/vite/dev.vite.config.mjs
@@ -43,34 +43,43 @@ const packageData = jsoncParse(
fs.readFileSync(path.resolve('package.json'), 'utf8')
)
const pkg_version = packageData['version']
-const daffodilVersion = packageData['daffodilVersion']
-const serverPackage = `daffodil-debugger-${daffodilVersion}-${pkg_version}`
-const zipFilePath = path.resolve(
- `debugger/target/universal/${serverPackage}.zip`
-)
+const scalaVersions = ['2.12', '2.13', '3']
function unzipAfterBuild() {
return {
name: 'unzip-server-package',
apply: 'build',
async closeBundle() {
- const serverPackageFolder = path.join(
- path.resolve('dist/package'),
- serverPackage
- )
-
- // remove debugger package folder if exists
- if (fs.existsSync(serverPackageFolder)) {
- fs.rmSync(serverPackageFolder, { recursive: true, force: true })
- }
-
- await new Promise((resolve, reject) => {
- const stream = fs
- .createReadStream(zipFilePath)
- // @ts-ignore types for unzip-stream
- .pipe(unzip.Extract({ path: '.' }))
- stream.on('close', () => resolve())
- stream.on('error', (err) => reject(err))
+ scalaVersions.forEach(async (scalaVersion) => {
+ const serverPackage =
`daffodil-debugger-${scalaVersion}-${pkg_version}`
+ const jvmFolderName = `jvm-${scalaVersion}`
+ const zipFilePath = path.resolve(
+ `debugger/target/${jvmFolderName}/universal/${serverPackage}.zip`
+ )
+
+ const serverPackageFolder = path.join(
+ path.resolve('dist/package'),
+ serverPackage
+ )
+
+ // remove debugger package folder if exists
+ if (fs.existsSync(serverPackageFolder)) {
+ fs.rmSync(serverPackageFolder, { recursive: true, force: true })
+ }
+
+ // if the debugger package doesn't exist continue
+ if (!fs.existsSync(zipFilePath)) {
+ return
+ }
+
+ await new Promise((resolve, reject) => {
+ const stream = fs
+ .createReadStream(zipFilePath)
+ // @ts-ignore types for unzip-stream
+ .pipe(unzip.Extract({ path: '.' }))
+ stream.on('close', () => resolve())
+ stream.on('error', (err) => reject(err))
+ })
})
},
}
diff --git a/vite/package.vite.config.mjs b/vite/package.vite.config.mjs
index 497ca04..0e5c650 100644
--- a/vite/package.vite.config.mjs
+++ b/vite/package.vite.config.mjs
@@ -43,34 +43,43 @@ const packageData = jsoncParse(
fs.readFileSync(path.resolve('package.json'), 'utf8')
)
const pkg_version = packageData['version']
-const daffodilVersion = packageData['daffodilVersion']
-const serverPackage = `daffodil-debugger-${daffodilVersion}-${pkg_version}`
-const zipFilePath = path.resolve(
- `debugger/target/universal/${serverPackage}.zip`
-)
+const scalaVersions = ['2.12', '2.13', '3']
function unzipAfterBuild() {
return {
name: 'unzip-server-package',
apply: 'build',
async closeBundle() {
- const serverPackageFolder = path.join(
- path.resolve('dist/package'),
- serverPackage
- )
-
- // remove debugger package folder if exists
- if (fs.existsSync(serverPackageFolder)) {
- fs.rmSync(serverPackageFolder, { recursive: true, force: true })
- }
-
- await new Promise((resolve, reject) => {
- const stream = fs
- .createReadStream(zipFilePath)
- // @ts-ignore types for unzip-stream
- .pipe(unzip.Extract({ path: 'dist/package' }))
- stream.on('close', () => resolve())
- stream.on('error', (err) => reject(err))
+ scalaVersions.forEach(async (scalaVersion) => {
+ const serverPackage =
`daffodil-debugger-${scalaVersion}-${pkg_version}`
+ const jvmFolderName = `jvm-${scalaVersion}`
+ const zipFilePath = path.resolve(
+ `debugger/target/${jvmFolderName}/universal/${serverPackage}.zip`
+ )
+
+ const serverPackageFolder = path.join(
+ path.resolve('dist/package'),
+ serverPackage
+ )
+
+ // remove debugger package folder if exists
+ if (fs.existsSync(serverPackageFolder)) {
+ fs.rmSync(serverPackageFolder, { recursive: true, force: true })
+ }
+
+ // if the debugger package doesn't exist continue
+ if (!fs.existsSync(zipFilePath)) {
+ return
+ }
+
+ await new Promise((resolve, reject) => {
+ const stream = fs
+ .createReadStream(zipFilePath)
+ // @ts-ignore types for unzip-stream
+ .pipe(unzip.Extract({ path: 'dist/package' }))
+ stream.on('close', () => resolve())
+ stream.on('error', (err) => reject(err))
+ })
})
},
}
@@ -109,23 +118,34 @@ function copyToPkgDirPlugin() {
{ from: 'src/styles/styles.css', to: `${pkg_dir}/src/styles/styles.css` },
{ from: 'src/tdmlEditor/', to: `${pkg_dir}/src/tdmlEditor` },
]
- const serverPackageFolder = path.join(
- path.resolve('dist/package'),
- serverPackage
- )
-
- console.debug(`== [Vite] | serverPackageFolder: ${serverPackageFolder}`)
- // remove debugger package folder if exists
- if (fs.existsSync(serverPackageFolder)) {
- fs.rmSync(serverPackageFolder, { recursive: true })
- }
+
+ const serverPackageFolders = []
+
+ scalaVersions.forEach((scalaVersion) => {
+ serverPackageFolders.push(
+ path.join(
+ path.resolve('dist/package'),
+ `daffodil-debugger-${scalaVersion}-${pkg_version}`
+ )
+ )
+ })
+
+ serverPackageFolders.forEach((serverPackageFolder) => {
+ console.debug(`== [Vite] | serverPackageFolder: ${serverPackageFolder}`)
+ // remove debugger package folder if exists
+ if (fs.existsSync(serverPackageFolder)) {
+ fs.rmSync(serverPackageFolder, { recursive: true })
+ }
+ })
return {
name: 'copy-patterns-plugin',
apply: 'build',
async buildStart(opts) {
if (!fs.existsSync(pkg_dir)) {
- fs.mkdirSync(serverPackageFolder, { recursive: true })
+ serverPackageFolders.forEach((serverPackageFolder) => {
+ fs.mkdirSync(serverPackageFolder, { recursive: true })
+ })
fs.mkdirSync(pkg_dir + '/dist')
fs.mkdirSync(pkg_dir + '/src/language', {
recursive: true,