diff --git a/avaje-config/src/main/java/io/avaje/config/InitialLoader.java b/avaje-config/src/main/java/io/avaje/config/InitialLoader.java index dbfa651d..677bd41a 100644 --- a/avaje-config/src/main/java/io/avaje/config/InitialLoader.java +++ b/avaje-config/src/main/java/io/avaje/config/InitialLoader.java @@ -147,7 +147,9 @@ void loadViaCommandLine(String[] args) { private void loadCommandLineArg(String arg) { if (isValidExtension(arg)) { - loadViaPaths(arg); + for (String path : splitPaths(arg)) { + loadWithExtensionCheck(loadContext.eval(path)); + } } } @@ -193,7 +195,32 @@ private boolean loadTest() { private void loadViaIndirection() { String paths = loadContext.indirectLocation(); if (paths != null) { - loadViaPaths(paths); + var stack = new ArrayDeque(); + splitAndAddPaths(stack, paths); + String path; + var sentinel = 0; + while ((path = stack.poll()) != null) { + loadWithExtensionCheck(loadContext.eval(path)); + var newPath = loadContext.indirectLocation(); + if (newPath == null) throw new IllegalStateException("truly impossible"); + if (!paths.equals(newPath)) { + paths = newPath; + splitAndAddPaths(stack, paths); + } + + sentinel++; + if (sentinel == 69) { + throw new IllegalStateException( + "Failed to resolve load.properties after 69 iterations. Perhaps Circular load.properties reference?"); + } + } + } + } + + private void splitAndAddPaths(ArrayDeque stack, String paths) { + var split = splitPaths(paths); + for (int i = split.length - 1; i >= 0; i--) { + stack.addFirst(split[i]); } } @@ -217,12 +244,6 @@ private void loadViaProfiles(Source source) { } } - private void loadViaPaths(String paths) { - for (String path : splitPaths(paths)) { - loadWithExtensionCheck(loadContext.eval(path)); - } - } - int size() { return loadContext.size(); } diff --git a/avaje-config/src/test/java/io/avaje/config/InitialLoaderTest.java b/avaje-config/src/test/java/io/avaje/config/InitialLoaderTest.java index 11cc2f17..f2161c24 100644 --- a/avaje-config/src/test/java/io/avaje/config/InitialLoaderTest.java +++ b/avaje-config/src/test/java/io/avaje/config/InitialLoaderTest.java @@ -138,4 +138,16 @@ void load_withSuppressTestResource() { System.clearProperty("suppressTestResource"); } } + + @Test + void load_withLoadPropertyChain() { + InitialLoader loader = newInitialLoader(); + loader.loadWithExtensionCheck("test-properties/chain/main.properties"); + var properties = evalFor(loader.load()); + assertThat(properties.get("value.a").value()).isEqualTo("true"); + assertThat(properties.get("value.b").value()).isEqualTo("true"); + assertThat(properties.get("value.c").value()).isEqualTo("true"); + assertThat(properties.get("value.d").value()).isEqualTo("true"); + assertThat(properties.get("override").value()).isEqualTo("d"); + } } diff --git a/avaje-config/src/test/resources/test-properties/chain/a.properties b/avaje-config/src/test/resources/test-properties/chain/a.properties new file mode 100644 index 00000000..6202d504 --- /dev/null +++ b/avaje-config/src/test/resources/test-properties/chain/a.properties @@ -0,0 +1,3 @@ +value.a=true +override=a +load.properties=test-properties/chain/c.properties diff --git a/avaje-config/src/test/resources/test-properties/chain/b.properties b/avaje-config/src/test/resources/test-properties/chain/b.properties new file mode 100644 index 00000000..c41fe6ad --- /dev/null +++ b/avaje-config/src/test/resources/test-properties/chain/b.properties @@ -0,0 +1,3 @@ +value.b=true +override=b +load.properties=test-properties/chain/c.properties diff --git a/avaje-config/src/test/resources/test-properties/chain/c.properties b/avaje-config/src/test/resources/test-properties/chain/c.properties new file mode 100644 index 00000000..eedbcce3 --- /dev/null +++ b/avaje-config/src/test/resources/test-properties/chain/c.properties @@ -0,0 +1,2 @@ +value.c=true +override=c diff --git a/avaje-config/src/test/resources/test-properties/chain/d.properties b/avaje-config/src/test/resources/test-properties/chain/d.properties new file mode 100644 index 00000000..8eb728c8 --- /dev/null +++ b/avaje-config/src/test/resources/test-properties/chain/d.properties @@ -0,0 +1,2 @@ +value.d=true +override=d diff --git a/avaje-config/src/test/resources/test-properties/chain/main.properties b/avaje-config/src/test/resources/test-properties/chain/main.properties new file mode 100644 index 00000000..9911ad48 --- /dev/null +++ b/avaje-config/src/test/resources/test-properties/chain/main.properties @@ -0,0 +1 @@ +load.properties=test-properties/chain/a.properties test-properties/chain/b.properties, test-properties/chain/d.properties \ No newline at end of file