From 870068e1cf9a929d289fca759968f92534a3d718 Mon Sep 17 00:00:00 2001 From: Tosox <57193602+Tosox@users.noreply.github.com> Date: Sat, 2 May 2026 13:00:07 +0200 Subject: [PATCH] feat: Extend setup syntax (#70) - Support explicit source to destination mapping Closes #70 --- .../install/ModEntryInstaller.java | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/main/java/de/tosox/zonerelay/infrastructure/install/ModEntryInstaller.java b/src/main/java/de/tosox/zonerelay/infrastructure/install/ModEntryInstaller.java index dcaa3aa..9486ec1 100644 --- a/src/main/java/de/tosox/zonerelay/infrastructure/install/ModEntryInstaller.java +++ b/src/main/java/de/tosox/zonerelay/infrastructure/install/ModEntryInstaller.java @@ -83,12 +83,11 @@ public void install(ModEntry entry, File archive, ProgressListener progressListe for (int i = 0; i < total; i++) { String instruction = setup.get(i); - Path source = tempDir.resolve(instruction); - Path destination = targetDir.resolve(source.getFileName()); + SetupMapping mapping = resolveMapping(instruction, tempDir, targetDir); - uiLogger.info(localizer.translate("MSG_COPY_TO", instruction, source.getFileName())); - fileLogger.info("Copying %s → %s", source, destination); - FileUtils.copyDirectory(source.toFile(), destination.toFile()); + uiLogger.info(localizer.translate("MSG_COPY_TO", mapping.source().getFileName(), mapping.destination())); + fileLogger.info("Copying %s → %s", mapping.source(), mapping.destination()); + copyEntry(mapping.source(), mapping.destination()); progressListener.onProgressUpdate(i + 1, total); } @@ -103,4 +102,36 @@ public void install(ModEntry entry, File archive, ProgressListener progressListe } progressListener.onProgressUpdate(1, 1); } + + private SetupMapping resolveMapping(String instruction, Path tempDir, Path targetDir) { + if (instruction.contains("->")) { + String[] parts = instruction.split("->", 2); + Path source = tempDir.resolve(parts[0].trim()); + String dstPart = parts[1].trim(); + Path dstBase = targetDir.resolve(dstPart); + + Path destination; + if (Files.isDirectory(source) || !FilenameUtils.getExtension(dstPart).isEmpty()) { + destination = dstBase; + } else { + destination = dstBase.resolve(source.getFileName()); + } + + return new SetupMapping(source, destination); + } + + Path source = tempDir.resolve(instruction); + return new SetupMapping(source, targetDir.resolve(source.getFileName())); + } + + private void copyEntry(Path source, Path destination) throws Exception { + if (Files.isDirectory(source)) { + FileUtils.copyDirectory(source.toFile(), destination.toFile()); + } else { + Files.createDirectories(destination.getParent()); + FileUtils.copyFile(source.toFile(), destination.toFile()); + } + } + + private record SetupMapping(Path source, Path destination) {} }