From 77680f480fa9ee33d34e3a3eb3f2efad0a9be0dc Mon Sep 17 00:00:00 2001 From: Jonathan Shook Date: Thu, 11 Jan 2024 12:54:08 -0600 Subject: [PATCH] improve atfile support for arg formats --- .../engine/cli/atfiles/NBAtFile.java | 2 +- .../engine/cli/atfiles/NBAtFileFormats.java | 71 ++++++++++++++----- .../engine/cli/atfiles/NBAtFileTest.java | 8 ++- .../test/resources/atfiles/global_opts.yaml | 4 ++ 4 files changed, 65 insertions(+), 20 deletions(-) create mode 100644 engine-cli/src/test/resources/atfiles/global_opts.yaml diff --git a/engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFile.java b/engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFile.java index f8ba6dd41..b658bbe49 100644 --- a/engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFile.java +++ b/engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFile.java @@ -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() + "'"); } } diff --git a/engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFileFormats.java b/engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFileFormats.java index 44e2951d0..4713be970 100644 --- a/engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFileFormats.java +++ b/engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFileFormats.java @@ -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 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( - "^(?--[a-zA-Z][a-zA-Z0-9_.-]*) +(?.+)$" + private final static Pattern doubleDashOption = Pattern.compile( + "^(?--[a-zA-Z][a-zA-Z0-9_.-]*)((=|\\s+)(?.+))?$" ); 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()); } } diff --git a/engine-cli/src/test/java/io/nosqlbench/engine/cli/atfiles/NBAtFileTest.java b/engine-cli/src/test/java/io/nosqlbench/engine/cli/atfiles/NBAtFileTest.java index cbb10a180..3b39f727d 100644 --- a/engine-cli/src/test/java/io/nosqlbench/engine/cli/atfiles/NBAtFileTest.java +++ b/engine-cli/src/test/java/io/nosqlbench/engine/cli/atfiles/NBAtFileTest.java @@ -34,7 +34,7 @@ class NBAtFileTest { @Test public void testParseSimpleMapDefaultFmt() { LinkedList 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 strings = NBAtFile.includeAt("@src/test/resources/atfiles/global_opts.yaml>--"); + assertThat(strings).containsExactly("--option1", "--option2=value2", "--option3=value3", "--option4=value4"); + } + } diff --git a/engine-cli/src/test/resources/atfiles/global_opts.yaml b/engine-cli/src/test/resources/atfiles/global_opts.yaml new file mode 100644 index 000000000..f29e952c5 --- /dev/null +++ b/engine-cli/src/test/resources/atfiles/global_opts.yaml @@ -0,0 +1,4 @@ +- --option1 +- --option2=value2 +- --option3='value3' +- --option4="value4"