improve atfile support for arg formats

This commit is contained in:
Jonathan Shook 2024-01-11 12:54:08 -06:00
parent 6a668f3947
commit 77680f480f
4 changed files with 65 additions and 20 deletions

View File

@ -130,7 +130,7 @@ public class NBAtFile {
}
return formatted(scopeOfInclude, fmt);
} else {
throw new RuntimeException("Unable to match at-file specifier: " + spec + " to known syntax");
throw new RuntimeException("Unable to match at-file specifier: " + spec + " to pattern '" + includePattern.pattern() + "'");
}
}

View File

@ -23,10 +23,46 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public enum NBAtFileFormats {
Default("", s -> s.length <=2, s -> (s.length==1) ? s[0] : s[0] + ":" + s[1]),
MapWithEquals("=", s -> s.length == 2, s -> s[0] + "=" + s[1]),
MapWithColons(":", s -> s.length == 2, s -> s[0] + ":" + s[1]),
GlobalWithDoubleDashes("--", s -> s.length<=2 && s[0].startsWith("--"), NBAtFileFormats::formatDashDashOption);
Default("", s -> s.length <= 2, NBAtFileFormats::formatDefaultDashOption),
MapWithEquals("=", s -> s.length <= 2, NBAtFileFormats::formatNameEqualsValue),
MapWithColons(":", s -> s.length <= 2, NBAtFileFormats::formatNameColonValue),
GlobalWithDoubleDashes("--", s -> s.length <= 2 && s[0].startsWith("--"), NBAtFileFormats::formatDashDashOption);
private static String formatNameEqualsValue(String[] strings) {
if (strings.length == 2) {
return strings[0] + "=" + strings[1];
} else if (strings.length == 1 && strings[0].matches("[a-zA-Z_][a-zA-Z_]*[=:].*")) {
String[] parts = strings[0].split("[=:]", 2);
return parts[0]+"="+parts[1];
} else {
throw new RuntimeException("Unable to match data for namedd value form: " + String.join("|",Arrays.asList(strings)));
}
}
private static String formatNameColonValue(String[] strings) {
if (strings.length == 2) {
return strings[0] + ":" + strings[1];
} else if (strings.length == 1 && strings[0].matches("[a-zA-Z_][a-zA-Z_]*[=:].*")) {
String[] parts = strings[0].split("[=:]", 2);
return parts[0]+":"+parts[1];
} else {
throw new RuntimeException("Unable to match data for namedd value form: " + String.join("|",Arrays.asList(strings)));
}
}
private static String formatDefaultDashOption(String[] strings) {
if (strings.length == 1 && strings[0].startsWith("--")) {
return formatDashDashOption(strings);
} else if (strings.length == 1 && strings[0].matches("[a-zA-Z_][a-zA-Z0-9._]*[=:].*")) {
return formatNameEqualsValue(strings);
} else if (strings.length == 2) {
return formatNameEqualsValue(strings);
} else if (strings.length==1) {
return strings[0];
} else {
throw new RuntimeException("Unable to match data for --global option form: " + String.join("|",Arrays.asList(strings)));
}
}
private final String spec;
private final Predicate<String[]> validator;
@ -49,33 +85,32 @@ public enum NBAtFileFormats {
public void validate(String[] ary) {
if (!validator.test(ary)) {
throw new RuntimeException("With fmt '" + this.name() + "': input data not valid for format specifier '" + spec + "': data:[" + String.join("],[",Arrays.asList(ary)) + "]");
throw new RuntimeException("With fmt '" + this.name() + "': input data not valid for format specifier '" + spec + "': data:[" + String.join("],[", Arrays.asList(ary)) + "]");
}
}
private final static Pattern doubleOptionSpace = Pattern.compile(
"^(?<optname>--[a-zA-Z][a-zA-Z0-9_.-]*) +(?<optvalue>.+)$"
private final static Pattern doubleDashOption = Pattern.compile(
"^(?<optname>--[a-zA-Z][a-zA-Z0-9_.-]*)((=|\\s+)(?<optvalue>.+))?$"
);
private static String formatDashDashOption(String[] words) {
if (words[0].contains("=")) {
if (words.length==1) {
return words[0];
} else {
throw new RuntimeException("Unrecognized option form " + String.join(" (space) " + Arrays.asList(words)));
}
}
if (words.length>1) {
if (words.length > 1) {
throw new RuntimeException("too many values for rendering --option in at-file: " + Arrays.asList(words));
}
Matcher matcher = doubleOptionSpace.matcher(words[0]);
Matcher matcher = doubleDashOption.matcher(words[0]);
if (matcher.matches()) {
String optname = matcher.group("optname");
String optvalue = matcher.group("optvalue");
return optname + "=" + optvalue;
if (optvalue!=null) {
optvalue = (optvalue.matches("'.+'") ? optvalue.substring(1, optvalue.length() - 1) : optvalue);
optvalue = (optvalue.matches("\".+\"") ? optvalue.substring(1, optvalue.length() - 1) : optvalue);
return optname + "=" + optvalue;
} else {
return optname;
}
} else {
throw new RuntimeException("Unable to convert atfile option: "+ Arrays.asList(words));
throw new RuntimeException("Unable to match option '" + words[0] + "' with pattern " + doubleDashOption.pattern());
}
}

View File

@ -34,7 +34,7 @@ class NBAtFileTest {
@Test
public void testParseSimpleMapDefaultFmt() {
LinkedList<String> strings = NBAtFile.includeAt("@src/test/resources/atfiles/simple_map.yaml");
assertThat(strings).containsExactly("arg1:val1","arg2:val2","arg3:val3");
assertThat(strings).containsExactly("arg1=val1","arg2=val2","arg3=val3");
}
@Test
@ -67,4 +67,10 @@ class NBAtFileTest {
assertThat(strings).containsExactly("key1=value1","key2=value2");
}
@Test
public void testGlobalOptionForms() {
LinkedList<String> strings = NBAtFile.includeAt("@src/test/resources/atfiles/global_opts.yaml>--");
assertThat(strings).containsExactly("--option1", "--option2=value2", "--option3=value3", "--option4=value4");
}
}

View File

@ -0,0 +1,4 @@
- --option1
- --option2=value2
- --option3='value3'
- --option4="value4"