Skip to content

Commit

Permalink
Fix broken TDML append, copy and execute functionality
Browse files Browse the repository at this point in the history
Fixed review comments

format check

Fixed test

lint updates
  • Loading branch information
hdalsania authored and rthomas320 committed May 30, 2024
1 parent 5bd426e commit 418c91f
Show file tree
Hide file tree
Showing 7 changed files with 377 additions and 78 deletions.
10 changes: 9 additions & 1 deletion debugger/src/main/scala/org.apache.daffodil.tdml/TDML.scala
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ object TDML {
.relativize(new File(path.toString()).toURI())
.getPath()
.toString()
.trim()
}

// Generate a new TDML file.
Expand Down Expand Up @@ -253,7 +254,13 @@ object TDML {
// Returns a tuple containing the following (Path to DFDL Schema, Path to Data File)
// All paths returned could be either relative or absolute - it depends on what exists in the TDML file
def execute(tdmlName: String, tdmlDescription: String, tdmlPath: String): Option[(Path, Path)] = {
val basePath = Paths.get(tdmlPath).toAbsolutePath().getParent()

// Correct basepath for Windows OS
var basePath = ""
if (System.getProperty("os.name").toLowerCase.startsWith("win") == true)
(
basePath = Paths.get(tdmlPath).toAbsolutePath().getParent().toString()
)

val testCaseList = JAXBContext
.newInstance(classOf[TestSuite])
Expand All @@ -278,6 +285,7 @@ object TDML {
.asInstanceOf[JAXBElement[DocumentPartType]]
.getValue()
.getValue()
.trim()
)
.normalize()
(schemaPath, dataPath)
Expand Down
12 changes: 10 additions & 2 deletions debugger/src/test/scala/org.apache.daffodil.tdml/TDMLSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,18 @@ class TDMLSuite extends munit.FunSuite {
}

test("Test Execute") {

var schemaPathExecute = Paths.get("/debugger/src/test/data/emptySchema.xml")
var dataPathExecute = Paths.get("/debugger/src/test/data/emptyData.xml")

if (System.getProperty("os.name").toLowerCase.startsWith("win") == true) {
schemaPathExecute = schemaPath
dataPathExecute = dataPath
}
TDML.generate(infosetPath, schemaPath, dataPath, tdmlName, tdmlDescription, tdmlPath.toString())
val executePaths = TDML.execute(tdmlName, tdmlDescription, tdmlPath.toString())
val executePaths = TDML.execute(tdmlName, tdmlDescription, tdmlPath.toAbsolutePath().toString())

assertEquals(executePaths, Option[(Path, Path)]((schemaPath.normalize(), dataPath.normalize())))
assertEquals(executePaths, Option[(Path, Path)]((schemaPathExecute.normalize(), dataPathExecute.normalize())))
}

test("Test convertToRelativePath") {
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
"onCommand:extension.dfdl-debug.getTDMLDescription",
"onCommand:extension.dfdl-debug.getTDMLPath",
"onCommand:extension.dfdl-debug.getValidatedTDMLPath",
"onCommand:extension.dfdl-debug.getValidatedTDMLCopyPath",
"onCommand:launch.config",
"onCommand:extension.data.edit",
"onCommand:extension.dfdl-debug.debugLastEditorContents"
Expand Down Expand Up @@ -749,7 +750,11 @@
"variables": {
"AskForSchemaName": "extension.dfdl-debug.getSchemaName",
"AskForDataName": "extension.dfdl-debug.getDataName",
"AskForValidatedTDMLPath": "extension.dfdl-debug.getValidatedTDMLPath"
"AskForTDMLName": "extension.dfdl-debug.getTDMLName",
"AskForTDMLDescription": "extension.dfdl-debug.getTDMLDescription",
"AskForTDMLPath": "extension.dfdl-debug.getTDMLPath",
"AskForValidatedTDMLPath": "extension.dfdl-debug.getValidatedTDMLPath",
"AskForValidatedTDMLCopyPath": "extension.dfdl-debug.getValidatedTDMLCopyPath"
}
}
],
Expand Down
175 changes: 156 additions & 19 deletions src/adapter/activateDaffodilDebug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import * as dfdlExt from '../language/semantics/dfdlExt'
import {
appendTestCase,
getTmpTDMLFilePath,
readTDMLFileContents,
copyTestCase,
} from '../tdmlEditor/utilities/tdmlXmlUtils'
import xmlFormat from 'xml-formatter'

Expand Down Expand Up @@ -85,6 +85,46 @@ async function getFile(fileRequested, label, title) {
return file
}

/** Method to show dialog to save TDML file
* Details:
* Required so that the vscode api commands:
* - extension.dfdl-debug.getValidatedTDMLCopyPath
* can be sent a file instead of always opening up a prompt.
*/
async function showTDMLSaveDialog(fileRequested, label, title) {
let file = ''

file = await vscode.window
.showSaveDialog({
saveLabel: label,
title: title,
filters: {
TDML: ['tdml'],
},
})
.then((fileUri) => {
if (fileUri) {
let path = fileUri.fsPath

if (
process.platform === 'win32' &&
path.length > 2 &&
path.charCodeAt(0) > 97 &&
path.charCodeAt(0) <= 122 &&
path.charAt(1) === ':'
) {
path = path.charAt(0).toUpperCase() + path.slice(1)
}

return path
}

return ''
})

return file
}

// Function for setting up the commands for Run and Debug file
function createDebugRunFileConfigs(
resource: vscode.Uri,
Expand Down Expand Up @@ -115,6 +155,12 @@ function createDebugRunFileConfigs(

if (tdmlAction) {
tdmlConfig.action = tdmlAction

if (tdmlAction === 'execute') {
tdmlConfig.name = '${command:AskForTDMLName}'
tdmlConfig.description = '${command:AskForTDMLDescription}'
tdmlConfig.path = targetResource.fsPath
}
}

vscode.debug.startDebugging(
Expand All @@ -124,11 +170,12 @@ function createDebugRunFileConfigs(
request: 'launch',
type: 'dfdl',
schema: {
path: targetResource.fsPath,
path: tdmlConfig.action === 'execute' ? '' : targetResource.fsPath,
rootName: null,
rootNamespace: null,
},
data: '${command:AskForDataName}',
data:
tdmlConfig.action === 'execute' ? '' : '${command:AskForDataName}',
debugServer: false,
infosetFormat: 'xml',
infosetOutput: {
Expand Down Expand Up @@ -189,10 +236,7 @@ export function activateDaffodilDebug(
targetResource = vscode.window.activeTextEditor.document.uri
}
if (targetResource) {
appendTestCase(
await readTDMLFileContents(getTmpTDMLFilePath()),
await readTDMLFileContents(targetResource.fsPath)
)
appendTestCase(getTmpTDMLFilePath(), targetResource.fsPath)
.then((appendedBuffer) => {
fs.writeFileSync(targetResource.fsPath, xmlFormat(appendedBuffer))
})
Expand All @@ -209,19 +253,43 @@ export function activateDaffodilDebug(
createDebugRunFileConfigs(resource, 'run', 'execute')
}
),
vscode.commands.registerCommand('extension.dfdl-debug.copyTDML', (_) => {
// Ask for destination path
// Copy file in /tmp to destination path
// TDMLConfig.path should not be used here because that only matters when sending to the server
// We could make it so that if someone wants to specify the path and set the action to 'copy', but
// that doesn't make a whole lot of sense.
let targetResource = vscode.commands.executeCommand(
'extension.dfdl-debug.getTDMLPath'
)
vscode.commands.registerCommand(
'extension.dfdl-debug.copyTDML',
async (_) => {
// Ask for destination path
// Copy file in /tmp to destination path
// TDMLConfig.path should not be used here because that only matters when sending to the server
// We could make it so that if someone wants to specify the path and set the action to 'copy', but
// that doesn't make a whole lot of sense.
let targetResource = await vscode.commands.executeCommand(
'extension.dfdl-debug.getValidatedTDMLCopyPath'
)

// Is there a better way of error checking this?
fs.copyFileSync(getTmpTDMLFilePath(), targetResource as unknown as string)
}),
// Is there a better way of error checking this?
if (targetResource) {
copyTestCase(
getTmpTDMLFilePath(),
targetResource as unknown as string
)
.then((copiedBuffer) => {
fs.writeFileSync(
targetResource as unknown as string,
xmlFormat(copiedBuffer)
)
})
.catch((reason) => {
// Not sure if we need to do something different/more here
console.log(reason)
})
}

// fs.copyFile(
// getTmpTDMLFilePath(),
// targetResource as unknown as string,
// (_) => {}
// )
}
),
vscode.commands.registerCommand(
'extension.dfdl-debug.toggleFormatting',
(_) => {
Expand Down Expand Up @@ -272,6 +340,74 @@ export function activateDaffodilDebug(
)
)

context.subscriptions.push(
vscode.commands.registerCommand(
'extension.dfdl-debug.getValidatedTDMLCopyPath',
async (fileRequested = null) => {
// Open native file explorer to allow user to select data file from anywhere on their machine
if (fileRequested && fs.existsSync(fileRequested)) {
return fileRequested
} else if (fileRequested && !fs.existsSync(fileRequested)) {
return ''
} else {
return await showTDMLSaveDialog(
fileRequested,
'Save TDML File',
'Save TDML File'
)
}
}
)
)

context.subscriptions.push(
vscode.commands.registerCommand(
'extension.dfdl-debug.getTDMLName',
async (_) => {
return await vscode.window
.showInputBox({
prompt: 'Test Case Name: ',
value: 'Default Test Case',
})
.then((value) => {
return value
})
}
)
)

context.subscriptions.push(
vscode.commands.registerCommand(
'extension.dfdl-debug.getTDMLDescription',
async (_) => {
return await vscode.window
.showInputBox({
prompt: 'Test Case Description: ',
value: 'Generated by DFDL VSCode Extension',
})
.then((value) => {
return value
})
}
)
)

context.subscriptions.push(
vscode.commands.registerCommand(
'extension.dfdl-debug.getTDMLPath',
async (_) => {
return await vscode.window
.showInputBox({
prompt: 'TDML File: ',
value: '${workspaceFolder}/infoset.tdml',
})
.then((value) => {
return value
})
}
)
)

// register a configuration provider for 'dfdl' debug type
const provider = new DaffodilConfigurationProvider(context)
context.subscriptions.push(
Expand Down Expand Up @@ -462,6 +598,7 @@ class DaffodilConfigurationProvider
!dataFolder.includes('${command:AskForSchemaName}') &&
!dataFolder.includes('${command:AskForDataName}') &&
!dataFolder.includes('${workspaceFolder}') &&
config.tdmlConfig.action !== 'execute' &&
vscode.workspace.workspaceFolders &&
dataFolder !== vscode.workspace.workspaceFolders[0].uri.fsPath &&
dataFolder.split('.').length === 1 &&
Expand Down
41 changes: 31 additions & 10 deletions src/daffodilDebugger/debugger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { runDebugger, stopDebugger, stopDebugging } from './utils'
import {
getDefaultTDMLTestCaseDescription,
getDefaultTDMLTestCaseName,
getTmpTDMLFilePath,
} from '../tdmlEditor/utilities/tdmlXmlUtils'

// Function to get data file given a folder
Expand Down Expand Up @@ -57,22 +58,42 @@ async function getTDMLConfig(
// Might need to add `schema` here if we move the `Execute TDML` command
// away from the detected dfdl language in VSCode.
config.data = ''
config.schema.path = ''

if (config?.tdmlConfig?.path === undefined)
config.tdmlConfig.path = await vscode.commands.executeCommand(
'extension.dfdl-debug.getValidatedTDMLPath'
)
}

if (
config?.tdmlConfig?.action === 'generate' ||
config?.tdmlConfig?.action === 'execute'
) {
if (config?.tdmlConfig?.name === undefined)
config.tdmlConfig.name = getDefaultTDMLTestCaseName()
config.tdmlConfig.name = await vscode.commands.executeCommand(
'extension.dfdl-debug.getTDMLName'
)

if (config?.tdmlConfig?.description === undefined)
config.tdmlConfig.description = await vscode.commands.executeCommand(
'extension.dfdl-debug.getTDMLDescription'
)
}

if (config?.tdmlConfig?.action === 'generate') {
if (
config?.tdmlConfig?.name === undefined ||
config?.tdmlConfig?.name === 'undefined'
)
config.tdmlConfig.name = getDefaultTDMLTestCaseName()

if (
config?.tdmlConfig?.description === undefined ||
config?.tdmlConfig?.description === 'undefined'
)
config.tdmlConfig.description = getDefaultTDMLTestCaseDescription()

if (
config?.tdmlConfig?.path === undefined ||
config?.tdmlConfig?.path === 'undefined'
)
config.tdmlConfig.path = getTmpTDMLFilePath()
}

if (config?.tdmlConfig?.action !== 'execute' && config.data === '') {
Expand Down Expand Up @@ -133,6 +154,10 @@ export async function getDebugger(
if (vscode.workspace.workspaceFolders !== undefined) {
await stopDebugger()

if (!(await getTDMLConfig(config))) {
return await stopDebugging().then((_) => undefined)
}

// Get schema file before debugger starts to avoid timeout
if (config.schema.path.includes('${command:AskForSchemaName}')) {
config.schema.path = await vscode.commands.executeCommand(
Expand All @@ -147,10 +172,6 @@ export async function getDebugger(
)
}

if (!(await getTDMLConfig(config))) {
return await stopDebugging().then((_) => undefined)
}

let workspaceFolder = vscode.workspace.workspaceFolders[0].uri.fsPath

// Get daffodilDebugger class paths to be added to the debugger
Expand Down
Loading

0 comments on commit 418c91f

Please sign in to comment.