Fix foundry overwrite option
Resolves #14
Change-Id: Iaaeaf499ec3dad1b8c5b33a28ff60e8703217486
diff --git a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt
index 646980c..9a789a7 100644
--- a/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt
+++ b/app/src/main/kotlin/de/ids_mannheim/korapxmltools/KorapXmlTool.kt
@@ -1227,7 +1227,7 @@
if (annotateWith.isNotEmpty()) {
// Detect external foundry label once from annotateWith command
- externalFoundry = detectFoundryFromAnnotateCmd(annotateWith)
+ externalFoundry = foundryOverride ?: detectFoundryFromAnnotateCmd(annotateWith)
// Initialize ZIP output stream BEFORE creating worker pool, if needed
if (outputFormat == OutputFormat.KORAP_XML) {
// Determine output filename - respect outputDir consistently
@@ -1943,15 +1943,17 @@
dbFactory = DocumentBuilderFactory.newInstance()
dBuilder = dbFactory!!.newDocumentBuilder()
- // Respect outputDir option consistently
+ // Determine output filename - respect outputDir consistently
val baseZipName = File(zipFilePath).name.replace(Regex("\\.zip$"), "")
- val outputMorphoZipFileName = File(outputDir, "$baseZipName.$targetFoundry.zip").absolutePath
- targetZipFileName = outputMorphoZipFileName
- LOGGER.info("Output ZIP file: $outputMorphoZipFileName")
+ val autoOutputFileName = File(outputDir, "$baseZipName.$targetFoundry.zip").absolutePath
+ val finalOutputFileName = outputFile ?: autoOutputFileName
+ targetZipFileName = finalOutputFileName
+ val outputMorphoZipFileName = finalOutputFileName
+ LOGGER.info("Output ZIP file: $targetZipFileName")
// Check for existing output file BEFORE redirecting logging, so user sees the message
- if (File(outputMorphoZipFileName).exists() && !overwrite) {
- val errorMsg = "Output file $outputMorphoZipFileName already exists. Use --force to overwrite."
+ if (File(targetZipFileName).exists() && !overwrite) {
+ val errorMsg = "Output file $targetZipFileName already exists. Use --force to overwrite."
System.err.println("ERROR: $errorMsg")
LOGGER.severe(errorMsg)
exitProcess(1)
@@ -3949,7 +3951,9 @@
}
// Use extracted foundry from CoNLL-U output if available
- val actualFoundry = if (extractedFoundry != null) {
+ val actualFoundry = if (foundryOverride != null) {
+ foundryOverride!!
+ } else if (extractedFoundry != null) {
LOGGER.info("Using foundry from CoNLL-U output: $extractedFoundry (was: $foundry)")
// Update the global externalFoundry variable for consistent naming
externalFoundry = extractedFoundry
diff --git a/app/src/test/kotlin/de/ids_mannheim/korapxmltools/FoundryOverrideTest.kt b/app/src/test/kotlin/de/ids_mannheim/korapxmltools/FoundryOverrideTest.kt
new file mode 100644
index 0000000..8e1f1d9
--- /dev/null
+++ b/app/src/test/kotlin/de/ids_mannheim/korapxmltools/FoundryOverrideTest.kt
@@ -0,0 +1,116 @@
+package de.ids_mannheim.korapxmltools
+
+import org.junit.After
+import org.junit.Before
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.PrintStream
+import java.net.URL
+import kotlin.test.Ignore
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertTrue
+import kotlin.test.assertFalse
+
+class FoundryOverrideTest {
+ private val outContent = ByteArrayOutputStream(10000000)
+ private val errContent = ByteArrayOutputStream()
+ private val originalOut: PrintStream = System.out
+ private val originalErr: PrintStream = System.err
+
+ @Before
+ fun setUpStreams() {
+ System.setOut(PrintStream(outContent))
+ System.setErr(PrintStream(errContent))
+ }
+
+ @After
+ fun restoreStreams() {
+ System.setOut(originalOut)
+ System.setErr(originalErr)
+ }
+
+ private fun loadResource(path: String): URL {
+ val resource = Thread.currentThread().contextClassLoader.getResource(path)
+ requireNotNull(resource) { "Resource $path not found" }
+ return resource
+ }
+
+ @Test
+ fun testFoundryOverrideWithTagger() {
+ val outputDir = File.createTempFile("foundry_override_test", "").apply {
+ delete()
+ mkdirs()
+ }
+ try {
+ val baseZip = loadResource("wud24_sample.zip").path
+ val args = arrayOf(
+ "-f",
+ "-T", "spacy",
+ "-q",
+ "-D", outputDir.path,
+ "-F", "xyz",
+ "-t", "zip",
+ baseZip
+ )
+
+ // Using debug() which calls KorapXmlTool().call()
+ val exitCode = debug(args)
+ assertEquals(0, exitCode, "Tool execution should succeed")
+
+ // Check if the correct file exists
+ val expectedFile = File(outputDir, "wud24_sample.xyz.zip")
+ assertTrue(expectedFile.exists(), "Output file should be named wud24_sample.xyz.zip")
+
+ // Check if the wrong file does NOT exist
+ val wrongFile = File(outputDir, "wud24_sample.spacy.zip")
+ assertFalse(wrongFile.exists(), "Output file wud24_sample.spacy.zip should NOT exist")
+
+ // Check content of the zip
+ val zipEntries = org.apache.commons.compress.archivers.zip.ZipFile.builder()
+ .setFile(expectedFile)
+ .get()
+ .use { zip ->
+ zip.entries.asSequence().map { it.name }.toList()
+ }
+
+ assertTrue(zipEntries.any { it.contains("/xyz/morpho.xml") }, "Zip should contain entries with 'xyz' foundry")
+ assertFalse(zipEntries.any { it.contains("/spacy/morpho.xml") }, "Zip should NOT contain entries with 'spacy' foundry")
+
+ } finally {
+ outputDir.deleteRecursively()
+ }
+ }
+
+ @Ignore("This test is ignored until -o is fixed")
+ fun testOutputOptionHasPriority() {
+ val outputDir = File.createTempFile("output_option_test", "").apply {
+ delete()
+ mkdirs()
+ }
+ try {
+ val baseZip = loadResource("wud24_sample.zip").path
+ val explicitOutputFile = File(outputDir, "my_custom_output.zip")
+ val args = arrayOf(
+ "-f",
+ "-q",
+ "-T", "spacy",
+ "-o", explicitOutputFile.path,
+ "-t", "zip",
+ baseZip
+ )
+
+ val exitCode = debug(args)
+ assertEquals(0, exitCode, "Tool execution should succeed")
+
+ assertTrue(explicitOutputFile.exists(), "Explicit output file should exist: ${explicitOutputFile.path}")
+
+ // Ensure the default-named file does NOT exist
+ val defaultFile = File(outputDir, "wud24_sample.spacy.zip")
+ assertFalse(defaultFile.exists(), "Default output file should NOT exist when -o is used")
+
+ } finally {
+ outputDir.deleteRecursively()
+ }
+ }
+}