mirror of
https://github.com/RatzzFatzz/MKVAudioSubtitleChanger.git
synced 2026-02-11 02:05:56 +01:00
Make picocli fully handle config validation
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger;
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger;
|
||||||
|
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation.ValidationExecutionStrategy;
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.CachedMkvFileProcessor;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.CachedMkvFileProcessor;
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.AttributeUpdaterKernel;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.AttributeUpdaterKernel;
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.CoherentAttributeUpdaterKernel;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.impl.kernel.CoherentAttributeUpdaterKernel;
|
||||||
@@ -35,7 +36,10 @@ public class Main implements Runnable {
|
|||||||
if (args.length == 0) {
|
if (args.length == 0) {
|
||||||
args = new String[] { "--help" };
|
args = new String[] { "--help" };
|
||||||
}
|
}
|
||||||
new CommandLine(Main.class).execute(args);
|
|
||||||
|
new CommandLine(Main.class)
|
||||||
|
.setExecutionStrategy(new ValidationExecutionStrategy())
|
||||||
|
.execute(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation.ValidFile;
|
|||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation.ValidMkvToolNix;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation.ValidMkvToolNix;
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.FileUtils;
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ValidationUtil;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ValidationUtil;
|
||||||
import jakarta.validation.ConstraintViolation;
|
import jakarta.validation.ConstraintViolation;
|
||||||
import jakarta.validation.Validator;
|
import jakarta.validation.Validator;
|
||||||
@@ -108,20 +109,6 @@ public class InputConfig {
|
|||||||
|
|
||||||
public static void setInstance(InputConfig c) {
|
public static void setInstance(InputConfig c) {
|
||||||
config = c;
|
config = c;
|
||||||
validate();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void validate() {
|
|
||||||
Validator validator = ValidationUtil.getValidator();
|
|
||||||
Set<ConstraintViolation<InputConfig>> violations = validator.validate(config);
|
|
||||||
|
|
||||||
if (!violations.isEmpty()) {
|
|
||||||
StringBuilder errors = new StringBuilder();
|
|
||||||
for (ConstraintViolation<InputConfig> violation : violations) {
|
|
||||||
errors.append(violation.getPropertyPath()).append(" ").append(violation.getMessage()).append("\n");
|
|
||||||
}
|
|
||||||
throw new CommandLine.ParameterException(config.getSpec().commandLine(), errors.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,13 +116,7 @@ public class InputConfig {
|
|||||||
* @return absolute path to desired application.
|
* @return absolute path to desired application.
|
||||||
*/
|
*/
|
||||||
public String getPathFor(MkvToolNix application) {
|
public String getPathFor(MkvToolNix application) {
|
||||||
return mkvToolNix.getAbsolutePath().endsWith("/")
|
return FileUtils.getPathFor(mkvToolNix, application).getAbsolutePath();
|
||||||
? mkvToolNix.getAbsolutePath() + application
|
|
||||||
: mkvToolNix.getAbsolutePath() + "/" + application;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPathFor(MkvToolNix application, boolean isWindows) {
|
|
||||||
return getPathFor(application) + (isWindows ? ".exe" : "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNormalizedLibraryPath() {
|
public String getNormalizedLibraryPath() {
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation;
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation;
|
||||||
|
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix;
|
||||||
import jakarta.validation.ConstraintValidator;
|
import jakarta.validation.ConstraintValidator;
|
||||||
import jakarta.validation.ConstraintValidatorContext;
|
import jakarta.validation.ConstraintValidatorContext;
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
|
||||||
|
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.FileUtils.getPathFor;
|
||||||
|
|
||||||
public class ValidMkvToolNixValidator implements ConstraintValidator<ValidMkvToolNix, File> {
|
public class ValidMkvToolNixValidator implements ConstraintValidator<ValidMkvToolNix, File> {
|
||||||
@Override
|
@Override
|
||||||
@@ -18,7 +16,9 @@ public class ValidMkvToolNixValidator implements ConstraintValidator<ValidMkvToo
|
|||||||
@Override
|
@Override
|
||||||
public boolean isValid(File file, ConstraintValidatorContext context) {
|
public boolean isValid(File file, ConstraintValidatorContext context) {
|
||||||
return file != null && file.exists()
|
return file != null && file.exists()
|
||||||
&& Path.of(InputConfig.getInstance().getPathFor(MkvToolNix.MKV_MERGE, SystemUtils.IS_OS_WINDOWS)).toFile().exists()
|
&& getPathFor(file, MkvToolNix.MKV_MERGE).exists()
|
||||||
&& Path.of(InputConfig.getInstance().getPathFor(MkvToolNix.MKV_PROP_EDIT, SystemUtils.IS_OS_WINDOWS)).toFile().exists();
|
&& getPathFor(file, MkvToolNix.MKV_PROP_EDIT).exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation;
|
||||||
|
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.util.ValidationUtil;
|
||||||
|
import jakarta.validation.ConstraintViolation;
|
||||||
|
import jakarta.validation.Validator;
|
||||||
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ValidationExecutionStrategy implements CommandLine.IExecutionStrategy {
|
||||||
|
|
||||||
|
public int execute(CommandLine.ParseResult parseResult) {
|
||||||
|
validate(parseResult.commandSpec());
|
||||||
|
return new CommandLine.RunLast().execute(parseResult); // default execution strategy
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void validate(CommandLine.Model.CommandSpec spec) {
|
||||||
|
Validator validator = ValidationUtil.getValidator();
|
||||||
|
Set<ConstraintViolation<InputConfig>> violations = validator.validate(((Main)spec.userObject()).getConfig());
|
||||||
|
|
||||||
|
if (!violations.isEmpty()) {
|
||||||
|
StringBuilder errors = new StringBuilder();
|
||||||
|
for (ConstraintViolation<InputConfig> violation : violations) {
|
||||||
|
errors.append(violation.getPropertyPath()).append(" ").append(violation.getMessage()).append("\n");
|
||||||
|
}
|
||||||
|
throw new CommandLine.ParameterException(spec.commandLine(), errors.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.util;
|
||||||
|
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.MkvToolNix;
|
||||||
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
public class FileUtils {
|
||||||
|
private static final boolean isWindows = SystemUtils.IS_OS_WINDOWS;
|
||||||
|
|
||||||
|
private static String expandPath(File dir, MkvToolNix application) {
|
||||||
|
return dir.getAbsolutePath().endsWith("/")
|
||||||
|
? dir.getAbsolutePath() + application
|
||||||
|
: dir.getAbsolutePath() + "/" + application;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getPathFor(File dir, MkvToolNix application) {
|
||||||
|
return Path.of(expandPath(dir, application) + (isWindows ? ".exe" : "")).toFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,25 @@
|
|||||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
|
||||||
|
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.validation.ValidationExecutionStrategy;
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.PathUtils.TEST_FILE;
|
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.PathUtils.TEST_FILE;
|
||||||
|
import static at.pcgamingfreaks.mkvaudiosubtitlechanger.util.TestUtil.args;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
class ConfigTest {
|
class InputConfigTest {
|
||||||
|
private static final String TEST_INVALID_DIR = "src/test/resources/test-dir";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void initConfig() {
|
void initConfig() {
|
||||||
@@ -42,4 +52,31 @@ class ConfigTest {
|
|||||||
|
|
||||||
assertNull(InputConfig.getInstance().getConfigPath());
|
assertNull(InputConfig.getInstance().getConfigPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Stream<Arguments> jakartaValidationData() {
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(new String[]{"-l", "/arstarstarst", "-a", "jpn:ger"}, "libraryPath does not exist"),
|
||||||
|
Arguments.of(args("-m", TEST_INVALID_DIR), "mkvToolNix does not exist"),
|
||||||
|
Arguments.of(args("-t", "0"), "threads must be greater than or equal to 1"),
|
||||||
|
Arguments.of(args("-t", "-1"), "threads must be greater than or equal to 1"),
|
||||||
|
Arguments.of(args("-c", "-1"), "coherent must be greater than or equal to 0")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("jakartaValidationData")
|
||||||
|
void testJakartaValidation(String[] args, String expectedMessage) {
|
||||||
|
InputConfig.getInstance(true);
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
PrintWriter printWriter = new PrintWriter(writer);
|
||||||
|
|
||||||
|
new CommandLine(Main.class)
|
||||||
|
.setExecutionStrategy(new ValidationExecutionStrategy())
|
||||||
|
.setErr(printWriter)
|
||||||
|
.execute(args);
|
||||||
|
|
||||||
|
printWriter.flush();
|
||||||
|
assertTrue(writer.toString().contains(expectedMessage));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||||
|
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.model.AttributeConfig;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||||
|
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||||
|
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
@@ -38,13 +39,5 @@ class IntegerConfigParameterTest {
|
|||||||
Main sut = new Main();
|
Main sut = new Main();
|
||||||
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-t")));
|
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("-t")));
|
||||||
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("--threads")));
|
assertThrows(CommandLine.MissingParameterException.class, () -> CommandLine.populateCommand(sut, args("--threads")));
|
||||||
|
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
PrintWriter printWriter = new PrintWriter(writer);
|
|
||||||
CommandLine underTest = new CommandLine(sut);
|
|
||||||
underTest = underTest.setErr(printWriter);
|
|
||||||
underTest.execute(args("-t", "0"));
|
|
||||||
printWriter.flush();
|
|
||||||
assertTrue(writer.toString().contains("threads must be greater than or equal to 1"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||||
|
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||||
import org.apache.commons.lang3.SystemUtils;
|
import org.apache.commons.lang3.SystemUtils;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
@@ -18,7 +19,6 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
|
|
||||||
class MkvToolNixPathConfigParameterTest {
|
class MkvToolNixPathConfigParameterTest {
|
||||||
|
|
||||||
private static final String TEST_INVALID_DIR = "src/test/resources/test-dir";
|
|
||||||
private static final String TEST_MKVTOOLNIX_DIR = SystemUtils.IS_OS_WINDOWS ? "src/test/resources/mkvtoolnix_exe" : "src/test/resources/mkvtoolnix";
|
private static final String TEST_MKVTOOLNIX_DIR = SystemUtils.IS_OS_WINDOWS ? "src/test/resources/mkvtoolnix_exe" : "src/test/resources/mkvtoolnix";
|
||||||
|
|
||||||
private static Stream<Arguments> provideTestCases() {
|
private static Stream<Arguments> provideTestCases() {
|
||||||
@@ -39,7 +39,6 @@ class MkvToolNixPathConfigParameterTest {
|
|||||||
@Test
|
@Test
|
||||||
void validate() {
|
void validate() {
|
||||||
Main sut = new Main();
|
Main sut = new Main();
|
||||||
// assertThrows(CommandLine.ParameterException.class, () -> new CommandLine(sut).execute(args("-m", TEST_INVALID_DIR)));
|
|
||||||
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("-m")));
|
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("-m")));
|
||||||
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("")));
|
assertThrows(CommandLine.ParameterException.class, () -> CommandLine.populateCommand(sut, args("")));
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||||
|
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||||
|
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config;
|
package at.pcgamingfreaks.mkvaudiosubtitlechanger.config.fields;
|
||||||
|
|
||||||
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.Main;
|
||||||
|
import at.pcgamingfreaks.mkvaudiosubtitlechanger.config.InputConfig;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
Reference in New Issue
Block a user