diff --git a/nb-engine/nb-engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFile.java b/nb-engine/nb-engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFile.java index f47ce4dfa..584481543 100644 --- a/nb-engine/nb-engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFile.java +++ b/nb-engine/nb-engine-cli/src/main/java/io/nosqlbench/engine/cli/atfiles/NBAtFile.java @@ -21,6 +21,7 @@ import io.nosqlbench.nb.api.nbio.NBIO; import io.nosqlbench.nb.api.nbio.NBPathsAPI; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; import org.snakeyaml.engine.v2.api.Load; import org.snakeyaml.engine.v2.api.LoadSettings; @@ -49,6 +50,12 @@ public class NBAtFile { *
  • {@code >-- } asserts each value starts with global option syntax (--)
  • * * + *

    Files can be included recursively using a format like

    {@code
    +     * - include:${DIR}/somefile.yaml
    +     * }

    + * + * Standard formatting specifiers above should work in this mode as well. + * * @param processInPlace The linked list which is statefully modified. If you need * an unmodified copy, then this is the responsibility of the caller. * @return An updated list with all values expanded and injected @@ -59,10 +66,10 @@ public class NBAtFile { ListIterator iter = processInPlace.listIterator(); while (iter.hasNext()) { String spec = iter.next(); - if (spec.startsWith("@")) { + if (spec.startsWith("@") || spec.startsWith("include=")|| spec.startsWith("include:")) { iter.previous(); iter.remove(); - LinkedList spliceIn = includeAt(spec); + LinkedList spliceIn = includeAt(spec.replaceFirst("include=","@").replaceFirst("include:","@")); for (String s : spliceIn) { iter.add(s); } @@ -89,6 +96,22 @@ public class NBAtFile { * @return The linked list of arguments which is to be spliced into the caller's command list */ public static LinkedList includeAt(String spec) { + LinkedList toInclude = doInclude(spec); + boolean recurse = false; + for (String s : toInclude) { + if (s.startsWith("include=")||s.startsWith("include:")) { + recurse=true; + break; + } + } + if (recurse) { + toInclude=includeAt(toInclude); + } + return toInclude; + + } + + private static @NotNull LinkedList doInclude(String spec) { Matcher matcher = includePattern.matcher(spec); if (matcher.matches()) { String filepathSpec = matcher.group("filepath"); @@ -135,7 +158,6 @@ public class NBAtFile { } else { throw new RuntimeException("Unable to match at-file specifier: " + spec + " to pattern '" + includePattern.pattern() + "'"); } - } private static LinkedList interposePath(LinkedList formatted, Path atPath) { diff --git a/nb-engine/nb-engine-cli/src/test/java/io/nosqlbench/engine/cli/atfiles/NBAtFileTest.java b/nb-engine/nb-engine-cli/src/test/java/io/nosqlbench/engine/cli/atfiles/NBAtFileTest.java index c42744096..fc53effa8 100644 --- a/nb-engine/nb-engine-cli/src/test/java/io/nosqlbench/engine/cli/atfiles/NBAtFileTest.java +++ b/nb-engine/nb-engine-cli/src/test/java/io/nosqlbench/engine/cli/atfiles/NBAtFileTest.java @@ -79,4 +79,9 @@ class NBAtFileTest { assertThat(strings).containsExactly("--option1", "--option2=value2", "--option3=value3", "--option4=value4"); } + @Test + public void testAtfileRecursion() { + LinkedList strings = NBAtFile.includeAt("@src/test/resources/atfiles/simple_recursion.yaml"); + assertThat(strings).containsExactly("arg1","arg1","arg2","arg3","arg3"); + } } diff --git a/nb-engine/nb-engine-cli/src/test/resources/atfiles/simple_recursion.yaml b/nb-engine/nb-engine-cli/src/test/resources/atfiles/simple_recursion.yaml new file mode 100644 index 000000000..08adde1c2 --- /dev/null +++ b/nb-engine/nb-engine-cli/src/test/resources/atfiles/simple_recursion.yaml @@ -0,0 +1,3 @@ +- arg1 +- include:${DIR}/simple_list.yaml +- arg3