You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kw...@apache.org on 2024/11/11 18:13:21 UTC
(maven-doxia-converter) branch feature/support-git-mv created (now 197088c)
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a change to branch feature/support-git-mv
in repository https://gitbox.apache.org/repos/asf/maven-doxia-converter.git
at 197088c [DOXIATOOLS-90] Optionally post-process output with 'git mv'
This branch includes the following new commits:
new 197088c [DOXIATOOLS-90] Optionally post-process output with 'git mv'
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(maven-doxia-converter) 01/01: [DOXIATOOLS-90] Optionally post-process output with 'git mv'
Posted by kw...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch feature/support-git-mv
in repository https://gitbox.apache.org/repos/asf/maven-doxia-converter.git
commit 197088c3c50d9015f5d44e366d856f10f67a891c
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Mon Nov 11 19:13:16 2024 +0100
[DOXIATOOLS-90] Optionally post-process output with 'git mv'
This allows to keep the git history of converted input files (in case
those are part of a git repository)
---
.../java/org/apache/maven/doxia/Converter.java | 8 +++
.../org/apache/maven/doxia/DefaultConverter.java | 63 +++++++++++++++++++---
.../org/apache/maven/doxia/cli/CLIManager.java | 10 +++-
.../org/apache/maven/doxia/cli/ConverterCli.java | 21 ++++++--
.../maven/doxia/wrapper/InputFileWrapper.java | 36 ++-----------
.../apache/maven/doxia/DefaultConverterTest.java | 40 ++++++++++++++
6 files changed, 133 insertions(+), 45 deletions(-)
diff --git a/src/main/java/org/apache/maven/doxia/Converter.java b/src/main/java/org/apache/maven/doxia/Converter.java
index 360632a..63dae08 100644
--- a/src/main/java/org/apache/maven/doxia/Converter.java
+++ b/src/main/java/org/apache/maven/doxia/Converter.java
@@ -29,6 +29,12 @@ import org.apache.maven.doxia.wrapper.OutputStreamWrapper;
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
*/
public interface Converter {
+ enum PostProcess {
+ NONE,
+ REMOVE_AFTER_CONVERSION,
+ GIT_MV_INPUT_TO_OUTPUT,
+ }
+
/**
* @param input an input file wrapper, not null.
* @param output an output file wrapper, not null.
@@ -55,4 +61,6 @@ public interface Converter {
* @param formatOutput <code>true</code> to format the generated files, <code>false</code> otherwise.
*/
void setFormatOutput(boolean formatOutput);
+
+ void setPostProcess(PostProcess postProcess);
}
diff --git a/src/main/java/org/apache/maven/doxia/DefaultConverter.java b/src/main/java/org/apache/maven/doxia/DefaultConverter.java
index 250d968..313cb4f 100644
--- a/src/main/java/org/apache/maven/doxia/DefaultConverter.java
+++ b/src/main/java/org/apache/maven/doxia/DefaultConverter.java
@@ -30,12 +30,15 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
+import java.util.Scanner;
import com.ibm.icu.text.CharsetDetector;
import com.ibm.icu.text.CharsetMatch;
@@ -204,6 +207,8 @@ public class DefaultConverter implements Converter {
}
}
+ private PostProcess postProcess = PostProcess.NONE;
+
/** Flag to format the generated files, actually only for XML based sinks. */
private boolean formatOutput;
@@ -229,7 +234,6 @@ public class DefaultConverter implements Converter {
try {
if (input.getFile().isFile()) {
convert(input.getFile(), input.getEncoding(), input.getFormat(), output);
- cleanUp(input, input.getFile());
} else {
List<File> files;
try {
@@ -250,7 +254,6 @@ public class DefaultConverter implements Converter {
File relativeOutputDirectory = new File(
PathTool.getRelativeFilePath(input.getFile().getAbsolutePath(), f.getParent()));
convert(f, input.getEncoding(), input.getFormat(), output, relativeOutputDirectory);
- cleanUp(input, f);
}
}
} finally {
@@ -258,12 +261,44 @@ public class DefaultConverter implements Converter {
}
}
- private void cleanUp(InputFileWrapper input, File f) {
- if (input.cleanUp(f)) {
- LOGGER.info("Removed input file \"{}\" after successful conversion", f);
+ private void postProcessFiles(File inputFile, File outputFile) throws IOException, InterruptedException {
+ switch (postProcess) {
+ case REMOVE_AFTER_CONVERSION:
+ Files.delete(inputFile.toPath());
+ LOGGER.info("Removed input file \"{}\" after successful conversion", inputFile);
+ break;
+ case GIT_MV_INPUT_TO_OUTPUT:
+ // first replace input by (converted) output file
+ Files.move(outputFile.toPath(), inputFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ // then rename input file to have the proper extension
+ executeCommand(String.format("git mv %s %s", inputFile, outputFile));
+ LOGGER.info("Git moved \"{}\" to \"{}\"", inputFile, outputFile);
+ break;
+ default:
+ break;
+ }
+ }
+
+ static void executeCommand(String command) throws IOException, InterruptedException {
+ Process process = Runtime.getRuntime().exec(command);
+ int exitCode = process.waitFor();
+ if (exitCode != 0) {
+ logOutput(process.getInputStream(), "");
+ logOutput(process.getErrorStream(), "Error: ");
+ throw new IOException("Command " + command + " failed with exit code " + exitCode);
}
}
+ static void logOutput(InputStream inputStream, String prefix) {
+ new Thread(() -> {
+ Scanner scanner = new Scanner(inputStream, "UTF-8");
+ while (scanner.hasNextLine()) {
+ LOGGER.error("{}{}", prefix, scanner.nextLine());
+ }
+ scanner.close();
+ }).start();
+ }
+
/** {@inheritDoc} */
@Override
public void convert(InputReaderWrapper input, OutputStreamWrapper output)
@@ -313,6 +348,11 @@ public class DefaultConverter implements Converter {
this.formatOutput = formatOutput;
}
+ @Override
+ public void setPostProcess(PostProcess postProcess) {
+ this.postProcess = postProcess;
+ }
+
// ----------------------------------------------------------------------
// Private methods
// ----------------------------------------------------------------------
@@ -336,10 +376,11 @@ public class DefaultConverter implements Converter {
* @param parserFormat a not null supported format
* @param output not null OutputFileWrapper object
* @param relativeOutputDirectory the relative output directory (may be null, created if it does not exist yet)
+ * @return the output file
* @throws ConverterException if any
* @throws UnsupportedFormatException if any
*/
- private void convert(
+ private File convert(
File inputFile,
String inputEncoding,
DoxiaFormat parserFormat,
@@ -438,6 +479,16 @@ public class DefaultConverter implements Converter {
"Successfully converted file \"{}\" to \"{}\"",
inputFile.getAbsolutePath(),
outputFile.getAbsolutePath());
+ try {
+ postProcessFiles(inputFile, outputFile);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new ConverterException("Error post processing files: " + e.getMessage(), e);
+ }
+ catch (IOException e) {
+ throw new ConverterException("Error post processing files: " + e.getMessage(), e);
+ }
+ return outputFile;
}
/**
diff --git a/src/main/java/org/apache/maven/doxia/cli/CLIManager.java b/src/main/java/org/apache/maven/doxia/cli/CLIManager.java
index e8a0759..8818060 100644
--- a/src/main/java/org/apache/maven/doxia/cli/CLIManager.java
+++ b/src/main/java/org/apache/maven/doxia/cli/CLIManager.java
@@ -28,6 +28,7 @@ import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
+import org.apache.maven.doxia.Converter;
import org.apache.maven.doxia.DefaultConverter;
import static org.apache.commons.lang3.StringUtils.join;
@@ -49,6 +50,8 @@ class CLIManager {
static final String REMOVE_IN = "removeIn";
+ static final String GIT_MV_INPUT_TO_OUTPUT = "gitMvInputToOutput";
+
/** out String */
static final String OUT = "out";
@@ -99,6 +102,9 @@ class CLIManager {
.longOpt("removeInputAfterConversion")
.desc("Whether to remove the input file(s) after successful conversion")
.build());
+ OPTIONS.addOption(Option.builder(GIT_MV_INPUT_TO_OUTPUT)
+ .desc("When this flag is set the output file(s) is(are) written to the input file(s) and afterwards renamed to have the proper extension with 'git mv'")
+ .build());
OPTIONS.addOption(Option.builder(OUT)
.longOpt("output")
.desc("Output file or directory.")
@@ -160,11 +166,11 @@ class CLIManager {
private static String getSupportedFormat() {
String fromFormats = EnumSet.allOf(DefaultConverter.DoxiaFormat.class).stream()
- .filter(DefaultConverter.DoxiaFormat::hasParser)
+ .filter(Converter.DoxiaFormat::hasParser)
.map(f -> f.toString().toLowerCase())
.collect(Collectors.joining(", "));
String toFormats = EnumSet.allOf(DefaultConverter.DoxiaFormat.class).stream()
- .filter(DefaultConverter.DoxiaFormat::hasSink)
+ .filter(Converter.DoxiaFormat::hasSink)
.map(f -> f.toString().toLowerCase())
.collect(Collectors.joining(", "));
return EOL + "Supported Formats:" + EOL + " from: " + fromFormats
diff --git a/src/main/java/org/apache/maven/doxia/cli/ConverterCli.java b/src/main/java/org/apache/maven/doxia/cli/ConverterCli.java
index 3ad605b..579e1d8 100644
--- a/src/main/java/org/apache/maven/doxia/cli/ConverterCli.java
+++ b/src/main/java/org/apache/maven/doxia/cli/ConverterCli.java
@@ -31,6 +31,7 @@ import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.maven.doxia.Converter;
+import org.apache.maven.doxia.Converter.PostProcess;
import org.apache.maven.doxia.ConverterException;
import org.apache.maven.doxia.DefaultConverter;
import org.apache.maven.doxia.UnsupportedFormatException;
@@ -114,26 +115,35 @@ public class ConverterCli {
InputFileWrapper input;
OutputFileWrapper output;
+ final PostProcess postProcess;
try {
String sourceFormat = commandLine.getOptionValue(CLIManager.FROM, CLIManager.AUTO_FORMAT);
final DefaultConverter.DoxiaFormat parserFormat;
if (CLIManager.AUTO_FORMAT.equalsIgnoreCase(sourceFormat)) {
File inputFile = new File(commandLine.getOptionValue(CLIManager.IN));
- parserFormat = DefaultConverter.DoxiaFormat.autoDetectFormat(inputFile);
+ parserFormat = Converter.DoxiaFormat.autoDetectFormat(inputFile);
if (debug) {
System.out.println("Auto detected input format: " + parserFormat);
}
} else {
- parserFormat = DefaultConverter.DoxiaFormat.valueOf(sourceFormat.toUpperCase());
+ parserFormat = Converter.DoxiaFormat.valueOf(sourceFormat.toUpperCase());
}
String targetFormat = commandLine.getOptionValue(CLIManager.TO);
+ if (commandLine.hasOption(CLIManager.REMOVE_IN) && commandLine.hasOption(CLIManager.GIT_MV_INPUT_TO_OUTPUT)) {
+ throw new IllegalArgumentException("Options 'removeIn' and 'gitMvInputToOutput' are mutually exclusive.");
+ } else if (commandLine.hasOption(CLIManager.REMOVE_IN)) {
+ postProcess = PostProcess.REMOVE_AFTER_CONVERSION;
+ } else if (commandLine.hasOption(CLIManager.GIT_MV_INPUT_TO_OUTPUT)) {
+ postProcess = PostProcess.GIT_MV_INPUT_TO_OUTPUT;
+ } else {
+ postProcess = PostProcess.NONE;
+ }
final DefaultConverter.DoxiaFormat sinkFormat =
- DefaultConverter.DoxiaFormat.valueOf(targetFormat.toUpperCase());
+ Converter.DoxiaFormat.valueOf(targetFormat.toUpperCase());
input = InputFileWrapper.valueOf(
commandLine.getOptionValue(CLIManager.IN),
parserFormat,
- commandLine.getOptionValue(CLIManager.INENCODING),
- commandLine.hasOption(CLIManager.REMOVE_IN));
+ commandLine.getOptionValue(CLIManager.INENCODING));
output = OutputFileWrapper.valueOf(
commandLine.getOptionValue(CLIManager.OUT),
sinkFormat,
@@ -152,6 +162,7 @@ public class ConverterCli {
boolean format = commandLine.hasOption(CLIManager.FORMAT);
converter.setFormatOutput(format);
+ converter.setPostProcess(postProcess);
try {
converter.convert(input, output);
diff --git a/src/main/java/org/apache/maven/doxia/wrapper/InputFileWrapper.java b/src/main/java/org/apache/maven/doxia/wrapper/InputFileWrapper.java
index 2b20c1c..3722122 100644
--- a/src/main/java/org/apache/maven/doxia/wrapper/InputFileWrapper.java
+++ b/src/main/java/org/apache/maven/doxia/wrapper/InputFileWrapper.java
@@ -36,11 +36,6 @@ public class InputFileWrapper extends AbstractFileWrapper {
private final DefaultConverter.DoxiaFormat format;
- /**
- * If true, the related input file(s) will be removed after the conversion.
- */
- private final boolean removeAfterConversion;
-
/**
* Private constructor.
*
@@ -50,13 +45,11 @@ public class InputFileWrapper extends AbstractFileWrapper {
* @throws UnsupportedEncodingException if the encoding is unsupported.
* @throws FileNotFoundException if the file for absolutePath is not found.
*/
- private InputFileWrapper(
- String absolutePath, DefaultConverter.DoxiaFormat format, String charsetName, boolean removeAfterConversion)
+ private InputFileWrapper(String absolutePath, DefaultConverter.DoxiaFormat format, String charsetName)
throws UnsupportedEncodingException, FileNotFoundException {
super(absolutePath, charsetName);
this.format = format;
- this.removeAfterConversion = removeAfterConversion;
if (!getFile().exists()) {
throw new FileNotFoundException("The file '" + getFile().getAbsolutePath() + "' doesn't exist.");
}
@@ -72,42 +65,21 @@ public class InputFileWrapper extends AbstractFileWrapper {
*/
public static InputFileWrapper valueOf(String absolutePath, DefaultConverter.DoxiaFormat format)
throws UnsupportedEncodingException, FileNotFoundException {
- return valueOf(absolutePath, format, WriterFactory.UTF_8, false);
+ return valueOf(absolutePath, format, WriterFactory.UTF_8);
}
- /**
- * Performs potential clean up operations on the given file
- * @param file the file to clean up, not null.
- * @return {@code true} if the file was removed.
- */
- public boolean cleanUp(File file) {
- if (!file.toString().startsWith(getFile().toString())) {
- throw new IllegalStateException(
- "The given file " + file + " is not related to the input file: " + getFile());
- }
- if (removeAfterConversion) {
- return file.delete();
- }
- return false;
- }
-
- public static InputFileWrapper valueOf(String absolutePath, DefaultConverter.DoxiaFormat format, String charsetName)
- throws UnsupportedEncodingException, FileNotFoundException {
- return valueOf(absolutePath, format, charsetName, false);
- }
/**
* @param absolutePath for a wanted file or a wanted directory, not null.
* @param format not null
* @param charsetName could be null
- * @param removeAfterConversion if true, the file will be removed after the conversion
* @return a type safe input reader
* @throws UnsupportedEncodingException if the encoding is unsupported.
* @throws FileNotFoundException if the file for absolutePath is not found.
*/
public static InputFileWrapper valueOf(
- String absolutePath, DefaultConverter.DoxiaFormat format, String charsetName, boolean removeAfterConversion)
+ String absolutePath, DefaultConverter.DoxiaFormat format, String charsetName)
throws UnsupportedEncodingException, FileNotFoundException {
- return new InputFileWrapper(absolutePath, format, charsetName, removeAfterConversion);
+ return new InputFileWrapper(absolutePath, format, charsetName);
}
public DefaultConverter.DoxiaFormat getFormat() {
diff --git a/src/test/java/org/apache/maven/doxia/DefaultConverterTest.java b/src/test/java/org/apache/maven/doxia/DefaultConverterTest.java
new file mode 100644
index 0000000..a4abe28
--- /dev/null
+++ b/src/test/java/org/apache/maven/doxia/DefaultConverterTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+package org.apache.maven.doxia;
+
+import java.io.IOException;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class DefaultConverterTest {
+
+ @Test
+ void testExecuteCommand() throws IOException, InterruptedException {
+ DefaultConverter.executeCommand("git version");
+ }
+
+ @Test
+ void testExecuteInvalidCommand() throws IOException, InterruptedException {
+ assertThrows(IOException.class, () -> {
+ DefaultConverter.executeCommand("invalid command");
+ });
+ }
+}